From: drh Date: Sat, 23 Feb 2019 00:56:05 +0000 (+0000) Subject: Import from trunk the new fix to ticket [df46dfb631f75694] in which X-Git-Tag: version-3.27.2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=746f546c0e418aa58b4100a08148f7a7e6e2dc62;p=thirdparty%2Fsqlite.git Import from trunk the new fix to ticket [df46dfb631f75694] in which all ephemeral tables used as the RHS of an IN operator be index btrees and never table btrees so that they can always be reused. FossilOrigin-Name: 0e64ac122aac469aff4ca7f55a494c8d2d34bbcc1b854f3d579db5926590a660 --- diff --git a/manifest b/manifest index 93a4de4b8d..9d19ede273 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increment\sthe\sversion\snumber\sto\s3.27.2. -D 2019-02-20T13:14:23.660 +C Import\sfrom\strunk\sthe\snew\sfix\sto\sticket\s[df46dfb631f75694]\sin\swhich\nall\sephemeral\stables\sused\sas\sthe\sRHS\sof\san\sIN\soperator\sbe\sindex\sbtrees\nand\snever\stable\sbtrees\sso\sthat\sthey\scan\salways\sbe\sreused. +D 2019-02-23T00:56:05.548 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 178d8eb6840771149cee40b322d1b3be30d330198c522c903c1b66fb5a1bfca4 @@ -466,7 +466,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 182dc9ff30aa6a430b7f728ce84fda85ec10890e29fdf75be1e871d13222a99c +F src/expr.c f2d0ecf68213770be4fad83128ce02e67667deebaa0a44061313f7e4f2a4ae28 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c bd0138acdc008c1845ccf92f8e73787880562de649471804801c06fed814c765 F src/func.c 0341881d22903aac5ba7f352b188806d6436e1d6ae4235ff01e44d56879dfe63 @@ -475,7 +475,7 @@ F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 3ed9ceaa4b7d56a6f2613355e1cd1ae5cfe31712bce2bf5aa93c5f1f130704b2 +F src/insert.c 7b71ba94e3283b497c076068fdeea760ce93b9db7d6784bdf5404fc842b721e5 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c e6f10875d52aca3b7e57ce1ec174aeafc9b6c00b43000cd30d791f9cb490b7a6 F src/main.c 27d7265625ea6eaccdfe7c53ef41adc179c9357a077702a860c1a3b0a037a16f @@ -519,7 +519,7 @@ F src/shell.c.in f2c1adbee3f6f36686b4a38d2168ebfc25298b4ad1e6d95199fc4e95b539251 F src/sqlite.h.in 7da74fd5bd7a9dbe92297060f036935520b26e240457287c5e67c7b9db51a986 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683 -F src/sqliteInt.h f657e35d824fdc17ddf46bb85f0193df3b965e8354ded9ec37825057e3224bcc +F src/sqliteInt.h ea0b5769140ca4bed03aeca8e7abb5c7a3eef4ffac723c8db3cfde88c390f807 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -585,7 +585,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c 82a2e3f691a3b654be872e305dab1f455e565dedf5e6a90c818c1ab307c00432 F src/vacuum.c a9f389f41556c0ec310bc9169dc9476603c30a0a913ad92bfbc75c86886967ca -F src/vdbe.c b7b6f965153607072917dbd81d654a268abf4872c58d556701d1549550766c02 +F src/vdbe.c 2c61090f2328ad125c8e55b4dab0712a78cfdfac893152fae34bed7e015b7cd7 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h a76d5eed62c76bcd8de7afd3147fac1bc40c5a870582664bcd7d071ef437c37f F src/vdbeapi.c 57a2d794a8833f269b878dbc24e955369bdb379af6c4e93ebc5ce1a20fa3daf4 @@ -601,7 +601,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c 7607f1a68130c028255d8d56094ea602fc402c79e1e35a46e6282849d90d5fe4 F src/where.c 8a207cb2ca6b99e1edb1e4bbff9b0504385a759cbf66180d1deb34d80ca4b799 F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88 -F src/wherecode.c 5ee878f714218352a2f452907572d4bf1e4303393288458f87ffc86edaf2cfbe +F src/wherecode.c 061848646cc46a137d9038e47e666a955b3b2a1b458365eeed76b004c0053f3b F src/whereexpr.c 36b47f7261d6b6f1a72d774c113b74beddf6745aba1018e64b196e29db233442 F src/window.c df2456386e0b1553a8d1fcf3a0ddc4c058fe2c650ea8c74b6bf8862082ddafc9 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1645,7 +1645,7 @@ F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417 F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 F test/walvfs.test c0faffda13d045a96dfc541347886bb1a3d6f3205857fc98e683edfab766ea88 -F test/where.test 8215d220633f08da331781cf9ede7fb7aed50eb113473c10acd39a643fd258ba +F test/where.test 93738e224cd5e7819565a9f272c19fd0ee5893d9cd7f5238ce026bae09b8d710 F test/where2.test 478d2170637b9211f593120648858593bf2445a1 F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8 @@ -1804,7 +1804,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 55e38d53adf1b3e95b0931359f8e135f0b2c063f34676b8dd27d933acdd6af5f -R 027b5d93617809fb316cea967931a5e7 +P a70d67d8af3dd41fb7139e213e433516e4469a71aaededd3c88cf6e225288bf1 +Q +d3915230e3ee5878fe2e65a0afb7e91ee124aaf46b4e28c6e00053d6df13d445 +R 529ec9abee9d7082d40b473e097c7f60 U drh -Z 9cf90ec2a6f82b28c22cd026c4884d86 +Z c36fc67223c62b267adb844e47f924d2 diff --git a/manifest.uuid b/manifest.uuid index 9dd174670c..d92c5bcc03 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a70d67d8af3dd41fb7139e213e433516e4469a71aaededd3c88cf6e225288bf1 \ No newline at end of file +0e64ac122aac469aff4ca7f55a494c8d2d34bbcc1b854f3d579db5926590a660 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 03ecf1567d..e39b6408c4 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2552,14 +2552,11 @@ int sqlite3FindInIndex( eType = IN_INDEX_EPH; if( inFlags & IN_INDEX_LOOP ){ pParse->nQueryLoop = 0; - if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){ - eType = IN_INDEX_ROWID; - } }else if( prRhsHasNull ){ *prRhsHasNull = rMayHaveNull = ++pParse->nMem; } assert( pX->op==TK_IN ); - sqlite3CodeRhsOfIN(pParse, pX, iTab, eType==IN_INDEX_ROWID); + sqlite3CodeRhsOfIN(pParse, pX, iTab); if( rMayHaveNull ){ sqlite3SetHasNullFlag(v, iTab, rMayHaveNull); } @@ -2660,12 +2657,6 @@ void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ ** however the cursor number returned might not be the same, as it might ** have been duplicated using OP_OpenDup. ** -** If parameter isRowid is non-zero, then LHS of the IN operator is guaranteed -** to be a non-null integer. In this case, the ephemeral table can be an -** table B-Tree that keyed by only integers. The more general cases uses -** an index B-Tree which can have arbitrary keys, but is slower to both -** read and write. -** ** If the LHS expression ("x" in the examples) is a column value, or ** the SELECT statement returns a column value, then the affinity of that ** column is used to build the index keys. If both 'x' and the @@ -2677,8 +2668,7 @@ void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ void sqlite3CodeRhsOfIN( Parse *pParse, /* Parsing context */ Expr *pExpr, /* The IN operator */ - int iTab, /* Use this cursor number */ - int isRowid /* If true, LHS is a rowid */ + int iTab /* Use this cursor number */ ){ int addrOnce = 0; /* Address of the OP_Once instruction at top */ int addr; /* Address of OP_OpenEphemeral instruction */ @@ -2731,14 +2721,12 @@ void sqlite3CodeRhsOfIN( /* Check to see if this is a vector IN operator */ pLeft = pExpr->pLeft; nVal = sqlite3ExprVectorSize(pLeft); - assert( !isRowid || nVal==1 ); /* Construct the ephemeral table that will contain the content of ** RHS of the IN operator. */ pExpr->iTable = iTab; - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, - pExpr->iTable, (isRowid?0:nVal)); + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal); #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS if( ExprHasProperty(pExpr, EP_xIsSelect) ){ VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId)); @@ -2746,7 +2734,7 @@ void sqlite3CodeRhsOfIN( VdbeComment((v, "RHS of IN operator")); } #endif - pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1); + pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ /* Case 1: expr IN (SELECT ...) @@ -2760,7 +2748,6 @@ void sqlite3CodeRhsOfIN( ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY %d", addrOnce?"":"CORRELATED ", pSelect->selId )); - assert( !isRowid ); /* If the LHS and RHS of the IN operator do not match, that ** error will have been caught long before we reach this point. */ if( ALWAYS(pEList->nExpr==nVal) ){ @@ -2813,10 +2800,8 @@ void sqlite3CodeRhsOfIN( /* Loop through each expression in . */ r1 = sqlite3GetTempReg(pParse); r2 = sqlite3GetTempReg(pParse); - if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC); for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ Expr *pE2 = pItem->pExpr; - int iValToIns; /* If the expression is not constant then we will need to ** disable the test that was generated above that makes sure @@ -2829,20 +2814,9 @@ void sqlite3CodeRhsOfIN( } /* Evaluate the expression and insert it into the temp table */ - if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){ - sqlite3VdbeAddOp3(v, OP_InsertInt, iTab, r2, iValToIns); - }else{ - r3 = sqlite3ExprCodeTarget(pParse, pE2, r1); - if( isRowid ){ - sqlite3VdbeAddOp2(v, OP_MustBeInt, r3, - sqlite3VdbeCurrentAddr(v)+2); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_Insert, iTab, r2, r3); - }else{ - sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r3, 1); - } - } + r3 = sqlite3ExprCodeTarget(pParse, pE2, r1); + sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r3, 1); } sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempReg(pParse, r2); diff --git a/src/insert.c b/src/insert.c index a69e625a11..8d069b00ef 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1919,10 +1919,13 @@ void sqlite3CompleteInsertion( pik_flags |= (update_flags & OPFLAG_SAVEPOSITION); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK if( update_flags==0 ){ - sqlite3VdbeAddOp4(v, OP_InsertInt, - iIdxCur+i, aRegIdx[i], 0, (char*)pTab, P4_TABLE + int r = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Integer, 0, r); + sqlite3VdbeAddOp4(v, OP_Insert, + iIdxCur+i, aRegIdx[i], r, (char*)pTab, P4_TABLE ); sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); + sqlite3ReleaseTempReg(pParse, r); } #endif } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 774d3e5011..4940511dc4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4279,7 +4279,7 @@ void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); int sqlite3GetToken(const unsigned char *, int *); void sqlite3NestedParse(Parse*, const char*, ...); void sqlite3ExpirePreparedStatements(sqlite3*, int); -void sqlite3CodeRhsOfIN(Parse*, Expr*, int, int); +void sqlite3CodeRhsOfIN(Parse*, Expr*, int); int sqlite3CodeSubselect(Parse*, Expr*); void sqlite3SelectPrep(Parse*, Select*, NameContext*); void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); diff --git a/src/vdbe.c b/src/vdbe.c index 98df0a3977..9f37624b59 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4580,14 +4580,7 @@ case OP_NewRowid: { /* out2 */ ** This instruction only works on tables. The equivalent instruction ** for indices is OP_IdxInsert. */ -/* Opcode: InsertInt P1 P2 P3 P4 P5 -** Synopsis: intkey=P3 data=r[P2] -** -** This works exactly like OP_Insert except that the key is the -** integer value P3, not the value of the integer stored in register P3. -*/ -case OP_Insert: -case OP_InsertInt: { +case OP_Insert: { Mem *pData; /* MEM cell holding data for the record to be inserted */ Mem *pKey; /* MEM cell holding key for the record */ VdbeCursor *pC; /* Cursor to table into which insert is written */ @@ -4608,16 +4601,11 @@ case OP_InsertInt: { REGISTER_TRACE(pOp->p2, pData); sqlite3VdbeIncrWriteCounter(p, pC); - if( pOp->opcode==OP_Insert ){ - pKey = &aMem[pOp->p3]; - assert( pKey->flags & MEM_Int ); - assert( memIsValid(pKey) ); - REGISTER_TRACE(pOp->p3, pKey); - x.nKey = pKey->u.i; - }else{ - assert( pOp->opcode==OP_InsertInt ); - x.nKey = pOp->p3; - } + pKey = &aMem[pOp->p3]; + assert( pKey->flags & MEM_Int ); + assert( memIsValid(pKey) ); + REGISTER_TRACE(pOp->p3, pKey); + x.nKey = pKey->u.i; if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ assert( pC->iDb>=0 ); diff --git a/src/wherecode.c b/src/wherecode.c index 5441752ed1..79189386b6 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -582,7 +582,6 @@ static int codeEqualityTerm( if( pLoop->aLTerm[i]->pExpr==pX ){ int iOut = iReg + i - iEq; if( eType==IN_INDEX_ROWID ){ - testcase( nEq>1 ); /* Happens with a UNIQUE index on ROWID */ pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); }else{ int iCol = aiMap ? aiMap[iMap++] : 0; @@ -1344,7 +1343,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg); VdbeCoverage(v); pLevel->op = OP_Noop; - pTerm->wtFlags |= TERM_CODED; + if( (pTerm->prereqAll & pLevel->notReady)==0 ){ + pTerm->wtFlags |= TERM_CODED; + } }else if( (pLoop->wsFlags & WHERE_IPK)!=0 && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0 ){ diff --git a/test/where.test b/test/where.test index 1f38065c65..e1b81aa053 100644 --- a/test/where.test +++ b/test/where.test @@ -1425,5 +1425,17 @@ do_execsql_test where-22.1 { SELECT count(*) FROM t1 LEFT JOIN t2 ON a IS NOT NULL; } {5} +# 20190-02-22: A bug introduced by checkin +# https://www.sqlite.org/src/info/fa792714ae62fa98. +# +do_execsql_test where-23.0 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY); + INSERT INTO t1(a) VALUES(1),(2),(3); + CREATE TABLE t2(x INTEGER PRIMARY KEY, y INT); + INSERT INTO t2(y) VALUES(2),(3); + SELECT * FROM t1, t2 WHERE a=y AND y=3; +} {3 2 3} finish_test