SQLite

Check-in [eff43715d1]
Login

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

Overview
Comment:Fix the xfer optimization for WITHOUT ROWID tables so that it correctly updates the change count returned by sqlite3_changes().
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: eff43715d1a3a9ce3fe5da194dbb76ec0c06e13c
User & Date: drh 2015-07-28 18:53:37.424
Context
2015-07-29
14:58
Update comments in fts5.h describing the xColumnCount() API function. (check-in: a623eb55d1 user: dan tags: trunk)
2015-07-28
19:35
Update batch build tool library paths for MSVC 2015. (check-in: d431d4e11a user: mistachkin tags: msvc2015)
18:53
Fix the xfer optimization for WITHOUT ROWID tables so that it correctly updates the change count returned by sqlite3_changes(). (check-in: eff43715d1 user: drh tags: trunk)
2015-07-27
19:57
Clarification to the documentation for sqlite3_result_zeroblob64(). No changes to code. (check-in: c98175e900 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/insert.c.
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
    sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
  }else{
    sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName);
    sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
  }
  for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
    u8 useSeekResult = 0;
    for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
      if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
    }
    assert( pSrcIdx );
    sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc);
    sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx);
    VdbeComment((v, "%s", pSrcIdx->zName));







|







1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
    sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
  }else{
    sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName);
    sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
  }
  for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
    u8 idxInsFlags = 0;
    for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
      if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
    }
    assert( pSrcIdx );
    sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc);
    sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx);
    VdbeComment((v, "%s", pSrcIdx->zName));
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037



2038
2039
2040
2041
2042
2043
2044
2045
2046
      ** sorted order.  */
      for(i=0; i<pSrcIdx->nColumn; i++){
        char *zColl = pSrcIdx->azColl[i];
        assert( zColl!=0 );
        if( sqlite3_stricmp("BINARY", zColl) ) break;
      }
      if( i==pSrcIdx->nColumn ){
        useSeekResult = OPFLAG_USESEEKRESULT;
        sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
      }
    }



    sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
    sqlite3VdbeChangeP5(v, useSeekResult);
    sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
    sqlite3VdbeJumpHere(v, addr1);
    sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
  }
  if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest);
  sqlite3ReleaseTempReg(pParse, regRowid);







|



>
>
>

|







2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
      ** sorted order.  */
      for(i=0; i<pSrcIdx->nColumn; i++){
        char *zColl = pSrcIdx->azColl[i];
        assert( zColl!=0 );
        if( sqlite3_stricmp("BINARY", zColl) ) break;
      }
      if( i==pSrcIdx->nColumn ){
        idxInsFlags = OPFLAG_USESEEKRESULT;
        sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
      }
    }
    if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){
      idxInsFlags |= OPFLAG_NCHANGE;
    }
    sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
    sqlite3VdbeChangeP5(v, idxInsFlags);
    sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
    sqlite3VdbeJumpHere(v, addr1);
    sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
    sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
  }
  if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest);
  sqlite3ReleaseTempReg(pParse, regRowid);
Changes to test/without_rowid3.test.
2076
2077
2078
2079
2080
2081
2082
















2083
2084
  }
} {1 {FOREIGN KEY constraint failed}}
do_test without_rowid3-ce7c13.1.6 {
  catchsql {
    UPDATE tce73 set a = 101 where a = 100;
  }
} {1 {FOREIGN KEY constraint failed}}

















finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
  }
} {1 {FOREIGN KEY constraint failed}}
do_test without_rowid3-ce7c13.1.6 {
  catchsql {
    UPDATE tce73 set a = 101 where a = 100;
  }
} {1 {FOREIGN KEY constraint failed}}

# Confirm that changes() works on WITHOUT ROWID tables that use the
# xfer optimization.
#
db close
sqlite3 db :memory:
do_execsql_test without_rowid3-30.1 {
  CREATE TABLE t1(a,b,PRIMARY KEY(a,b)) WITHOUT ROWID;
  CREATE TABLE t2(a,b,PRIMARY KEY(a,b)) WITHOUT ROWID;
  INSERT INTO t1 VALUES(1,2),(3,4),(5,6);
  SELECT changes();
} {3}
do_execsql_test without_rowid3-30.2 {
  INSERT INTO t2 SELECT * FROM t1;
  SELECT changes();
} {3}

finish_test