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:
+2
-2
@@ -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 ){
|
||||
|
||||
+2
-7
@@ -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;
|
||||
|
||||
+2
-2
@@ -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*);
|
||||
|
||||
+14
-4
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user