aboutsummaryrefslogtreecommitdiff
path: root/src/insert.c
diff options
context:
space:
mode:
authordan <dan@noemail.net>2013-11-05 16:39:31 +0000
committerdan <dan@noemail.net>2013-11-05 16:39:31 +0000
commit427ebba10cd97f34141fceb7c38483c5ccda702f (patch)
tree8d573509e06e1369b2d9c6185c0fbe82b8c18441 /src/insert.c
parent7b3d1860afdcf779a3b4bc1052105835dc860d42 (diff)
downloadsqlite-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.c52
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 ){