diff options
author | dan <dan@noemail.net> | 2013-11-05 16:39:31 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2013-11-05 16:39:31 +0000 |
commit | 427ebba10cd97f34141fceb7c38483c5ccda702f (patch) | |
tree | 8d573509e06e1369b2d9c6185c0fbe82b8c18441 /src/insert.c | |
parent | 7b3d1860afdcf779a3b4bc1052105835dc860d42 (diff) | |
download | sqlite-427ebba10cd97f34141fceb7c38483c5ccda702f.tar.gz sqlite-427ebba10cd97f34141fceb7c38483c5ccda702f.zip |
Unless the destination table is completely empty, disable the xfer optimization for WITHOUT ROWID tables.
FossilOrigin-Name: 3877c9f50582b51817dcf3cd75d836891a34e590
Diffstat (limited to 'src/insert.c')
-rw-r--r-- | src/insert.c | 52 |
1 files changed, 24 insertions, 28 deletions
diff --git a/src/insert.c b/src/insert.c index 90752033a..d65c49ed5 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1897,9 +1897,6 @@ static int xferOptimization( if( pDest->iPKey!=pSrc->iPKey ){ return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ } - if( HasRowid(pDest)!=HasRowid(pSrc) ){ - return 0; /* source and destination must both be WITHOUT ROWID or not */ - } for(i=0; i<pDest->nCol; i++){ if( pDest->aCol[i].affinity!=pSrc->aCol[i].affinity ){ return 0; /* Affinity must be the same on all columns */ @@ -1958,32 +1955,31 @@ static int xferOptimization( regAutoinc = autoIncBegin(pParse, iDbDest, pDest); regData = sqlite3GetTempReg(pParse); regRowid = sqlite3GetTempReg(pParse); + sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); + assert( HasRowid(pDest) || destHasUniqueIdx ); + if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ + || destHasUniqueIdx /* (2) */ + || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */ + ){ + /* In some circumstances, we are able to run the xfer optimization + ** only if the destination table is initially empty. This code makes + ** that determination. Conditions under which the destination must + ** be empty: + ** + ** (1) There is no INTEGER PRIMARY KEY but there are indices. + ** (If the destination is not initially empty, the rowid fields + ** of index entries might need to change.) + ** + ** (2) The destination has a unique index. (The xfer optimization + ** is unable to test uniqueness.) + ** + ** (3) onError is something other than OE_Abort and OE_Rollback. + */ + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); + emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); + sqlite3VdbeJumpHere(v, addr1); + } if( HasRowid(pSrc) ){ - sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); - if( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ - || destHasUniqueIdx /* (2) */ - || (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */ - ){ - /* In some circumstances, we are able to run the xfer optimization - ** only if the destination table is initially empty. This code makes - ** that determination. Conditions under which the destination must - ** be empty: - ** - ** (1) There is no INTEGER PRIMARY KEY but there are indices. - ** (If the destination is not initially empty, the rowid fields - ** of index entries might need to change.) - ** - ** (2) The destination has a unique index. (The xfer optimization - ** is unable to test uniqueness.) - ** - ** (3) onError is something other than OE_Abort and OE_Rollback. - */ - addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); - emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); - sqlite3VdbeJumpHere(v, addr1); - }else{ - emptyDestTest = 0; - } sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead); emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); if( pDest->iPKey>=0 ){ |