mirror of https://github.com/sqlite/sqlite
When extracting values from a record to use in an UPDATEd version of that record, apply OP_RealAffinity if required. Fix for #3992. (CVS 6945)
FossilOrigin-Name: 3616766a6f5c8179cc55444c29ecf29cc69f88ce
This commit is contained in:
parent
a53c704fec
commit
c7538b5f63
21
manifest
21
manifest
|
@ -1,5 +1,5 @@
|
|||
C The\snoReadlock\sproperty\son\sa\spager\sobject\simplies\sthe\sreadOnly\sproperty.\nUse\sthis\sfact\sto\ssimplify\sthe\slogic\sin\ssqlite3PagerSharedLock().\s(CVS\s6944)
|
||||
D 2009-07-25T22:13:35
|
||||
C When\sextracting\svalues\sfrom\sa\srecord\sto\suse\sin\san\sUPDATEd\sversion\sof\sthat\srecord,\sapply\sOP_RealAffinity\sif\srequired.\sFix\sfor\s#3992.\s(CVS\s6945)
|
||||
D 2009-07-27T10:05:05
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in df9359da7a726ccb67a45db905c5447d5c00c6ef
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
|
@ -113,8 +113,8 @@ F src/build.c a15de7c5d020a778b641fca0b2510126843f4b30
|
|||
F src/callback.c cb68b21b0d4ae7d11ae0e487933bce3323784dcf
|
||||
F src/complete.c 5ad5c6cd4548211867c204c41a126d73a9fbcea0
|
||||
F src/date.c ab5f7137656652a48434d64f96bdcdc823bb23b3
|
||||
F src/delete.c 6f0192ecf2ae97dbbf4cccfa32639b504da70d4a
|
||||
F src/expr.c f6f21604c1367354b28d03c983a83279071a2948
|
||||
F src/delete.c fb2dfdd9696dfc4ef232c806ccecf307f94ea277
|
||||
F src/expr.c d069ba1e060f296ea4f18fb85198fafefd00b22f
|
||||
F src/fault.c dc88c821842157460750d2d61a8a8b4197d047ff
|
||||
F src/func.c 9856373f5315f6b8690d7f07f7191aa9f279ca87
|
||||
F src/global.c 448419c44ce0701104c2121b0e06919b44514c0c
|
||||
|
@ -163,7 +163,7 @@ F src/select.c 71748b8e244112cf73df9446c4246c192276c30d
|
|||
F src/shell.c db2643650b9268df89a4bedca3f1c6d9e786f1bb
|
||||
F src/sqlite.h.in 5672d9a6e19f80c1c7f1276dbe10e7d51c8fd97b
|
||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
||||
F src/sqliteInt.h 11d239cc658823c719a3077ea2c7691795002c34
|
||||
F src/sqliteInt.h 1199395d32e77658835bf6e976208d59f792f7ed
|
||||
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
||||
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
||||
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
|
||||
|
@ -200,7 +200,7 @@ F src/test_thread.c b8a1ab7ca1a632f18e8a361880d5d65eeea08eac
|
|||
F src/test_wsd.c 3ae5101de6cbfda2720152ab659ea84079719241
|
||||
F src/tokenize.c af8a56e6a50c5042fc305bfa796275e9bf26ff2b
|
||||
F src/trigger.c c07c5157c58fcdb704f65d5f5e4775276e45bb8b
|
||||
F src/update.c 7570d90842f0d9338906eeea443193358869ca97
|
||||
F src/update.c 245a652c0c1b1affd7ccf2a1970a465977e7bfa2
|
||||
F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
|
||||
F src/util.c 861d5b5c58be4921f0a254489ea94cb15f550ef8
|
||||
F src/vacuum.c 3fe0eebea6d2311c1c2ab2962887d11f7a4dcfb0
|
||||
|
@ -657,6 +657,7 @@ F test/tkt3918.test e6cdf6bfcfe9ba939d86a4238a9dc55d6eec5d42
|
|||
F test/tkt3922.test 022ace32c049e3964f68492c12eb803e8e4856d8
|
||||
F test/tkt3929.test 6a4c3baefb4e75127356b7d675b5df42c35c00d1
|
||||
F test/tkt3935.test e15261fedb9e30a4305a311da614a5d8e693c767
|
||||
F test/tkt3992.test c193b9643b1c25d020c503a986d5e4089e65c530
|
||||
F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
|
||||
F test/trace.test 19ffbc09885c3321d56358a5738feae8587fb377
|
||||
F test/trans.test d887cb07630dc39879a322d958ad8b006137485c
|
||||
|
@ -738,7 +739,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
|
||||
P f0024b3189245d608a0cb57fa7e472c6daa1406f
|
||||
R 25fcba4dba5a24b6461a64df15761046
|
||||
U drh
|
||||
Z 68027e399a7581e7ca33dd0037ba76d1
|
||||
P 886e665f6cf780464b280c286b03c9fb5c1a6b2a
|
||||
R 899fdca0f993aff7c16e3dca0f2bd4bf
|
||||
U danielk1977
|
||||
Z 8a5d8493499fa3d337872f4bdb3cfbf7
|
||||
|
|
|
@ -1 +1 @@
|
|||
886e665f6cf780464b280c286b03c9fb5c1a6b2a
|
||||
3616766a6f5c8179cc55444c29ecf29cc69f88ce
|
|
@ -12,7 +12,7 @@
|
|||
** This file contains C code routines that are called by the parser
|
||||
** in order to generate code for DELETE FROM statements.
|
||||
**
|
||||
** $Id: delete.c,v 1.205 2009/07/24 17:58:53 danielk1977 Exp $
|
||||
** $Id: delete.c,v 1.206 2009/07/27 10:05:05 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
|
@ -617,7 +617,7 @@ int sqlite3GenerateIndexKey(
|
|||
sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
|
||||
}else{
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
|
||||
sqlite3ColumnDefault(v, pTab, idx);
|
||||
sqlite3ColumnDefault(v, pTab, idx, -1);
|
||||
}
|
||||
}
|
||||
if( doMakeRec ){
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
** This file contains routines used for analyzing expressions and
|
||||
** for generating VDBE code that evaluates expressions in SQLite.
|
||||
**
|
||||
** $Id: expr.c,v 1.447 2009/07/16 12:41:06 drh Exp $
|
||||
** $Id: expr.c,v 1.448 2009/07/27 10:05:05 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
|
@ -1924,12 +1924,7 @@ int sqlite3ExprCodeGetColumn(
|
|||
}else if( ALWAYS(pTab!=0) ){
|
||||
int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
|
||||
sqlite3VdbeAddOp3(v, op, iTable, iColumn, iReg);
|
||||
sqlite3ColumnDefault(v, pTab, iColumn);
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){
|
||||
sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
|
||||
}
|
||||
#endif
|
||||
sqlite3ColumnDefault(v, pTab, iColumn, iReg);
|
||||
}
|
||||
sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg);
|
||||
return iReg;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.894 2009/07/24 17:58:53 danielk1977 Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.895 2009/07/27 10:05:05 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
|
@ -2801,7 +2801,7 @@ void sqlite3SelectPrep(Parse*, Select*, NameContext*);
|
|||
int sqlite3ResolveExprNames(NameContext*, Expr*);
|
||||
void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
|
||||
int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
|
||||
void sqlite3ColumnDefault(Vdbe *, Table *, int);
|
||||
void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
|
||||
void sqlite3AlterFinishAddColumn(Parse *, Token *);
|
||||
void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
|
||||
CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char*);
|
||||
|
|
18
src/update.c
18
src/update.c
|
@ -12,7 +12,7 @@
|
|||
** This file contains C code routines that are called by the parser
|
||||
** to handle UPDATE statements.
|
||||
**
|
||||
** $Id: update.c,v 1.205 2009/07/24 17:58:53 danielk1977 Exp $
|
||||
** $Id: update.c,v 1.206 2009/07/27 10:05:06 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
|
@ -53,8 +53,13 @@ static void updateVirtualTable(
|
|||
** the column is a literal number, string or null. The sqlite3ValueFromExpr()
|
||||
** function is capable of transforming these types of expressions into
|
||||
** sqlite3_value objects.
|
||||
**
|
||||
** If parameter iReg is not negative, code an OP_RealAffinity instruction
|
||||
** on register iReg. This is used when an equivalent integer value is
|
||||
** stored in place of an 8-byte floating point value in order to save
|
||||
** space.
|
||||
*/
|
||||
void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){
|
||||
void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
|
||||
assert( pTab!=0 );
|
||||
if( !pTab->pSelect ){
|
||||
sqlite3_value *pValue;
|
||||
|
@ -67,6 +72,11 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){
|
|||
if( pValue ){
|
||||
sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_FLOATING_POINT
|
||||
if( iReg>=0 && pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
|
||||
sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,7 +461,7 @@ void sqlite3Update(
|
|||
if( (i<32 && (new_col_mask&((u32)1<<i))!=0) || new_col_mask==0xffffffff ){
|
||||
if( j<0 ){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regCols+i);
|
||||
sqlite3ColumnDefault(v, pTab, i);
|
||||
sqlite3ColumnDefault(v, pTab, i, -1);
|
||||
}else{
|
||||
sqlite3ExprCodeAndCache(pParse, pChanges->a[j].pExpr, regCols+i);
|
||||
}
|
||||
|
@ -502,7 +512,7 @@ void sqlite3Update(
|
|||
j = aXRef[i];
|
||||
if( j<0 ){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regData+i);
|
||||
sqlite3ColumnDefault(v, pTab, i);
|
||||
sqlite3ColumnDefault(v, pTab, i, regData+i);
|
||||
}else{
|
||||
sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regData+i);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
# 2001 September 15
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
# $Id: tkt3992.test,v 1.1 2009/07/27 10:05:06 danielk1977 Exp $
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
do_test tkt3992-1.1 {
|
||||
execsql {
|
||||
CREATE TABLE parameters1(
|
||||
mountcnt INT NOT NULL CHECK (typeof(mountcnt) == 'integer'),
|
||||
version REAL NOT NULL
|
||||
);
|
||||
INSERT INTO parameters1(mountcnt, version) VALUES(1, 1.0);
|
||||
|
||||
CREATE TABLE parameters2(
|
||||
mountcnt INT NOT NULL CHECK (typeof(mountcnt) == 'integer'),
|
||||
version REAL CHECK (typeof(version) == 'real')
|
||||
);
|
||||
INSERT INTO parameters2(mountcnt, version) VALUES(1, 1.0);
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test tkt3992-1.2 {
|
||||
execsql {
|
||||
UPDATE parameters1 SET mountcnt = mountcnt + 1;
|
||||
SELECT * FROM parameters1;
|
||||
}
|
||||
} {2 1.0}
|
||||
|
||||
do_test tkt3992-1.3 {
|
||||
execsql {
|
||||
UPDATE parameters2 SET mountcnt = mountcnt + 1;
|
||||
SELECT * FROM parameters2;
|
||||
}
|
||||
} {2 1.0}
|
||||
|
||||
do_test tkt3992-2.1 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a, b);
|
||||
INSERT INTO t1 VALUES(1, 2);
|
||||
ALTER TABLE t1 ADD COLUMN c DEFAULT 3;
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {1 2 3}
|
||||
do_test tkt3992-2.2 {
|
||||
execsql {
|
||||
UPDATE t1 SET a = 'one';
|
||||
SELECT * FROM t1;
|
||||
}
|
||||
} {one 2 3}
|
||||
|
||||
db function tcl eval
|
||||
do_test tkt3992-2.3 {
|
||||
execsql {
|
||||
CREATE TABLE t2(a REAL, b REAL, c REAL);
|
||||
INSERT INTO t2 VALUES(1, 2, 3);
|
||||
CREATE TRIGGER tr2 BEFORE UPDATE ON t2 BEGIN
|
||||
SELECT tcl('set res', typeof(new.c));
|
||||
END;
|
||||
|
||||
UPDATE t2 SET a = 'I';
|
||||
}
|
||||
set res
|
||||
} {real}
|
||||
explain {
|
||||
UPDATE t2 SET a = 'I';
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
Loading…
Reference in New Issue