From 2c7188732d7c62a0b04bc972c3b161442e693e28 Mon Sep 17 00:00:00 2001 From: dan <Dan Kennedy> Date: Tue, 22 Jun 2021 18:32:05 +0000 Subject: [PATCH] Add the sqlite3_changes64() and sqlite3_total_changes64() API functions. FossilOrigin-Name: 48fdec22c966003f5577e0bf52906ef90df11e4e395723a646304e67ed976f37 --- manifest | 34 +++++++++++++++++----------------- manifest.uuid | 2 +- src/btree.c | 4 ++-- src/btree.h | 2 +- src/func.c | 2 +- src/main.c | 10 ++++++++-- src/sqlite.h.in | 21 +++++++++++++++------ src/sqliteInt.h | 6 +++--- src/tclsqlite.c | 4 ++-- src/vacuum.c | 4 ++-- src/vdbe.c | 2 +- src/vdbeInt.h | 6 +++--- src/vdbeaux.c | 2 +- test/changes.test | 6 ++++++ 14 files changed, 63 insertions(+), 42 deletions(-) diff --git a/manifest b/manifest index 6b799dd407..9a44b2b29f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\scausing\ssqlite3_changes()\sto\sreturn\san\sincorrect\svalue\sfollowing\sa\s"DELETE\sFROM\stbl"\scommand\son\san\sintkey\stable\s(because\sinternal\sb+tree\scells\swere\sbeing\sincluded\sin\sthe\scount). -D 2021-06-22T18:06:23.070 +C Add\sthe\ssqlite3_changes64()\sand\ssqlite3_total_changes64()\sAPI\sfunctions. +D 2021-06-22T18:32:05.878 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,8 +485,8 @@ F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 34f14b261a0de31a2c195c88a698e940e93e112c137845c620a7149fde493300 -F src/btree.h ace9c1c243612bb95c32d848e3f9e159340c2caefcb68412b441569f56328f65 +F src/btree.c e204a9c8fb4fe5dbb910a863ba487f4af9b5c501254ec4ccbfcdd6b1f65b7fb4 +F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 F src/build.c ea28944f65b04f771e7aa5d614d406faa1bde5fe4ce882e2ead73049f03ed568 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c @@ -499,7 +499,7 @@ F src/delete.c 62451bba9fe641159e9c0b7d9d2bab1c48d0cff11e16de2d14000603d2af1fcf F src/expr.c 30a2abf526531ce6bd45fbc85bfec0fc3f6e5a0fb490cd2350855f2fc34dd789 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 -F src/func.c 9eb67f0aaf1cf439c21d6fc8afe270973d6e8345af3f1ebda98ad42186d30f5b +F src/func.c 29264c728fc02a167eabc7c30c6c7719d8c9020f7ce5795061d25cf3322ed2d8 F src/global.c 25ba4d58476f6be29bba9d9d14f7f146b78476d3a4d75ebb8c3b736328afe0f9 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -508,7 +508,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 2189e0e596010a0dc5405d9f14f78db1ee2fa71138c931f5b6ea96610b95bfc1 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 12684b3f19cd103cea97cdf14d0758196d0c646e12a898d7245141a9abfde9a4 -F src/main.c 9c06f8dc6137aaa990692ce30db1c00c3e6a574c5a4756640625c19b507c65ec +F src/main.c c49a03dc832c479fbdce6f0bb51f20ac3c7c2541a956c8cba68a2f61c4d23ba6 F src/malloc.c cbc93cdd429c4594912017d92ab656e2579aca64dbd1c6888551275bed46f25b F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -546,14 +546,14 @@ F src/resolve.c 35630effd4d16d2373caa41bae40a3d71f853f3ad0cb4f572f2ed4b8c350c1e9 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 4fa607bab6bcc580f12dbaf9c800b2250a1e408f10321a1d3bcb1dd30c447e62 F src/shell.c.in f3e91c697f33daae14923355dcadfc26bb0c1eabdb343e5508706893e017a0a6 -F src/sqlite.h.in 8549395aa13361d5dcea04e3a57d680af10f7ee0989c45ebfffe3a3bcb2cdc3d +F src/sqlite.h.in ee3df0ee7aa8ca2364377861bfa0ebd33b86c34d212f915147df9fc6a09b980f F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h ab37a8dd95884fc25ef1eb7b6d53d6674905c67298affc2b5bf947f739096504 +F src/sqliteInt.h fccf952bd572fe52f3bd2928982bd80933308c1118fdde27f667d0de7c77fb30 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c 97645e4a15dde6a6ad6de8d81057ff9869413b866015a89e208fedacd709493e +F src/tclsqlite.c 05663f6b5010b044eac0ef22fc8fb5ea3406d2502700a898261683258042c88b F src/test1.c 2100f4c28bae21ce83a9a0c5ec6827efd0e15d11b93b569b614daa5654b3fcf6 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 @@ -615,12 +615,12 @@ F src/update.c 56fa0458b1ffc1042629f926443e8ed44203983df3ab2b0db2ba556e6ceed68c F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 -F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c 226deb5bc5d88c4feb215cccaecdbe36924078737f27629fa06123d4da10f609 +F src/vacuum.c 454973a59fb20bb982efc2df568a098616db6328a0491b6e84e2e07f7333db45 +F src/vdbe.c e86894469af9c4c7824832df00f38ef727f6127080c69a7ad2f06d519c6db9aa F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe -F src/vdbeInt.h 465fcb494db4ca6630fb9c19b2f3dfed597fbe885b0d4204193a5093b0dd7dc6 +F src/vdbeInt.h 1fc1e3581afcd3f56bdbe930639edac84ee823c034f31da97f49c35522f4c8c2 F src/vdbeapi.c aa5aaf2c37676b83af5724c6cd8207a3064ed46a217fd180957f75ac84f7a2a5 -F src/vdbeaux.c 17e5f6a491d439396296dd20427829fad14c78a6be8f84415d253ff94c31ce9a +F src/vdbeaux.c 23f9800742b11eb6d1d775fd332a88252e44e9f7ba94b826e211a5d9dbfe0ced F src/vdbeblob.c c6b8db50b227f66fb404215732068df76485b5b433e5f9d4d9ac27410b218193 F src/vdbemem.c 53881aa0a7845922a075b3f375695588618098871a7a4120af4c297b80fa3e64 F src/vdbesort.c cd5130f683706c1a43e165a74187745fb3351cb56052cf9dc91de820634bbde2 @@ -756,7 +756,7 @@ F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/carray01.test 3f2658bbddd75a013735a296ae2178ff441aca3f00ba623cfbae00b732ede792 F test/cast.test 336fa21989b5170ebcaf90c24266be22dd97b3e23d1fad5ecf6ad4efb04c4423 F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef -F test/changes.test 5d39e302b1d8047897961fdd682b4ce74a8abae6a7ba921a949d12ad0c4a9673 +F test/changes.test 9dd8e597d84072122fc8a4fcdea837f4a54a461e6e536053ea984303e8ca937b F test/check.test 4a2a91ed67eee84a6be16057c48d5198b6fb24849cd6da6cd855981de3fbb416 F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014 F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760 @@ -1919,7 +1919,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 53f64e83b39cb56ac7211ffc80d06da13318e1da9dbca7b9123954f5be229a0d -R b8b931728b78e63830e81de935919c1c +P f662ff4746aaa43e63e20710b8cbfeeceab3183e953ac1685c41846d2e9d124c +R d7ab321cd3717ae98c57b82526dde848 U dan -Z 0889b85b76d9b21be2f69e6657d9c993 +Z 21b9ccfdea30ed9e9c32e68e5722010b diff --git a/manifest.uuid b/manifest.uuid index 698f3426e2..a38d536818 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f662ff4746aaa43e63e20710b8cbfeeceab3183e953ac1685c41846d2e9d124c \ No newline at end of file +48fdec22c966003f5577e0bf52906ef90df11e4e395723a646304e67ed976f37 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index f6e6ec545f..57c556cc26 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9543,7 +9543,7 @@ static int clearDatabasePage( BtShared *pBt, /* The BTree that contains the table */ Pgno pgno, /* Page number to clear */ int freePageFlag, /* Deallocate page if true */ - int *pnChange /* Add number of Cells freed to this counter */ + i64 *pnChange /* Add number of Cells freed to this counter */ ){ MemPage *pPage; int rc; @@ -9606,7 +9606,7 @@ cleardatabasepage_out: ** If pnChange is not NULL, then the integer value pointed to by pnChange ** is incremented by the number of entries in the table. */ -int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ +int sqlite3BtreeClearTable(Btree *p, int iTable, i64 *pnChange){ int rc; BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); diff --git a/src/btree.h b/src/btree.h index fe724d6bb5..f80ba4a97b 100644 --- a/src/btree.h +++ b/src/btree.h @@ -123,7 +123,7 @@ int sqlite3BtreeIncrVacuum(Btree *); #define BTREE_BLOBKEY 2 /* Table has keys only - no data */ int sqlite3BtreeDropTable(Btree*, int, int*); -int sqlite3BtreeClearTable(Btree*, int, int*); +int sqlite3BtreeClearTable(Btree*, int, i64*); int sqlite3BtreeClearTableOfCursor(BtCursor*); int sqlite3BtreeTripAllCursors(Btree*, int, int); diff --git a/src/func.c b/src/func.c index dc19ec7222..807b4574a1 100644 --- a/src/func.c +++ b/src/func.c @@ -582,7 +582,7 @@ static void changes( ){ sqlite3 *db = sqlite3_context_db_handle(context); UNUSED_PARAMETER2(NotUsed, NotUsed2); - sqlite3_result_int(context, sqlite3_changes(db)); + sqlite3_result_int64(context, sqlite3_changes64(db)); } /* diff --git a/src/main.c b/src/main.c index a04a6bc0f2..f73f103f2a 100644 --- a/src/main.c +++ b/src/main.c @@ -1086,7 +1086,7 @@ void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid){ /* ** Return the number of changes in the most recent call to sqlite3_exec(). */ -int sqlite3_changes(sqlite3 *db){ +sqlite3_int64 sqlite3_changes64(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; @@ -1095,11 +1095,14 @@ int sqlite3_changes(sqlite3 *db){ #endif return db->nChange; } +int sqlite3_changes(sqlite3 *db){ + return (int)sqlite3_changes64(db); +} /* ** Return the number of changes since the database handle was opened. */ -int sqlite3_total_changes(sqlite3 *db){ +sqlite3_int64 sqlite3_total_changes64(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; @@ -1108,6 +1111,9 @@ int sqlite3_total_changes(sqlite3 *db){ #endif return db->nTotalChange; } +int sqlite3_total_changes(sqlite3 *db){ + return (int)sqlite3_total_changes64(db); +} /* ** Close all open savepoints. This function only manipulates fields of the diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f8037a2d94..28c4bf01ef 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2464,11 +2464,14 @@ void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** CAPI3REF: Count The Number Of Rows Modified ** METHOD: sqlite3 ** -** ^This function returns the number of rows modified, inserted or +** ^These functions return the number of rows modified, inserted or ** deleted by the most recently completed INSERT, UPDATE or DELETE ** statement on the database connection specified by the only parameter. -** ^Executing any other type of SQL statement does not modify the value -** returned by this function. +** The two functions are identical except for the type of the return value +** and that if the number of rows modified by the most recent INSERT, UPDATE +** or DELETE is greater than the maximum value supported by type "int", then +** the return value of sqlite3_changes() is undefined. ^Executing any other +** type of SQL statement does not modify the value returned by these functions. ** ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are ** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], @@ -2517,16 +2520,21 @@ void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** </ul> */ int sqlite3_changes(sqlite3*); +sqlite3_int64 sqlite3_changes64(sqlite3*); /* ** CAPI3REF: Total Number Of Rows Modified ** METHOD: sqlite3 ** -** ^This function returns the total number of rows inserted, modified or +** ^These functions return the total number of rows inserted, modified or ** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed ** since the database connection was opened, including those executed as -** part of trigger programs. ^Executing any other type of SQL statement -** does not affect the value returned by sqlite3_total_changes(). +** part of trigger programs. The two functions are identical except for the +** type of the return value and that if the number of rows modified by the +** connection exceeds the maximum value supported by type "int", then +** the return value of sqlite3_total_changes() is undefined. ^Executing +** any other type of SQL statement does not affect the value returned by +** sqlite3_total_changes(). ** ** ^Changes made as part of [foreign key actions] are included in the ** count, but those made as part of REPLACE constraint resolution are @@ -2554,6 +2562,7 @@ int sqlite3_changes(sqlite3*); ** </ul> */ int sqlite3_total_changes(sqlite3*); +sqlite3_int64 sqlite3_total_changes64(sqlite3*); /* ** CAPI3REF: Interrupt A Long-Running Query diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 91af412bbd..6906d7ed57 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1522,8 +1522,8 @@ struct sqlite3 { 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() */ - int nTotalChange; /* Value returned by sqlite3_total_changes() */ + i64 nChange; /* Value returned by sqlite3_changes() */ + i64 nTotalChange; /* Value returned by sqlite3_total_changes() */ int aLimit[SQLITE_N_LIMIT]; /* Limits */ int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */ struct sqlite3InitInfo { /* Information used during initialization */ @@ -4741,7 +4741,7 @@ Expr *sqlite3ExprSkipCollateAndLikely(Expr*); int sqlite3CheckCollSeq(Parse *, CollSeq *); int sqlite3WritableSchema(sqlite3*); int sqlite3CheckObjectName(Parse*, const char*,const char*,const char*); -void sqlite3VdbeSetChanges(sqlite3 *, int); +void sqlite3VdbeSetChanges(sqlite3 *, i64); int sqlite3AddInt64(i64*,i64); int sqlite3SubInt64(i64*,i64); int sqlite3MulInt64(i64*,i64); diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 2206bca321..8874ab7699 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2207,7 +2207,7 @@ static int SQLITE_TCLAPI DbObjCmd( return TCL_ERROR; } pResult = Tcl_GetObjResult(interp); - Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db)); + Tcl_SetWideIntObj(pResult, sqlite3_changes64(pDb->db)); break; } @@ -3255,7 +3255,7 @@ deserialize_error: return TCL_ERROR; } pResult = Tcl_GetObjResult(interp); - Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db)); + Tcl_SetWideIntObj(pResult, sqlite3_total_changes64(pDb->db)); break; } diff --git a/src/vacuum.c b/src/vacuum.c index 93e2307d1a..be0e17535d 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -151,8 +151,8 @@ SQLITE_NOINLINE int sqlite3RunVacuum( Btree *pTemp; /* The temporary database we vacuum into */ u32 saved_mDbFlags; /* Saved value of db->mDbFlags */ u64 saved_flags; /* Saved value of db->flags */ - int saved_nChange; /* Saved value of db->nChange */ - int saved_nTotalChange; /* Saved value of db->nTotalChange */ + i64 saved_nChange; /* Saved value of db->nChange */ + i64 saved_nTotalChange; /* Saved value of db->nTotalChange */ u32 saved_openFlags; /* Saved value of db->openFlags */ u8 saved_mTrace; /* Saved trace settings */ Db *pDb = 0; /* Database to detach at end of vacuum */ diff --git a/src/vdbe.c b/src/vdbe.c index 6623009aac..e21e0a55f0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6250,7 +6250,7 @@ case OP_Destroy: { /* out2 */ ** See also: Destroy */ case OP_Clear: { - int nChange; + i64 nChange; sqlite3VdbeIncrWriteCounter(p, 0); nChange = 0; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index b6e0288807..4a41c43a52 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -180,8 +180,8 @@ struct VdbeFrame { int nMem; /* Number of entries in aMem */ int nChildMem; /* Number of memory cells for child frame */ int nChildCsr; /* Number of cursors for child frame */ - int nChange; /* Statement changes (Vdbe.nChange) */ - int nDbChange; /* Value of db->nChange */ + i64 nChange; /* Statement changes (Vdbe.nChange) */ + i64 nDbChange; /* Value of db->nChange */ }; /* Magic number for sanity checking on VdbeFrame objects */ @@ -388,7 +388,7 @@ struct Vdbe { 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 */ + i64 nChange; /* Number of db changes made since last reset */ int iStatement; /* Statement number (or 0 if has no opened stmt) */ i64 iCurrentTime; /* Value of julianday('now') for this statement */ i64 nFkConstraint; /* Number of imm. FK constraints this VM */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index edbf062749..7f08b5d25b 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -5009,7 +5009,7 @@ int sqlite3VdbeIdxKeyCompare( ** This routine sets the value to be returned by subsequent calls to ** sqlite3_changes() on the database handle 'db'. */ -void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){ +void sqlite3VdbeSetChanges(sqlite3 *db, i64 nChange){ assert( sqlite3_mutex_held(db->mutex) ); db->nChange = nChange; db->nTotalChange += nChange; diff --git a/test/changes.test b/test/changes.test index 3b31c50c0d..21db075f96 100644 --- a/test/changes.test +++ b/test/changes.test @@ -16,6 +16,12 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix changes +# To test that the change-counters do not suffer from 32-bit signed integer +# rollover, add the following line to the array of test cases below. The +# test will take will over an hour to run. +# +# 7 (1<<31)+10 "" +# foreach {tn nRow wor} { 1 50 ""