aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <dan@noemail.net>2010-03-05 16:32:12 +0000
committerdan <dan@noemail.net>2010-03-05 16:32:12 +0000
commitb7dca7d7335b02122a3fd1846723c07a3a5af32f (patch)
tree1b544e6fb8e1422be2e9441147557f0f60bb4ca6 /src
parentf8b4d8c682ecc60197c9c3f5e76f55a3beda9981 (diff)
downloadsqlite-b7dca7d7335b02122a3fd1846723c07a3a5af32f.tar.gz
sqlite-b7dca7d7335b02122a3fd1846723c07a3a5af32f.zip
Modify the vdbe so that the comparison operator opcodes do not modify the data type of operands. Fix for [aa92c76cd4].
FossilOrigin-Name: 8858042fa1449516a2c7dbb991dca3eb6c5794cb
Diffstat (limited to 'src')
-rw-r--r--src/expr.c4
-rw-r--r--src/main.c4
-rw-r--r--src/prepare.c2
-rw-r--r--src/sqliteInt.h2
-rw-r--r--src/utf.c8
-rw-r--r--src/vdbe.c31
6 files changed, 35 insertions, 16 deletions
diff --git a/src/expr.c b/src/expr.c
index dcadd9856..034088faf 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -248,10 +248,6 @@ static int codeCompare(
addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
(void*)p4, P4_COLLSEQ);
sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5);
- if( (p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_NONE ){
- sqlite3ExprCacheAffinityChange(pParse, in1, 1);
- sqlite3ExprCacheAffinityChange(pParse, in2, 1);
- }
return addr;
}
diff --git a/src/main.c b/src/main.c
index 879907fad..c80250791 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1050,7 +1050,7 @@ int sqlite3_create_function16(
char *zFunc8;
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
- zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1);
+ zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal);
sqlite3DbFree(db, zFunc8);
rc = sqlite3ApiExit(db, rc);
@@ -1873,7 +1873,7 @@ int sqlite3_create_collation16(
char *zName8;
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
- zName8 = sqlite3Utf16to8(db, zName, -1);
+ zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE);
if( zName8 ){
rc = createCollation(db, zName8, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0);
sqlite3DbFree(db, zName8);
diff --git a/src/prepare.c b/src/prepare.c
index c15cd1302..f1b1e0057 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -800,7 +800,7 @@ static int sqlite3Prepare16(
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
- zSql8 = sqlite3Utf16to8(db, zSql, nBytes);
+ zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE);
if( zSql8 ){
rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, ppStmt, &zTail8);
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 86e869663..5720b9cf5 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -2858,7 +2858,7 @@ void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
void(*)(void*));
void sqlite3ValueFree(sqlite3_value*);
sqlite3_value *sqlite3ValueNew(sqlite3 *);
-char *sqlite3Utf16to8(sqlite3 *, const void*, int);
+char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
#ifdef SQLITE_ENABLE_STAT2
char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *);
#endif
diff --git a/src/utf.c b/src/utf.c
index 4ea63eedd..8312cf933 100644
--- a/src/utf.c
+++ b/src/utf.c
@@ -437,11 +437,11 @@ int sqlite3Utf8To8(unsigned char *zIn){
**
** NULL is returned if there is an allocation error.
*/
-char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte){
+char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 enc){
Mem m;
memset(&m, 0, sizeof(m));
m.db = db;
- sqlite3VdbeMemSetStr(&m, z, nByte, SQLITE_UTF16NATIVE, SQLITE_STATIC);
+ sqlite3VdbeMemSetStr(&m, z, nByte, enc, SQLITE_STATIC);
sqlite3VdbeChangeEncoding(&m, SQLITE_UTF8);
if( db->mallocFailed ){
sqlite3VdbeMemRelease(&m);
@@ -449,7 +449,9 @@ char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte){
}
assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
- return (m.flags & MEM_Dyn)!=0 ? m.z : sqlite3DbStrDup(db, m.z);
+ assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed );
+ assert( m.z || db->mallocFailed );
+ return m.z;
}
/*
diff --git a/src/vdbe.c b/src/vdbe.c
index c85531fa7..33dd2dac7 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -239,17 +239,30 @@ static VdbeCursor *allocateCursor(
static void applyNumericAffinity(Mem *pRec){
if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){
int realnum;
+ u8 enc = pRec->enc;
sqlite3VdbeMemNulTerminate(pRec);
- if( (pRec->flags&MEM_Str)
- && sqlite3IsNumber(pRec->z, &realnum, pRec->enc) ){
+ if( (pRec->flags&MEM_Str) && sqlite3IsNumber(pRec->z, &realnum, enc) ){
i64 value;
- sqlite3VdbeChangeEncoding(pRec, SQLITE_UTF8);
- if( !realnum && sqlite3Atoi64(pRec->z, &value) ){
+ char *zUtf8 = pRec->z;
+#ifndef SQLITE_OMIT_UTF16
+ if( enc!=SQLITE_UTF8 ){
+ assert( pRec->db );
+ zUtf8 = sqlite3Utf16to8(pRec->db, pRec->z, pRec->n, enc);
+ if( !zUtf8 ) return;
+ }
+#endif
+ if( !realnum && sqlite3Atoi64(zUtf8, &value) ){
pRec->u.i = value;
MemSetTypeFlag(pRec, MEM_Int);
}else{
- sqlite3VdbeMemRealify(pRec);
+ sqlite3AtoF(zUtf8, &pRec->r);
+ MemSetTypeFlag(pRec, MEM_Real);
}
+#ifndef SQLITE_OMIT_UTF16
+ if( enc!=SQLITE_UTF8 ){
+ sqlite3DbFree(pRec->db, zUtf8);
+ }
+#endif
}
}
}
@@ -1731,9 +1744,13 @@ case OP_Gt: /* same as TK_GT, jump, in1, in3 */
case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
int res; /* Result of the comparison of pIn1 against pIn3 */
char affinity; /* Affinity to use for comparison */
+ u16 flags1; /* Copy of initial value of pIn1->flags */
+ u16 flags3; /* Copy of initial value of pIn3->flags */
pIn1 = &aMem[pOp->p1];
pIn3 = &aMem[pOp->p3];
+ flags1 = pIn1->flags;
+ flags3 = pIn3->flags;
if( (pIn1->flags | pIn3->flags)&MEM_Null ){
/* One or both operands are NULL */
if( pOp->p5 & SQLITE_NULLEQ ){
@@ -1788,6 +1805,10 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
}else if( res ){
pc = pOp->p2-1;
}
+
+ /* Undo any changes made by applyAffinity() to the input registers. */
+ pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (flags1&MEM_TypeMask);
+ pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (flags3&MEM_TypeMask);
break;
}