/ Check-in [936146b1]
Login

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

Overview
Comment:Fix a SQL NULL handling bug in the vector IN operator code generation.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | rowvalue
Files: files | file ages | folders
SHA1:936146b12e27784f15a68fe65732c6d92c3a12f3
User & Date: drh 2016-08-18 19:04:57
Context
2016-08-19
15:41
Merge recent enhancements from trunk. check-in: b1787236 user: drh tags: rowvalue
2016-08-18
19:04
Fix a SQL NULL handling bug in the vector IN operator code generation. check-in: 936146b1 user: drh tags: rowvalue
18:09
Display SELECT_COLUMN expressions in the .wheretrace debugging output. check-in: 3b27a5da user: drh tags: rowvalue
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/wherecode.c.

495
496
497
498
499
500
501

502
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
       sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
                              sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
    pIn = pLevel->u.in.aInLoop;
    if( pIn ){
      int iMap = 0;               /* Index in aiMap[] */
      pIn += i;
      for(i=iEq;i<pLoop->nLTerm; i++, pIn++){

        if( pLoop->aLTerm[i]->pExpr==pX ){
          if( eType==IN_INDEX_ROWID ){
            assert( nEq==1 && i==iEq );
            pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg);
          }else{
            int iCol = aiMap ? aiMap[iMap++] : 0;
            int iOut = iReg + i - iEq;
            pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut);
          }

          if( i==iEq ){
            pIn->iCur = iTab;
            pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
          }else{
            pIn->eEndLoopOp = OP_Noop;
          }
        }
        sqlite3VdbeAddOp1(v, OP_IsNull, iReg); VdbeCoverage(v);
      }
    }else{
      pLevel->u.in.nIn = 0;
    }
    sqlite3DbFree(pParse->db, aiMap);
#endif
  }







>






|


>







<







495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519

520
521
522
523
524
525
526
       sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
                              sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
    pIn = pLevel->u.in.aInLoop;
    if( pIn ){
      int iMap = 0;               /* Index in aiMap[] */
      pIn += i;
      for(i=iEq;i<pLoop->nLTerm; i++, pIn++){
        int iOut = iReg;
        if( pLoop->aLTerm[i]->pExpr==pX ){
          if( eType==IN_INDEX_ROWID ){
            assert( nEq==1 && i==iEq );
            pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg);
          }else{
            int iCol = aiMap ? aiMap[iMap++] : 0;
            iOut = iReg + i - iEq;
            pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut);
          }
          sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v);
          if( i==iEq ){
            pIn->iCur = iTab;
            pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
          }else{
            pIn->eEndLoopOp = OP_Noop;
          }
        }

      }
    }else{
      pLevel->u.in.nIn = 0;
    }
    sqlite3DbFree(pParse->db, aiMap);
#endif
  }

Added test/rowvalue6.test.









































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 2016-08-18
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# The focus of this file is handling of NULL values in row-value IN
# expressions.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix rowvalue6

do_execsql_test 1.1 {
  CREATE TABLE t1(a,b,c);
  CREATE INDEX t1x1 ON t1(a,b);
  INSERT INTO t1 VALUES(1,NULL,200);

  CREATE TABLE t2(x,y,z);
  INSERT INTO t2 VALUES(1,NULL,55);

  SELECT c FROM t1 WHERE (a,b) IN (SELECT x,y FROM t2 WHERE z==55);
} {}
do_execsql_test 1.2 {
  INSERT INTO t1 VALUES(2,3,400);
  INSERT INTO t2 VALUES(2,3,55);  

  SELECT c FROM t1 WHERE (a,b) IN (SELECT x,y FROM t2 WHERE z==55);
} {400}

finish_test