From: dan Date: Tue, 5 Mar 2024 17:23:13 +0000 (+0000) Subject: Simplify changes on this branch by avoiding any special handling until SQLITE_LIMIT_C... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=752cb42dc7f50ffaf4b8dbd9c4215e66d6e4fea8;p=thirdparty%2Fsqlite.git Simplify changes on this branch by avoiding any special handling until SQLITE_LIMIT_COMPOUND_SELECT rows are reached. FossilOrigin-Name: 9cbceaac8f3c557f6eb266e15c57d71d3b6ad5dfdc8c0c39e5fc75e505673d17 --- diff --git a/manifest b/manifest index e7b60c543c..059fca65e1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sproblems\swith\s"VALUES(...)\sUNION\s..."\sand\ssimilar\son\sthis\sbranch. -D 2024-03-04T18:50:17.133 +C Simplify\schanges\son\sthis\sbranch\sby\savoiding\sany\sspecial\shandling\suntil\sSQLITE_LIMIT_COMPOUND_SELECT\srows\sare\sreached. +D 2024-03-05T17:23:13.046 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 e1a27669e658c44fe90e59c292f9c999c1c78a5f1dba96db4974c52ca2edc199 +F src/insert.c 455bd07274de3e58974ccbf755ac6fb8ca47db00ee3c36f7173028c5fab29b11 F src/json.c 3b4e2778d95d923d6d77e8a5efd51a6265017b466782d597303f5f094fcd68af F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36 @@ -739,7 +739,7 @@ F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c ff60e98138d2499082ac6230f01ac508aba545315debccfca2fd6042f5f10fcd F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a -F src/parse.y d4eb1a3b020414cb28d371edd2c3d6552bfa9d869ac6c55ebf099b59cd9ee4fb +F src/parse.y 9b9923ee2c2de30bddd4120fc096007c2bfb2c63194d18e140d365cae8be9812 F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00 @@ -748,14 +748,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c 371f6115cb69286ebc12c6f2d7511279c2e47d9f54f475d46a554d687a3b312c F src/printf.c 10e8bad30042f8bd6114a013b4afc229ec8ad255ab27518d7d9f52e8cbc5cd0a F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resolve.c 117cf4a43399f2302fc7187890ce75cf61f5c58446565e3ca1c54547ac294a52 +F src/resolve.c d77c6160bc8f249c2196fdd3e75f66a1dd70e37aa25c39aedc7b1f93c42b7c6d F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 69907af4859b57e6571a2c360a8bec94974faf82c0b1dc46a3557111fc39e531 +F src/select.c 43fabfc01bf87addd15e39f112f1e2ade15b19594835ab8a9e5bd50839d4e1b1 F src/shell.c.in 2ec564ed3ff0147036be313efeb47b3dbfb8753d5eb5ea0e90636427c6b3a365 F src/sqlite.h.in 19a2db3995a699bd7f6dfb423856242bfceb7ec849a93c91d241d19fc28d9f0f F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 -F src/sqliteInt.h 56b8fc5703eb9bdeb687c01bb558132e724b98058a93ada3ff0536cb1c9abdff +F src/sqliteInt.h 616591f3bc242446caba3160f7c1ebca4817f06cea2ed6a5da5b988203834c09 F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -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 be2ded90c28af2bcb97ca9c23f0c126572ec3ded08cb118ff7b99068549f86de +F test/values.test c16b1a7efa9316152711e0f97bffb5f113b161f295875ca1dc97094855ad24e5 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 6d4f1ae2fcabdaca4e2c12224a8807c6fe2c62353dff435a0c0030fa58312df6 -R fdcf3c2a1975e9339e3c52056ea69312 +P 5d6797716d4be5b9d448f697b05f36a62c180e836dd142307f06b945a7ddb43c +R b78adccb9bee7eab4f908c966fe08e61 U dan -Z 49b6a609d29e5dfaa997072dac3f32d5 +Z 5a061837657e2df4c4adc4cc28150d89 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 323599b6cc..0960267d0d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d6797716d4be5b9d448f697b05f36a62c180e836dd142307f06b945a7ddb43c \ No newline at end of file +9cbceaac8f3c557f6eb266e15c57d71d3b6ad5dfdc8c0c39e5fc75e505673d17 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 036bd3279c..b5f9b4950d 100644 --- a/src/insert.c +++ b/src/insert.c @@ -610,40 +610,68 @@ static void insertEndCoroutine(Vdbe *v, int regYield, int addrTop){ sqlite3VdbeJumpHere(v, addrTop - 1); } -Select *sqlite3InsertMultiValues(Parse *pParse, Select *pSel, ExprList *pRow){ +Select *sqlite3InsertMultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){ MultiValues *pVal = pParse->pValues; Select *pRight; - pRight = sqlite3SelectNew(pParse,pRow, 0,0,0,0,0, SF_Values, 0); - + pRight = sqlite3SelectNew(pParse,pRow, 0,0,0,0,0, SF_Values|SF_MultiValue, 0); + pLeft->selFlags &= ~SF_MultiValue; if( pRight ){ - if( pVal && pVal->pSelect==pSel ){ - if( isConstantRow(pRight->pEList) ){ - if( pRight->pEList->nExpr!=pSel->pEList->nExpr ){ - sqlite3SelectWrongNumTermsError(pParse, pRight); - }else{ + if( pVal && pVal->pSelect==pLeft ){ + int explain = pParse->explain; + pParse->explain = 255; + sqlite3Select(pParse, pRight, &pVal->dest); + pParse->explain = explain; + sqlite3SelectDelete(pParse->db, pRight); + pRight = pLeft; + }else{ + pRight->op = TK_ALL; + pRight->pPrior = pLeft; + } + }else{ + pRight = pLeft; + } + + 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) + ){ + 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); pParse->explain = 255; - sqlite3Select(pParse, pRight, &pVal->dest); + p->pPrior = 0; + sqlite3Select(pParse, p, &pVal->dest); pParse->explain = explain; + if( p!=pRight ) sqlite3SelectDelete(pParse->db, p); + p = pNext; } - sqlite3SelectDelete(pParse->db, pRight); - return pSel; - }else{ - assert( pVal->bEnd==0 ); - insertEndCoroutine(pParse->pVdbe, pVal->regYield, pVal->addrTop); - pVal->bEnd = 1; + sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pVal); } } - - pSel->selFlags &= ~SF_MultiValue; - pRight->selFlags &= ~SF_MultiValue; - pRight->op = TK_ALL; - pRight->pPrior = pSel; - pSel = pRight; } - return pSel; + return pRight; } /* Forward declaration */ diff --git a/src/parse.y b/src/parse.y index 805d09f16d..6d010d24ac 100644 --- a/src/parse.y +++ b/src/parse.y @@ -532,7 +532,7 @@ cmd ::= select(X). { } if( (p->selFlags & SF_MultiValue)==0 && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && - cnt>mxSelect + (cnt>mxSelect || (pParse->pValues && pParse->pValues->pSelect==pNext)) ){ sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); } @@ -622,24 +622,13 @@ oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y) %endif -oneselect(A) ::= values(A). { - if( pParse->pValues && pParse->pValues->pSelect==A ){ - MultiValues *pValues = pParse->pValues; - if( pValues->bEnd==0 ){ - sqlite3VdbeEndCoroutine(pParse->pVdbe, pValues->regYield); - sqlite3VdbeJumpHere(pParse->pVdbe, pValues->addrTop - 1); - pValues->bEnd = 1; - } - } -} +oneselect(A) ::= values(A). %type values {Select*} %destructor values {sqlite3SelectDelete(pParse->db, $$);} values(A) ::= VALUES(T) LP nexprlist(X) RP. { - A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0); - if( T.z==pParse->zValuesToken && yyLookahead==TK_COMMA ){ - sqlite3MultiValuesStart(pParse, A); - } + int f = SF_Values | ((T.z==pParse->zValuesToken) ? SF_InsertValues : 0); + A = sqlite3SelectNew(pParse,X,0,0,0,0,0,f,0); } values(A) ::= values(A) COMMA LP nexprlist(Y) RP. { A = sqlite3InsertMultiValues(pParse,A,Y); diff --git a/src/resolve.c b/src/resolve.c index 2cadea8604..5d0801e82e 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1791,7 +1791,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ pLeftmost = p; while( p ){ assert( (p->selFlags & SF_Expanded)!=0 ); - assert( (p->selFlags & SF_Resolved)==0 || pParse->pValues ); + assert( (p->selFlags & SF_Resolved)==0 ); p->selFlags |= SF_Resolved; /* Resolve the expressions in the LIMIT and OFFSET clauses. These diff --git a/src/select.c b/src/select.c index 65a1e67420..81e802d6e4 100644 --- a/src/select.c +++ b/src/select.c @@ -1246,11 +1246,6 @@ static void selectInnerLoop( assert( hasDistinct==0 ); pSort->pDeferredRowLoad = &sRowLoadInfo; regOrig = 0; - }else if( pParse->pValues && pParse->pValues->pSelect==p ){ - MultiValues *pValues = pParse->pValues; - sqlite3ExprCodeMove(pParse, - pValues->dest.iSdst, pDest->iSdst, pDest->nSdst - ); }else{ innerLoopLoadRow(pParse, p, &sRowLoadInfo); } @@ -7965,22 +7960,11 @@ int sqlite3Select( }else #endif /* SQLITE_OMIT_WINDOWFUNC */ { - MultiValues *pValues = pParse->pValues; - int addrYield = 0; - if( pValues && pValues->pSelect==p ){ - addrYield = sqlite3VdbeAddOp1(v, OP_Yield, pValues->regYield); - } - /* Use the standard inner loop. */ selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, sqlite3WhereContinueLabel(pWInfo), sqlite3WhereBreakLabel(pWInfo)); - if( pValues && pValues->pSelect==p ){ - sqlite3VdbeAddOp2(v, OP_Goto, 0, addrYield); - sqlite3VdbeChangeP2(v, addrYield, sqlite3VdbeCurrentAddr(v)); - } - /* End the database scan loop. */ TREETRACE(0x2,pParse,p,("WhereEnd\n")); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 088cfc1516..2c96daf126 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3571,6 +3571,7 @@ struct Select { #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ #define SF_UpdateFrom 0x10000000 /* Query originates with UPDATE FROM */ +#define SF_InsertValues 0x20000000 /* Is VALUES that follows an INSERT */ /* True if S exists and has SF_NestedFrom */ #define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0) diff --git a/test/values.test b/test/values.test index 961be162b0..faf1af419d 100644 --- a/test/values.test +++ b/test/values.test @@ -20,71 +20,79 @@ do_execsql_test 1.0 { CREATE TABLE x1(a, b, c); } +sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 2 + +explain_i { + INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4); +} do_execsql_test 1.1.1 { - INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2) UNION ALL SELECT 3, 3, 3; + INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4); } - do_execsql_test 1.1.2 { SELECT * FROM x1; } { 1 1 1 2 2 2 3 3 3 + 4 4 4 } -set a 3 -set b 3 -set c 4 -do_execsql_test 1.2.1 { - DELETE FROM x1; - INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2), ($a, $b, 3), (4, 4, $c); +do_execsql_test 1.2.0 { + DELETE FROM x1 } +do_catchsql_test 1.2.1 { + INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3) UNION ALL SELECT 4, 4, 4; +} {1 {too many terms in compound SELECT}} -do_execsql_test 1.2.2 { - SELECT * FROM x1; -} { - 1 1 1 - 2 2 2 - 3 3 3 - 4 4 4 -} +sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 4 -do_execsql_test 1.3.1 { - DELETE FROM x1; - INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2) UNION SELECT 1, 2, 3 ORDER BY 1; -} -do_execsql_test 1.3.2 { - SELECT * FROM x1; -} { - 1 1 1 - 1 2 3 - 2 2 2 -} +do_catchsql_test 1.2.2 { + INSERT INTO x1 + VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5) + UNION ALL SELECT 6, 6, 6; +} {1 {too many terms in compound SELECT}} -do_execsql_test 1.4.0 { - DELETE FROM x1; -} -do_execsql_test 1.4.1 { - INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2) UNION ALL SELECT 1, 2, 3 ORDER BY 1; -} -do_execsql_test 1.4.2 { +do_catchsql_test 1.2.3 { + INSERT INTO x1 + VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4) + UNION ALL SELECT 6, 6, 6; +} {1 {too many terms in compound SELECT}} + +do_execsql_test 1.2.4 { + INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3) UNION ALL SELECT 6, 6, 6; SELECT * FROM x1; } { - 1 1 1 - 1 2 3 - 2 2 2 + 1 1 1 + 2 2 2 + 3 3 3 + 6 6 6 } -do_execsql_test 1.5.1 { +if 0 { + +set a 4 +set b 5 +set c 6 +do_execsql_test 1.2.5 { DELETE FROM x1; INSERT INTO x1 - VALUES(3, 3, 3), (2, 2, 2), (1, 1, 1) EXCEPT SELECT 2, 2, 2; + VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), + (4, 4, $a), (5, 5, $b), (6, 6, $c) } -do_execsql_test 1.5.2 { + +do_execsql_test 1.2.6 { SELECT * FROM x1; } { 1 1 1 + 2 2 2 3 3 3 + 4 4 4 + 5 5 5 + 6 6 6 } +} + + + finish_test