Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Suppress more instances of unnecessary OP_IsNull and OP_Affinity opcodes. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
bf6c0bd1c5568c6292ea0a64c8a5071e |
User & Date: | drh 2009-11-18 01:25:27.000 |
Context
2009-11-18
| ||
23:01 | Performance improvement by avoiding unnecessary calls to memset(). (check-in: 85940468e6 user: drh tags: trunk) | |
01:25 | Suppress more instances of unnecessary OP_IsNull and OP_Affinity opcodes. (check-in: bf6c0bd1c5 user: drh tags: trunk) | |
2009-11-17
| ||
23:59 | Enhancements to the VDBE opcode loop to reduce the number of machine-code instructions evaluated by about 10%. (check-in: 9744ffb3f5 user: drh tags: trunk) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 | case TK_FLOAT: case TK_BLOB: return 0; default: return 1; } } /* ** Return TRUE if the given expression is a constant which would be ** unchanged by OP_Affinity with the affinity given in the second ** argument. ** ** This routine is used to determine if the OP_Affinity operation | > > > > > > > > > > > > > > > > > > | 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 | case TK_FLOAT: case TK_BLOB: return 0; default: return 1; } } /* ** Generate an OP_IsNull instruction that tests register iReg and jumps ** to location iDest if the value in iReg is NULL. The value in iReg ** was computed by pExpr. If we can look at pExpr at compile-time and ** determine that it can never generate a NULL, then the OP_IsNull operation ** can be omitted. */ void sqlite3ExprCodeIsNullJump( Vdbe *v, /* The VDBE under construction */ const Expr *pExpr, /* Only generate OP_IsNull if this expr can be NULL */ int iReg, /* Test the value in this register for NULL */ int iDest /* Jump here if the value is null */ ){ if( sqlite3ExprCanBeNull(pExpr) ){ sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iDest); } } /* ** Return TRUE if the given expression is a constant which would be ** unchanged by OP_Affinity with the affinity given in the second ** argument. ** ** This routine is used to determine if the OP_Affinity operation |
︙ | ︙ | |||
1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 | } case TK_STRING: { return aff==SQLITE_AFF_TEXT; } case TK_BLOB: { return 1; } default: { return 0; } } } /* | > > > > | 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 | } case TK_STRING: { return aff==SQLITE_AFF_TEXT; } case TK_BLOB: { return 1; } case TK_COLUMN: { return p->iTable>=0 && p->iColumn<0 && (aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC); } default: { return 0; } } } /* |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 | void sqlite3Savepoint(Parse*, int, Token*); void sqlite3CloseSavepoints(sqlite3 *); int sqlite3ExprIsConstant(Expr*); int sqlite3ExprIsConstantNotJoin(Expr*); int sqlite3ExprIsConstantOrFunction(Expr*); int sqlite3ExprIsInteger(Expr*, int*); int sqlite3ExprCanBeNull(const Expr*); int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); int sqlite3IsRowid(const char*); void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int); void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*); int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int); void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int, int*,int,int,int,int,int*); | > | 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 | void sqlite3Savepoint(Parse*, int, Token*); void sqlite3CloseSavepoints(sqlite3 *); int sqlite3ExprIsConstant(Expr*); int sqlite3ExprIsConstantNotJoin(Expr*); int sqlite3ExprIsConstantOrFunction(Expr*); int sqlite3ExprIsInteger(Expr*, int*); int sqlite3ExprCanBeNull(const Expr*); void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int); int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); int sqlite3IsRowid(const char*); void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int); void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*); int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int); void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int, int*,int,int,int,int,int*); |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
2785 2786 2787 2788 2789 2790 2791 | sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j); } } testcase( pTerm->eOperator & WO_ISNULL ); testcase( pTerm->eOperator & WO_IN ); if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){ Expr *pRight = pTerm->pExpr->pRight; | < | < | 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 | sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j); } } testcase( pTerm->eOperator & WO_ISNULL ); testcase( pTerm->eOperator & WO_IN ); if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){ Expr *pRight = pTerm->pExpr->pRight; sqlite3ExprCodeIsNullJump(v, pRight, regBase+j, pLevel->addrBrk); if( zAff ){ if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_NONE ){ zAff[j] = SQLITE_AFF_NONE; } if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ zAff[j] = SQLITE_AFF_NONE; } |
︙ | ︙ | |||
3120 3121 3122 3123 3124 3125 3126 | start_constraints = pRangeStart || nEq>0; /* Seek the index cursor to the start of the range. */ nConstraint = nEq; if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; sqlite3ExprCode(pParse, pRight, regBase+nEq); | | | 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 | start_constraints = pRangeStart || nEq>0; /* Seek the index cursor to the start of the range. */ nConstraint = nEq; if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; sqlite3ExprCode(pParse, pRight, regBase+nEq); sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); if( zAff ){ if( sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE){ /* Since the comparison is to be performed with no conversions ** applied to the operands, set the affinity to apply to pRight to ** SQLITE_AFF_NONE. */ zAff[nConstraint] = SQLITE_AFF_NONE; } |
︙ | ︙ | |||
3158 3159 3160 3161 3162 3163 3164 | ** range (if any). */ nConstraint = nEq; if( pRangeEnd ){ Expr *pRight = pRangeEnd->pExpr->pRight; sqlite3ExprCacheRemove(pParse, regBase+nEq); sqlite3ExprCode(pParse, pRight, regBase+nEq); | | | 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 | ** range (if any). */ nConstraint = nEq; if( pRangeEnd ){ Expr *pRight = pRangeEnd->pExpr->pRight; sqlite3ExprCacheRemove(pParse, regBase+nEq); sqlite3ExprCode(pParse, pRight, regBase+nEq); sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); if( zAff ){ if( sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE){ /* Since the comparison is to be performed with no conversions ** applied to the operands, set the affinity to apply to pRight to ** SQLITE_AFF_NONE. */ zAff[nConstraint] = SQLITE_AFF_NONE; } |
︙ | ︙ |