diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sqlite.h.in | 12 | ||||
-rw-r--r-- | src/update.c | 2 | ||||
-rw-r--r-- | src/vdbe.c | 15 | ||||
-rw-r--r-- | src/vdbeInt.h | 1 | ||||
-rw-r--r-- | src/vdbeapi.c | 19 |
5 files changed, 44 insertions, 5 deletions
diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f63b02931..ba673748e 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -8298,6 +8298,18 @@ int sqlite3_vtab_config(sqlite3*, int op, ...); int sqlite3_vtab_on_conflict(sqlite3 *); /* +** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE +** +** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] +** method of a [virtual table], then it returns true if and only if the +** column is being fetched as part of an UPDATE operation during which the +** column value will not change. Applications might use this to substitute +** a lighter-weight value to return that the corresponding [xUpdate] method +** understands as a "no-change" value. +*/ +int sqlite3_vtab_nochange(sqlite3_context*); + +/* ** CAPI3REF: Determine The Collation For a Virtual Table Constraint ** ** This function may only be called from within a call to the [xBestIndex] diff --git a/src/update.c b/src/update.c index 3e9d11bbf..3de36fe21 100644 --- a/src/update.c +++ b/src/update.c @@ -827,7 +827,7 @@ static void updateVirtualTable( if( aXRef[i]>=0 ){ sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i); }else{ - sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i); + sqlite3VdbeAddOp4Int(v, OP_VColumn, iCsr, i, regArg+2+i, 1); } } if( HasRowid(pTab) ){ diff --git a/src/vdbe.c b/src/vdbe.c index 4d643d726..b00174bb1 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6693,12 +6693,18 @@ case OP_VFilter: { /* jump */ #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE -/* Opcode: VColumn P1 P2 P3 * * +/* Opcode: VColumn P1 P2 P3 P4 * ** Synopsis: r[P3]=vcolumn(P2) ** -** Store the value of the P2-th column of -** the row of the virtual-table that the -** P1 cursor is pointing to into register P3. +** Store in register P3 the value of the P2-th column of +** the current row of the virtual-table of cursor P1. +** +** If the VColumn opcode is being used to fetch the value of +** an unchanging column during an UPDATE operation, then the P4 +** value is 1. Otherwise, P4 is 0. The P4 value is returned +** by sqlite3_vtab_nochange() routine can can be used +** by virtual table implementations to return special "no-change" +** marks which can be more efficient, depending on the virtual table. */ case OP_VColumn: { sqlite3_vtab *pVtab; @@ -6720,6 +6726,7 @@ case OP_VColumn: { assert( pModule->xColumn ); memset(&sContext, 0, sizeof(sContext)); sContext.pOut = pDest; + sContext.bVtabNoChng = pOp->p4.i!=0; MemSetTypeFlag(pDest, MEM_Null); rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2); sqlite3VtabImportErrmsg(p, pVtab); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index cb783653c..f646a4036 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -318,6 +318,7 @@ struct sqlite3_context { int isError; /* Error code returned by the function. */ u8 skipFlag; /* Skip accumulator loading if true */ u8 fErrorOrAux; /* isError!=0 or pVdbe->pAuxData modified */ + u8 bVtabNoChng; /* Fetching an unchanging column in a vtab UPDATE */ u8 argc; /* Number of arguments */ sqlite3_value *argv[1]; /* Argument set */ }; diff --git a/src/vdbeapi.c b/src/vdbeapi.c index b9df40b8f..19aa783bb 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -746,6 +746,25 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ } /* +** If this routine is invoked from within an xColumn method of a virtual +** table, then it returns true if and only if the the call is during an +** UPDATE operation and the value of the column will not be modified +** by the UPDATE. +** +** If this routine is called from any context other than within the +** xColumn method of a virtual table, then the return value is meaningless +** and arbitrary. +** +** Virtual table implements might use this routine to optimize their +** performance by substituting a NULL result, or some other light-weight +** value, as a signal to the xUpdate routine that the column is unchanged. +*/ +int sqlite3_vtab_nochange(sqlite3_context *p){ + assert( p ); + return p->bVtabNoChng; +} + +/* ** Return the current time for a statement. If the current time ** is requested more than once within the same run of a single prepared ** statement, the exact same time is returned for each invocation regardless |