| Index: third_party/sqlite/src/src/insert.c
 | 
| diff --git a/third_party/sqlite/src/src/insert.c b/third_party/sqlite/src/src/insert.c
 | 
| index f27d50f23eb344cc1d8dce4a8e316d5bc234a22e..adf6ef2ed41eb2ad38b224c5cc32c91c4f61772d 100644
 | 
| --- a/third_party/sqlite/src/src/insert.c
 | 
| +++ b/third_party/sqlite/src/src/insert.c
 | 
| @@ -11,8 +11,6 @@
 | 
|  *************************************************************************
 | 
|  ** This file contains C code routines that are called by the parser
 | 
|  ** to handle INSERT statements in SQLite.
 | 
| -**
 | 
| -** $Id: insert.c,v 1.270 2009/07/24 17:58:53 danielk1977 Exp $
 | 
|  */
 | 
|  #include "sqliteInt.h"
 | 
|  
 | 
| @@ -69,7 +67,7 @@ const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
 | 
|      int n;
 | 
|      Table *pTab = pIdx->pTable;
 | 
|      sqlite3 *db = sqlite3VdbeDb(v);
 | 
| -    pIdx->zColAff = (char *)sqlite3Malloc(pIdx->nColumn+2);
 | 
| +    pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+2);
 | 
|      if( !pIdx->zColAff ){
 | 
|        db->mallocFailed = 1;
 | 
|        return 0;
 | 
| @@ -111,7 +109,7 @@ void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
 | 
|      int i;
 | 
|      sqlite3 *db = sqlite3VdbeDb(v);
 | 
|  
 | 
| -    zColAff = (char *)sqlite3Malloc(pTab->nCol+1);
 | 
| +    zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
 | 
|      if( !zColAff ){
 | 
|        db->mallocFailed = 1;
 | 
|        return;
 | 
| @@ -729,7 +727,7 @@ void sqlite3Insert(
 | 
|          }else{
 | 
|            sqlite3ErrorMsg(pParse, "table %S has no column named %s",
 | 
|                pTabList, 0, pColumn->a[i].zName);
 | 
| -          pParse->nErr++;
 | 
| +          pParse->checkSchema = 1;
 | 
|            goto insert_cleanup;
 | 
|          }
 | 
|        }
 | 
| @@ -848,7 +846,7 @@ void sqlite3Insert(
 | 
|            if( pColumn->a[j].idx==i ) break;
 | 
|          }
 | 
|        }
 | 
| -      if( pColumn && j>=pColumn->nId ){
 | 
| +      if( (!useTempTable && !pList) || (pColumn && j>=pColumn->nId) ){
 | 
|          sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1);
 | 
|        }else if( useTempTable ){
 | 
|          sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1); 
 | 
| @@ -870,7 +868,7 @@ void sqlite3Insert(
 | 
|  
 | 
|      /* Fire BEFORE or INSTEAD OF triggers */
 | 
|      sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, 
 | 
| -        pTab, -1, regCols-pTab->nCol-1, onError, endOfLoop);
 | 
| +        pTab, regCols-pTab->nCol-1, onError, endOfLoop);
 | 
|  
 | 
|      sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1);
 | 
|    }
 | 
| @@ -979,6 +977,7 @@ void sqlite3Insert(
 | 
|        sqlite3GenerateConstraintChecks(pParse, pTab, baseCur, regIns, aRegIdx,
 | 
|            keyColumn>=0, 0, onError, endOfLoop, &isReplace
 | 
|        );
 | 
| +      sqlite3FkCheck(pParse, pTab, 0, regIns);
 | 
|        sqlite3CompleteInsertion(
 | 
|            pParse, pTab, baseCur, regIns, aRegIdx, 0, appendFlag, isReplace==0
 | 
|        );
 | 
| @@ -994,7 +993,7 @@ void sqlite3Insert(
 | 
|    if( pTrigger ){
 | 
|      /* Code AFTER triggers */
 | 
|      sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, 
 | 
| -        pTab, -1, regData-2-pTab->nCol, onError, endOfLoop);
 | 
| +        pTab, regData-2-pTab->nCol, onError, endOfLoop);
 | 
|    }
 | 
|  
 | 
|    /* The bottom of the main insertion loop, if the data source
 | 
| @@ -1046,6 +1045,20 @@ insert_cleanup:
 | 
|    sqlite3DbFree(db, aRegIdx);
 | 
|  }
 | 
|  
 | 
| +/* Make sure "isView" and other macros defined above are undefined. Otherwise
 | 
| +** thely may interfere with compilation of other functions in this file
 | 
| +** (or in another file, if this file becomes part of the amalgamation).  */
 | 
| +#ifdef isView
 | 
| + #undef isView
 | 
| +#endif
 | 
| +#ifdef pTrigger
 | 
| + #undef pTrigger
 | 
| +#endif
 | 
| +#ifdef tmask
 | 
| + #undef tmask
 | 
| +#endif
 | 
| +
 | 
| +
 | 
|  /*
 | 
|  ** Generate code to do constraint checks prior to an INSERT or an UPDATE.
 | 
|  **
 | 
| @@ -1207,6 +1220,7 @@ void sqlite3GenerateConstraintChecks(
 | 
|      if( onError==OE_Ignore ){
 | 
|        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
 | 
|      }else{
 | 
| +      if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
 | 
|        sqlite3HaltConstraint(pParse, onError, 0, 0);
 | 
|      }
 | 
|      sqlite3VdbeResolveLabel(v, allOk);
 | 
| @@ -1225,58 +1239,71 @@ void sqlite3GenerateConstraintChecks(
 | 
|        onError = OE_Abort;
 | 
|      }
 | 
|      
 | 
| -    if( onError!=OE_Replace || pTab->pIndex ){
 | 
| -      if( isUpdate ){
 | 
| -        j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, rowidChng);
 | 
| +    if( isUpdate ){
 | 
| +      j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, rowidChng);
 | 
| +    }
 | 
| +    j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
 | 
| +    switch( onError ){
 | 
| +      default: {
 | 
| +        onError = OE_Abort;
 | 
| +        /* Fall thru into the next case */
 | 
|        }
 | 
| -      j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid);
 | 
| -      switch( onError ){
 | 
| -        default: {
 | 
| -          onError = OE_Abort;
 | 
| -          /* Fall thru into the next case */
 | 
| -        }
 | 
| -        case OE_Rollback:
 | 
| -        case OE_Abort:
 | 
| -        case OE_Fail: {
 | 
| -          sqlite3HaltConstraint(
 | 
| -            pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
 | 
| -          break;
 | 
| -        }
 | 
| -        case OE_Replace: {
 | 
| -          /* If there are DELETE triggers on this table and the
 | 
| -          ** recursive-triggers flag is set, call GenerateRowDelete() to
 | 
| -          ** remove the conflicting row from the the table. This will fire
 | 
| -          ** the triggers and remove both the table and index b-tree entries.
 | 
| -          **
 | 
| -          ** Otherwise, if there are no triggers or the recursive-triggers
 | 
| -          ** flag is not set, call GenerateRowIndexDelete(). This removes
 | 
| -          ** the index b-tree entries only. The table b-tree entry will be 
 | 
| -          ** replaced by the new entry when it is inserted.  */
 | 
| -          Trigger *pTrigger = 0;
 | 
| -          if( pParse->db->flags&SQLITE_RecTriggers ){
 | 
| -            pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
 | 
| -          }
 | 
| -          if( pTrigger ){
 | 
| -            sqlite3GenerateRowDelete(
 | 
| -                pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace
 | 
| -            );
 | 
| -          }else{
 | 
| -            sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0);
 | 
| -          }
 | 
| -          seenReplace = 1;
 | 
| -          break;
 | 
| +      case OE_Rollback:
 | 
| +      case OE_Abort:
 | 
| +      case OE_Fail: {
 | 
| +        sqlite3HaltConstraint(
 | 
| +          pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
 | 
| +        break;
 | 
| +      }
 | 
| +      case OE_Replace: {
 | 
| +        /* If there are DELETE triggers on this table and the
 | 
| +        ** recursive-triggers flag is set, call GenerateRowDelete() to
 | 
| +        ** remove the conflicting row from the the table. This will fire
 | 
| +        ** the triggers and remove both the table and index b-tree entries.
 | 
| +        **
 | 
| +        ** Otherwise, if there are no triggers or the recursive-triggers
 | 
| +        ** flag is not set, but the table has one or more indexes, call 
 | 
| +        ** GenerateRowIndexDelete(). This removes the index b-tree entries 
 | 
| +        ** only. The table b-tree entry will be replaced by the new entry 
 | 
| +        ** when it is inserted.  
 | 
| +        **
 | 
| +        ** If either GenerateRowDelete() or GenerateRowIndexDelete() is called,
 | 
| +        ** also invoke MultiWrite() to indicate that this VDBE may require
 | 
| +        ** statement rollback (if the statement is aborted after the delete
 | 
| +        ** takes place). Earlier versions called sqlite3MultiWrite() regardless,
 | 
| +        ** but being more selective here allows statements like:
 | 
| +        **
 | 
| +        **   REPLACE INTO t(rowid) VALUES($newrowid)
 | 
| +        **
 | 
| +        ** to run without a statement journal if there are no indexes on the
 | 
| +        ** table.
 | 
| +        */
 | 
| +        Trigger *pTrigger = 0;
 | 
| +        if( pParse->db->flags&SQLITE_RecTriggers ){
 | 
| +          pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
 | 
|          }
 | 
| -        case OE_Ignore: {
 | 
| -          assert( seenReplace==0 );
 | 
| -          sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
 | 
| -          break;
 | 
| +        if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){
 | 
| +          sqlite3MultiWrite(pParse);
 | 
| +          sqlite3GenerateRowDelete(
 | 
| +              pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace
 | 
| +          );
 | 
| +        }else if( pTab->pIndex ){
 | 
| +          sqlite3MultiWrite(pParse);
 | 
| +          sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0);
 | 
|          }
 | 
| +        seenReplace = 1;
 | 
| +        break;
 | 
|        }
 | 
| -      sqlite3VdbeJumpHere(v, j3);
 | 
| -      if( isUpdate ){
 | 
| -        sqlite3VdbeJumpHere(v, j2);
 | 
| +      case OE_Ignore: {
 | 
| +        assert( seenReplace==0 );
 | 
| +        sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
 | 
| +        break;
 | 
|        }
 | 
|      }
 | 
| +    sqlite3VdbeJumpHere(v, j3);
 | 
| +    if( isUpdate ){
 | 
| +      sqlite3VdbeJumpHere(v, j2);
 | 
| +    }
 | 
|    }
 | 
|  
 | 
|    /* Test all UNIQUE constraints by creating entries for each UNIQUE
 | 
| @@ -1364,6 +1391,7 @@ void sqlite3GenerateConstraintChecks(
 | 
|        default: {
 | 
|          Trigger *pTrigger = 0;
 | 
|          assert( onError==OE_Replace );
 | 
| +        sqlite3MultiWrite(pParse);
 | 
|          if( pParse->db->flags&SQLITE_RecTriggers ){
 | 
|            pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
 | 
|          }
 | 
| @@ -1377,7 +1405,7 @@ void sqlite3GenerateConstraintChecks(
 | 
|      sqlite3VdbeJumpHere(v, j3);
 | 
|      sqlite3ReleaseTempReg(pParse, regR);
 | 
|    }
 | 
| -
 | 
| +  
 | 
|    if( pbMayReplace ){
 | 
|      *pbMayReplace = seenReplace;
 | 
|    }
 | 
| @@ -1702,7 +1730,7 @@ static int xferOptimization(
 | 
|      }
 | 
|    }
 | 
|  #ifndef SQLITE_OMIT_CHECK
 | 
| -  if( pDest->pCheck && !sqlite3ExprCompare(pSrc->pCheck, pDest->pCheck) ){
 | 
| +  if( pDest->pCheck && sqlite3ExprCompare(pSrc->pCheck, pDest->pCheck) ){
 | 
|      return 0;   /* Tables have different CHECK constraints.  Ticket #2252 */
 | 
|    }
 | 
|  #endif
 | 
| @@ -1800,8 +1828,3 @@ static int xferOptimization(
 | 
|    }
 | 
|  }
 | 
|  #endif /* SQLITE_OMIT_XFER_OPT */
 | 
| -
 | 
| -/* Make sure "isView" gets undefined in case this file becomes part of
 | 
| -** the amalgamation - so that subsequent files do not see isView as a
 | 
| -** macro. */
 | 
| -#undef isView
 | 
| 
 |