]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Split the (internal) sqlite3VdbeCheckFk() routine into two variants,
authordrh <>
Sat, 19 Jul 2025 18:46:03 +0000 (18:46 +0000)
committerdrh <>
Sat, 19 Jul 2025 18:46:03 +0000 (18:46 +0000)
sqlite3VdbeCheckFkImmediate() and sqlite3VdbeCheckFkDeferred(), which
run faster than the combined general-purpose variant.

FossilOrigin-Name: 872b1b52ed93ef85911c2ef87b15673f9e102aef564f208e0a916af62671df93

manifest
manifest.uuid
src/vdbe.c
src/vdbeInt.h
src/vdbeaux.c

index 553c8345e1047f91ee9e88932c853bd13790afbd..1ab5f88f209356add7715aa75f428fc3a420258e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Use\sfewer\sCPU\scycles\sto\scommit\sa\sread\stransaction.
-D 2025-07-19T18:17:06.185
+C Split\sthe\s(internal)\ssqlite3VdbeCheckFk()\sroutine\sinto\stwo\svariants,\nsqlite3VdbeCheckFkImmediate()\sand\ssqlite3VdbeCheckFkDeferred(),\swhich\nrun\sfaster\sthan\sthe\scombined\sgeneral-purpose\svariant.
+D 2025-07-19T18:46:03.562
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -853,11 +853,11 @@ F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
 F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165
 F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3
 F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789
-F src/vdbe.c e505b8b879a330e8dafbe3ed9582eae2fc671b44a64748d1b58c07e4e0f527da
+F src/vdbe.c a5873cd566a0e2a0344a86dd946add9d34fae3feeae8b126277ef7af8dc11f91
 F src/vdbe.h ea1f1b52f0efe422f80d88da3c57e4eadc72856e29a22f1ff08e502ec6ba5f08
-F src/vdbeInt.h 626465ff6d673f73a2476dc230b7cd07bdaf4acea9d4ecceaa12a5174bb2c8d7
+F src/vdbeInt.h d604607ce8c958fb66b8cb5a6915ba2f09a352c7dc38fee7e3157b951c84eac5
 F src/vdbeapi.c f9a4881a9674fec3fa13da35044a1484d3c4b95f9ec891cc8ffb02ef2b7a41df
-F src/vdbeaux.c 933a024b84154776b6b8d01f0de266d6d512530962e9793cf90fe1be5bb3697a
+F src/vdbeaux.c 3561afec5a01566ce2ded6cd213b54c8e892cbe910982b601458bf86dcb507d0
 F src/vdbeblob.c b3f0640db9642fbdc88bd6ebcc83d6009514cafc98f062f675f2c8d505d82692
 F src/vdbemem.c e67d9c6484d868c879d20c70d00bf4a9058082f1d4058607ca15d50eb3aebc21
 F src/vdbesort.c cb6f472e83ca12c46aa7de0ac0a9d11458b357986f2617a1c90dfb19a542ecbe
@@ -2213,8 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P fdd15e938ccfac9e871d781d1c8fe8be6dbd9e8cbbcb8b7f0b035e5ceebb8746
-R 5e8f8aa890f0c52df0b513b08f31622c
+P 861e55656abb208b4f1f2c8808c76c0454427af85a8930ab53f9c053605f39c7
+R 71d278a50d9f151128c82b71a7f4f17d
 U drh
-Z 7befb42110fb8e7ba3c32234f7f25e7b
+Z 773a4a3987f3155f05d8ed62835821fe
 # Remove this line to create a well-formed Fossil manifest.
index 6a3fe4ae0a21a58c7628f092f1f71fae50426611..37e4471fa1c920665a748c9cf9559aa22fd2befb 100644 (file)
@@ -1 +1 @@
-861e55656abb208b4f1f2c8808c76c0454427af85a8930ab53f9c053605f39c7
+872b1b52ed93ef85911c2ef87b15673f9e102aef564f208e0a916af62671df93
index 9e456a1cd5d9c1cef121013ddf033463cd631aca..0465ba27a8a6225bd43508b1665eabca6ae4363c 100644 (file)
@@ -1726,7 +1726,7 @@ case OP_IntCopy: {            /* out2 */
 ** RETURNING clause.
 */
 case OP_FkCheck: {
-  if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){
+  if( (rc = sqlite3VdbeCheckFkImmediate(p))!=SQLITE_OK ){
     goto abort_due_to_error;
   }
   break;
@@ -3910,7 +3910,7 @@ case OP_Savepoint: {
       */
       int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint;
       if( isTransaction && p1==SAVEPOINT_RELEASE ){
-        if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
+        if( (rc = sqlite3VdbeCheckFkDeferred(p))!=SQLITE_OK ){
           goto vdbe_return;
         }
         db->autoCommit = 1;
@@ -4028,7 +4028,7 @@ case OP_AutoCommit: {
                           "SQL statements in progress");
       rc = SQLITE_BUSY;
       goto abort_due_to_error;
-    }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
+    }else if( (rc = sqlite3VdbeCheckFkDeferred(p))!=SQLITE_OK ){
       goto vdbe_return;
     }else{
       db->autoCommit = (u8)desiredAutoCommit;
index 07160f59014751536d9a9565909e5b8c7e905278..0a944c6d8743bc10d07344a739487d9f08aa0882 100644 (file)
@@ -721,9 +721,11 @@ int sqlite3VdbeCheckMemInvariants(Mem*);
 #endif
 
 #ifndef SQLITE_OMIT_FOREIGN_KEY
-int sqlite3VdbeCheckFk(Vdbe *, int);
+int sqlite3VdbeCheckFkImmediate(Vdbe*);
+int sqlite3VdbeCheckFkDeferred(Vdbe*);
 #else
-# define sqlite3VdbeCheckFk(p,i) 0
+# define sqlite3VdbeCheckFkImmediate(p) 0
+# define sqlite3VdbeCheckFkDeferred(p) 0
 #endif
 
 #ifdef SQLITE_DEBUG
index 3c8e18393f5a72b74fda9dbcab019b37ffe6eceb..249175c7a03279da11595fef7e1bf4197bd0cf8a 100644 (file)
@@ -3267,28 +3267,31 @@ int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
 
 
 /*
-** This function is called when a transaction opened by the database
+** These functions are called when a transaction opened by the database
 ** handle associated with the VM passed as an argument is about to be
-** committed. If there are outstanding deferred foreign key constraint
-** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK.
+** committed. If there are outstanding foreign key constraint violations
+** return an error code. Otherwise, SQLITE_OK.
 **
 ** If there are outstanding FK violations and this function returns
-** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY
-** and write an error message to it. Then return SQLITE_ERROR.
+** non-zero, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY
+** and write an error message to it.
 */
 #ifndef SQLITE_OMIT_FOREIGN_KEY
-int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
+static SQLITE_NOINLINE int vdbeFkError(Vdbe *p){
+  p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
+  p->errorAction = OE_Abort;
+  sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
+  if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ) return SQLITE_ERROR;
+  return SQLITE_CONSTRAINT_FOREIGNKEY;
+}
+int sqlite3VdbeCheckFkImmediate(Vdbe *p){
+  if( p->nFkConstraint==0 ) return SQLITE_OK;
+  return vdbeFkError(p);
+}
+int sqlite3VdbeCheckFkDeferred(Vdbe *p){
   sqlite3 *db = p->db;
-  if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0)
-   || (!deferred && p->nFkConstraint>0)
-  ){
-    p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
-    p->errorAction = OE_Abort;
-    sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
-    if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ) return SQLITE_ERROR;
-    return SQLITE_CONSTRAINT_FOREIGNKEY;
-  }
-  return SQLITE_OK;
+  if( (db->nDeferredCons+db->nDeferredImmCons)==0 ) return SQLITE_OK;
+  return vdbeFkError(p);
 }
 #endif
 
@@ -3382,7 +3385,7 @@ int sqlite3VdbeHalt(Vdbe *p){
 
     /* Check for immediate foreign key violations. */
     if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
-      (void)sqlite3VdbeCheckFk(p, 0);
+      (void)sqlite3VdbeCheckFkImmediate(p);
     }
 
     /* If the auto-commit flag is set and this is the only active writer
@@ -3396,7 +3399,7 @@ int sqlite3VdbeHalt(Vdbe *p){
      && db->nVdbeWrite==(p->readOnly==0)
     ){
       if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
-        rc = sqlite3VdbeCheckFk(p, 1);
+        rc = sqlite3VdbeCheckFkDeferred(p);
         if( rc!=SQLITE_OK ){
           if( NEVER(p->readOnly) ){
             sqlite3VdbeLeave(p);