Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add VdbeCoverage() macros on newly added VDBE branch operations. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | rowvalue |
Files: | files | file ages | folders |
SHA1: |
381aa73141db8ec59adbcb09e71af660 |
User & Date: | drh 2016-08-12 11:25:49.567 |
Context
2016-08-18
| ||
15:15 | Simplify the vector comparison code generator logic, and the resulting VDBE code. (check-in: e2ad0b5d8e user: drh tags: rowvalue) | |
2016-08-13
| ||
10:02 | Attempt to simplify the logic and generated code for vector comparisons. Basic comparison operators are working, but there are many indexing test failures still to be worked through. (check-in: dfc028cfbe user: drh tags: vector-compare) | |
2016-08-12
| ||
11:25 | Add VdbeCoverage() macros on newly added VDBE branch operations. (check-in: 381aa73141 user: drh tags: rowvalue) | |
11:01 | Fix a post-OOM memory leak. (check-in: 14009b32b9 user: drh tags: rowvalue) | |
Changes
Changes to src/expr.c.
︙ | ︙ | |||
2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 | ** operator is NULL, then the result is false if the index is ** completely empty, or NULL otherwise. */ if( destIfNull==destIfFalse ){ for(i=0; i<nVector; i++){ Expr *p = sqlite3ExprVectorField(pExpr->pLeft, i); if( sqlite3ExprCanBeNull(p) ){ sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull); } } }else if( nVector==1 && sqlite3ExprCanBeNull(pExpr->pLeft) ){ int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); VdbeCoverage(v); sqlite3VdbeGoto(v, destIfNull); | > | 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 | ** operator is NULL, then the result is false if the index is ** completely empty, or NULL otherwise. */ if( destIfNull==destIfFalse ){ for(i=0; i<nVector; i++){ Expr *p = sqlite3ExprVectorField(pExpr->pLeft, i); if( sqlite3ExprCanBeNull(p) ){ sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull); VdbeCoverage(v); } } }else if( nVector==1 && sqlite3ExprCanBeNull(pExpr->pLeft) ){ int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse); VdbeCoverage(v); sqlite3VdbeGoto(v, destIfNull); |
︙ | ︙ | |||
2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 | if( nVector>1 && destIfNull!=destIfFalse ){ int iIdx = pExpr->iTable; int addr; int addrNext; /* Search the index for the key. */ addr = sqlite3VdbeAddOp4Int(v, OP_Found, iIdx, 0, r1, nVector); /* At this point the specified key is not present in the index, ** so the result of the IN(..) operator must be either NULL or ** 0. The vdbe code generated below figures out which. */ addrNext = 1+sqlite3VdbeAddOp2(v, OP_Rewind, iIdx, destIfFalse); for(i=0; i<nVector; i++){ Expr *p; CollSeq *pColl; int r2 = sqlite3GetTempReg(pParse); p = sqlite3ExprVectorField(pLeft, i); pColl = sqlite3ExprCollSeq(pParse, p); sqlite3VdbeAddOp3(v, OP_Column, iIdx, i, r2); sqlite3VdbeAddOp4(v, OP_Eq, r1+i, 0, r2, (void*)pColl,P4_COLLSEQ); sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); sqlite3VdbeAddOp2(v, OP_Next, iIdx, addrNext); sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-3); sqlite3ReleaseTempReg(pParse, r2); } sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); /* The key was found in the index. If it contains any NULL values, ** then the result of the IN(...) operator is NULL. Otherwise, the ** result is 1. */ sqlite3VdbeJumpHere(v, addr); for(i=0; i<nVector; i++){ Expr *p = sqlite3ExprVectorField(pExpr->pLeft, i); if( sqlite3ExprCanBeNull(p) ){ sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull); } } }else if( rRhsHasNull==0 ){ /* This branch runs if it is known at compile time that the RHS ** cannot contain NULL values. This happens as a result ** of "NOT NULL" constraints in the database schema. | > > > > > | 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 | if( nVector>1 && destIfNull!=destIfFalse ){ int iIdx = pExpr->iTable; int addr; int addrNext; /* Search the index for the key. */ addr = sqlite3VdbeAddOp4Int(v, OP_Found, iIdx, 0, r1, nVector); VdbeCoverage(v); /* At this point the specified key is not present in the index, ** so the result of the IN(..) operator must be either NULL or ** 0. The vdbe code generated below figures out which. */ addrNext = 1+sqlite3VdbeAddOp2(v, OP_Rewind, iIdx, destIfFalse); VdbeCoverage(v); for(i=0; i<nVector; i++){ Expr *p; CollSeq *pColl; int r2 = sqlite3GetTempReg(pParse); p = sqlite3ExprVectorField(pLeft, i); pColl = sqlite3ExprCollSeq(pParse, p); sqlite3VdbeAddOp3(v, OP_Column, iIdx, i, r2); sqlite3VdbeAddOp4(v, OP_Eq, r1+i, 0, r2, (void*)pColl,P4_COLLSEQ); sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Next, iIdx, addrNext); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-3); sqlite3ReleaseTempReg(pParse, r2); } sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull); /* The key was found in the index. If it contains any NULL values, ** then the result of the IN(...) operator is NULL. Otherwise, the ** result is 1. */ sqlite3VdbeJumpHere(v, addr); for(i=0; i<nVector; i++){ Expr *p = sqlite3ExprVectorField(pExpr->pLeft, i); if( sqlite3ExprCanBeNull(p) ){ sqlite3VdbeAddOp2(v, OP_IsNull, r1+aiMap[i], destIfNull); VdbeCoverage(v); } } }else if( rRhsHasNull==0 ){ /* This branch runs if it is known at compile time that the RHS ** cannot contain NULL values. This happens as a result ** of "NOT NULL" constraints in the database schema. |
︙ | ︙ |