-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
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
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
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
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
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.
-5d6797716d4be5b9d448f697b05f36a62c180e836dd142307f06b945a7ddb43c
\ No newline at end of file
+9cbceaac8f3c557f6eb266e15c57d71d3b6ad5dfdc8c0c39e5fc75e505673d17
\ No newline at end of file
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 */
}
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");
}
%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);
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
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);
}
}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"));
#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)
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