mirror of
https://github.com/sqlite/sqlite.git
synced 2026-01-06 08:01:16 +03:00
Merge trunk enhancements into the right-join branch.
FossilOrigin-Name: 3fd9706bba4a71cb5c7ce1341c3be0a7727941445820a073e7b2f0f32512e8ef
This commit is contained in:
@@ -79,4 +79,9 @@ do_test 1.7 {
|
||||
|
||||
rbu close
|
||||
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
test_sqlite3_log
|
||||
sqlite3_initialize
|
||||
finish_test
|
||||
|
||||
|
||||
28
manifest
28
manifest
@@ -1,5 +1,5 @@
|
||||
C Merge\senhancements\sand\sfixes\sfrom\strunk\sinto\sthe\sright-join\sbranch.
|
||||
D 2022-04-23T19:26:34.244
|
||||
C Merge\strunk\senhancements\sinto\sthe\sright-join\sbranch.
|
||||
D 2022-04-28T12:52:49.755
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -358,7 +358,7 @@ F ext/rbu/rbuA.test b34a90cb495682c25b5fc03a9d5e7a4fc99541c29256f25e2e2a4f6542b4
|
||||
F ext/rbu/rbuB.test 52b07158824c6927b7e25554ace92a695cdebfc296ae3d308ac386984aded9bc
|
||||
F ext/rbu/rbuC.test 80f1cc2fb74f44b1128fd0ed8eedab3a76fefeb72a947860e2869ef76fc8dc6b
|
||||
F ext/rbu/rbu_common.tcl 60d904133ff843fe72cc0514e9dd2486707181e6e0fbab20979da28c48d21de9
|
||||
F ext/rbu/rbubusy.test 35a6ad081b374281f728b26264ef4f0b0e7888ccb5ace1843aed30ed99c2e1ca
|
||||
F ext/rbu/rbubusy.test f38ef557358564491b8a2ee70e4cad31e40fcea57a16f27bc56ba40a59bbde50
|
||||
F ext/rbu/rbucollate.test cac528a9a46318cba42e61258bb42660bbbf4fdb9a8c863de5a54ad0c658d197
|
||||
F ext/rbu/rbucrash.test 000981a1fe8a6e4d9a684232f6a129e66a3ef595f5ed74655e2f9c68ffa613b4
|
||||
F ext/rbu/rbucrash2.test efa143cc94228eb0266d3f1abfbee60a5838a84cef7cc3fcb8c145b74d96fd41
|
||||
@@ -487,7 +487,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c 9395ece9850ad57c6fbb453aeb5185be4bae3b159c4b37611425c565124ee849
|
||||
F src/analyze.c 3a119baeb03053c154029877454d41bb8fd79d4d1eb583392f2289b3554a75bc
|
||||
F src/analyze.c aabdf3769c7fd9954a8ec508eb7041ae174b66f88d12c47199fabbea9a646467
|
||||
F src/attach.c 4431f82f0247bf3aaf91589acafdff77d1882235c95407b36da1585c765fbbc8
|
||||
F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
|
||||
F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7
|
||||
@@ -496,7 +496,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c df695e953c2ce78ce4878ee5016751df9bc9a921dc0500a0f53ab3bb3196e505
|
||||
F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22
|
||||
F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e
|
||||
F src/build.c 470be339e458a48456cb317ad207ab3cb68ace8b2d76625d2a7eace660fc9674
|
||||
F src/build.c e8e776b52bc145cbf4e9fb88b99830083880fc2b174c2f96518fff15cbc72396
|
||||
F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad
|
||||
@@ -504,7 +504,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f
|
||||
F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68
|
||||
F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
|
||||
F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce
|
||||
F src/expr.c 6763de6e372ae113f4a079c5c155956ab18470d52c144ccf3ecb9d3df0704a4a
|
||||
F src/expr.c 132e30b849d7b3b8afbd61635a5c0365b3e5ae8dd39faa920b26b5e7eb46345d
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e
|
||||
F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761
|
||||
@@ -553,12 +553,12 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757
|
||||
F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
|
||||
F src/resolve.c b14bf8a4a1e3cb01eefc48a7e4129b15bb6a18b56d16dd4eca676586464337d0
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c 7236f3c4c1c27bd348dca60c746b1d48354c36d59223c673400c2115b871785e
|
||||
F src/select.c be3da92c2ba294d781facd4ea8a3e00de327354a44828e390716f60fd6b6c3d1
|
||||
F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35
|
||||
F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e
|
||||
F src/sqliteInt.h 1805e812191a7b38bfcc3a05e532603b39764191231dc41b1ea29973b7f82743
|
||||
F src/sqliteInt.h 0266967fa78be24d3c32c42bc2c4ab44a2a2c670cebaa9fd9fa22ad63c106fc6
|
||||
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
|
||||
F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@@ -640,7 +640,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
|
||||
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
|
||||
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
|
||||
F src/where.c bd4895fbb6ac9cc5b772d191b93dd5a240a505e3113be9aee0dc8c957568dd41
|
||||
F src/where.c 43085b3a4ce2e56315fabb0b240a56e76667d9e03c79f287695bcae7b76152d5
|
||||
F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556
|
||||
F src/wherecode.c 55a33d9db1759970c30220904bcc628ba66a1ccb63b5437ef4642f7ea6267b03
|
||||
F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5
|
||||
@@ -705,7 +705,7 @@ F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1
|
||||
F test/auth3.test 76d20a7fa136d63bcfcf8bcb65c0b1455ed71078d81f22bcd0550d3eb18594ab
|
||||
F test/autoanalyze1.test b9cc3f32a990fa56669b668d237c6d53e983554ae80c0604992e18869a0b2dec
|
||||
F test/autoinc.test 997d6f185f138229dc4251583a1d04816423dddc2fc034871a01aeb1d728cb39
|
||||
F test/autoindex1.test 523b26034dc5e0c5ff0865055b4593f75863b82f17748dec9ca64bb8b267c502
|
||||
F test/autoindex1.test cdc336e80cfd586c0e09426d58bec412db7527ca22dfabe88eab690e3acbb406
|
||||
F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
|
||||
F test/autoindex3.test 2d13958a5617e987624a428d7aed91bf51f322b49b476e3573fadec697ce6da5
|
||||
F test/autoindex4.test 5df39313526b6f22a26bd119bbd97ca69f28386ab3c671fc10568d921c41eb08
|
||||
@@ -815,7 +815,7 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
|
||||
F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b
|
||||
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
|
||||
F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af
|
||||
F test/corruptL.test 21a951d1eb09120f3c1561af5bac30ed49be2d9dfcad039f71759c5d9e28a349
|
||||
F test/corruptL.test ecce40d7b9b909a670a42a45d86e30d927735d7e7f09041af438b19529d35532
|
||||
F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067
|
||||
F test/corruptN.test 60b5a62944b4f0029ba07edaa5fd8e670539d6b0a8d99db26c068d435675cbfe
|
||||
F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576
|
||||
@@ -1951,8 +1951,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 f6ab67965b718b0c6d7faf769c7e47384cfd2ddbb03df518e0c5d367f8583387 3aefc874d31885c64a5e02868edb2aa56a2b4429252d494e67e4088a9298ce5b
|
||||
R 3897a09d3fd5e51780f1f3781df050fc
|
||||
P 2fb165cf8bd1e43248612aa2922bd311df30dcbb3c2f1daee73c363e409c501f e1f4a115df34e45cf1bcf98961c699b582f564a58a979e95853b219bda06212c
|
||||
R faed2a835a5b5dfd45bc593080cb511f
|
||||
U drh
|
||||
Z b6d265eae00430fdbf139ad32757b2a2
|
||||
Z 3711ae6870270d64360e9cabb9baf423
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
@@ -1 +1 @@
|
||||
2fb165cf8bd1e43248612aa2922bd311df30dcbb3c2f1daee73c363e409c501f
|
||||
3fd9706bba4a71cb5c7ce1341c3be0a7727941445820a073e7b2f0f32512e8ef
|
||||
@@ -847,9 +847,14 @@ static void statGet(
|
||||
** * "WHERE a=? AND b=?" matches 2 rows.
|
||||
**
|
||||
** If D is the count of distinct values and K is the total number of
|
||||
** rows, then each estimate is computed as:
|
||||
** rows, then each estimate is usually computed as:
|
||||
**
|
||||
** I = (K+D-1)/D
|
||||
**
|
||||
** In other words, I is K/D rounded up to the next whole integer.
|
||||
** However, if I is between 1.0 and 1.1 (in other words if I is
|
||||
** close to 1.0 but just a little larger) then do not round up but
|
||||
** instead keep the I value at 1.0.
|
||||
*/
|
||||
sqlite3_str sStat; /* Text of the constructed "stat" line */
|
||||
int i; /* Loop counter */
|
||||
@@ -860,6 +865,7 @@ static void statGet(
|
||||
for(i=0; i<p->nKeyCol; i++){
|
||||
u64 nDistinct = p->current.anDLt[i] + 1;
|
||||
u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
|
||||
if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1;
|
||||
sqlite3_str_appendf(&sStat, " %llu", iVal);
|
||||
assert( p->current.anEq[i] );
|
||||
}
|
||||
|
||||
15
src/build.c
15
src/build.c
@@ -172,9 +172,7 @@ void sqlite3FinishCoding(Parse *pParse){
|
||||
int i;
|
||||
int reg;
|
||||
|
||||
if( NEVER(pReturning->nRetCol==0) ){
|
||||
assert( CORRUPT_DB );
|
||||
}else{
|
||||
if( pReturning->nRetCol ){
|
||||
sqlite3VdbeAddOp0(v, OP_FkCheck);
|
||||
addrRewind =
|
||||
sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur);
|
||||
@@ -270,9 +268,7 @@ void sqlite3FinishCoding(Parse *pParse){
|
||||
|
||||
if( pParse->bReturning ){
|
||||
Returning *pRet = pParse->u1.pReturning;
|
||||
if( NEVER(pRet->nRetCol==0) ){
|
||||
assert( CORRUPT_DB );
|
||||
}else{
|
||||
if( pRet->nRetCol ){
|
||||
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol);
|
||||
}
|
||||
}
|
||||
@@ -3059,7 +3055,6 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
Table *pSelTab; /* A fake table from which we get the result set */
|
||||
Select *pSel; /* Copy of the SELECT that implements the view */
|
||||
int nErr = 0; /* Number of errors encountered */
|
||||
int n; /* Temporarily holds the number of cursors assigned */
|
||||
sqlite3 *db = pParse->db; /* Database connection for malloc errors */
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
int rc;
|
||||
@@ -3117,8 +3112,9 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
pSel = sqlite3SelectDup(db, pTable->u.view.pSelect, 0);
|
||||
if( pSel ){
|
||||
u8 eParseMode = pParse->eParseMode;
|
||||
int nTab = pParse->nTab;
|
||||
int nSelect = pParse->nSelect;
|
||||
pParse->eParseMode = PARSE_MODE_NORMAL;
|
||||
n = pParse->nTab;
|
||||
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
|
||||
pTable->nCol = -1;
|
||||
DisableLookaside;
|
||||
@@ -3130,7 +3126,8 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
|
||||
#else
|
||||
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE);
|
||||
#endif
|
||||
pParse->nTab = n;
|
||||
pParse->nTab = nTab;
|
||||
pParse->nSelect = nSelect;
|
||||
if( pSelTab==0 ){
|
||||
pTable->nCol = 0;
|
||||
nErr++;
|
||||
|
||||
36
src/expr.c
36
src/expr.c
@@ -2297,6 +2297,42 @@ int sqlite3ExprIsTableConstant(Expr *p, int iCur){
|
||||
return exprIsConst(p, 3, iCur);
|
||||
}
|
||||
|
||||
/*
|
||||
** Check pExpr to see if it is an invariant constraint on data source pSrc.
|
||||
** This is an optimization. False negatives will perhaps cause slower
|
||||
** queries, but false positives will yield incorrect answers. So when in
|
||||
** doubt, return 0.
|
||||
**
|
||||
** To be an invariant constraint, the following must be true:
|
||||
**
|
||||
** (1) pExpr cannot refer to any table other than pSrc->iCursor.
|
||||
**
|
||||
** (2) pExpr cannot use subqueries or non-deterministic functions.
|
||||
**
|
||||
** (3) pSrc cannot be part of the left operand for a RIGHT JOIN.
|
||||
** (Is there some way to relax this constraint?)
|
||||
**
|
||||
** (4) If pSrc is the right operand of a LEFT JOIN, then...
|
||||
** (4a) pExpr must come from an ON clause..
|
||||
(4b) and specifically the ON clause associated with the LEFT JOIN.
|
||||
**
|
||||
** (5) If pSrc is not the right operand of a LEFT JOIN or the left
|
||||
** operand of a RIGHT JOIN, then pExpr must be from the WHERE
|
||||
** clause, not an ON clause.
|
||||
*/
|
||||
int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){
|
||||
if( pSrc->fg.jointype & JT_LTORJ ){
|
||||
return 0; /* rule (3) */
|
||||
}
|
||||
if( pSrc->fg.jointype & JT_LEFT ){
|
||||
if( !ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (4a) */
|
||||
if( pExpr->w.iJoin!=pSrc->iCursor ) return 0; /* rule (4b) */
|
||||
}else{
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (5) */
|
||||
}
|
||||
return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy().
|
||||
|
||||
22
src/select.c
22
src/select.c
@@ -4329,6 +4329,7 @@ static int flattenSubquery(
|
||||
|
||||
if( pSrc->nSrc>1 ){
|
||||
if( pParse->nSelect>500 ) return 0;
|
||||
if( OptimizationDisabled(db, SQLITE_FlttnUnionAll) ) return 0;
|
||||
aCsrMap = sqlite3DbMallocZero(db, ((i64)pParse->nTab+1)*sizeof(int));
|
||||
if( aCsrMap ) aCsrMap[0] = pParse->nTab;
|
||||
}
|
||||
@@ -4957,13 +4958,13 @@ static int pushDownWhereTerms(
|
||||
Parse *pParse, /* Parse context (for malloc() and error reporting) */
|
||||
Select *pSubq, /* The subquery whose WHERE clause is to be augmented */
|
||||
Expr *pWhere, /* The WHERE clause of the outer query */
|
||||
int iCursor, /* Cursor number of the subquery */
|
||||
int isLeftJoin /* True if pSubq is the right term of a LEFT JOIN */
|
||||
SrcItem *pSrc /* The subquery term of the outer FROM clause */
|
||||
){
|
||||
Expr *pNew;
|
||||
int nChng = 0;
|
||||
if( pWhere==0 ) return 0;
|
||||
if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0;
|
||||
if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ) return 0;
|
||||
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( pSubq->pPrior ){
|
||||
@@ -4993,10 +4994,11 @@ static int pushDownWhereTerms(
|
||||
return 0; /* restriction (3) */
|
||||
}
|
||||
while( pWhere->op==TK_AND ){
|
||||
nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight,
|
||||
iCursor, isLeftJoin);
|
||||
nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrc);
|
||||
pWhere = pWhere->pLeft;
|
||||
}
|
||||
|
||||
#if 0 /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */
|
||||
if( isLeftJoin
|
||||
&& (ExprHasProperty(pWhere,EP_FromJoin)==0
|
||||
|| pWhere->w.iJoin!=iCursor)
|
||||
@@ -5008,7 +5010,9 @@ static int pushDownWhereTerms(
|
||||
){
|
||||
return 0; /* restriction (5) */
|
||||
}
|
||||
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
|
||||
#endif
|
||||
|
||||
if( sqlite3ExprIsTableConstraint(pWhere, pSrc) ){
|
||||
nChng++;
|
||||
pSubq->selFlags |= SF_PushDown;
|
||||
while( pSubq ){
|
||||
@@ -5016,8 +5020,8 @@ static int pushDownWhereTerms(
|
||||
pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
|
||||
unsetJoinExpr(pNew, -1);
|
||||
x.pParse = pParse;
|
||||
x.iTable = iCursor;
|
||||
x.iNewTable = iCursor;
|
||||
x.iTable = pSrc->iCursor;
|
||||
x.iNewTable = pSrc->iCursor;
|
||||
x.isOuterJoin = 0;
|
||||
x.pEList = pSubq->pEList;
|
||||
pNew = substExpr(&x, pNew);
|
||||
@@ -6870,9 +6874,7 @@ int sqlite3Select(
|
||||
if( OptimizationEnabled(db, SQLITE_PushDown)
|
||||
&& (pItem->fg.isCte==0
|
||||
|| (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2))
|
||||
&& (pItem->fg.jointype & JT_RIGHT)==0
|
||||
&& pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor,
|
||||
(pItem->fg.jointype & JT_OUTER)!=0)
|
||||
&& pushDownWhereTerms(pParse, pSub, p->pWhere, pItem)
|
||||
){
|
||||
#if TREETRACE_ENABLED
|
||||
if( sqlite3TreeTrace & 0x100 ){
|
||||
|
||||
@@ -1780,6 +1780,7 @@ struct sqlite3 {
|
||||
#define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */
|
||||
#define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */
|
||||
#define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */
|
||||
#define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */
|
||||
#define SQLITE_AllOpts 0xffffffff /* All optimizations */
|
||||
|
||||
/*
|
||||
@@ -4753,6 +4754,7 @@ int sqlite3ExprIsConstantNotJoin(Expr*);
|
||||
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
|
||||
int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
|
||||
int sqlite3ExprIsTableConstant(Expr*,int);
|
||||
int sqlite3ExprIsTableConstraint(Expr*,const SrcItem*);
|
||||
#ifdef SQLITE_ENABLE_CURSOR_HINTS
|
||||
int sqlite3ExprContainsSubquery(Expr*);
|
||||
#endif
|
||||
|
||||
@@ -832,9 +832,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
|
||||
** WHERE clause (or the ON clause of a LEFT join) that constrain which
|
||||
** rows of the target table (pSrc) that can be used. */
|
||||
if( (pTerm->wtFlags & TERM_VIRTUAL)==0
|
||||
&& ((pSrc->fg.jointype&(JT_LEFT|JT_LTORJ))==0
|
||||
|| ExprHasProperty(pExpr,EP_FromJoin))
|
||||
&& sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor)
|
||||
&& sqlite3ExprIsTableConstraint(pExpr, pSrc)
|
||||
){
|
||||
pPartial = sqlite3ExprAnd(pParse, pPartial,
|
||||
sqlite3ExprDup(pParse->db, pExpr, 0));
|
||||
@@ -1073,7 +1071,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
|
||||
for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){
|
||||
Expr *pExpr = pTerm->pExpr;
|
||||
if( (pTerm->wtFlags & TERM_VIRTUAL)==0
|
||||
&& sqlite3ExprIsTableConstant(pExpr, iCur)
|
||||
&& sqlite3ExprIsTableConstraint(pExpr, pItem)
|
||||
){
|
||||
sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
|
||||
}
|
||||
|
||||
@@ -542,7 +542,23 @@ do_execsql_test autoindex1-1020 {
|
||||
SELECT count(*) FROM t11 LEFT JOIN t12 WHERE t12.y IS t11.w;
|
||||
} 0
|
||||
|
||||
|
||||
|
||||
# 2022-04-25
|
||||
# https://sqlite.org/forum/forumpost/0d3200f4f3bcd3a3
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test autoindex-1100 {
|
||||
CREATE TABLE t1(a INT, b INT);
|
||||
CREATE TABLE t2(c INT, d INT);
|
||||
CREATE TABLE t3(e TEXT, f TEXT);
|
||||
INSERT INTO t1 VALUES(1, 1);
|
||||
INSERT INTO t2 VALUES(1, 2);
|
||||
INSERT INTO t3 VALUES('abc', 'def');
|
||||
} {}
|
||||
do_execsql_test autoindex-1110 {
|
||||
SELECT * FROM t1, t2 LEFT JOIN t3 ON (t2.d=1) WHERE t2.c = +t1.a;
|
||||
} {1 1 1 2 {} {}}
|
||||
do_execsql_test autoindex-1120 {
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON (t2.c=+t1.a) LEFT JOIN t3 ON (t2.d IS NULL);
|
||||
} {1 1 1 2 {} {}}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -1480,8 +1480,12 @@ do_execsql_test 19.1 {
|
||||
PRAGMA writable_schema=ON;
|
||||
}
|
||||
|
||||
set err "UNIQUE constraint failed: index 'a'"
|
||||
ifcapable oversize_cell_check {
|
||||
set err "database disk image is malformed"
|
||||
}
|
||||
do_catchsql_test 19.2 {
|
||||
UPDATE t1 SET a=1;
|
||||
} {1 {UNIQUE constraint failed: index 'a'}}
|
||||
} [list 1 $err]
|
||||
|
||||
finish_test
|
||||
|
||||
Reference in New Issue
Block a user