aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/expr.c21
-rw-r--r--src/vdbe.c24
2 files changed, 32 insertions, 13 deletions
diff --git a/src/expr.c b/src/expr.c
index f592fc75a..1ac37e0b7 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1602,6 +1602,7 @@ void sqlite3CodeSubselect(
sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
Expr *pE2 = pItem->pExpr;
+ int iValToIns;
/* If the expression is not constant then we will need to
** disable the test that was generated above that makes sure
@@ -1614,14 +1615,19 @@ void sqlite3CodeSubselect(
}
/* Evaluate the expression and insert it into the temp table */
- r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
- if( isRowid ){
- sqlite3VdbeAddOp2(v, OP_MustBeInt, r3, sqlite3VdbeCurrentAddr(v)+2);
- sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
+ if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
+ sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
}else{
- sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
- sqlite3ExprCacheAffinityChange(pParse, r3, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2);
+ r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
+ if( isRowid ){
+ sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
+ sqlite3VdbeCurrentAddr(v)+2);
+ sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
+ }else{
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
+ sqlite3ExprCacheAffinityChange(pParse, r3, 1);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2);
+ }
}
}
sqlite3ReleaseTempReg(pParse, r1);
@@ -2875,6 +2881,7 @@ static int isAppropriateForFactoring(Expr *p){
static int evalConstExpr(Walker *pWalker, Expr *pExpr){
Parse *pParse = pWalker->pParse;
switch( pExpr->op ){
+ case TK_IN:
case TK_REGISTER: {
return WRC_Prune;
}
diff --git a/src/vdbe.c b/src/vdbe.c
index 6847b9027..3e316fc68 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -3758,7 +3758,13 @@ case OP_NewRowid: { /* out2-prerelease */
** This instruction only works on tables. The equivalent instruction
** for indices is OP_IdxInsert.
*/
-case OP_Insert: {
+/* Opcode: InsertInt P1 P2 P3 P4 P5
+**
+** This works exactly like OP_Insert except that the key is the
+** integer value P3, not the value of the integer stored in register P3.
+*/
+case OP_Insert:
+case OP_InsertInt: {
Mem *pData; /* MEM cell holding data for the record to be inserted */
Mem *pKey; /* MEM cell holding key for the record */
i64 iKey; /* The integer ROWID or key for the record to be inserted */
@@ -3770,20 +3776,26 @@ case OP_Insert: {
int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
pData = &p->aMem[pOp->p2];
- pKey = &p->aMem[pOp->p3];
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->pCursor!=0 );
assert( pC->pseudoTableReg==0 );
- assert( pKey->flags & MEM_Int );
assert( pC->isTable );
REGISTER_TRACE(pOp->p2, pData);
- REGISTER_TRACE(pOp->p3, pKey);
- iKey = pKey->u.i;
+ if( pOp->opcode==OP_Insert ){
+ pKey = &p->aMem[pOp->p3];
+ assert( pKey->flags & MEM_Int );
+ REGISTER_TRACE(pOp->p3, pKey);
+ iKey = pKey->u.i;
+ }else{
+ assert( pOp->opcode==OP_InsertInt );
+ iKey = pOp->p3;
+ }
+
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = pKey->u.i;
+ if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = iKey;
if( pData->flags & MEM_Null ){
pData->z = 0;
pData->n = 0;