]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix the xfer-optimization such that if the destination table has
authordrh <>
Mon, 11 May 2026 16:58:05 +0000 (16:58 +0000)
committerdrh <>
Mon, 11 May 2026 16:58:05 +0000 (16:58 +0000)
constraints on the hidden rowid, the optimization is not attempted.
[forum:/forumpost/6dcc95e3ca|Forum post 6dcc95e3ca].

FossilOrigin-Name: da9ca357fb24f39a4a3292ca447773c6233a3084721abfbd5665a45ee8a4bed4

manifest
manifest.uuid
src/insert.c
test/insert4.test

index 9e7ba56db32c5eff9b90d813f5d8d28ea65534da..3cc216a3a68b2feef8dc1de87802e0cdcc739b84 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Prevent\sinternal-use-only\sSQL\sfunctions\sfrom\sbeing\sused\sinside\sof\sa\sCHECK\nconstraint\sadded\susing\sALTER\sTABLE\sADD\sCONSTRAINT.\n[forum:/forumpost/6256ee34ed|Forum\spost\s6256ee34ed].
-D 2026-05-11T14:22:45.851
+C Fix\sthe\sxfer-optimization\ssuch\sthat\sif\sthe\sdestination\stable\shas\nconstraints\son\sthe\shidden\srowid,\sthe\soptimization\sis\snot\sattempted.\n[forum:/forumpost/6dcc95e3ca|Forum\spost\s6dcc95e3ca].
+D 2026-05-11T16:58:05.251
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -696,7 +696,7 @@ F src/hash.c 03c8c0f4be9e8bcb6de65aa26d34a61d48a9430747084a69f9469fbb00ea52ca
 F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf
 F src/hwtime.h 21c2cf1f736e7b97502c3674d0c386db3f06870d6f10d0cf8174e2a4b8cb726e
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
-F src/insert.c 2b84fbcb063c29648f15f3704f902e404a0be7580c8d9559a9d369f03d6b6598
+F src/insert.c 66cb27a8cb3509ca4fa9204d8beba31baaf23a40dca2e23156393bce09655417
 F src/json.c ed93368fab7943a4822bc179fd914e63f5a2a18d6ef429c16ac49ea13eaffd49
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 78d5b06f18996ffa1203129b28fea043f63a87a4117539678f1d761c30b4ff65
@@ -1313,7 +1313,7 @@ F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
 F test/insert.test 97cfb30b83ca1622b9422a1e4c4831b4cb767cf5d654660945036d1e72067e70
 F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208
 F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30
-F test/insert4.test 2bf81535a990c969665d66db51fcf76c23499b39893b5109f413d1de4ad34cd3
+F test/insert4.test c57951c5db531509b3ad55a65c642b6250d51fa4f92bc67613ef900a32e9c3bd
 F test/insert5.test 79f6b6efd0d3db5f4e3ff442300b7d9e7185adb345b29aacc3ea5a9c58ab9beb
 F test/insertfault.test ac63d14ea3b49c573673a572f4014b9117383a03e497c58f308b5c776e4a7f74
 F test/instr.test 67ba309e9697c24a304e98a7c8f372456177dd4e32237d2a305e1e05f7bb79c2
@@ -2204,9 +2204,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee
 F tool/warnings.sh a554d13f6e5cf3760f041b87939e3d616ec6961859c3245e8ef701d1eafc2ca2
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
 F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c
-P 87b653731171a26396f9796b0a5c436593571d39e991d8d040ef4473cf459b67 7a85921ae585f948f084bd8fccc1cc002539415e629aa0021d58afc17e5471a3
-R 2a707e2c4c5fac58a7ce25fe390d4d94
-T +closed 7a85921ae585f948f084bd8fccc1cc002539415e629aa0021d58afc17e5471a3
+P 07beb966daddd0dfea36265eb38ebfcfbb10b0cbccda458dea501eda330a49f0
+R 1955398b2f2da5d960daeec18f38ded2
 U drh
-Z 188e9734e7f0fed6075a207e631c04b9
+Z 071b161c34e74b182ba62199af464639
 # Remove this line to create a well-formed Fossil manifest.
index c94bd2c33eb90284a76d2ea12a1fc1ec1ba1ab08..7dae3384dff6472b30c4497b14e8310b6306a3a1 100644 (file)
@@ -1 +1 @@
-07beb966daddd0dfea36265eb38ebfcfbb10b0cbccda458dea501eda330a49f0
+da9ca357fb24f39a4a3292ca447773c6233a3084721abfbd5665a45ee8a4bed4
index 5656b0d7effae7d4dbd01a42c6c4cbce693927fb..f9af6ea2435066762d1f6483618b3be5db22ccf4 100644 (file)
@@ -2987,6 +2987,44 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
   return 1;
 }
 
+/*
+** Examine an expression node and abort if it references the ROWID.
+** This is a Walker callback used by xferCompatibleCheck()
+*/
+static int xferCheckRowid(Walker *pWalk, Expr *pExpr){
+  if( pExpr->op==TK_COLUMN && pExpr->iColumn<0 ){
+    pWalk->eCode = 1;
+    return WRC_Abort;
+  }else{
+    return WRC_Continue;
+  }
+}
+
+/*
+** Analyze CHECK constraints on the source and destination tables and
+** return true if those CHECK constraints are compatible with the
+** xfer-optimization.
+**
+**    *  The pDest and pSrc tables must have identical CHECK constraints.
+**
+**    *  If the destination table, pDest, does not have an
+**       INTEGER PRIMARY KEY column, then no CHECK constraint may
+**       referenced the ROWID.  (See forum post 2026-05-11T13:15:57Z)
+*/
+static int xferCompatibleCheck(Table *pDest, Table *pSrc){
+  if( sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
+    return 0;
+  }
+  if( pDest->iPKey<0 ){
+    Walker w;
+    memset(&w, 0, sizeof(w));
+    w.xExprCallback = xferCheckRowid;
+    sqlite3WalkExprList(&w,pDest->pCheck);
+    if( w.eCode ) return 0;
+  }
+  return 1;
+}
+
 /*
 ** Attempt the transfer optimization on INSERTs of the form
 **
@@ -3219,7 +3257,7 @@ static int xferOptimization(
 #ifndef SQLITE_OMIT_CHECK
   if( pDest->pCheck
    && (db->mDbFlags & DBFLAG_Vacuum)==0
-   && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1)
+   && !xferCompatibleCheck(pDest,pSrc)
   ){
     return 0;   /* Tables have different CHECK constraints.  Ticket #2252 */
   }
index 8bd65a006f40a6d021c5bdd3a58c908f634cfc52..d5aab56c831b01c878d5bcb2690799ce0e7d6297 100644 (file)
@@ -625,4 +625,45 @@ do_execsql_test 11.0 {
   PRAGMA integrity_check;
 } {1 1 1  2 2 2  3 3 3  ok}
 
+#-------------------------------------------------------------------------
+# forum post 2026-05-11T13:15:57Z
+#
+do_execsql_test 12.0 {
+  CREATE TABLE src(x,y,z, CONSTRAINT c1 CHECK(rowid<=5));
+  CREATE TABLE dest(x,y,z, CONSTRAINT c2 CHECK(rowid<=5));
+  INSERT INTO src(x) VALUES(22),(33),(44);
+  UPDATE src SET y=x+100, z=x*100;
+  INSERT INTO dest(x) VALUES(55),(66),(77);
+  UPDATE dest SET y=x+100, z=x*100;
+  PRAGMA integrity_check;
+} ok
+set sqlite3_xferopt_count 0
+do_catchsql_test 12.1 {
+  INSERT INTO dest SELECT * FROM src;
+} {1 {CHECK constraint failed: c2}}
+do_test 12.2 {
+  set sqlite3_xferopt_count
+} 0
+do_execsql_test 12.3 {
+  SELECT rowid, x FROM dest;
+  PRAGMA integrity_check;
+} {1 55 2 66 3 77 ok}
+do_execsql_test 12.4 {
+  ALTER TABLE src DROP CONSTRAINT c1;
+  ALTER TABLE dest DROP CONSTRAINT c2;
+}
+set sqlite3_xferopt_count 0
+do_catchsql_test 12.5 {
+  INSERT INTO dest SELECT * FROM src;
+} {0 {}}
+do_test 12.6 {
+  set sqlite3_xferopt_count
+} 1
+do_execsql_test 12.7 {
+  SELECT rowid, x FROM dest;
+  PRAGMA integrity_check;
+} {1 55 2 66 3 77 4 22 5 33 6 44 ok}
+
+
+
 finish_test