/ Check-in [75146165]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Improved performance in sqlite3ExprCodeTarget().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 75146165dcc1ae1faab46b1a7333ef795d5eeac5
User & Date: drh 2016-09-19 10:24:19
Context
2016-09-19
11:00
Fix a segfault introduced by the row-value enhancement that comes up on a skip-scan where the first term of the index is unconstrained and the second term is of the form "columm IN (SELECT...)". check-in: 2401ea5a user: drh tags: trunk
10:24
Improved performance in sqlite3ExprCodeTarget(). check-in: 75146165 user: drh tags: trunk
02:19
Small performance optimization in the expression walker. check-in: c6e6afb9 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/expr.c.

  3344   3344   int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
  3345   3345     Vdbe *v = pParse->pVdbe;  /* The VM under construction */
  3346   3346     int op;                   /* The opcode being coded */
  3347   3347     int inReg = target;       /* Results stored in register inReg */
  3348   3348     int regFree1 = 0;         /* If non-zero free this temporary register */
  3349   3349     int regFree2 = 0;         /* If non-zero free this temporary register */
  3350   3350     int r1, r2;               /* Various register numbers */
  3351         -  sqlite3 *db = pParse->db; /* The database connection */
  3352   3351     Expr tempX;               /* Temporary expression node */
  3353   3352     int p5 = 0;
  3354   3353   
  3355   3354     assert( target>0 && target<=pParse->nMem );
  3356   3355     if( v==0 ){
  3357   3356       assert( pParse->db->mallocFailed );
  3358   3357       return 0;
................................................................................
  3365   3364     }
  3366   3365     switch( op ){
  3367   3366       case TK_AGG_COLUMN: {
  3368   3367         AggInfo *pAggInfo = pExpr->pAggInfo;
  3369   3368         struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
  3370   3369         if( !pAggInfo->directMode ){
  3371   3370           assert( pCol->iMem>0 );
  3372         -        inReg = pCol->iMem;
  3373         -        break;
         3371  +        return pCol->iMem;
  3374   3372         }else if( pAggInfo->useSortingIdx ){
  3375   3373           sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
  3376   3374                                 pCol->iSorterColumn, target);
  3377         -        break;
         3375  +        return target;
  3378   3376         }
  3379   3377         /* Otherwise, fall thru into the TK_COLUMN case */
  3380   3378       }
  3381   3379       case TK_COLUMN: {
  3382   3380         int iTab = pExpr->iTable;
  3383   3381         if( iTab<0 ){
  3384   3382           if( pParse->ckBase>0 ){
  3385   3383             /* Generating CHECK constraints or inserting into partial index */
  3386         -          inReg = pExpr->iColumn + pParse->ckBase;
  3387         -          break;
         3384  +          return pExpr->iColumn + pParse->ckBase;
  3388   3385           }else{
  3389   3386             /* Coding an expression that is part of an index where column names
  3390   3387             ** in the index refer to the table to which the index belongs */
  3391   3388             iTab = pParse->iSelfTab;
  3392   3389           }
  3393   3390         }
  3394         -      inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
         3391  +      return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
  3395   3392                                  pExpr->iColumn, iTab, target,
  3396   3393                                  pExpr->op2);
  3397         -      break;
  3398   3394       }
  3399   3395       case TK_INTEGER: {
  3400   3396         codeInteger(pParse, pExpr, 0, target);
  3401         -      break;
         3397  +      return target;
  3402   3398       }
  3403   3399   #ifndef SQLITE_OMIT_FLOATING_POINT
  3404   3400       case TK_FLOAT: {
  3405   3401         assert( !ExprHasProperty(pExpr, EP_IntValue) );
  3406   3402         codeReal(v, pExpr->u.zToken, 0, target);
  3407         -      break;
         3403  +      return target;
  3408   3404       }
  3409   3405   #endif
  3410   3406       case TK_STRING: {
  3411   3407         assert( !ExprHasProperty(pExpr, EP_IntValue) );
  3412   3408         sqlite3VdbeLoadString(v, target, pExpr->u.zToken);
  3413         -      break;
         3409  +      return target;
  3414   3410       }
  3415   3411       case TK_NULL: {
  3416   3412         sqlite3VdbeAddOp2(v, OP_Null, 0, target);
  3417         -      break;
         3413  +      return target;
  3418   3414       }
  3419   3415   #ifndef SQLITE_OMIT_BLOB_LITERAL
  3420   3416       case TK_BLOB: {
  3421   3417         int n;
  3422   3418         const char *z;
  3423   3419         char *zBlob;
  3424   3420         assert( !ExprHasProperty(pExpr, EP_IntValue) );
................................................................................
  3425   3421         assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
  3426   3422         assert( pExpr->u.zToken[1]=='\'' );
  3427   3423         z = &pExpr->u.zToken[2];
  3428   3424         n = sqlite3Strlen30(z) - 1;
  3429   3425         assert( z[n]=='\'' );
  3430   3426         zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n);
  3431   3427         sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC);
  3432         -      break;
         3428  +      return target;
  3433   3429       }
  3434   3430   #endif
  3435   3431       case TK_VARIABLE: {
  3436   3432         assert( !ExprHasProperty(pExpr, EP_IntValue) );
  3437   3433         assert( pExpr->u.zToken!=0 );
  3438   3434         assert( pExpr->u.zToken[0]!=0 );
  3439   3435         sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
  3440   3436         if( pExpr->u.zToken[1]!=0 ){
  3441   3437           assert( pExpr->u.zToken[0]=='?' 
  3442   3438                || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 );
  3443   3439           sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC);
  3444   3440         }
  3445         -      break;
         3441  +      return target;
  3446   3442       }
  3447   3443       case TK_REGISTER: {
  3448         -      inReg = pExpr->iTable;
  3449         -      break;
         3444  +      return pExpr->iTable;
  3450   3445       }
  3451   3446   #ifndef SQLITE_OMIT_CAST
  3452   3447       case TK_CAST: {
  3453   3448         /* Expressions of the form:   CAST(pLeft AS token) */
  3454   3449         inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
  3455   3450         if( inReg!=target ){
  3456   3451           sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
  3457   3452           inReg = target;
  3458   3453         }
  3459   3454         sqlite3VdbeAddOp2(v, OP_Cast, target,
  3460   3455                           sqlite3AffinityType(pExpr->u.zToken, 0));
  3461   3456         testcase( usedAsColumnCache(pParse, inReg, inReg) );
  3462   3457         sqlite3ExprCacheAffinityChange(pParse, inReg, 1);
  3463         -      break;
         3458  +      return inReg;
  3464   3459       }
  3465   3460   #endif /* SQLITE_OMIT_CAST */
  3466   3461       case TK_IS:
  3467   3462       case TK_ISNOT:
  3468   3463         op = (op==TK_IS) ? TK_EQ : TK_NE;
  3469   3464         p5 = SQLITE_NULLEQ;
  3470   3465         /* fall-through */
................................................................................
  3524   3519         break;
  3525   3520       }
  3526   3521       case TK_UMINUS: {
  3527   3522         Expr *pLeft = pExpr->pLeft;
  3528   3523         assert( pLeft );
  3529   3524         if( pLeft->op==TK_INTEGER ){
  3530   3525           codeInteger(pParse, pLeft, 1, target);
         3526  +        return target;
  3531   3527   #ifndef SQLITE_OMIT_FLOATING_POINT
  3532   3528         }else if( pLeft->op==TK_FLOAT ){
  3533   3529           assert( !ExprHasProperty(pExpr, EP_IntValue) );
  3534   3530           codeReal(v, pLeft->u.zToken, 1, target);
         3531  +        return target;
  3535   3532   #endif
  3536   3533         }else{
  3537   3534           tempX.op = TK_INTEGER;
  3538   3535           tempX.flags = EP_IntValue|EP_TokenOnly;
  3539   3536           tempX.u.iValue = 0;
  3540   3537           r1 = sqlite3ExprCodeTemp(pParse, &tempX, &regFree1);
  3541   3538           r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree2);
  3542   3539           sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
  3543   3540           testcase( regFree2==0 );
  3544   3541         }
  3545         -      inReg = target;
  3546   3542         break;
  3547   3543       }
  3548   3544       case TK_BITNOT:
  3549   3545       case TK_NOT: {
  3550   3546         assert( TK_BITNOT==OP_BitNot );   testcase( op==TK_BITNOT );
  3551   3547         assert( TK_NOT==OP_Not );         testcase( op==TK_NOT );
  3552   3548         r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
  3553   3549         testcase( regFree1==0 );
  3554         -      inReg = target;
  3555   3550         sqlite3VdbeAddOp2(v, op, r1, inReg);
  3556   3551         break;
  3557   3552       }
  3558   3553       case TK_ISNULL:
  3559   3554       case TK_NOTNULL: {
  3560   3555         int addr;
  3561   3556         assert( TK_ISNULL==OP_IsNull );   testcase( op==TK_ISNULL );
................................................................................
  3572   3567       }
  3573   3568       case TK_AGG_FUNCTION: {
  3574   3569         AggInfo *pInfo = pExpr->pAggInfo;
  3575   3570         if( pInfo==0 ){
  3576   3571           assert( !ExprHasProperty(pExpr, EP_IntValue) );
  3577   3572           sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
  3578   3573         }else{
  3579         -        inReg = pInfo->aFunc[pExpr->iAgg].iMem;
         3574  +        return pInfo->aFunc[pExpr->iAgg].iMem;
  3580   3575         }
  3581   3576         break;
  3582   3577       }
  3583   3578       case TK_FUNCTION: {
  3584   3579         ExprList *pFarg;       /* List of function arguments */
  3585   3580         int nFarg;             /* Number of function arguments */
  3586   3581         FuncDef *pDef;         /* The function definition object */
  3587   3582         const char *zId;       /* The function name */
  3588   3583         u32 constMask = 0;     /* Mask of function arguments that are constant */
  3589   3584         int i;                 /* Loop counter */
         3585  +      sqlite3 *db = pParse->db;  /* The database connection */
  3590   3586         u8 enc = ENC(db);      /* The text encoding used by this database */
  3591   3587         CollSeq *pColl = 0;    /* A collating sequence */
  3592   3588   
  3593   3589         assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
  3594   3590         if( ExprHasProperty(pExpr, EP_TokenOnly) ){
  3595   3591           pFarg = 0;
  3596   3592         }else{
................................................................................
  3631   3627         }
  3632   3628   
  3633   3629         /* The UNLIKELY() function is a no-op.  The result is the value
  3634   3630         ** of the first argument.
  3635   3631         */
  3636   3632         if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
  3637   3633           assert( nFarg>=1 );
  3638         -        inReg = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
  3639         -        break;
         3634  +        return sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
  3640   3635         }
  3641   3636   
  3642   3637         for(i=0; i<nFarg; i++){
  3643   3638           if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
  3644   3639             testcase( i==31 );
  3645   3640             constMask |= MASKBIT32(i);
  3646   3641           }
................................................................................
  3707   3702         }
  3708   3703         sqlite3VdbeAddOp4(v, OP_Function0, constMask, r1, target,
  3709   3704                           (char*)pDef, P4_FUNCDEF);
  3710   3705         sqlite3VdbeChangeP5(v, (u8)nFarg);
  3711   3706         if( nFarg && constMask==0 ){
  3712   3707           sqlite3ReleaseTempRange(pParse, r1, nFarg);
  3713   3708         }
  3714         -      break;
         3709  +      return target;
  3715   3710       }
  3716   3711   #ifndef SQLITE_OMIT_SUBQUERY
  3717   3712       case TK_EXISTS:
  3718   3713       case TK_SELECT: {
  3719   3714         int nCol;
  3720   3715         testcase( op==TK_EXISTS );
  3721   3716         testcase( op==TK_SELECT );
  3722   3717         if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
  3723   3718           sqlite3SubselectError(pParse, nCol, 1);
  3724   3719         }else{
  3725         -        inReg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
         3720  +        return sqlite3CodeSubselect(pParse, pExpr, 0, 0);
  3726   3721         }
  3727   3722         break;
  3728   3723       }
  3729   3724       case TK_SELECT_COLUMN: {
  3730   3725         if( pExpr->pLeft->iTable==0 ){
  3731   3726           pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0);
  3732   3727         }
  3733         -      inReg = pExpr->pLeft->iTable + pExpr->iColumn;
  3734         -      break;
         3728  +      return pExpr->pLeft->iTable + pExpr->iColumn;
  3735   3729       }
  3736   3730       case TK_IN: {
  3737   3731         int destIfFalse = sqlite3VdbeMakeLabel(v);
  3738   3732         int destIfNull = sqlite3VdbeMakeLabel(v);
  3739   3733         sqlite3VdbeAddOp2(v, OP_Null, 0, target);
  3740   3734         sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
  3741   3735         sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
  3742   3736         sqlite3VdbeResolveLabel(v, destIfFalse);
  3743   3737         sqlite3VdbeAddOp2(v, OP_AddImm, target, 0);
  3744   3738         sqlite3VdbeResolveLabel(v, destIfNull);
  3745         -      break;
         3739  +      return target;
  3746   3740       }
  3747   3741   #endif /* SQLITE_OMIT_SUBQUERY */
  3748   3742   
  3749   3743   
  3750   3744       /*
  3751   3745       **    x BETWEEN y AND z
  3752   3746       **
................................................................................
  3756   3750       **
  3757   3751       ** X is stored in pExpr->pLeft.
  3758   3752       ** Y is stored in pExpr->pList->a[0].pExpr.
  3759   3753       ** Z is stored in pExpr->pList->a[1].pExpr.
  3760   3754       */
  3761   3755       case TK_BETWEEN: {
  3762   3756         exprCodeBetween(pParse, pExpr, target, 0, 0);
  3763         -      break;
         3757  +      return target;
  3764   3758       }
  3765   3759       case TK_SPAN:
  3766   3760       case TK_COLLATE: 
  3767   3761       case TK_UPLUS: {
  3768         -      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
  3769         -      break;
         3762  +      return sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
  3770   3763       }
  3771   3764   
  3772   3765       case TK_TRIGGER: {
  3773   3766         /* If the opcode is TK_TRIGGER, then the expression is a reference
  3774   3767         ** to a column in the new.* or old.* pseudo-tables available to
  3775   3768         ** trigger programs. In this case Expr.iTable is set to 1 for the
  3776   3769         ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
................................................................................
  3904   3897         if( (nExpr&1)!=0 ){
  3905   3898           sqlite3ExprCachePush(pParse);
  3906   3899           sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target);
  3907   3900           sqlite3ExprCachePop(pParse);
  3908   3901         }else{
  3909   3902           sqlite3VdbeAddOp2(v, OP_Null, 0, target);
  3910   3903         }
  3911         -      assert( db->mallocFailed || pParse->nErr>0 
         3904  +      assert( pParse->db->mallocFailed || pParse->nErr>0 
  3912   3905              || pParse->iCacheLevel==iCacheLevel );
  3913   3906         sqlite3VdbeResolveLabel(v, endLabel);
  3914   3907         break;
  3915   3908       }
  3916   3909   #ifndef SQLITE_OMIT_TRIGGER
  3917   3910       case TK_RAISE: {
  3918   3911         assert( pExpr->affinity==OE_Rollback