Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Apply optimizations to simplify OR clauses that contain constant terms. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | simplify-or-clause |
Files: | files | file ages | folders |
SHA1: |
d533e23f059621364bd5dac5fae794f5 |
User & Date: | drh 2015-10-29 12:27:38.220 |
Context
2015-10-29
| ||
14:29 | The optimization on this branch is logically incorrect. It changes the return value of "SELECT 0 OR 'xyzzy'" FROM 0 to 'xyzzy'. (Closed-Leaf check-in: a0c08d2689 user: drh tags: simplify-or-clause) | |
12:27 | Apply optimizations to simplify OR clauses that contain constant terms. (check-in: d533e23f05 user: drh tags: simplify-or-clause) | |
01:11 | Enhance comments in the MSVC batch build tool. (check-in: 2964ce2586 user: mistachkin tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
529 530 531 532 533 534 535 | pRoot->pLeft = pLeft; pRoot->flags |= EP_Propagate & pLeft->flags; } exprSetHeight(pRoot); } } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 529 530 531 532 533 534 535 536 537 538 539 540 541 542 | pRoot->pLeft = pLeft; pRoot->flags |= EP_Propagate & pLeft->flags; } exprSetHeight(pRoot); } } /* ** If the expression is always either TRUE or FALSE (respectively), ** then return 1. If one cannot determine the truth value of the ** expression at compile-time return 0. ** ** This is an optimization. If is OK to return 0 here even if ** the expression really is always false or false (a false negative). |
︙ | ︙ | |||
607 608 609 610 611 612 613 614 615 616 617 618 619 620 | return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0); }else{ Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0); sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight); return pNew; } } /* ** Construct a new expression node for a function with multiple ** arguments. */ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ Expr *pNew; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 | return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0); }else{ Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0); sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight); return pNew; } } /* 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. */ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){ Expr *pNew; |
︙ | ︙ |
Changes to test/where2.test.
︙ | ︙ | |||
294 295 296 297 298 299 300 301 302 303 304 305 306 307 | } } {99 6 10000 10006 nosort t1 i1w} } # Verify that OR clauses get translated into IN operators. # set ::idx {} ifcapable subquery {set ::idx i1w} do_test where2-6.1.1 { queryplan { SELECT * FROM t1 WHERE w=99 OR w=100 ORDER BY +w } } [list 99 6 10000 10006 100 6 10201 10207 sort t1 $::idx] do_test where2-6.1.2 { | > | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | } } {99 6 10000 10006 nosort t1 i1w} } # Verify that OR clauses get translated into IN operators. # set ::idx {} exit ifcapable subquery {set ::idx i1w} do_test where2-6.1.1 { queryplan { SELECT * FROM t1 WHERE w=99 OR w=100 ORDER BY +w } } [list 99 6 10000 10006 100 6 10201 10207 sort t1 $::idx] do_test where2-6.1.2 { |
︙ | ︙ |