From: dan Date: Wed, 6 Mar 2024 14:55:18 +0000 (+0000) Subject: Handle VALUES clauses having different number of values in different rows. Also the... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e51c78fa6ae1d81fa6d59918f2b6b5773986b6f2;p=thirdparty%2Fsqlite.git Handle VALUES clauses having different number of values in different rows. Also the case where SQLITE_LIMIT_COMPOUND_SELECT is set to 0. FossilOrigin-Name: f5074b29d96e8e642e597ce855d2481220628f6892110b9699e27c3806084f5d --- diff --git a/manifest b/manifest index 26f57faf0f..ebec6333a7 100644 --- 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. diff --git a/manifest.uuid b/manifest.uuid index 75cab7c1a6..fb444696e4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -551caba93bc1ab0c57451bc3f0cd29d16a9d577874d22d5083ac53fe09a5e60a \ No newline at end of file +f5074b29d96e8e642e597ce855d2481220628f6892110b9699e27c3806084f5d \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 779d8ab60f..a545f6b597 100644 --- a/src/insert.c +++ b/src/insert.c @@ -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); } } } diff --git a/test/values.test b/test/values.test index a8880acac8..7817307186 100644 --- a/test/values.test +++ b/test/values.test @@ -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 +} {} +