From: drh Date: Thu, 29 Oct 2015 12:27:38 +0000 (+0000) Subject: Apply optimizations to simplify OR clauses that contain constant terms. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=04903ebd6488c05c7e322b157fb6194164c7e5bd;p=thirdparty%2Fsqlite.git Apply optimizations to simplify OR clauses that contain constant terms. FossilOrigin-Name: d533e23f059621364bd5dac5fae794f5973b1349 --- diff --git a/manifest b/manifest index 8948b0157f..5bcc4ac7de 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\scomments\sin\sthe\sMSVC\sbatch\sbuild\stool. -D 2015-10-29T01:11:39.776 +C Apply\soptimizations\sto\ssimplify\sOR\sclauses\sthat\scontain\sconstant\sterms. +D 2015-10-29T12:27:38.220 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -292,7 +292,7 @@ F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a F src/date.c fb1c99172017dcc8e237339132c91a21a0788584 F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7 F src/delete.c c4c6fb9da78b946fcba2a6aac5b24bc5c15e752a -F src/expr.c 0080c0f12806eca91e75a23a121a68918e9da357 +F src/expr.c 16043ce1cae327c6d2741ce957d330dc886cc9bd F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0 F src/func.c ecdd69ec6a1e406f04cc73324be2ebbf6354197f @@ -1299,7 +1299,7 @@ F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e F test/where.test 66d4c107e82dfe86c01a96277b77e7a8809aff0b -F test/where2.test af78c55589cbc82d793449493adba0dc3d659f23 +F test/where2.test bf89ae340ec5232139c92dca73d1c7a63bff8a5a F test/where3.test 1ad55ba900bd7747f98b6082e65bd3e442c5004e F test/where4.test 44f506bf1737cf0fa4fc795e340208250f1fcd89 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 @@ -1395,7 +1395,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b10ab59fb8a696d11a269f3904e799c687246aea -R cc38e20a3bed22c727ef2060f0363586 -U mistachkin -Z f9c898158c1864e737c38818df859932 +P 2964ce25864e8aec86272af741caf49c23c86590 +R 57486ab12cf1b6d70dfe1218fae485c0 +T *branch * simplify-or-clause +T *sym-simplify-or-clause * +T -sym-trunk * +U drh +Z 9ae1cb934c0243b6a4710d4055ef8330 diff --git a/manifest.uuid b/manifest.uuid index 2101e8fe36..c665ab655b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2964ce25864e8aec86272af741caf49c23c86590 \ No newline at end of file +d533e23f059621364bd5dac5fae794f5973b1349 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6371e15ca7..3d57d9edf0 100644 --- a/src/expr.c +++ b/src/expr.c @@ -533,34 +533,6 @@ void sqlite3ExprAttachSubtrees( } } -/* -** Allocate an Expr node which joins as many as two subtrees. -** -** One or both of the subtrees can be NULL. Return a pointer to the new -** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed, -** free the subtrees and return NULL. -*/ -Expr *sqlite3PExpr( - Parse *pParse, /* Parsing context */ - int op, /* Expression opcode */ - Expr *pLeft, /* Left operand */ - Expr *pRight, /* Right operand */ - const Token *pToken /* Argument token */ -){ - Expr *p; - if( op==TK_AND && pParse->nErr==0 ){ - /* Take advantage of short-circuit false optimization for AND */ - p = sqlite3ExprAnd(pParse->db, pLeft, pRight); - }else{ - p = sqlite3ExprAlloc(pParse->db, op & TKFLG_MASK, pToken, 1); - sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); - } - if( p ) { - sqlite3ExprCheckHeight(pParse, p->nHeight); - } - return p; -} - /* ** If the expression is always either TRUE or FALSE (respectively), ** then return 1. If one cannot determine the truth value of the @@ -612,6 +584,62 @@ Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){ } } +/* Join expressions pLeft and pRight using OR. Apply constant-folding +** style optimizations. For example, "x OR 1" becomes just "1". +*/ +static Expr *sqlite3ExprOr(sqlite3 *db, Expr *pLeft, Expr *pRight){ + if( pLeft && exprAlwaysFalse(pLeft) ){ + sqlite3ExprDelete(db, pLeft); + pLeft = 0; + } + if( pRight==0 || exprAlwaysFalse(pRight) ){ + sqlite3ExprDelete(db, pRight); + if( pLeft ) return pLeft; + return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0); + } + if( pLeft==0 ) return pRight; + if( exprAlwaysTrue(pLeft) || exprAlwaysTrue(pRight) ){ + sqlite3ExprDelete(db, pLeft); + sqlite3ExprDelete(db, pRight); + return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0); + }else{ + Expr *pNew = sqlite3ExprAlloc(db, TK_OR, 0, 0); + sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight); + return pNew; + } +} + +/* +** Allocate an Expr node which joins as many as two subtrees. +** +** One or both of the subtrees can be NULL. Return a pointer to the new +** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed, +** free the subtrees and return NULL. +*/ +Expr *sqlite3PExpr( + Parse *pParse, /* Parsing context */ + int op, /* Expression opcode */ + Expr *pLeft, /* Left operand */ + Expr *pRight, /* Right operand */ + const Token *pToken /* Argument token */ +){ + Expr *p; + if( pParse->nErr==0 && op==TK_AND ){ + /* Take advantage of short-circuit false optimization for AND */ + p = sqlite3ExprAnd(pParse->db, pLeft, pRight); + }else if( pParse->nErr==0 && op==TK_OR ){ + /* Take advantage of short-circuit false optimization for OR */ + p = sqlite3ExprOr(pParse->db, pLeft, pRight); + }else{ + p = sqlite3ExprAlloc(pParse->db, op & TKFLG_MASK, pToken, 1); + sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); + } + if( p ) { + sqlite3ExprCheckHeight(pParse, p->nHeight); + } + return p; +} + /* ** Construct a new expression node for a function with multiple ** arguments. diff --git a/test/where2.test b/test/where2.test index 434a7bcd9a..e471580e7f 100644 --- a/test/where2.test +++ b/test/where2.test @@ -298,6 +298,7 @@ ifcapable subquery { # Verify that OR clauses get translated into IN operators. # set ::idx {} +exit ifcapable subquery {set ::idx i1w} do_test where2-6.1.1 { queryplan {