/ Check-in [381aa731]
Login

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 | SQL archive
Timelines: family | ancestors | descendants | both | rowvalue
Files: files | file ages | folders
SHA1:381aa73141db8ec59adbcb09e71af660ee4ae5ce
User & Date: drh 2016-08-12 11:25:49
Context
2016-08-18
15:15
Simplify the vector comparison code generator logic, and the resulting VDBE code. check-in: e2ad0b5d 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: dfc028cf user: drh tags: vector-compare
2016-08-12
11:25
Add VdbeCoverage() macros on newly added VDBE branch operations. check-in: 381aa731 user: drh tags: rowvalue
11:01
Fix a post-OOM memory leak. check-in: 14009b32 user: drh tags: rowvalue
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

2602
2603
2604
2605
2606
2607
2608

2609
2610
2611
2612
2613
2614
2615
....
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
    ** 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);
................................................................................
      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.







>







 







>





>











>

>







 







>







2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
....
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
    ** 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);
................................................................................
      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.