/ Check-in [e3ed2f49]
Login

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

Overview
Comment:Simplification of the WHERE loop code generator for NULLS LAST saves a few CPU cycles and about a hundred bytes of code space.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | nulls-last
Files: files | file ages | folders
SHA3-256: e3ed2f496f51234a8f81d90d47ba603b06dbed38b8bd8f1934294379cde74d3a
User & Date: drh 2019-08-23 16:12:20
Context
2019-08-23
17:00
Additional simplifications of the WHERE loop code generator logic for NULLS LAST. check-in: 1383680d user: drh tags: nulls-last
16:12
Simplification of the WHERE loop code generator for NULLS LAST saves a few CPU cycles and about a hundred bytes of code space. check-in: e3ed2f49 user: drh tags: nulls-last
13:32
Invert the meaning of the regBignull flag so that it is 1 when doing the normal scan and 1 when scanning nulls. This enables the re-do jump at the bottom of the loop to be coded with a single OP_IfNotZero opcode, rather than a sequence of OP_If, OP_Integer, OP_Goto. check-in: bf875e1a user: drh tags: nulls-last
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/wherecode.c.

1667
1668
1669
1670
1671
1672
1673
1674
1675
1676

1677

1678
1679
1680
1681
1682
1683
1684
....
1701
1702
1703
1704
1705
1706
1707

1708


1709
1710
1711
1712
1713

1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
      if( sqlite3ExprIsVector(pRight)==0 ){
        disableTerm(pLevel, pRangeStart);
      }else{
        startEq = 1;
      }
      bSeekPastNull = 0;
    }else if( bSeekPastNull ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
      nConstraint++;
      startEq = 0;

      start_constraints = 1;

    }else if( regBignull ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
      start_constraints = 1;
      nConstraint++;
    }
    codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
    if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){
................................................................................
      VdbeCoverageIf(v, op==OP_Rewind);  testcase( op==OP_Rewind );
      VdbeCoverageIf(v, op==OP_Last);    testcase( op==OP_Last );
      VdbeCoverageIf(v, op==OP_SeekGT);  testcase( op==OP_SeekGT );
      VdbeCoverageIf(v, op==OP_SeekGE);  testcase( op==OP_SeekGE );
      VdbeCoverageIf(v, op==OP_SeekLE);  testcase( op==OP_SeekLE );
      VdbeCoverageIf(v, op==OP_SeekLT);  testcase( op==OP_SeekLT );


      if( regBignull ){


        sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);
        if( bStopAtNull ){
          start_constraints = (nConstraint>1);
          op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
          sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint-1);

          VdbeCoverage(v);
          VdbeCoverageIf(v, op==OP_Rewind);  testcase( op==OP_Rewind );
          VdbeCoverageIf(v, op==OP_Last);    testcase( op==OP_Last );
          VdbeCoverageIf(v, op==OP_SeekGT);  testcase( op==OP_SeekGT );
          VdbeCoverageIf(v, op==OP_SeekGE);  testcase( op==OP_SeekGE );
          VdbeCoverageIf(v, op==OP_SeekLE);  testcase( op==OP_SeekLE );
          VdbeCoverageIf(v, op==OP_SeekLT);  testcase( op==OP_SeekLT );
        }else{
          op = aStartOp[(start_constraints<<2) + ((!startEq)<<1) + bRev];
          sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
          VdbeCoverage(v);
          VdbeCoverageIf(v, op==OP_Rewind);  testcase( op==OP_Rewind );
          VdbeCoverageIf(v, op==OP_Last);    testcase( op==OP_Last );
          VdbeCoverageIf(v, op==OP_SeekGT);  testcase( op==OP_SeekGT );
          VdbeCoverageIf(v, op==OP_SeekGE);  testcase( op==OP_SeekGE );
          VdbeCoverageIf(v, op==OP_SeekLE);  testcase( op==OP_SeekLE );
          VdbeCoverageIf(v, op==OP_SeekLT);  testcase( op==OP_SeekLT );
        }
      }
    }

    /* Load the value for the inequality constraint at the end of the
    ** range (if any).
    */
    nConstraint = nEq;







<
<

>

>







 







>

>
>

<
|
<
|
>
|
|
|
<
|
|
<
|
<
<
<
<
<
<
<
<
<
<







1667
1668
1669
1670
1671
1672
1673


1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
....
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712

1713

1714
1715
1716
1717
1718

1719
1720

1721










1722
1723
1724
1725
1726
1727
1728
      if( sqlite3ExprIsVector(pRight)==0 ){
        disableTerm(pLevel, pRangeStart);
      }else{
        startEq = 1;
      }
      bSeekPastNull = 0;
    }else if( bSeekPastNull ){


      startEq = 0;
      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
      start_constraints = 1;
      nConstraint++;
    }else if( regBignull ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
      start_constraints = 1;
      nConstraint++;
    }
    codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
    if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){
................................................................................
      VdbeCoverageIf(v, op==OP_Rewind);  testcase( op==OP_Rewind );
      VdbeCoverageIf(v, op==OP_Last);    testcase( op==OP_Last );
      VdbeCoverageIf(v, op==OP_SeekGT);  testcase( op==OP_SeekGT );
      VdbeCoverageIf(v, op==OP_SeekGE);  testcase( op==OP_SeekGE );
      VdbeCoverageIf(v, op==OP_SeekLE);  testcase( op==OP_SeekLE );
      VdbeCoverageIf(v, op==OP_SeekLT);  testcase( op==OP_SeekLT );

      assert( bSeekPastNull==0 || bStopAtNull==0 );
      if( regBignull ){
        assert( bSeekPastNull==1 || bStopAtNull==1 );
        assert( bStopAtNull==startEq );
        sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2);

        op = aStartOp[(nConstraint>1)*4 + 2 + bRev];

        sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, 
                             nConstraint-startEq);
        VdbeCoverage(v);
        VdbeCoverageIf(v, op==OP_Rewind);  testcase( op==OP_Rewind );
        VdbeCoverageIf(v, op==OP_Last);    testcase( op==OP_Last );

        VdbeCoverageIf(v, op==OP_SeekGE);  testcase( op==OP_SeekGE );
        VdbeCoverageIf(v, op==OP_SeekLE);  testcase( op==OP_SeekLE );

        assert( op==OP_Rewind || op==OP_Last || op==OP_SeekGE || op==OP_SeekLE);










      }
    }

    /* Load the value for the inequality constraint at the end of the
    ** range (if any).
    */
    nConstraint = nEq;