Continuing work toward detecting and fixing shallow-copy misuse.

FossilOrigin-Name: d0342f4bb9d25dd1dba3957778faa993fb9cc81c
diff --git a/src/expr.c b/src/expr.c
index f972bd5..5da3d35 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -2867,10 +2867,14 @@
   int inReg;
 
   assert( target>0 && target<=pParse->nMem );
-  inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
-  assert( pParse->pVdbe || pParse->db->mallocFailed );
-  if( inReg!=target && pParse->pVdbe ){
-    sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
+  if( pExpr && pExpr->op==TK_REGISTER ){
+    sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target);
+  }else{
+    inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
+    assert( pParse->pVdbe || pParse->db->mallocFailed );
+    if( inReg!=target && pParse->pVdbe ){
+      sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
+    }
   }
   return target;
 }
diff --git a/src/fkey.c b/src/fkey.c
index f0ad40d..a385b81 100644
--- a/src/fkey.c
+++ b/src/fkey.c
@@ -380,7 +380,7 @@
       sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
       sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF);
       for(i=0; i<nCol; i++){
-        sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[i]+1+regData, regTemp+i);
+        sqlite3VdbeAddOp2(v, OP_Copy, aiCol[i]+1+regData, regTemp+i);
       }
   
       /* If the parent table is the same as the child table, and we are about
diff --git a/src/vdbe.c b/src/vdbe.c
index 81a6952..ce01fe3 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -1142,7 +1142,7 @@
   pMem = p->pResultSet = &aMem[pOp->p1];
   for(i=0; i<pOp->p2; i++){
     assert( memIsValid(&pMem[i]) );
-    memAboutToChange(p, &pMem[i]);
+    Deephemeralize(&pMem[i]);
     sqlite3VdbeMemNulTerminate(&pMem[i]);
     sqlite3VdbeMemStoreType(&pMem[i]);
     REGISTER_TRACE(pOp->p1+i, &pMem[i]);
@@ -1368,6 +1368,9 @@
   n = pOp->p5;
   apVal = p->apArg;
   assert( apVal || n==0 );
+  assert( pOp->p3>0 && pOp->p3<=p->nMem );
+  pOut = &aMem[pOp->p3];
+  memAboutToChange(p, pOut);
 
   assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem+1) );
   assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
@@ -1375,7 +1378,7 @@
   for(i=0; i<n; i++, pArg++){
     assert( memIsValid(pArg) );
     apVal[i] = pArg;
-    memAboutToChange(p, pArg);
+    Deephemeralize(pArg);
     sqlite3VdbeMemStoreType(pArg);
     REGISTER_TRACE(pOp->p2+i, pArg);
   }
@@ -1389,9 +1392,6 @@
     ctx.pFunc = ctx.pVdbeFunc->pFunc;
   }
 
-  assert( pOp->p3>0 && pOp->p3<=p->nMem );
-  pOut = &aMem[pOp->p3];
-  memAboutToChange(p, pOut);
   ctx.s.flags = MEM_Null;
   ctx.s.db = db;
   ctx.s.xDel = 0;
diff --git a/src/vdbemem.c b/src/vdbemem.c
index f556edf..0b7c70d 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -132,6 +132,9 @@
     pMem->z[pMem->n] = 0;
     pMem->z[pMem->n+1] = 0;
     pMem->flags |= MEM_Term;
+#ifdef SQLITE_DEBUG
+    pMem->pScopyFrom = 0;
+#endif
   }
 
   return SQLITE_OK;