summaryrefslogtreecommitdiffstats
path: root/lib/libsqlite3/src/insert.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libsqlite3/src/insert.c')
-rw-r--r--lib/libsqlite3/src/insert.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/lib/libsqlite3/src/insert.c b/lib/libsqlite3/src/insert.c
index 9a5661f59a7..1c2cabb938b 100644
--- a/lib/libsqlite3/src/insert.c
+++ b/lib/libsqlite3/src/insert.c
@@ -1379,9 +1379,19 @@ void sqlite3GenerateConstraintChecks(
for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
int regIdx;
int regR;
+ int addrSkipRow = 0;
if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
+ if( pIdx->pPartIdxWhere ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[iCur]);
+ addrSkipRow = sqlite3VdbeMakeLabel(v);
+ pParse->ckBase = regData;
+ sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrSkipRow,
+ SQLITE_JUMPIFNULL);
+ pParse->ckBase = 0;
+ }
+
/* Create a key for accessing the index entry */
regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
for(i=0; i<pIdx->nColumn; i++){
@@ -1401,6 +1411,7 @@ void sqlite3GenerateConstraintChecks(
onError = pIdx->onError;
if( onError==OE_None ){
sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
+ sqlite3VdbeResolveLabel(v, addrSkipRow);
continue; /* pIdx is not a UNIQUE index */
}
if( overrideError!=OE_Default ){
@@ -1470,6 +1481,7 @@ void sqlite3GenerateConstraintChecks(
}
}
sqlite3VdbeJumpHere(v, j3);
+ sqlite3VdbeResolveLabel(v, addrSkipRow);
sqlite3ReleaseTempReg(pParse, regR);
}
@@ -1499,7 +1511,6 @@ void sqlite3CompleteInsertion(
){
int i;
Vdbe *v;
- int nIdx;
Index *pIdx;
u8 pik_flags;
int regData;
@@ -1508,9 +1519,11 @@ void sqlite3CompleteInsertion(
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
- for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
- for(i=nIdx-1; i>=0; i--){
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( aRegIdx[i]==0 ) continue;
+ if( pIdx->pPartIdxWhere ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
+ }
sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
if( useSeekResult ){
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
@@ -1612,6 +1625,7 @@ static int xferCompatibleCollation(const char *z1, const char *z2){
** * The same DESC and ASC markings occurs on all columns
** * The same onError processing (OE_Abort, OE_Ignore, etc)
** * The same collating sequence on each column
+** * The index has the exact same WHERE clause
*/
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
int i;
@@ -1634,6 +1648,9 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
return 0; /* Different collating sequences */
}
}
+ if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
+ return 0; /* Different WHERE clauses */
+ }
/* If no test above fails then the indices must be compatible */
return 1;
@@ -1789,7 +1806,7 @@ static int xferOptimization(
}
}
#ifndef SQLITE_OMIT_CHECK
- if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck, pDest->pCheck) ){
+ if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
return 0; /* Tables have different CHECK constraints. Ticket #2252 */
}
#endif