]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Handle VALUES clauses having different number of values in different rows. Also the...
authordan <Dan Kennedy>
Wed, 6 Mar 2024 14:55:18 +0000 (14:55 +0000)
committerdan <Dan Kennedy>
Wed, 6 Mar 2024 14:55:18 +0000 (14:55 +0000)
FossilOrigin-Name: f5074b29d96e8e642e597ce855d2481220628f6892110b9699e27c3806084f5d

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

index 26f57faf0f65d50327f6432aa62ccd5613ee2e21..ebec6333a7baebf1f97bbd6736993a0b1b238a33 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\scomments\sfor\sthe\snew\scode\son\sthis\sbranch.
-D 2024-03-05T20:33:48.969
+C Handle\sVALUES\sclauses\shaving\sdifferent\snumber\sof\svalues\sin\sdifferent\srows.\sAlso\sthe\scase\swhere\sSQLITE_LIMIT_COMPOUND_SELECT\sis\sset\sto\s0.
+D 2024-03-06T14:55:18.413
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -709,7 +709,7 @@ F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
 F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
-F src/insert.c d1cf81c7668c59307c7b4e1dc95a0374b4cc5333f1cc2fe181d21c7bed90e188
+F src/insert.c eb6f1f2ee17e6e219ec0e7d7a13d57c6f77357397b5670584933878f7737650a
 F src/json.c 9337dac9d9d4c77461db55fd3e06e4d006f4283cb1da2b3a9b1f8d750701583e
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
@@ -1920,7 +1920,7 @@ F test/vacuum4.test 7ea76b769fffeb41f925303b04cbcf5a5bbeabe55e4c60ae754ff24eeeb7
 F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2f48c
 F test/vacuum6.test b137b04bf3392d3f5c3b8fda0ce85a6775a70ca112f6559f74ff52dc9ce042fd
 F test/vacuummem.test 4b30f5b95a9ff86e9d5c20741e50a898b2dc10b0962a3211571eb165357003fb
-F test/values.test 81e0863873b6ec9db79c332d17812c31368130cc401a647c6d1d0e5fc3a27fe4
+F test/values.test 8a0c4fbff834ac2b5c00ec78d179692506e9e0a5d695410385531c3de425cdd0
 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62
 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
 F test/view.test d4c4281e1679245829db35597817282f60dc513fc39cc5439078f009bd118487
@@ -2177,8 +2177,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 a003fffafdb532de4ff3876a81e73dbccbdf83debecd83a2a9ae2d449bf02adc
-R 55010f332167e59d2e243052f3e4e866
+P 551caba93bc1ab0c57451bc3f0cd29d16a9d577874d22d5083ac53fe09a5e60a
+R 734a2e418a4fb63b2f2067774781bb7d
 U dan
-Z 749255c97ae7f51a891e46cc76606f6a
+Z a8613604e9b33f81bf4f9c0d1f448292
 # Remove this line to create a well-formed Fossil manifest.
index 75cab7c1a6083d77a205dcc03a863f4889222b8e..fb444696e47e2b8f9f39f54b50685c0cc1359d5e 100644 (file)
@@ -1 +1 @@
-551caba93bc1ab0c57451bc3f0cd29d16a9d577874d22d5083ac53fe09a5e60a
\ No newline at end of file
+f5074b29d96e8e642e597ce855d2481220628f6892110b9699e27c3806084f5d
\ No newline at end of file
index 779d8ab60f629609db240f6589d24f369467c2f0..a545f6b5971bead67976b729fd59ac4b1f5b9824 100644 (file)
@@ -590,6 +590,9 @@ Select *sqlite3InsertMultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){
   pRight = sqlite3SelectNew(pParse,pRow, 0,0,0,0,0, SF_Values|SF_MultiValue, 0);
   pLeft->selFlags &= ~SF_MultiValue;
   if( pRight ){
+    if( pRow->nExpr!=pLeft->pEList->nExpr ){
+      sqlite3SelectWrongNumTermsError(pParse, pRight);
+    }
     if( pVal && pVal->pSelect==pLeft ){
       /* Option (a) above */
       int explain = pParse->explain;
@@ -608,45 +611,45 @@ Select *sqlite3InsertMultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){
     pRight = pLeft;
   }
 
-  /* If the co-routine has not already been started, but more than
-  ** SQLITE_LIMIT_COMPOUND_SELECT select statements have been create during
-  ** this parse, check if the co-routine should be started now. */
-  if( pVal==0 && pParse->zValuesToken 
-   && (pParse->nSelect > pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])
-  ){
-    int nSelect = 1;
-    Select *p;
-    pParse->zValuesToken = 0;
-    for(p=pRight; p->pPrior; p=p->pPrior ) nSelect++;
-    if( nSelect>pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT] 
-     && (p->selFlags & SF_InsertValues)
-    ){
-      /* Start coding the co-routine */
-      Vdbe *v = sqlite3GetVdbe(pParse);
-      pVal = (MultiValues*)sqlite3DbMallocZero(pParse->db, sizeof(*pVal));
-      if( v && pVal ){
-        pParse->pValues = pVal;
-        pVal->pSelect = p;
-        pVal->regYield = ++pParse->nMem;
-        pVal->addrTop = sqlite3VdbeCurrentAddr(v) + 1;
-        sqlite3VdbeAddOp3(v, OP_InitCoroutine, pVal->regYield,0,pVal->addrTop);
-        sqlite3SelectDestInit(&pVal->dest, SRT_Coroutine, pVal->regYield);
-        for(p=pRight; p->pPrior; p=p->pPrior ){
-          p->pPrior->pNext = p;
-        }
-        pRight = p;
-        while( p ){
-          Select *pNext = p->pNext;
-          int explain = pParse->explain;
-          p->selFlags = p->selFlags & (~SF_Values);
-          p->pPrior = 0;
-          pParse->explain = 255;
-          sqlite3Select(pParse, p, &pVal->dest);
-          pParse->explain = explain;
-          if( p!=pRight ) sqlite3SelectDelete(pParse->db, p);
-          p = pNext;
+  if( pVal==0 && pParse->zValuesToken ){
+    int iLimit = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT];
+
+    /* If the co-routine has not already been started, but more than
+    ** SQLITE_LIMIT_COMPOUND_SELECT select statements have been create 
+    ** during this parse, check if the co-routine should be started now. */
+    if( pParse->nSelect>iLimit ){
+      int nSelect = 1;
+      Select *p;
+      pParse->zValuesToken = 0;
+      for(p=pRight; p->pPrior; p=p->pPrior ) nSelect++;
+      if( iLimit>0 && nSelect>iLimit && (p->selFlags & SF_InsertValues) ){
+        Vdbe *v = sqlite3GetVdbe(pParse);
+        pVal = (MultiValues*)sqlite3DbMallocZero(pParse->db, sizeof(*pVal));
+        if( v && pVal ){
+          /* Start coding the co-routine */
+          pParse->pValues = pVal;
+          pVal->pSelect = p;
+          pVal->regYield = ++pParse->nMem;
+          pVal->addrTop = sqlite3VdbeCurrentAddr(v) + 1;
+          sqlite3VdbeAddOp3(v, OP_InitCoroutine,pVal->regYield,0,pVal->addrTop);
+          sqlite3SelectDestInit(&pVal->dest, SRT_Coroutine, pVal->regYield);
+          for(p=pRight; p->pPrior; p=p->pPrior ){
+            p->pPrior->pNext = p;
+          }
+          pRight = p;
+          while( p ){
+            Select *pNext = p->pNext;
+            int explain = pParse->explain;
+            p->selFlags = p->selFlags & (~SF_Values);
+            p->pPrior = 0;
+            pParse->explain = 255;
+            sqlite3Select(pParse, p, &pVal->dest);
+            pParse->explain = explain;
+            if( p!=pRight ) sqlite3SelectDelete(pParse->db, p);
+            p = pNext;
+          }
+          sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pVal);
         }
-        sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pVal);
       }
     }
   }
index a8880acac80fe2f3123c2a5e2f9dc8c087cb13e9..781730718670c7fd3555600b6c5676cbd07e5d87 100644 (file)
@@ -87,9 +87,76 @@ do_execsql_test 1.2.6 {
 }
 
 #-------------------------------------------------------------------------
-# different number of columns error.
 # SQLITE_LIMIT_COMPOUND_SELECT set to 0.
 #
+reset_db
+
+do_execsql_test 2.0 {
+  CREATE TABLE x1(a, b, c);
+}
+
+sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 3
+
+do_catchsql_test 2.1.1 {
+  INSERT INTO x1 VALUES
+      (1, 1, 1), 
+      (2, 2, 2), 
+      (3, 3, 3), 
+      (4, 4, 4), 
+      (5, 5, 5), 
+      (6, 6, 6), 
+      (7, 7, 7), 
+      (8, 8, 8), 
+      (9, 9, 9), 
+      (10, 10, 10, 10)
+} {1 {all VALUES must have the same number of terms}}
+
+do_catchsql_test 2.1.2 {
+  INSERT INTO x1 VALUES
+      (1, 1, 1), 
+      (2, 2, 2, 2), 
+      (3, 3, 3), 
+      (4, 4, 4), 
+      (5, 5, 5), 
+      (6, 6, 6), 
+      (7, 7, 7), 
+      (8, 8, 8), 
+      (9, 9, 9), 
+      (10, 10, 10)
+} {1 {all VALUES must have the same number of terms}}
+
+sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 0
+
+do_execsql_test 2.2 {
+  INSERT INTO x1 VALUES
+      (1, 1, 1), 
+      (2, 2, 2), 
+      (3, 3, 3), 
+      (4, 4, 4), 
+      (5, 5, 5), 
+      (6, 6, 6), 
+      (7, 7, 7), 
+      (8, 8, 8), 
+      (9, 9, 9), 
+      (10, 10, 10)
+} {}
+do_execsql_test 2.3 {
+  INSERT INTO x1 VALUES
+      (1, 1, 1), 
+      (2, 2, 2), 
+      (3, 3, 3), 
+      (4, 4, 4), 
+      (5, 5, 5), 
+      (6, 6, 6), 
+      (7, 7, 7), 
+      (8, 8, 8), 
+      (9, 9, 9), 
+      (10, 10, 10)
+      UNION ALL 
+      SELECT 5, 12, 12
+      ORDER BY 1
+} {}
+