mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Merge latest trunk changes into this branch.
FossilOrigin-Name: 6232519899efc568465d8fcc9fcd79d46a2ce4ec05109d26d5eb1ebd239cd596
This commit is contained in:
@@ -133,6 +133,7 @@ struct Rtree {
|
||||
u32 nBusy; /* Current number of users of this structure */
|
||||
i64 nRowEst; /* Estimated number of rows in this table */
|
||||
u32 nCursor; /* Number of open cursors */
|
||||
u32 nNodeRef; /* Number RtreeNodes with positive nRef */
|
||||
char *zReadAuxSql; /* SQL for statement to read aux data */
|
||||
|
||||
/* List of nodes removed during a CondenseTree operation. List is
|
||||
@@ -534,6 +535,7 @@ static int writeInt64(u8 *p, i64 i){
|
||||
*/
|
||||
static void nodeReference(RtreeNode *p){
|
||||
if( p ){
|
||||
assert( p->nRef>0 );
|
||||
p->nRef++;
|
||||
}
|
||||
}
|
||||
@@ -601,6 +603,7 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
|
||||
memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize);
|
||||
pNode->zData = (u8 *)&pNode[1];
|
||||
pNode->nRef = 1;
|
||||
pRtree->nNodeRef++;
|
||||
pNode->pParent = pParent;
|
||||
pNode->isDirty = 1;
|
||||
nodeReference(pParent);
|
||||
@@ -634,10 +637,10 @@ static int nodeAcquire(
|
||||
/* Check if the requested node is already in the hash table. If so,
|
||||
** increase its reference count and return it.
|
||||
*/
|
||||
if( (pNode = nodeHashLookup(pRtree, iNode)) ){
|
||||
if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
|
||||
assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
|
||||
if( pParent && !pNode->pParent ){
|
||||
nodeReference(pParent);
|
||||
pParent->nRef++;
|
||||
pNode->pParent = pParent;
|
||||
}
|
||||
pNode->nRef++;
|
||||
@@ -676,6 +679,7 @@ static int nodeAcquire(
|
||||
pNode->pParent = pParent;
|
||||
pNode->zData = (u8 *)&pNode[1];
|
||||
pNode->nRef = 1;
|
||||
pRtree->nNodeRef++;
|
||||
pNode->iNode = iNode;
|
||||
pNode->isDirty = 0;
|
||||
pNode->pNext = 0;
|
||||
@@ -716,7 +720,10 @@ static int nodeAcquire(
|
||||
}
|
||||
*ppNode = pNode;
|
||||
}else{
|
||||
if( pNode ){
|
||||
pRtree->nNodeRef--;
|
||||
sqlite3_free(pNode);
|
||||
}
|
||||
*ppNode = 0;
|
||||
}
|
||||
|
||||
@@ -813,8 +820,10 @@ static int nodeRelease(Rtree *pRtree, RtreeNode *pNode){
|
||||
int rc = SQLITE_OK;
|
||||
if( pNode ){
|
||||
assert( pNode->nRef>0 );
|
||||
assert( pRtree->nNodeRef>0 );
|
||||
pNode->nRef--;
|
||||
if( pNode->nRef==0 ){
|
||||
pRtree->nNodeRef--;
|
||||
if( pNode->iNode==1 ){
|
||||
pRtree->iDepth = -1;
|
||||
}
|
||||
@@ -931,8 +940,9 @@ static void rtreeRelease(Rtree *pRtree){
|
||||
pRtree->nBusy--;
|
||||
if( pRtree->nBusy==0 ){
|
||||
pRtree->inWrTrans = 0;
|
||||
pRtree->nCursor = 0;
|
||||
assert( pRtree->nCursor==0 );
|
||||
nodeBlobReset(pRtree);
|
||||
assert( pRtree->nNodeRef==0 );
|
||||
sqlite3_finalize(pRtree->pWriteNode);
|
||||
sqlite3_finalize(pRtree->pDeleteNode);
|
||||
sqlite3_finalize(pRtree->pReadRowid);
|
||||
@@ -1894,6 +1904,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
*/
|
||||
pIdxInfo->estimatedCost = 30.0;
|
||||
pIdxInfo->estimatedRows = 1;
|
||||
pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -2473,7 +2484,7 @@ static int SplitNode(
|
||||
}else{
|
||||
pLeft = pNode;
|
||||
pRight = nodeNew(pRtree, pLeft->pParent);
|
||||
nodeReference(pLeft);
|
||||
pLeft->nRef++;
|
||||
}
|
||||
|
||||
if( !pLeft || !pRight ){
|
||||
@@ -2963,6 +2974,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
|
||||
rc = reinsertNodeContent(pRtree, pLeaf);
|
||||
}
|
||||
pRtree->pDeleted = pLeaf->pNext;
|
||||
pRtree->nNodeRef--;
|
||||
sqlite3_free(pLeaf);
|
||||
}
|
||||
|
||||
@@ -3067,6 +3079,12 @@ static int rtreeUpdate(
|
||||
RtreeCell cell; /* New cell to insert if nData>1 */
|
||||
int bHaveRowid = 0; /* Set to 1 after new rowid is determined */
|
||||
|
||||
if( pRtree->nNodeRef ){
|
||||
/* Unable to write to the btree while another cursor is reading from it,
|
||||
** since the write might do a rebalance which would disrupt the read
|
||||
** cursor. */
|
||||
return SQLITE_LOCKED_VTAB;
|
||||
}
|
||||
rtreeReference(pRtree);
|
||||
assert(nData>=1);
|
||||
|
||||
|
@@ -476,11 +476,11 @@ foreach {tn sql_template testdata} {
|
||||
}
|
||||
|
||||
3 "UPDATE %CONF% t1 SET idx = 2 WHERE idx = 4" {
|
||||
ROLLBACK 1 1 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6}
|
||||
ABORT 1 1 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7}
|
||||
IGNORE 1 0 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7}
|
||||
FAIL 1 1 {1 1 2 3 4 2 2 3 4 5 3 3 4 5 6 4 4 5 6 7}
|
||||
REPLACE 1 0 {1 1 2 3 4 2 4 5 6 7 3 3 4 5 6}
|
||||
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}
|
||||
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 0 {1 1 2 3 4 2 4 5 6 7 3 3 4 5 6}
|
||||
}
|
||||
|
||||
3 "UPDATE %CONF% t1 SET idx = ((idx+1)%5)+1 WHERE idx > 2" {
|
||||
|
@@ -38,11 +38,20 @@ do_test rtree8-1.1.1 {
|
||||
} {}
|
||||
do_test rtree8-1.1.2 {
|
||||
set res [list]
|
||||
set rc [catch {
|
||||
db eval { SELECT * FROM t1 } {
|
||||
lappend res $x1 $x2
|
||||
if {$id==3} { db eval { DELETE FROM t1 WHERE id>3 } }
|
||||
}
|
||||
set res
|
||||
} msg];
|
||||
lappend rc $msg
|
||||
set rc
|
||||
} {1 {database table is locked}}
|
||||
do_test rtree8-1.1.2b {
|
||||
db eval { SELECT * FROM t1 ORDER BY +id } {
|
||||
if {$id==3} { db eval { DELETE FROM t1 WHERE id>3 } }
|
||||
}
|
||||
db eval {SELECT x1, x2 FROM t1}
|
||||
} {1 3 2 4 3 5}
|
||||
do_test rtree8-1.1.3 {
|
||||
execsql { SELECT * FROM t1 }
|
||||
@@ -170,5 +179,29 @@ do_test rtree8-5.4 {
|
||||
} {}
|
||||
do_rtree_integrity_test rtree8-5.5 t2
|
||||
|
||||
# 2018-05-24
|
||||
# The following script caused an assertion fault and/or segfault
|
||||
# prior to the fix that prevents simultaneous reads and writes on
|
||||
# the same rtree virtual table.
|
||||
#
|
||||
do_test rtree8-6.1 {
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
db eval {
|
||||
PRAGMA page_size=512;
|
||||
CREATE VIRTUAL TABLE t1 USING rtree(id,x1,x2,y1,y2);
|
||||
WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<49)
|
||||
INSERT INTO t1 SELECT x, x, x+1, x, x+1 FROM c;
|
||||
}
|
||||
set rc [catch {
|
||||
db eval {SELECT id FROM t1} x {
|
||||
db eval {DELETE FROM t1 WHERE id=$x(id)}
|
||||
}
|
||||
} msg]
|
||||
lappend rc $msg
|
||||
} {1 {database table is locked}}
|
||||
|
||||
|
||||
|
||||
|
||||
finish_test
|
||||
|
34
manifest
34
manifest
@@ -1,5 +1,5 @@
|
||||
C Fixes\sfor\s"ROWS\sBETWEEN\s<expr>\sFOLLOWING\sAND\s<expr>\sFOLLOWING"\sand\s"ROWS\nBETWEEN\s<expr>\sFOLLOWING\sAND\sUNBOUNDED\sFOLLOWING"
|
||||
D 2018-05-25T09:29:11.361
|
||||
C Merge\slatest\strunk\schanges\sinto\sthis\sbranch.
|
||||
D 2018-05-25T09:36:27.522
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in bfc40f350586923e0419d2ea4b559c37ec10ee4b6e210e08c14401f8e340f0da
|
||||
@@ -355,16 +355,16 @@ F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc782
|
||||
F ext/repair/test/checkindex01.test 6945d0ffc0c1dc993b2ce88036b26e0f5d6fcc65da70fc9df27c2647bb358b0f
|
||||
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
|
||||
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
|
||||
F ext/rtree/rtree.c 148ae743198ca9fe1dfdf2fed74e5c3b0e69330e5b71ddc0d9df9993324dcedc
|
||||
F ext/rtree/rtree.c cb6d4bd43c118354fe5b5213843da058259467ecdbac0c6f71ead0fd89acf4ec
|
||||
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
|
||||
F ext/rtree/rtree1.test 587889855b26fb8637417921b0709ca843cb6d36db94a882371fd8b7dcc3aa0b
|
||||
F ext/rtree/rtree1.test 309afc04d4287542b2cd74f933296832cc681c7b014d9405cb329b62053a5349
|
||||
F ext/rtree/rtree2.test 5f25b01acd03470067a2d52783b2eb0a50bf836803d4342d20ca39e541220fe2
|
||||
F ext/rtree/rtree3.test 4ee5d7df86040efe3d8d84f141f2962a7745452200a7cba1db06f86d97050499
|
||||
F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b
|
||||
F ext/rtree/rtree5.test 49c9041d713d54560b315c2c7ef7207ee287eba1b20f8266968a06f2e55d3142
|
||||
F ext/rtree/rtree6.test 593e0d36510d5ac1d1fb39b018274ff17604fe8fdca8cf1f8e16559cea1477f4
|
||||
F ext/rtree/rtree7.test c8fb2e555b128dd0f0bdb520c61380014f497f8a23c40f2e820acc9f9e4fdce5
|
||||
F ext/rtree/rtree8.test 649f5a37ec656028a4a32674b9b1183104285a7625a09d2a8f52a1cef72c93f2
|
||||
F ext/rtree/rtree8.test 924926d7c64ac59fcca0809de472d9dd73c612f54daae1cf992bdd7dac90305b
|
||||
F ext/rtree/rtree9.test c646f12c8c1c68ef015c6c043d86a0c42488e2e68ed1bb1b0771a7ca246cbabf
|
||||
F ext/rtree/rtreeA.test 20623ca337ca3bd7e008cc9fb49e44dbe97f1a80b238e10a12bb4afcd0da3776
|
||||
F ext/rtree/rtreeB.test 4cec297f8e5c588654bbf3c6ed0903f10612be8a2878055dd25faf8c71758bc9
|
||||
@@ -445,7 +445,7 @@ F src/ctime.c 849d4cebe008cfc6e4799b034a172b4eaf8856b100739632a852732ba66eee48
|
||||
F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
|
||||
F src/dbpage.c 8db4c97f630e7d83f884ea75caf1ffd0988c160e9d530194d93721c80821e0f6
|
||||
F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91
|
||||
F src/delete.c b0f90749e22d5e41a12dbf940f4811138cf97da54b46b737089b93eb64a2896f
|
||||
F src/delete.c 4c8c7604277a2041647f96b78f4b9a47858e9217e4fb333d35e7b5ab32c5b57f
|
||||
F src/expr.c bb57b0b5ba1351335091ce4ec43b40968746f03afd65c9e2920d7cbe4dc98133
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331
|
||||
@@ -455,7 +455,7 @@ F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
|
||||
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
||||
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 33a2c72b6182e8ddf697d604cc087c77ff5fc512a32b8b624641d41b390e249e
|
||||
F src/insert.c 25f2e3cb93821944dec28921c4cfb7729b3ac6e75d860fd7cd934265404a35b0
|
||||
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
|
||||
F src/loadext.c 6aae5739198d96c51ae6eb97c4a5b1744c22ed7a5a565a5399a717780d48a36b
|
||||
F src/main.c b56b2d62d5d11e3f5100b25fca34c13c62a0fe73941f6873454a7fa8a454170d
|
||||
@@ -496,7 +496,7 @@ F src/resolve.c 446f60b2e0d2440bb233d6a69a4ed0f2ad030a4e63ac4b3cfc0e98cf73d9c5a3
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c 8a7f842a049a3407079e0b0748de916dcd91c00377394b2e8b1aefc5972a0b2f
|
||||
F src/shell.c.in 51c100206f4b7f86cd9affd80b764825e0edc36ca0190c442e4ca7994611bfe2
|
||||
F src/sqlite.h.in 34be2d0d18bf4726538793bdc9854cd87f689fda4b3789515134cdbd68188cf4
|
||||
F src/sqlite.h.in e379906b85cc3539c6a37ab972f2c28711b28854a457f54e137d20f75db5db7c
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7
|
||||
F src/sqliteInt.h 735b04170551a899e8703421c376f98c19503b8210ad4cd2e0f35b85b6af595d
|
||||
@@ -531,7 +531,7 @@ F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64
|
||||
F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c
|
||||
F src/test_journal.c 619f2aa10e0d7a5f87c0f06825bc61dfce1c6b9c7f3ad990fb13de6c3b8874a3
|
||||
F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd
|
||||
F src/test_malloc.c 5201422e2403e66a7a9c2b7d8df806acd8d2a0429822adb7e932f324e7b5b3c6
|
||||
F src/test_malloc.c dec0aa821b230773aeb3dd11d652c1193f7cedb18a20b25659bc672288115242
|
||||
F src/test_md5.c 7268e1e8c399d4a5e181b64ac20e1e6f3bc4dd9fc87abac02db145a3d951fa8c
|
||||
F src/test_multiplex.c e054459f7633f3ff8ce1245da724f9a8be189e4e
|
||||
F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635
|
||||
@@ -559,12 +559,12 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c bbde32eac9eb1280f5292bcdfef66f5a57e43176cbf9347e0efab9f75e133f97
|
||||
F src/treeview.c 2c5c4bc0a443401db5fd621542150452ddf5055d38edd4eef868bc2b6bfb0260
|
||||
F src/trigger.c 4ace6d1d5ba9a89822deb287317f33c810440526eafe185c2d8a48c31df1e995
|
||||
F src/update.c 5be2f501ddc704fc04183bdb28b25eab930bb8553d973429a089ec94fa85cf2b
|
||||
F src/update.c 46dc24c6158446aaab45caee09b6d99327cb479268b83ffeb5b701823da3b67b
|
||||
F src/upsert.c ae4a4823b45c4daf87e8aea8c0f582a8844763271f5ed54ee5956c4c612734f4
|
||||
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
|
||||
F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
|
||||
F src/vacuum.c 37730af7540033135909ecaee3667dddec043293428d8718546d0d64ba4a5025
|
||||
F src/vdbe.c 89c76c95a24e2561f5f94ef8530bd0127d512ed56b62932047ef89076d58fa91
|
||||
F src/vdbe.c 976746c8e61744b18e76eb150007014db4577c4659a5fab63b424be2d822cbf7
|
||||
F src/vdbe.h d970d9738efdd09cb2df73e3a40856e7df13e88a3486789c49fcdd322c9eb8a2
|
||||
F src/vdbeInt.h 3878856fab3a8e64d27d472909e391db9d82f4f8b902a1737a1f7f351299ff52
|
||||
F src/vdbeapi.c 29d2baf9c1233131ec467d7bed1b7c8a03c27579048d768c4b04acf427838858
|
||||
@@ -627,7 +627,7 @@ F test/auth.test 3d6cd8f3978ba55b1202574e6ecd79c6e00914ca44b9bfd6c1fe6fb873fcac8
|
||||
F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1
|
||||
F test/auth3.test db21405b95257c24d29273b6b31d0efc59e1d337e3d5804ba2d1fd4897b1ae49
|
||||
F test/autoanalyze1.test b9cc3f32a990fa56669b668d237c6d53e983554ae80c0604992e18869a0b2dec
|
||||
F test/autoinc.test 83aad64411583aac9ff0b629159ab4662029ab4e3f47090fce4efd132b304484
|
||||
F test/autoinc.test c6df81f1de9a5499f912c58e5389d0bcb8d42459df832b65aee24338ad422a42
|
||||
F test/autoindex1.test a09958fa756129af10b6582bcbf3cbdf11e305e027b393f393caef801159dee0
|
||||
F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
|
||||
F test/autoindex3.test 2dd997d6590438b53e4f715f9278aa91c9299cf3f81246a0915269c35beb790e
|
||||
@@ -1279,7 +1279,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef
|
||||
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
|
||||
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
|
||||
F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c
|
||||
F test/speedtest1.c 20cc4028b0e88392b5a635c2ea5d5e777d569bf7258aead37f8be7a886c38344
|
||||
F test/speedtest1.c cc7e6b4a7c9f3e3d1a497ae3f75236a832a2ce0f6a9b017f95d996c821605bfb
|
||||
F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e
|
||||
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
|
||||
F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33
|
||||
@@ -1691,7 +1691,7 @@ F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c
|
||||
F tool/showwal.c ad9d768f96ca6199ad3a8c9562d679680bd032dd01204ea3e5ea6fb931d81847
|
||||
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
|
||||
F tool/spaceanal.tcl 4bfd19aad7eb3ce0372ef0255f58035e0bba4ff5e9acfd763a10c6fb365c8dec
|
||||
F tool/speed-check.sh 4ff9b095cf1a7643f0264e7fb7d23f0b12b7cce587a9de315877c378e90eeaf4
|
||||
F tool/speed-check.sh 27c7fe178d5b2f7c90a04a127907acda0bfe637fa85b13c43e03e5ed39b008b6
|
||||
F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355
|
||||
F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e
|
||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
@@ -1733,7 +1733,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 7b709a989c188dbcf429989a0785294b36c8a7e89b5de8cefc25decf1f5b7f5a
|
||||
R 5f959d7a0a7f70c41b9ccac874921e95
|
||||
P 5ac44872fd5c4f92851e7bf57d7207bb4d67de88ea2b5c746ff97f20bd6352e1 b816023ce07d01024d5769e16db924374a49bf909edd12dc1344a0a1ef693db5
|
||||
R 08a95b4b6cfd3d911449e2174d41c045
|
||||
U dan
|
||||
Z ca20d77c2db1ab2eada699a4eb9123fb
|
||||
Z 91662d48d0166ff2fae671b2e45e9cba
|
||||
|
@@ -1 +1 @@
|
||||
5ac44872fd5c4f92851e7bf57d7207bb4d67de88ea2b5c746ff97f20bd6352e1
|
||||
6232519899efc568465d8fcc9fcd79d46a2ce4ec05109d26d5eb1ebd239cd596
|
@@ -553,13 +553,16 @@ void sqlite3DeleteFrom(
|
||||
if( IsVirtual(pTab) ){
|
||||
const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
|
||||
sqlite3VtabMakeWritable(pParse, pTab);
|
||||
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
|
||||
sqlite3VdbeChangeP5(v, OE_Abort);
|
||||
assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
|
||||
sqlite3MayAbort(pParse);
|
||||
if( eOnePass==ONEPASS_SINGLE && sqlite3IsToplevel(pParse) ){
|
||||
if( eOnePass==ONEPASS_SINGLE ){
|
||||
sqlite3VdbeAddOp1(v, OP_Close, iTabCur);
|
||||
if( sqlite3IsToplevel(pParse) ){
|
||||
pParse->isMultiWrite = 0;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
|
||||
sqlite3VdbeChangeP5(v, OE_Abort);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
|
15
src/insert.c
15
src/insert.c
@@ -226,11 +226,26 @@ static int autoIncBegin(
|
||||
Table *pTab /* The table we are writing to */
|
||||
){
|
||||
int memId = 0; /* Register holding maximum rowid */
|
||||
assert( pParse->db->aDb[iDb].pSchema!=0 );
|
||||
if( (pTab->tabFlags & TF_Autoincrement)!=0
|
||||
&& (pParse->db->mDbFlags & DBFLAG_Vacuum)==0
|
||||
){
|
||||
Parse *pToplevel = sqlite3ParseToplevel(pParse);
|
||||
AutoincInfo *pInfo;
|
||||
Table *pSeqTab = pParse->db->aDb[iDb].pSchema->pSeqTab;
|
||||
|
||||
/* Verify that the sqlite_sequence table exists and is an ordinary
|
||||
** rowid table with exactly two columns.
|
||||
** Ticket d8dc2b3a58cd5dc2918a1d4acb 2018-05-23 */
|
||||
if( pSeqTab==0
|
||||
|| !HasRowid(pSeqTab)
|
||||
|| IsVirtual(pSeqTab)
|
||||
|| pSeqTab->nCol!=2
|
||||
){
|
||||
pParse->nErr++;
|
||||
pParse->rc = SQLITE_CORRUPT_SEQUENCE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pInfo = pToplevel->pAinc;
|
||||
while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
|
||||
|
@@ -504,6 +504,7 @@ int sqlite3_exec(
|
||||
#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
|
||||
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
|
||||
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
|
||||
#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
|
||||
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
|
||||
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
|
||||
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
|
||||
@@ -511,6 +512,7 @@ int sqlite3_exec(
|
||||
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
|
||||
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
|
||||
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
|
||||
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
|
||||
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
|
||||
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
|
||||
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
|
||||
@@ -8533,11 +8535,11 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
|
||||
** method of a [virtual table], then it returns true if and only if the
|
||||
** column is being fetched as part of an UPDATE operation during which the
|
||||
** column value will not change. Applications might use this to substitute
|
||||
** a lighter-weight value to return that the corresponding [xUpdate] method
|
||||
** understands as a "no-change" value.
|
||||
** a return value that is less expensive to compute and that the corresponding
|
||||
** [xUpdate] method understands as a "no-change" value.
|
||||
**
|
||||
** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
|
||||
** the column is not changed by the UPDATE statement, they the xColumn
|
||||
** the column is not changed by the UPDATE statement, then the xColumn
|
||||
** method can optionally return without setting a result, without calling
|
||||
** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
|
||||
** In that case, [sqlite3_value_nochange(X)] will return true for the
|
||||
|
@@ -32,6 +32,8 @@ static struct MemFault {
|
||||
int nRepeat; /* Number of times to repeat the failure */
|
||||
int nBenign; /* Number of benign failures seen since last config */
|
||||
int nFail; /* Number of failures seen since last config */
|
||||
int nOkBefore; /* Successful allocations prior to the first fault */
|
||||
int nOkAfter; /* Successful allocations after a fault */
|
||||
u8 enable; /* True if enabled */
|
||||
int isInstalled; /* True if the fault simulation layer is installed */
|
||||
int isBenignMode; /* True if malloc failures are considered benign */
|
||||
@@ -47,18 +49,32 @@ static void sqlite3Fault(void){
|
||||
cnt++;
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine exists as a place to set a breakpoint that will
|
||||
** fire the first time any malloc() fails on a single test case.
|
||||
** The sqlite3Fault() routine above runs on every malloc() failure.
|
||||
** This routine only runs on the first such failure.
|
||||
*/
|
||||
static void sqlite3FirstFault(void){
|
||||
static int cnt2 = 0;
|
||||
cnt2++;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check to see if a fault should be simulated. Return true to simulate
|
||||
** the fault. Return false if the fault should not be simulated.
|
||||
*/
|
||||
static int faultsimStep(void){
|
||||
if( likely(!memfault.enable) ){
|
||||
memfault.nOkAfter++;
|
||||
return 0;
|
||||
}
|
||||
if( memfault.iCountdown>0 ){
|
||||
memfault.iCountdown--;
|
||||
memfault.nOkBefore++;
|
||||
return 0;
|
||||
}
|
||||
if( memfault.nFail==0 ) sqlite3FirstFault();
|
||||
sqlite3Fault();
|
||||
memfault.nFail++;
|
||||
if( memfault.isBenignMode>0 ){
|
||||
@@ -133,6 +149,8 @@ static void faultsimConfig(int nDelay, int nRepeat){
|
||||
memfault.nRepeat = nRepeat;
|
||||
memfault.nBenign = 0;
|
||||
memfault.nFail = 0;
|
||||
memfault.nOkBefore = 0;
|
||||
memfault.nOkAfter = 0;
|
||||
memfault.enable = nDelay>=0;
|
||||
|
||||
/* Sometimes, when running multi-threaded tests, the isBenignMode
|
||||
|
14
src/update.c
14
src/update.c
@@ -845,7 +845,7 @@ static void updateVirtualTable(
|
||||
int regRowid; /* Register for ephem table rowid */
|
||||
int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */
|
||||
int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */
|
||||
int bOnePass; /* True to use onepass strategy */
|
||||
int eOnePass; /* True to use onepass strategy */
|
||||
int addr; /* Address of OP_OpenEphemeral */
|
||||
|
||||
/* Allocate nArg registers in which to gather the arguments for VUpdate. Then
|
||||
@@ -890,12 +890,16 @@ static void updateVirtualTable(
|
||||
sqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1);
|
||||
}
|
||||
|
||||
bOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
|
||||
eOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
|
||||
|
||||
if( bOnePass ){
|
||||
/* There is no ONEPASS_MULTI on virtual tables */
|
||||
assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
|
||||
|
||||
if( eOnePass ){
|
||||
/* If using the onepass strategy, no-op out the OP_OpenEphemeral coded
|
||||
** above. */
|
||||
sqlite3VdbeChangeToNoop(v, addr);
|
||||
sqlite3VdbeAddOp1(v, OP_Close, iCsr);
|
||||
}else{
|
||||
/* Create a record from the argument register contents and insert it into
|
||||
** the ephemeral table. */
|
||||
@@ -911,7 +915,7 @@ static void updateVirtualTable(
|
||||
}
|
||||
|
||||
|
||||
if( bOnePass==0 ){
|
||||
if( eOnePass==ONEPASS_OFF ){
|
||||
/* End the virtual table scan */
|
||||
sqlite3WhereEnd(pWInfo);
|
||||
|
||||
@@ -931,7 +935,7 @@ static void updateVirtualTable(
|
||||
|
||||
/* End of the ephemeral table scan. Or, if using the onepass strategy,
|
||||
** jump to here if the scan visited zero rows. */
|
||||
if( bOnePass==0 ){
|
||||
if( eOnePass==ONEPASS_OFF ){
|
||||
sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
|
||||
|
@@ -4287,11 +4287,8 @@ case OP_NewRowid: { /* out2 */
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
if( !pC->isTable ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
assert( pC!=0 );
|
||||
assert( pC->isTable );
|
||||
assert( pC->eCurType==CURTYPE_BTREE );
|
||||
assert( pC->uc.pCursor!=0 );
|
||||
{
|
||||
@@ -6751,7 +6748,7 @@ case OP_VFilter: { /* jump */
|
||||
** If the VColumn opcode is being used to fetch the value of
|
||||
** an unchanging column during an UPDATE operation, then the P5
|
||||
** value is 1. Otherwise, P5 is 0. The P5 value is returned
|
||||
** by sqlite3_vtab_nochange() routine can can be used
|
||||
** by sqlite3_vtab_nochange() routine and can be used
|
||||
** by virtual table implementations to return special "no-change"
|
||||
** marks which can be more efficient, depending on the virtual table.
|
||||
*/
|
||||
|
@@ -684,4 +684,159 @@ do_execsql_test autoinc-11.1 {
|
||||
SELECT seq FROM sqlite_sequence WHERE name='t11';
|
||||
} {5}
|
||||
|
||||
# 2018-05-23 ticket d8dc2b3a58cd5dc2918a1d4acbba4676a23ada4c
|
||||
# Does not crash if the sqlite_sequence table schema is missing
|
||||
# or corrupt.
|
||||
#
|
||||
do_test autoinc-12.1 {
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
CREATE TABLE fake_sequence(name TEXT PRIMARY KEY,seq) WITHOUT ROWID;
|
||||
PRAGMA writable_schema=on;
|
||||
UPDATE sqlite_master SET
|
||||
sql=replace(sql,'fake_','sqlite_'),
|
||||
name='sqlite_sequence',
|
||||
tbl_name='sqlite_sequence'
|
||||
WHERE name='fake_sequence';
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
set res [catch {db eval {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
|
||||
INSERT INTO t1(b) VALUES('one');
|
||||
}} msg]
|
||||
lappend res $msg
|
||||
} {1 {database disk image is malformed}}
|
||||
do_test autoinc-12.2 {
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
|
||||
INSERT INTO t1(b) VALUES('one');
|
||||
PRAGMA writable_schema=on;
|
||||
UPDATE sqlite_master SET
|
||||
sql=replace(sql,'sqlite_','x_'),
|
||||
name='x_sequence',
|
||||
tbl_name='x_sequence'
|
||||
WHERE name='sqlite_sequence';
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
set res [catch {db eval {
|
||||
INSERT INTO t1(b) VALUES('two');
|
||||
}} msg]
|
||||
lappend res $msg
|
||||
} {1 {database disk image is malformed}}
|
||||
do_test autoinc-12.3 {
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
|
||||
INSERT INTO t1(b) VALUES('one');
|
||||
PRAGMA writable_schema=on;
|
||||
UPDATE sqlite_master SET
|
||||
sql='CREATE VIRTUAL TABLE sqlite_sequence USING sqlite_dbpage'
|
||||
WHERE name='sqlite_sequence';
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
set res [catch {db eval {
|
||||
INSERT INTO t1(b) VALUES('two');
|
||||
}} msg]
|
||||
lappend res $msg
|
||||
} {1 {database disk image is malformed}}
|
||||
do_test autoinc-12.4 {
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
|
||||
INSERT INTO t1(b) VALUES('one');
|
||||
CREATE TABLE fake(name TEXT PRIMARY KEY,seq) WITHOUT ROWID;
|
||||
}
|
||||
set root1 [db one {SELECT rootpage FROM sqlite_master
|
||||
WHERE name='sqlite_sequence'}]
|
||||
set root2 [db one {SELECT rootpage FROM sqlite_master
|
||||
WHERE name='fake'}]
|
||||
db eval {
|
||||
PRAGMA writable_schema=on;
|
||||
UPDATE sqlite_master SET rootpage=$root2
|
||||
WHERE name='sqlite_sequence';
|
||||
UPDATE sqlite_master SET rootpage=$root1
|
||||
WHERE name='fake';
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
set res [catch {db eval {
|
||||
INSERT INTO t1(b) VALUES('two');
|
||||
}} msg]
|
||||
lappend res $msg
|
||||
} {1 {database disk image is malformed}}
|
||||
breakpoint
|
||||
do_test autoinc-12.5 {
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
|
||||
INSERT INTO t1(b) VALUES('one');
|
||||
PRAGMA writable_schema=on;
|
||||
UPDATE sqlite_master SET
|
||||
sql='CREATE TABLE sqlite_sequence(x)'
|
||||
WHERE name='sqlite_sequence';
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
set res [catch {db eval {
|
||||
INSERT INTO t1(b) VALUES('two');
|
||||
}} msg]
|
||||
lappend res $msg
|
||||
} {1 {database disk image is malformed}}
|
||||
do_test autoinc-12.6 {
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
|
||||
INSERT INTO t1(b) VALUES('one');
|
||||
PRAGMA writable_schema=on;
|
||||
UPDATE sqlite_master SET
|
||||
sql='CREATE TABLE sqlite_sequence(x,y INTEGER PRIMARY KEY)'
|
||||
WHERE name='sqlite_sequence';
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
set res [catch {db eval {
|
||||
INSERT INTO t1(b) VALUES('two'),('three'),('four');
|
||||
INSERT INTO t1(b) VALUES('five');
|
||||
PRAGMA integrity_check;
|
||||
}} msg]
|
||||
lappend res $msg
|
||||
} {0 ok}
|
||||
do_test autoinc-12.7 {
|
||||
db close
|
||||
forcedelete test.db
|
||||
sqlite3 db test.db
|
||||
db eval {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
|
||||
INSERT INTO t1(b) VALUES('one');
|
||||
PRAGMA writable_schema=on;
|
||||
UPDATE sqlite_master SET
|
||||
sql='CREATE TABLE sqlite_sequence(y INTEGER PRIMARY KEY,x)'
|
||||
WHERE name='sqlite_sequence';
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
set res [catch {db eval {
|
||||
INSERT INTO t1(b) VALUES('two'),('three'),('four');
|
||||
INSERT INTO t1(b) VALUES('five');
|
||||
PRAGMA integrity_check;
|
||||
}} msg]
|
||||
lappend res $msg
|
||||
} {0 ok}
|
||||
|
||||
finish_test
|
||||
|
@@ -1247,10 +1247,11 @@ void testset_rtree(int p1, int p2){
|
||||
unsigned mxCoord;
|
||||
unsigned x0, x1, y0, y1, z0, z1;
|
||||
unsigned iStep;
|
||||
unsigned mxRowid;
|
||||
int *aCheck = sqlite3_malloc( sizeof(int)*g.szTest*500 );
|
||||
|
||||
mxCoord = 15000;
|
||||
n = g.szTest*500;
|
||||
mxRowid = 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)");
|
||||
@@ -1277,7 +1278,7 @@ void testset_rtree(int p1, int p2){
|
||||
speedtest1_exec("INSERT INTO t1 SELECT * FROM rt1");
|
||||
speedtest1_end_test();
|
||||
|
||||
n = g.szTest*100;
|
||||
n = g.szTest*200;
|
||||
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;
|
||||
@@ -1290,7 +1291,7 @@ void testset_rtree(int p1, int p2){
|
||||
speedtest1_end_test();
|
||||
|
||||
if( g.bVerify ){
|
||||
n = g.szTest*100;
|
||||
n = g.szTest*200;
|
||||
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;
|
||||
@@ -1306,7 +1307,7 @@ void testset_rtree(int p1, int p2){
|
||||
speedtest1_end_test();
|
||||
}
|
||||
|
||||
n = g.szTest*100;
|
||||
n = g.szTest*200;
|
||||
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;
|
||||
@@ -1319,7 +1320,7 @@ void testset_rtree(int p1, int p2){
|
||||
speedtest1_end_test();
|
||||
|
||||
if( g.bVerify ){
|
||||
n = g.szTest*100;
|
||||
n = g.szTest*200;
|
||||
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;
|
||||
@@ -1336,7 +1337,7 @@ void testset_rtree(int p1, int p2){
|
||||
}
|
||||
|
||||
|
||||
n = g.szTest*100;
|
||||
n = g.szTest*200;
|
||||
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)");
|
||||
@@ -1373,6 +1374,52 @@ void testset_rtree(int p1, int p2){
|
||||
speedtest1_run();
|
||||
}
|
||||
speedtest1_end_test();
|
||||
|
||||
n = g.szTest*50;
|
||||
speedtest1_begin_test(150, "%d UPDATEs using rowid", n);
|
||||
speedtest1_prepare("UPDATE rt1 SET x0=x0+100, x1=x1+100 WHERE id=?1");
|
||||
for(i=1; i<=n; i++){
|
||||
sqlite3_bind_int(g.pStmt, 1, (i*251)%mxRowid + 1);
|
||||
speedtest1_run();
|
||||
}
|
||||
speedtest1_end_test();
|
||||
|
||||
n = g.szTest*5;
|
||||
speedtest1_begin_test(155, "%d UPDATEs using one-dimensional overlap", n);
|
||||
speedtest1_prepare("UPDATE rt1 SET x0=x0-100, x1=x1-100"
|
||||
" WHERE y1>=?1 AND y0<=?1+5");
|
||||
iStep = mxCoord/n;
|
||||
for(i=0; i<n; i++){
|
||||
sqlite3_bind_int(g.pStmt, 1, i*iStep);
|
||||
speedtest1_run();
|
||||
aCheck[i] = atoi(g.zResult);
|
||||
}
|
||||
speedtest1_end_test();
|
||||
|
||||
n = g.szTest*50;
|
||||
speedtest1_begin_test(160, "%d DELETEs using rowid", n);
|
||||
speedtest1_prepare("DELETE FROM rt1 WHERE id=?1");
|
||||
for(i=1; i<=n; i++){
|
||||
sqlite3_bind_int(g.pStmt, 1, (i*257)%mxRowid + 1);
|
||||
speedtest1_run();
|
||||
}
|
||||
speedtest1_end_test();
|
||||
|
||||
|
||||
n = g.szTest*5;
|
||||
speedtest1_begin_test(165, "%d DELETEs using one-dimensional overlap", n);
|
||||
speedtest1_prepare("DELETE FROM rt1 WHERE y1>=?1 AND y0<=?1+5");
|
||||
iStep = mxCoord/n;
|
||||
for(i=0; i<n; i++){
|
||||
sqlite3_bind_int(g.pStmt, 1, i*iStep);
|
||||
speedtest1_run();
|
||||
aCheck[i] = atoi(g.zResult);
|
||||
}
|
||||
speedtest1_end_test();
|
||||
|
||||
speedtest1_begin_test(170, "Restore deleted entries using INSERT OR IGNORE");
|
||||
speedtest1_exec("INSERT OR IGNORE INTO rt1 SELECT * FROM t1");
|
||||
speedtest1_end_test();
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_RTREE */
|
||||
|
||||
|
@@ -41,8 +41,12 @@ doExplain=0
|
||||
doCachegrind=1
|
||||
doVdbeProfile=0
|
||||
doWal=1
|
||||
doDiff=1
|
||||
while test "$1" != ""; do
|
||||
case $1 in
|
||||
--nodiff)
|
||||
doDiff=0
|
||||
;;
|
||||
--reprepare)
|
||||
SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
|
||||
;;
|
||||
@@ -179,6 +183,6 @@ if test $doVdbeProfile -eq 1; then
|
||||
tclsh ../sqlite/tool/vdbe_profile.tcl >vdbeprofile-$NAME.txt
|
||||
open vdbeprofile-$NAME.txt
|
||||
fi
|
||||
if test "$NAME" != "$BASELINE" -a $doVdbeProfile -ne 1; then
|
||||
if test "$NAME" != "$BASELINE" -a $doVdbeProfile -ne 1 -a $doDiff -ne 0; then
|
||||
fossil test-diff --tk -c 20 cout-$BASELINE.txt cout-$NAME.txt
|
||||
fi
|
||||
|
Reference in New Issue
Block a user