aboutsummaryrefslogtreecommitdiff
path: root/src/vdbe.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vdbe.c')
-rw-r--r--src/vdbe.c60
1 files changed, 47 insertions, 13 deletions
diff --git a/src/vdbe.c b/src/vdbe.c
index 5757cdc8a..050ab337b 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.559 2006/06/14 13:03:24 danielk1977 Exp $
+** $Id: vdbe.c,v 1.560 2006/06/14 19:00:22 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -4539,7 +4539,7 @@ case OP_TableLock: { /* no-push */
** P3 is the name of a virtual table in database P1. Call the xCreate method
** for that table.
*/
-case OP_VCreate: {
+case OP_VCreate: { /* no-push */
rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p3, &p->zErrMsg);
break;
}
@@ -4551,7 +4551,7 @@ case OP_VCreate: {
** P3 is the name of a virtual table in database P1. Call the xDestroy method
** of that table.
*/
-case OP_VDestroy: {
+case OP_VDestroy: { /* no-push */
rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p3);
break;
}
@@ -4564,7 +4564,7 @@ case OP_VDestroy: {
** P1 is a cursor number. This opcode opens a cursor to the virtual
** table and stores that cursor in P1.
*/
-case OP_VOpen: {
+case OP_VOpen: { /* no-push */
Cursor *pCur = 0;
sqlite3_vtab_cursor *pVtabCursor = 0;
@@ -4610,7 +4610,7 @@ case OP_VOpen: {
** A jump is made to P2 if the result set after filtering would be
** empty.
*/
-case OP_VFilter: {
+case OP_VFilter: { /* no-push */
int nArg;
const sqlite3_module *pModule;
@@ -4725,7 +4725,7 @@ case OP_VColumn: {
** jump to instruction P2. Or, if the virtual table has reached
** the end of its result set, then fall through to the next instruction.
*/
-case OP_VNext: {
+case OP_VNext: { /* no-push */
const sqlite3_module *pModule;
int res = 0;
@@ -4756,6 +4756,22 @@ case OP_VNext: {
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/* Opcode: VNoChange * * *
+**
+** Push an entry onto the stack which says to the VUpdate command
+** that the corresponding column of the row should not be modified.
+*/
+case OP_VNoChange: {
+ pTos++;
+ pTos->flags = 0;
+ pTos->n = 0;
+ break;
+}
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
+
+
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VUpdate * P2 P3
**
@@ -4764,23 +4780,41 @@ case OP_VNext: {
** are taken from the stack to pass to the xUpdate invocation. The
** value on the top of the stack corresponds to the p2th element
** of the argv array passed to xUpdate.
-*/
-case OP_VUpdate: {
+**
+** The xUpdate method will do a DELETE or an INSERT or both.
+** The argv[0] element (which corresponds to the P2-th element down
+** on the stack) is the rowid of a row to delete. If argv[0] is
+** NULL then no deletion occurs. The argv[1] element is the rowid
+** of the new row. This can be NULL to have the virtual table
+** select the new rowid for itself. The higher elements in the
+** stack are the values of columns in the new row. if any argv[i]
+** where i>=2 is a NULL pointer (that is to say if argv[i]==NULL
+** which is different from if sqlite3_value_type(argv[i])==SQLITE_NULL)
+** that means to preserve a copy of that element. In other words,
+** copy the corresponding value from the argv[0] row into the new row.
+**
+** If P2==1 then no insert is performed. argv[0] is the rowid of
+** a row to delete.
+*/
+case OP_VUpdate: { /* no-push */
sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p3);
sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
+ int nArg = pOp->p2;
+ assert( pOp->p3type==P3_VTAB );
if( pModule->xUpdate==0 ){
- sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xUpdate", 0);
+ sqlite3SetString(&p->zErrMsg, "read-only table", 0);
rc = SQLITE_ERROR;
}else{
int i;
Mem **apArg = p->apArg;
- int nArg = pOp->p1;
- for(i = 0; i<nArg; i++){
- apArg[i] = &pTos[i+1-nArg];
- storeTypeInfo(apArg[i], 0);
+ Mem *pX = &pTos[1-nArg];
+ for(i = 0; i<nArg; i++, pX++){
+ apArg[i] = pX->flags ? storeTypeInfo(pX,0), pX : 0;
}
rc = pModule->xUpdate(pVtab, nArg, apArg);
}
+ popStack(&pTos, nArg);
+ break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */