diff options
author | drh <drh@noemail.net> | 2018-01-12 23:18:38 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2018-01-12 23:18:38 +0000 |
commit | 41fb367a2c5aec8973fa004ba030f2aa55bbad5c (patch) | |
tree | 59f7c66ef7c66f94056931c9f7590703eb41ab78 /src | |
parent | ce2fbd1b029477fd8745ca6381cd0b264fd901c5 (diff) | |
download | sqlite-41fb367a2c5aec8973fa004ba030f2aa55bbad5c.tar.gz sqlite-41fb367a2c5aec8973fa004ba030f2aa55bbad5c.zip |
Improved comments. Slightly tighter implementation, but no big changes.
FossilOrigin-Name: a1b3f28569f2a8d82b2931527fdfe191b421f3e1ea18ee30e04211e1ad645993
Diffstat (limited to 'src')
-rw-r--r-- | src/sqlite.h.in | 9 | ||||
-rw-r--r-- | src/sqliteInt.h | 1 | ||||
-rw-r--r-- | src/update.c | 8 | ||||
-rw-r--r-- | src/vdbe.c | 14 |
4 files changed, 24 insertions, 8 deletions
diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 7579b9926..cd524a046 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4850,8 +4850,13 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), ** ^Within the [xUpdate] method of a [virtual table], the ** sqlite3_value_nochange(X) interface returns true if and only if ** the column corresponding to X is unchanged by the UPDATE operation -** and the [xColumn] method had previously queried [sqlite3_vtab_nochange()] -** for that column and returned a NULL as a result. +** that the xUpdate method call was invoked to implement and if +** and the prior [xColumn] method call that was invoked to extracted +** the value for that column returned without setting a result (probably +** because it queried [sqlite3_vtab_nochange()] and found that the column +** was unchanging). If sqlite3_value_nochange(X) is invoked anywhere other +** than within an [xUpdate] method call for an UPDATE statement, then +** the return value is arbitrary and meaningless. ** ** Please pay particular attention to the fact that the pointer returned ** from [sqlite3_value_blob()], [sqlite3_value_text()], or diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8e7913320..b7b402b8e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3117,6 +3117,7 @@ struct AuthContext { #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ #define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */ #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ +#define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */ /* * Each trigger present in the database schema is stored as an instance of diff --git a/src/update.c b/src/update.c index ee920d2a5..32c1a8371 100644 --- a/src/update.c +++ b/src/update.c @@ -828,7 +828,7 @@ static void updateVirtualTable( sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i); }else{ sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i); - sqlite3VdbeChangeP5(v, 1); + sqlite3VdbeChangeP5(v, 1); /* Enable sqlite3_vtab_nochange() */ } } if( HasRowid(pTab) ){ @@ -863,7 +863,11 @@ static void updateVirtualTable( /* Create a record from the argument register contents and insert it into ** the ephemeral table. */ sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec); - sqlite3VdbeChangeP5(v, 2); +#ifdef SQLITE_DEBUG + /* Signal an assert() within OP_MakeRecord that it is allowed to + ** accept no-change records with serial_type 10 */ + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); +#endif sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid); sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid); } diff --git a/src/vdbe.c b/src/vdbe.c index dc058b65f..d878ca8e3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2792,12 +2792,17 @@ case OP_MakeRecord: { pRec = pLast; do{ assert( memIsValid(pRec) ); - pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len); + serial_type = sqlite3VdbeSerialType(pRec, file_format, &len); if( pRec->flags & MEM_Zero ){ if( serial_type==0 ){ - assert( pOp->p5==2 || CORRUPT_DB ); - /* serial_type 10 used internally only */ - pRec->uTemp = 10; + /* Values with MEM_Null and MEM_Zero are created by xColumn virtual + ** table methods that never invoke sqlite3_result_xxxxx() while + ** computing an unchanging column value in an UPDATE statement. + ** Give such values a special internal-use-only serial-type of 10 + ** so that they can be passed through to xUpdate and have + ** a true sqlite3_value_nochange(). */ + assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB ); + serial_type = 10; }else if( nData ){ if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem; }else{ @@ -2809,6 +2814,7 @@ case OP_MakeRecord: { testcase( serial_type==127 ); testcase( serial_type==128 ); nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); + pRec->uTemp = serial_type; if( pRec==pData0 ) break; pRec--; }while(1); |