mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-11 01:42:22 +03:00
Refactoring the VM. The P3 parameter is changed to P4. A P5 parameter is
added (though not currently used.) Add routines sqlite3VdbeAddOpX() where X is one of 0, 1, 2, 3, or 4. (CVS 4660) FossilOrigin-Name: 027875e4d4c4bd7686dc880c6917a968049b2fec
This commit is contained in:
303
src/insert.c
303
src/insert.c
@@ -12,12 +12,12 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle INSERT statements in SQLite.
|
||||
**
|
||||
** $Id: insert.c,v 1.201 2008/01/02 16:27:10 danielk1977 Exp $
|
||||
** $Id: insert.c,v 1.202 2008/01/03 00:01:24 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
/*
|
||||
** Set P3 of the most recently inserted opcode to a column affinity
|
||||
** Set P4 of the most recently inserted opcode to a column affinity
|
||||
** string for index pIdx. A column affinity string has one character
|
||||
** for each column in the table, according to the affinity of the column:
|
||||
**
|
||||
@@ -52,11 +52,11 @@ void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
|
||||
pIdx->zColAff[pIdx->nColumn] = '\0';
|
||||
}
|
||||
|
||||
sqlite3VdbeChangeP3(v, -1, pIdx->zColAff, 0);
|
||||
sqlite3VdbeChangeP4(v, -1, pIdx->zColAff, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
** Set P3 of the most recently inserted opcode to a column affinity
|
||||
** Set P4 of the most recently inserted opcode to a column affinity
|
||||
** string for table pTab. A column affinity string has one character
|
||||
** for each column indexed by the index, according to the affinity of the
|
||||
** column:
|
||||
@@ -95,7 +95,7 @@ void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
|
||||
pTab->zColAff = zColAff;
|
||||
}
|
||||
|
||||
sqlite3VdbeChangeP3(v, -1, pTab->zColAff, 0);
|
||||
sqlite3VdbeChangeP4(v, -1, pTab->zColAff, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -129,9 +129,9 @@ static int readsTable(Vdbe *v, int iStartAddr, int iDb, Table *pTab){
|
||||
}
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( pOp->opcode==OP_VOpen && pOp->p3.p==(const char*)pTab->pVtab ){
|
||||
assert( pOp->p3.p!=0 );
|
||||
assert( pOp->p3type==P3_VTAB );
|
||||
if( pOp->opcode==OP_VOpen && pOp->p4.p==(const char*)pTab->pVtab ){
|
||||
assert( pOp->p4.p!=0 );
|
||||
assert( pOp->p4type==P4_VTAB );
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@@ -171,17 +171,17 @@ static int autoIncBegin(
|
||||
memId = pParse->nMem+1;
|
||||
pParse->nMem += 2;
|
||||
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
|
||||
sqlite3VdbeAddOp(v, OP_Rewind, iCur, addr+13);
|
||||
sqlite3VdbeAddOp(v, OP_Column, iCur, 0);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Ne, 0x100, addr+12);
|
||||
sqlite3VdbeAddOp(v, OP_Rowid, iCur, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, memId-1, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Column, iCur, 1);
|
||||
sqlite3VdbeAddOp(v, OP_MemStore, memId, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, addr+13);
|
||||
sqlite3VdbeAddOp(v, OP_Next, iCur, addr+4);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Rewind, iCur, addr+13);
|
||||
sqlite3VdbeAddOp2(v, OP_Column, iCur, 0);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Ne, 0x100, addr+12);
|
||||
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MemStore, memId-1, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Column, iCur, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_MemStore, memId, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+13);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+4);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
|
||||
}
|
||||
return memId;
|
||||
}
|
||||
@@ -196,7 +196,7 @@ static int autoIncBegin(
|
||||
*/
|
||||
static void autoIncStep(Parse *pParse, int memId){
|
||||
if( memId>0 ){
|
||||
sqlite3VdbeAddOp(pParse->pVdbe, OP_MemMax, memId, 0);
|
||||
sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,15 +219,15 @@ static void autoIncEnd(
|
||||
assert( v );
|
||||
addr = sqlite3VdbeCurrentAddr(v);
|
||||
sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, memId-1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, addr+7);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NewRowid, iCur, 0);
|
||||
sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, memId, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Insert, iCur, OPFLAG_APPEND);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MemLoad, memId-1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+7);
|
||||
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, iCur, 0);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MemLoad, memId, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MakeRecord, 2, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Insert, iCur, OPFLAG_APPEND);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -478,7 +478,7 @@ void sqlite3Insert(
|
||||
*/
|
||||
SelectDest dest = {SRT_Subroutine, 0, 0};
|
||||
int rc, iInitCode;
|
||||
iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
||||
iInitCode = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
|
||||
iSelectLoop = sqlite3VdbeCurrentAddr(v);
|
||||
iInsertBlock = sqlite3VdbeMakeLabel(v);
|
||||
dest.iParm = iInsertBlock;
|
||||
@@ -490,7 +490,7 @@ void sqlite3Insert(
|
||||
}
|
||||
|
||||
iCleanup = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, iCleanup);
|
||||
assert( pSelect->pEList );
|
||||
nColumn = pSelect->pEList->nExpr;
|
||||
|
||||
@@ -512,21 +512,21 @@ void sqlite3Insert(
|
||||
*/
|
||||
srcTab = pParse->nTab++;
|
||||
sqlite3VdbeResolveLabel(v, iInsertBlock);
|
||||
sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NewRowid, srcTab, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Insert, srcTab, OPFLAG_APPEND);
|
||||
sqlite3VdbeAddOp(v, OP_Return, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MakeRecord, nColumn, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Insert, srcTab, OPFLAG_APPEND);
|
||||
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
||||
|
||||
/* The following code runs first because the GOTO at the very top
|
||||
** of the program jumps to it. Create the temporary table, then jump
|
||||
** back up and execute the SELECT code above.
|
||||
*/
|
||||
sqlite3VdbeJumpHere(v, iInitCode);
|
||||
sqlite3VdbeAddOp(v, OP_OpenEphemeral, srcTab, 0);
|
||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, srcTab, nColumn);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
|
||||
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_SetNumColumns, srcTab, nColumn);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, iSelectLoop);
|
||||
sqlite3VdbeResolveLabel(v, iCleanup);
|
||||
}else{
|
||||
sqlite3VdbeJumpHere(v, iInitCode);
|
||||
@@ -616,15 +616,15 @@ void sqlite3Insert(
|
||||
/* Open the temp table for FOR EACH ROW triggers
|
||||
*/
|
||||
if( triggers_exist ){
|
||||
sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
|
||||
sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol);
|
||||
sqlite3VdbeAddOp2(v, OP_OpenPseudo, newIdx, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_SetNumColumns, newIdx, pTab->nCol);
|
||||
}
|
||||
|
||||
/* Initialize the count of rows to be inserted
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows ){
|
||||
iCntMem = pParse->nMem++;
|
||||
sqlite3VdbeAddOp(v, OP_MemInt, 0, iCntMem);
|
||||
sqlite3VdbeAddOp2(v, OP_MemInt, 0, iCntMem);
|
||||
}
|
||||
|
||||
/* If this is not a view, open the table and and all indices */
|
||||
@@ -640,12 +640,12 @@ void sqlite3Insert(
|
||||
*/
|
||||
if( useTempTable ){
|
||||
iBreak = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3VdbeAddOp(v, OP_Rewind, srcTab, iBreak);
|
||||
sqlite3VdbeAddOp2(v, OP_Rewind, srcTab, iBreak);
|
||||
iCont = sqlite3VdbeCurrentAddr(v);
|
||||
}else if( pSelect ){
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, iSelectLoop);
|
||||
sqlite3VdbeResolveLabel(v, iInsertBlock);
|
||||
sqlite3VdbeAddOp(v, OP_StackDepth, -1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0);
|
||||
}
|
||||
|
||||
/* Run the BEFORE and INSTEAD OF triggers, if there are any
|
||||
@@ -660,16 +660,16 @@ void sqlite3Insert(
|
||||
** not happened yet) so we substitute a rowid of -1
|
||||
*/
|
||||
if( keyColumn<0 ){
|
||||
sqlite3VdbeAddOp(v, OP_Integer, -1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, -1, 0);
|
||||
}else if( useTempTable ){
|
||||
sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn);
|
||||
sqlite3VdbeAddOp2(v, OP_Column, srcTab, keyColumn);
|
||||
}else{
|
||||
assert( pSelect==0 ); /* Otherwise useTempTable is true */
|
||||
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
|
||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, -1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
||||
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, -1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
|
||||
}
|
||||
|
||||
/* Cannot have triggers on a virtual table. If it were possible,
|
||||
@@ -690,13 +690,13 @@ void sqlite3Insert(
|
||||
if( pColumn && j>=pColumn->nId ){
|
||||
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
|
||||
}else if( useTempTable ){
|
||||
sqlite3VdbeAddOp(v, OP_Column, srcTab, j);
|
||||
sqlite3VdbeAddOp2(v, OP_Column, srcTab, j);
|
||||
}else{
|
||||
assert( pSelect==0 ); /* Otherwise useTempTable is true */
|
||||
sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr);
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
|
||||
/* If this is an INSERT on a view with an INSTEAD OF INSERT trigger,
|
||||
** do not attempt any conversions before assembling the record.
|
||||
@@ -706,7 +706,7 @@ void sqlite3Insert(
|
||||
if( !isView ){
|
||||
sqlite3TableAffinityStr(v, pTab);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Insert, newIdx, 0);
|
||||
|
||||
/* Fire BEFORE or INSTEAD OF triggers */
|
||||
if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab,
|
||||
@@ -723,13 +723,13 @@ void sqlite3Insert(
|
||||
if( !isView ){
|
||||
if( IsVirtual(pTab) ){
|
||||
/* The row that the VUpdate opcode will delete: none */
|
||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||
}
|
||||
if( keyColumn>=0 ){
|
||||
if( useTempTable ){
|
||||
sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn);
|
||||
sqlite3VdbeAddOp2(v, OP_Column, srcTab, keyColumn);
|
||||
}else if( pSelect ){
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, nColumn - keyColumn - 1, 1);
|
||||
}else{
|
||||
VdbeOp *pOp;
|
||||
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr);
|
||||
@@ -745,15 +745,15 @@ void sqlite3Insert(
|
||||
** to generate a unique primary key value.
|
||||
*/
|
||||
if( !appendFlag ){
|
||||
sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
|
||||
sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
|
||||
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, base, counterMem);
|
||||
sqlite3VdbeAddOp2(v, OP_MustBeInt, 0, 0);
|
||||
}
|
||||
}else if( IsVirtual(pTab) ){
|
||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||
}else{
|
||||
sqlite3VdbeAddOp(v, OP_NewRowid, base, counterMem);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, base, counterMem);
|
||||
appendFlag = 1;
|
||||
}
|
||||
autoIncStep(pParse, counterMem);
|
||||
@@ -768,7 +768,7 @@ void sqlite3Insert(
|
||||
** Whenever this column is read, the record number will be substituted
|
||||
** in its place. So will fill this column with a NULL to avoid
|
||||
** taking up data space with information that will never be used. */
|
||||
sqlite3VdbeAddOp(v, OP_Null, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
|
||||
continue;
|
||||
}
|
||||
if( pColumn==0 ){
|
||||
@@ -787,9 +787,9 @@ void sqlite3Insert(
|
||||
if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
|
||||
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
|
||||
}else if( useTempTable ){
|
||||
sqlite3VdbeAddOp(v, OP_Column, srcTab, j);
|
||||
sqlite3VdbeAddOp2(v, OP_Column, srcTab, j);
|
||||
}else if( pSelect ){
|
||||
sqlite3VdbeAddOp(v, OP_Dup, i+nColumn-j+IsVirtual(pTab), 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, i+nColumn-j+IsVirtual(pTab), 1);
|
||||
}else{
|
||||
sqlite3ExprCode(pParse, pList->a[j].pExpr);
|
||||
}
|
||||
@@ -801,8 +801,8 @@ void sqlite3Insert(
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
if( IsVirtual(pTab) ){
|
||||
pParse->pVirtualLock = pTab;
|
||||
sqlite3VdbeOp3(v, OP_VUpdate, 1, pTab->nCol+2,
|
||||
(const char*)pTab->pVtab, P3_VTAB);
|
||||
sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, 0,
|
||||
(const char*)pTab->pVtab, P4_VTAB);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
@@ -817,7 +817,7 @@ void sqlite3Insert(
|
||||
/* Update the count of rows that are inserted
|
||||
*/
|
||||
if( (db->flags & SQLITE_CountRows)!=0 ){
|
||||
sqlite3VdbeAddOp(v, OP_MemIncr, 1, iCntMem);
|
||||
sqlite3VdbeAddOp2(v, OP_MemIncr, 1, iCntMem);
|
||||
}
|
||||
|
||||
if( triggers_exist ){
|
||||
@@ -832,20 +832,20 @@ void sqlite3Insert(
|
||||
*/
|
||||
sqlite3VdbeResolveLabel(v, endOfLoop);
|
||||
if( useTempTable ){
|
||||
sqlite3VdbeAddOp(v, OP_Next, srcTab, iCont);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, srcTab, iCont);
|
||||
sqlite3VdbeResolveLabel(v, iBreak);
|
||||
sqlite3VdbeAddOp(v, OP_Close, srcTab, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, srcTab, 0);
|
||||
}else if( pSelect ){
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Return, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Pop, nColumn, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
|
||||
sqlite3VdbeResolveLabel(v, iCleanup);
|
||||
}
|
||||
|
||||
if( !IsVirtual(pTab) && !isView ){
|
||||
/* Close all tables opened */
|
||||
sqlite3VdbeAddOp(v, OP_Close, base, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, base, 0);
|
||||
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
||||
sqlite3VdbeAddOp(v, OP_Close, idx+base, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, idx+base, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -861,9 +861,9 @@ void sqlite3Insert(
|
||||
** invoke the callback function.
|
||||
*/
|
||||
if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){
|
||||
sqlite3VdbeAddOp(v, OP_ResultRow, iCntMem, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_ResultRow, iCntMem, 1);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", P3_STATIC);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", P4_STATIC);
|
||||
}
|
||||
|
||||
insert_cleanup:
|
||||
@@ -995,8 +995,8 @@ void sqlite3GenerateConstraintChecks(
|
||||
if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
|
||||
onError = OE_Abort;
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol-1-i, 1);
|
||||
addr = sqlite3VdbeAddOp(v, OP_NotNull, 1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol-1-i, 1);
|
||||
addr = sqlite3VdbeAddOp2(v, OP_NotNull, 1, 0);
|
||||
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|
||||
|| onError==OE_Ignore || onError==OE_Replace );
|
||||
switch( onError ){
|
||||
@@ -1004,20 +1004,20 @@ void sqlite3GenerateConstraintChecks(
|
||||
case OE_Abort:
|
||||
case OE_Fail: {
|
||||
char *zMsg = 0;
|
||||
sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_CONSTRAINT, onError);
|
||||
sqlite3SetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName,
|
||||
" may not be NULL", (char*)0);
|
||||
sqlite3VdbeChangeP3(v, -1, zMsg, P3_DYNAMIC);
|
||||
sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
|
||||
break;
|
||||
}
|
||||
case OE_Ignore: {
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
||||
sqlite3VdbeAddOp2(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||
break;
|
||||
}
|
||||
case OE_Replace: {
|
||||
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
|
||||
sqlite3VdbeAddOp(v, OP_Push, nCol-i, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Push, nCol-i, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1036,10 +1036,10 @@ void sqlite3GenerateConstraintChecks(
|
||||
pParse->ckOffset = 0;
|
||||
onError = overrideError!=OE_Default ? overrideError : OE_Abort;
|
||||
if( onError==OE_Ignore ){
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
||||
sqlite3VdbeAddOp2(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||
}else{
|
||||
sqlite3VdbeAddOp(v, OP_Halt, SQLITE_CONSTRAINT, onError);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_CONSTRAINT, onError);
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, allOk);
|
||||
}
|
||||
@@ -1058,12 +1058,12 @@ void sqlite3GenerateConstraintChecks(
|
||||
}
|
||||
|
||||
if( isUpdate ){
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
|
||||
jumpInst1 = sqlite3VdbeAddOp(v, OP_Eq, 0, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol+1, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol+1, 1);
|
||||
jumpInst1 = sqlite3VdbeAddOp2(v, OP_Eq, 0, 0);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol, 1);
|
||||
jumpInst2 = sqlite3VdbeAddOp(v, OP_NotExists, base, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol, 1);
|
||||
jumpInst2 = sqlite3VdbeAddOp2(v, OP_NotExists, base, 0);
|
||||
switch( onError ){
|
||||
default: {
|
||||
onError = OE_Abort;
|
||||
@@ -1072,31 +1072,31 @@ void sqlite3GenerateConstraintChecks(
|
||||
case OE_Rollback:
|
||||
case OE_Abort:
|
||||
case OE_Fail: {
|
||||
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError,
|
||||
"PRIMARY KEY must be unique", P3_STATIC);
|
||||
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
|
||||
"PRIMARY KEY must be unique", P4_STATIC);
|
||||
break;
|
||||
}
|
||||
case OE_Replace: {
|
||||
sqlite3GenerateRowIndexDelete(v, pTab, base, 0);
|
||||
if( isUpdate ){
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+hasTwoRowids, 1);
|
||||
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol+hasTwoRowids, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0);
|
||||
}
|
||||
seenReplace = 1;
|
||||
break;
|
||||
}
|
||||
case OE_Ignore: {
|
||||
assert( seenReplace==0 );
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
||||
sqlite3VdbeAddOp2(v, OP_Pop, nCol+1+hasTwoRowids, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||
break;
|
||||
}
|
||||
}
|
||||
sqlite3VdbeJumpHere(v, jumpInst2);
|
||||
if( isUpdate ){
|
||||
sqlite3VdbeJumpHere(v, jumpInst1);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+1, 1);
|
||||
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol+1, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1110,16 +1110,16 @@ void sqlite3GenerateConstraintChecks(
|
||||
extra++;
|
||||
|
||||
/* Create a key for accessing the index entry */
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+extra, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol+extra, 1);
|
||||
for(i=0; i<pIdx->nColumn; i++){
|
||||
int idx = pIdx->aiColumn[i];
|
||||
if( idx==pTab->iPKey ){
|
||||
sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, i+extra+nCol+1, 1);
|
||||
}else{
|
||||
sqlite3VdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, i+extra+nCol-idx, 1);
|
||||
}
|
||||
}
|
||||
jumpInst1 = sqlite3VdbeAddOp(v, OP_MakeIdxRec, pIdx->nColumn, 0);
|
||||
jumpInst1 = sqlite3VdbeAddOp2(v, OP_MakeIdxRec, pIdx->nColumn, 0);
|
||||
sqlite3IndexAffinityStr(v, pIdx);
|
||||
|
||||
/* Find out what action to take in case there is an indexing conflict */
|
||||
@@ -1137,8 +1137,8 @@ void sqlite3GenerateConstraintChecks(
|
||||
|
||||
|
||||
/* Check to see if the new index entry will be unique */
|
||||
sqlite3VdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRowids, 1);
|
||||
jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, extra+nCol+1+hasTwoRowids, 1);
|
||||
jumpInst2 = sqlite3VdbeAddOp2(v, OP_IsUnique, base+iCur+1, 0);
|
||||
|
||||
/* Generate code that executes if the new index entry is not unique */
|
||||
assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
|
||||
@@ -1170,20 +1170,20 @@ void sqlite3GenerateConstraintChecks(
|
||||
}
|
||||
sqlite3_snprintf(sizeof(zErrMsg)-n1, &zErrMsg[n1],
|
||||
pIdx->nColumn>1 ? " are not unique" : " is not unique");
|
||||
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError, zErrMsg, 0);
|
||||
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, zErrMsg,0);
|
||||
break;
|
||||
}
|
||||
case OE_Ignore: {
|
||||
assert( seenReplace==0 );
|
||||
sqlite3VdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRowids, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, ignoreDest);
|
||||
sqlite3VdbeAddOp2(v, OP_Pop, nCol+extra+3+hasTwoRowids, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest);
|
||||
break;
|
||||
}
|
||||
case OE_Replace: {
|
||||
sqlite3GenerateRowDelete(pParse->db, v, pTab, base, 0);
|
||||
if( isUpdate ){
|
||||
sqlite3VdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1);
|
||||
sqlite3VdbeAddOp(v, OP_MoveGe, base, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, nCol+extra+1+hasTwoRowids, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_MoveGe, base, 0);
|
||||
}
|
||||
seenReplace = 1;
|
||||
break;
|
||||
@@ -1228,15 +1228,15 @@ void sqlite3CompleteInsertion(
|
||||
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
|
||||
for(i=nIdx-1; i>=0; i--){
|
||||
if( aIdxUsed && aIdxUsed[i]==0 ) continue;
|
||||
sqlite3VdbeAddOp(v, OP_IdxInsert, base+i+1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_IdxInsert, base+i+1, 0);
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_MakeRecord, pTab->nCol, 0);
|
||||
sqlite3TableAffinityStr(v, pTab);
|
||||
#ifndef SQLITE_OMIT_TRIGGER
|
||||
if( newIdx>=0 ){
|
||||
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Insert, newIdx, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, 1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, 1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Insert, newIdx, 0);
|
||||
}
|
||||
#endif
|
||||
if( pParse->nested ){
|
||||
@@ -1248,13 +1248,13 @@ void sqlite3CompleteInsertion(
|
||||
if( appendBias ){
|
||||
pik_flags |= OPFLAG_APPEND;
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_Insert, base, pik_flags);
|
||||
sqlite3VdbeAddOp2(v, OP_Insert, base, pik_flags);
|
||||
if( !pParse->nested ){
|
||||
sqlite3VdbeChangeP3(v, -1, pTab->zName, P3_STATIC);
|
||||
sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
|
||||
}
|
||||
|
||||
if( isUpdate && rowidChng ){
|
||||
sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1282,9 +1282,10 @@ void sqlite3OpenTableAndIndices(
|
||||
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
|
||||
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
|
||||
assert( pIdx->pSchema==pTab->pSchema );
|
||||
sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, iDb, 0);
|
||||
VdbeComment((v, "%s", pIdx->zName));
|
||||
sqlite3VdbeOp3(v, op, i+base, pIdx->tnum, (char*)pKey, P3_KEYINFO_HANDOFF);
|
||||
sqlite3VdbeAddOp4(v, op, i+base, pIdx->tnum, 0,
|
||||
(char*)pKey, P4_KEYINFO_HANDOFF);
|
||||
}
|
||||
if( pParse->nTab<=base+i ){
|
||||
pParse->nTab = base+i;
|
||||
@@ -1545,64 +1546,64 @@ static int xferOptimization(
|
||||
** insure that all entries in the union of DEST and SRC will be
|
||||
** unique.
|
||||
*/
|
||||
addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iDest, 0);
|
||||
emptyDestTest = sqlite3VdbeAddOp(v, OP_Goto, 0, 0);
|
||||
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 = sqlite3VdbeAddOp(v, OP_Rewind, iSrc, 0);
|
||||
emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
|
||||
if( pDest->iPKey>=0 ){
|
||||
addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
|
||||
addr2 = sqlite3VdbeAddOp(v, OP_NotExists, iDest, 0);
|
||||
sqlite3VdbeOp3(v, OP_Halt, SQLITE_CONSTRAINT, onError,
|
||||
"PRIMARY KEY must be unique", P3_STATIC);
|
||||
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Dup, 0, 0);
|
||||
addr2 = sqlite3VdbeAddOp2(v, OP_NotExists, iDest, 0);
|
||||
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0,
|
||||
"PRIMARY KEY must be unique", P4_STATIC);
|
||||
sqlite3VdbeJumpHere(v, addr2);
|
||||
autoIncStep(pParse, counterMem);
|
||||
}else if( pDest->pIndex==0 ){
|
||||
addr1 = sqlite3VdbeAddOp(v, OP_NewRowid, iDest, 0);
|
||||
addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, 0);
|
||||
}else{
|
||||
addr1 = sqlite3VdbeAddOp(v, OP_Rowid, iSrc, 0);
|
||||
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, 0);
|
||||
assert( pDest->autoInc==0 );
|
||||
}
|
||||
sqlite3VdbeAddOp(v, OP_RowData, iSrc, 0);
|
||||
sqlite3VdbeOp3(v, OP_Insert, iDest,
|
||||
sqlite3VdbeAddOp2(v, OP_RowData, iSrc, 0);
|
||||
sqlite3VdbeAddOp4(v, OP_Insert, iDest, 0,
|
||||
OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND,
|
||||
pDest->zName, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Next, iSrc, addr1);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
|
||||
autoIncEnd(pParse, iDbDest, pDest, counterMem);
|
||||
for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
|
||||
for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
|
||||
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
|
||||
}
|
||||
assert( pSrcIdx );
|
||||
sqlite3VdbeAddOp(v, OP_Close, iSrc, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iDest, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, iDbSrc, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, iDbSrc, 0);
|
||||
pKey = sqlite3IndexKeyinfo(pParse, pSrcIdx);
|
||||
VdbeComment((v, "%s", pSrcIdx->zName));
|
||||
sqlite3VdbeOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum,
|
||||
(char*)pKey, P3_KEYINFO_HANDOFF);
|
||||
sqlite3VdbeAddOp(v, OP_Integer, iDbDest, 0);
|
||||
sqlite3VdbeAddOp4(v, OP_OpenRead, iSrc, pSrcIdx->tnum, 0,
|
||||
(char*)pKey, P4_KEYINFO_HANDOFF);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, iDbDest, 0);
|
||||
pKey = sqlite3IndexKeyinfo(pParse, pDestIdx);
|
||||
VdbeComment((v, "%s", pDestIdx->zName));
|
||||
sqlite3VdbeOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum,
|
||||
(char*)pKey, P3_KEYINFO_HANDOFF);
|
||||
addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iSrc, 0);
|
||||
sqlite3VdbeAddOp(v, OP_RowKey, iSrc, 0);
|
||||
sqlite3VdbeAddOp(v, OP_IdxInsert, iDest, 1);
|
||||
sqlite3VdbeAddOp(v, OP_Next, iSrc, addr1+1);
|
||||
sqlite3VdbeAddOp4(v, OP_OpenWrite, iDest, pDestIdx->tnum, 0,
|
||||
(char*)pKey, P4_KEYINFO_HANDOFF);
|
||||
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, 1);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
|
||||
sqlite3VdbeJumpHere(v, addr1);
|
||||
}
|
||||
sqlite3VdbeJumpHere(v, emptySrcTest);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iSrc, 0);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iDest, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
|
||||
if( emptyDestTest ){
|
||||
sqlite3VdbeAddOp(v, OP_Halt, SQLITE_OK, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
|
||||
sqlite3VdbeJumpHere(v, emptyDestTest);
|
||||
sqlite3VdbeAddOp(v, OP_Close, iDest, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
|
||||
return 0;
|
||||
}else{
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user