Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Do not name variables "operator" because some compilers do not realize that "operator" is not a reserved word in ANSI-C. Ticket #1625. (CVS 2997) |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
1f42a338e2ee90f4c24a9eb19054c4b8 |
User & Date: | drh 2006-01-23 13:22:09 |
Context
2006-01-23
| ||
13:28 | Fix to sqlite3AllocMalloc() when it is a no-op macro. (CVS 2998) check-in: 8caa9f95 user: drh tags: trunk | |
13:22 | Do not name variables "operator" because some compilers do not realize that "operator" is not a reserved word in ANSI-C. Ticket #1625. (CVS 2997) check-in: 1f42a338 user: drh tags: trunk | |
13:14 | Work around buggy malloc() implementations that cause problems on malloc(0). Ticket #1572. (CVS 2996) check-in: ada5490f user: drh tags: trunk | |
Changes
Changes to src/parse.y.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 .. 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 ... 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 |
** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** ** @(#) $Id: parse.y,v 1.192 2006/01/07 14:02:27 danielk1977 Exp $ */ // All token codes are small integers with #defines that begin with "TK_" %token_prefix TK_ // The type of the data attached to each token is Token. This is also the // default type for non-terminals. ................................................................................ }; /* ** An instance of this structure is used to store the LIKE, ** GLOB, NOT LIKE, and NOT GLOB operators. */ struct LikeOp { Token operator; /* "like" or "glob" or "regexp" */ int not; /* True if the NOT keyword is present */ }; /* ** An instance of the following structure describes the event of a ** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT, ** TK_DELETE, or TK_INSTEAD. If the event is of the form ................................................................................ expr(A) ::= expr(X) EQ|NE(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) CONCAT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} %type likeop {struct LikeOp} likeop(A) ::= LIKE_KW(X). {A.operator = X; A.not = 0;} likeop(A) ::= NOT LIKE_KW(X). {A.operator = X; A.not = 1;} %type escape {Expr*} %destructor escape {sqlite3ExprDelete($$);} escape(X) ::= ESCAPE expr(A). [ESCAPE] {X = A;} escape(X) ::= . [ESCAPE] {X = 0;} expr(A) ::= expr(X) likeop(OP) expr(Y) escape(E). [LIKE_KW] { ExprList *pList = sqlite3ExprListAppend(0, Y, 0); pList = sqlite3ExprListAppend(pList, X, 0); if( E ){ pList = sqlite3ExprListAppend(pList, E, 0); } A = sqlite3ExprFunction(pList, &OP.operator); if( OP.not ) A = sqlite3Expr(TK_NOT, A, 0, 0); sqlite3ExprSpan(A, &X->span, &Y->span); } expr(A) ::= expr(X) ISNULL|NOTNULL(E). { A = sqlite3Expr(@E, X, 0, 0); sqlite3ExprSpan(A,&X->span,&E); |
| | | | | |
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 .. 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 ... 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 |
** ************************************************************************* ** This file contains SQLite's grammar for SQL. Process this file ** using the lemon parser generator to generate C code that runs ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** ** @(#) $Id: parse.y,v 1.193 2006/01/23 13:22:09 drh Exp $ */ // All token codes are small integers with #defines that begin with "TK_" %token_prefix TK_ // The type of the data attached to each token is Token. This is also the // default type for non-terminals. ................................................................................ }; /* ** An instance of this structure is used to store the LIKE, ** GLOB, NOT LIKE, and NOT GLOB operators. */ struct LikeOp { Token eOperator; /* "like" or "glob" or "regexp" */ int not; /* True if the NOT keyword is present */ }; /* ** An instance of the following structure describes the event of a ** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT, ** TK_DELETE, or TK_INSTEAD. If the event is of the form ................................................................................ expr(A) ::= expr(X) EQ|NE(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} expr(A) ::= expr(X) CONCAT(OP) expr(Y). {A = sqlite3Expr(@OP, X, Y, 0);} %type likeop {struct LikeOp} likeop(A) ::= LIKE_KW(X). {A.eOperator = X; A.not = 0;} likeop(A) ::= NOT LIKE_KW(X). {A.eOperator = X; A.not = 1;} %type escape {Expr*} %destructor escape {sqlite3ExprDelete($$);} escape(X) ::= ESCAPE expr(A). [ESCAPE] {X = A;} escape(X) ::= . [ESCAPE] {X = 0;} expr(A) ::= expr(X) likeop(OP) expr(Y) escape(E). [LIKE_KW] { ExprList *pList = sqlite3ExprListAppend(0, Y, 0); pList = sqlite3ExprListAppend(pList, X, 0); if( E ){ pList = sqlite3ExprListAppend(pList, E, 0); } A = sqlite3ExprFunction(pList, &OP.eOperator); if( OP.not ) A = sqlite3Expr(TK_NOT, A, 0, 0); sqlite3ExprSpan(A, &X->span, &Y->span); } expr(A) ::= expr(X) ISNULL|NOTNULL(E). { A = sqlite3Expr(@E, X, 0, 0); sqlite3ExprSpan(A,&X->span,&E); |
Changes to src/where.c.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 .. 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 ... 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 ... 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 ... 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 ... 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 ... 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 .... 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 .... 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 .... 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 |
** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.201 2006/01/23 13:00:38 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) ................................................................................ */ typedef struct WhereTerm WhereTerm; struct WhereTerm { Expr *pExpr; /* Pointer to the subexpression */ i16 iParent; /* Disable pWC->a[iParent] when this term disabled */ i16 leftCursor; /* Cursor number of X in "X <op> <expr>" */ i16 leftColumn; /* Column number of X in "X <op> <expr>" */ u16 operator; /* A WO_xx value describing <op> */ u8 flags; /* Bit flags. See below */ u8 nChild; /* Number of children that must disable us */ WhereClause *pWC; /* The clause this term is part of */ Bitmask prereqRight; /* Bitmask of tables used by pRight */ Bitmask prereqAll; /* Bitmask of tables referenced by p */ }; ................................................................................ ){ WhereTerm *pTerm; int k; for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){ if( pTerm->leftCursor==iCur && (pTerm->prereqRight & notReady)==0 && pTerm->leftColumn==iColumn && (pTerm->operator & op)!=0 ){ if( iCur>=0 && pIdx ){ Expr *pX = pTerm->pExpr; CollSeq *pColl; char idxaff; int k; Parse *pParse = pWC->pParse; ................................................................................ prereqAll = exprTableUsage(pMaskSet, pExpr); if( ExprHasProperty(pExpr, EP_FromJoin) ){ prereqAll |= getMask(pMaskSet, pExpr->iRightJoinTable); } pTerm->prereqAll = prereqAll; pTerm->leftCursor = -1; pTerm->iParent = -1; pTerm->operator = 0; if( allowedOp(pExpr->op) && (pTerm->prereqRight & prereqLeft)==0 ){ Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; if( pLeft->op==TK_COLUMN ){ pTerm->leftCursor = pLeft->iTable; pTerm->leftColumn = pLeft->iColumn; pTerm->operator = operatorMask(pExpr->op); } if( pRight && pRight->op==TK_COLUMN ){ WhereTerm *pNew; Expr *pDup; if( pTerm->leftCursor>=0 ){ int idxNew; pDup = sqlite3ExprDup(pExpr); ................................................................................ } exprCommute(pDup); pLeft = pDup->pLeft; pNew->leftCursor = pLeft->iTable; pNew->leftColumn = pLeft->iColumn; pNew->prereqRight = prereqLeft; pNew->prereqAll = prereqAll; pNew->operator = operatorMask(pDup->op); } } #ifndef SQLITE_OMIT_BETWEEN_OPTIMIZATION /* If a term is the BETWEEN operator, create two new virtual terms ** that define the range that the BETWEEN implements. */ ................................................................................ assert( sOr.nTerm>0 ); j = 0; do{ iColumn = sOr.a[j].leftColumn; iCursor = sOr.a[j].leftCursor; ok = iCursor>=0; for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0 && ok; i--, pOrTerm++){ if( pOrTerm->operator!=WO_EQ ){ goto or_not_possible; } if( pOrTerm->leftCursor==iCursor && pOrTerm->leftColumn==iColumn ){ pOrTerm->flags |= TERM_OR_OK; }else if( (pOrTerm->flags & TERM_COPIED)!=0 || ((pOrTerm->flags & TERM_VIRTUAL)!=0 && (sOr.a[pOrTerm->iParent].flags & TERM_OR_OK)!=0) ){ ................................................................................ /* Check for a rowid=EXPR or rowid IN (...) constraints */ pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0); if( pTerm ){ Expr *pExpr; *ppIndex = 0; bestFlags = WHERE_ROWID_EQ; if( pTerm->operator & WO_EQ ){ /* Rowid== is always the best pick. Look no further. Because only ** a single row is generated, output is always in sorted order */ *pFlags = WHERE_ROWID_EQ | WHERE_UNIQUE; *pnEq = 1; TRACE(("... best is rowid\n")); return 0.0; }else if( (pExpr = pTerm->pExpr)->pList!=0 ){ ................................................................................ */ flags = 0; for(i=0; i<pProbe->nColumn; i++){ int j = pProbe->aiColumn[i]; pTerm = findTerm(pWC, iCur, j, notReady, WO_EQ|WO_IN, pProbe); if( pTerm==0 ) break; flags |= WHERE_COLUMN_EQ; if( pTerm->operator & WO_IN ){ Expr *pExpr = pTerm->pExpr; flags |= WHERE_COLUMN_IN; if( pExpr->pSelect!=0 ){ inMultiplier *= 100; }else if( pExpr->pList!=0 ){ inMultiplier *= pExpr->pList->nExpr + 1; } ................................................................................ Expr *pX; int k = pIdx->aiColumn[j]; pTerm = findTerm(&wc, iCur, k, notReady, topOp, pIdx); assert( pTerm!=0 ); pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); sqlite3ExprCode(pParse, pX->pRight); topEq = pTerm->operator & (WO_LE|WO_GE); disableTerm(pLevel, pTerm); testOp = OP_IdxGE; }else{ testOp = nEq>0 ? OP_IdxGE : OP_Noop; topEq = 1; } if( testOp!=OP_Noop ){ ................................................................................ Expr *pX; int k = pIdx->aiColumn[j]; pTerm = findTerm(&wc, iCur, k, notReady, btmOp, pIdx); assert( pTerm!=0 ); pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); sqlite3ExprCode(pParse, pX->pRight); btmEq = pTerm->operator & (WO_LE|WO_GE); disableTerm(pLevel, pTerm); }else{ btmEq = 1; } if( nEq>0 || btmLimit ){ int nCol = nEq + btmLimit; buildIndexProbe(v, nCol, 0, brk, pIdx); |
| | | | | | | | | | | |
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 .. 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 ... 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 ... 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 ... 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 ... 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 ... 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 .... 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 .... 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 .... 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 |
** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.202 2006/01/23 13:22:10 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) ................................................................................ */ typedef struct WhereTerm WhereTerm; struct WhereTerm { Expr *pExpr; /* Pointer to the subexpression */ i16 iParent; /* Disable pWC->a[iParent] when this term disabled */ i16 leftCursor; /* Cursor number of X in "X <op> <expr>" */ i16 leftColumn; /* Column number of X in "X <op> <expr>" */ u16 eOperator; /* A WO_xx value describing <op> */ u8 flags; /* Bit flags. See below */ u8 nChild; /* Number of children that must disable us */ WhereClause *pWC; /* The clause this term is part of */ Bitmask prereqRight; /* Bitmask of tables used by pRight */ Bitmask prereqAll; /* Bitmask of tables referenced by p */ }; ................................................................................ ){ WhereTerm *pTerm; int k; for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){ if( pTerm->leftCursor==iCur && (pTerm->prereqRight & notReady)==0 && pTerm->leftColumn==iColumn && (pTerm->eOperator & op)!=0 ){ if( iCur>=0 && pIdx ){ Expr *pX = pTerm->pExpr; CollSeq *pColl; char idxaff; int k; Parse *pParse = pWC->pParse; ................................................................................ prereqAll = exprTableUsage(pMaskSet, pExpr); if( ExprHasProperty(pExpr, EP_FromJoin) ){ prereqAll |= getMask(pMaskSet, pExpr->iRightJoinTable); } pTerm->prereqAll = prereqAll; pTerm->leftCursor = -1; pTerm->iParent = -1; pTerm->eOperator = 0; if( allowedOp(pExpr->op) && (pTerm->prereqRight & prereqLeft)==0 ){ Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; if( pLeft->op==TK_COLUMN ){ pTerm->leftCursor = pLeft->iTable; pTerm->leftColumn = pLeft->iColumn; pTerm->eOperator = operatorMask(pExpr->op); } if( pRight && pRight->op==TK_COLUMN ){ WhereTerm *pNew; Expr *pDup; if( pTerm->leftCursor>=0 ){ int idxNew; pDup = sqlite3ExprDup(pExpr); ................................................................................ } exprCommute(pDup); pLeft = pDup->pLeft; pNew->leftCursor = pLeft->iTable; pNew->leftColumn = pLeft->iColumn; pNew->prereqRight = prereqLeft; pNew->prereqAll = prereqAll; pNew->eOperator = operatorMask(pDup->op); } } #ifndef SQLITE_OMIT_BETWEEN_OPTIMIZATION /* If a term is the BETWEEN operator, create two new virtual terms ** that define the range that the BETWEEN implements. */ ................................................................................ assert( sOr.nTerm>0 ); j = 0; do{ iColumn = sOr.a[j].leftColumn; iCursor = sOr.a[j].leftCursor; ok = iCursor>=0; for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0 && ok; i--, pOrTerm++){ if( pOrTerm->eOperator!=WO_EQ ){ goto or_not_possible; } if( pOrTerm->leftCursor==iCursor && pOrTerm->leftColumn==iColumn ){ pOrTerm->flags |= TERM_OR_OK; }else if( (pOrTerm->flags & TERM_COPIED)!=0 || ((pOrTerm->flags & TERM_VIRTUAL)!=0 && (sOr.a[pOrTerm->iParent].flags & TERM_OR_OK)!=0) ){ ................................................................................ /* Check for a rowid=EXPR or rowid IN (...) constraints */ pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0); if( pTerm ){ Expr *pExpr; *ppIndex = 0; bestFlags = WHERE_ROWID_EQ; if( pTerm->eOperator & WO_EQ ){ /* Rowid== is always the best pick. Look no further. Because only ** a single row is generated, output is always in sorted order */ *pFlags = WHERE_ROWID_EQ | WHERE_UNIQUE; *pnEq = 1; TRACE(("... best is rowid\n")); return 0.0; }else if( (pExpr = pTerm->pExpr)->pList!=0 ){ ................................................................................ */ flags = 0; for(i=0; i<pProbe->nColumn; i++){ int j = pProbe->aiColumn[i]; pTerm = findTerm(pWC, iCur, j, notReady, WO_EQ|WO_IN, pProbe); if( pTerm==0 ) break; flags |= WHERE_COLUMN_EQ; if( pTerm->eOperator & WO_IN ){ Expr *pExpr = pTerm->pExpr; flags |= WHERE_COLUMN_IN; if( pExpr->pSelect!=0 ){ inMultiplier *= 100; }else if( pExpr->pList!=0 ){ inMultiplier *= pExpr->pList->nExpr + 1; } ................................................................................ Expr *pX; int k = pIdx->aiColumn[j]; pTerm = findTerm(&wc, iCur, k, notReady, topOp, pIdx); assert( pTerm!=0 ); pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); sqlite3ExprCode(pParse, pX->pRight); topEq = pTerm->eOperator & (WO_LE|WO_GE); disableTerm(pLevel, pTerm); testOp = OP_IdxGE; }else{ testOp = nEq>0 ? OP_IdxGE : OP_Noop; topEq = 1; } if( testOp!=OP_Noop ){ ................................................................................ Expr *pX; int k = pIdx->aiColumn[j]; pTerm = findTerm(&wc, iCur, k, notReady, btmOp, pIdx); assert( pTerm!=0 ); pX = pTerm->pExpr; assert( (pTerm->flags & TERM_CODED)==0 ); sqlite3ExprCode(pParse, pX->pRight); btmEq = pTerm->eOperator & (WO_LE|WO_GE); disableTerm(pLevel, pTerm); }else{ btmEq = 1; } if( nEq>0 || btmLimit ){ int nCol = nEq + btmLimit; buildIndexProbe(v, nCol, 0, brk, pIdx); |