SQLite

Check-in [381aa73141]
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
Timelines: family | ancestors | descendants | both | rowvalue
Files: files | file ages | folders
SHA1: 381aa73141db8ec59adbcb09e71af660ee4ae5ce
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
Unified Diff Ignore Whitespace Patch
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.