Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix typo reported by ticket #3888. Other minor edits to facilitate coverage testing. (CVS 6695) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
164adf261d2536f16c83e44f6482dfb3 |
User & Date: | drh 2009-05-30 23:35:43.000 |
Context
2009-05-31
| ||
17:16 | Fix the ".genfkey" command of the CLI so that it does not leak memory if sqlite3_realloc() fails. Ticket #3891. (CVS 6696) (check-in: a028d69c70 user: drh tags: trunk) | |
2009-05-30
| ||
23:35 | Fix typo reported by ticket #3888. Other minor edits to facilitate coverage testing. (CVS 6695) (check-in: 164adf261d user: drh tags: trunk) | |
20:49 | Simplifications to the expr.c source module resulting from structural testing. (CVS 6694) (check-in: f760bb7a03 user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.444 2009/05/30 23:35:43 drh Exp $ */ #include "sqliteInt.h" /* ** Return the 'affinity' of the expression pExpr if any. ** ** If pExpr is a column, a reference to a column via an 'AS' alias, |
︙ | ︙ | |||
2621 2622 2623 2624 2625 2626 2627 | assert( pTest!=0 ); opCompare.pRight = aListelem[i].pExpr; }else{ pTest = aListelem[i].pExpr; } nextCase = sqlite3VdbeMakeLabel(v); testcase( pTest->op==TK_COLUMN ); | < | 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 | assert( pTest!=0 ); opCompare.pRight = aListelem[i].pExpr; }else{ pTest = aListelem[i].pExpr; } nextCase = sqlite3VdbeMakeLabel(v); testcase( pTest->op==TK_COLUMN ); sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); testcase( aListelem[i+1].pExpr->op==TK_REGISTER ); sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel); sqlite3ExprCachePop(pParse, 1); sqlite3VdbeResolveLabel(v, nextCase); |
︙ | ︙ | |||
2726 2727 2728 2729 2730 2731 2732 | ** are reused. */ int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ Vdbe *v = pParse->pVdbe; int inReg; inReg = sqlite3ExprCode(pParse, pExpr, target); assert( target>0 ); | > > > > > > | | 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 | ** are reused. */ int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ Vdbe *v = pParse->pVdbe; int inReg; inReg = sqlite3ExprCode(pParse, pExpr, target); assert( target>0 ); /* This routine is called for terms to INSERT or UPDATE. And the only ** other place where expressions can be converted into TK_REGISTER is ** in WHERE clause processing. So as currently implemented, there is ** no way for a TK_REGISTER to exist here. But it seems prudent to ** keep the ALWAYS() in case the conditions above change with future ** modifications or enhancements. */ if( ALWAYS(pExpr->op!=TK_REGISTER) ){ int iMem; iMem = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem); pExpr->iTable = iMem; pExpr->op = TK_REGISTER; } return inReg; |
︙ | ︙ | |||
2783 2784 2785 2786 2787 2788 2789 | /* Single-instruction constants with a fixed destination are ** better done in-line. If we factor them, they will just end ** up generating an OP_SCopy to move the value to the destination ** register. */ return 0; } case TK_UMINUS: { | | | | | | 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 | /* Single-instruction constants with a fixed destination are ** better done in-line. If we factor them, they will just end ** up generating an OP_SCopy to move the value to the destination ** register. */ return 0; } case TK_UMINUS: { if( p->pLeft->op==TK_FLOAT || p->pLeft->op==TK_INTEGER ){ return 0; } break; } default: { break; } } return 1; } |
︙ | ︙ | |||
3209 3210 3211 3212 3213 3214 3215 | if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0; if( ExprHasProperty(pA, EP_IntValue) ){ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ return 0; } }else if( pA->op!=TK_COLUMN && pA->u.zToken ){ | | | 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 | if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0; if( ExprHasProperty(pA, EP_IntValue) ){ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ return 0; } }else if( pA->op!=TK_COLUMN && pA->u.zToken ){ if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 0; if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ){ return 0; } } return 1; } |
︙ | ︙ | |||
3273 3274 3275 3276 3277 3278 3279 | switch( pExpr->op ){ case TK_AGG_COLUMN: case TK_COLUMN: { testcase( pExpr->op==TK_AGG_COLUMN ); testcase( pExpr->op==TK_COLUMN ); /* Check to see if the column is in one of the tables in the FROM ** clause of the aggregate query */ | | | 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 | switch( pExpr->op ){ case TK_AGG_COLUMN: case TK_COLUMN: { testcase( pExpr->op==TK_AGG_COLUMN ); testcase( pExpr->op==TK_COLUMN ); /* Check to see if the column is in one of the tables in the FROM ** clause of the aggregate query */ if( ALWAYS(pSrcList!=0) ){ struct SrcList_item *pItem = pSrcList->a; for(i=0; i<pSrcList->nSrc; i++, pItem++){ struct AggInfo_col *pCol; assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) ); if( pExpr->iTable==pItem->iCursor ){ /* If we reach this point, it means that pExpr refers to a table ** that is in the FROM clause of the aggregate query. |
︙ | ︙ | |||
3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 | ** analyzed by sqlite3ResolveExprNames(). */ void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ Walker w; w.xExprCallback = analyzeAggregate; w.xSelectCallback = analyzeAggregatesInSelect; w.u.pNC = pNC; sqlite3WalkExpr(&w, pExpr); } /* ** Call sqlite3ExprAnalyzeAggregates() for every expression in an ** expression list. Return the number of errors. ** | > | 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 | ** analyzed by sqlite3ResolveExprNames(). */ void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ Walker w; w.xExprCallback = analyzeAggregate; w.xSelectCallback = analyzeAggregatesInSelect; w.u.pNC = pNC; assert( pNC->pSrcList!=0 ); sqlite3WalkExpr(&w, pExpr); } /* ** Call sqlite3ExprAnalyzeAggregates() for every expression in an ** expression list. Return the number of errors. ** |
︙ | ︙ |