From: dan Date: Fri, 5 Mar 2010 16:32:12 +0000 (+0000) Subject: Modify the vdbe so that the comparison operator opcodes do not modify the data type... X-Git-Tag: version-3.7.2~556 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b7dca7d7335b02122a3fd1846723c07a3a5af32f;p=thirdparty%2Fsqlite.git Modify the vdbe so that the comparison operator opcodes do not modify the data type of operands. Fix for [aa92c76cd4]. FossilOrigin-Name: 8858042fa1449516a2c7dbb991dca3eb6c5794cb --- diff --git a/manifest b/manifest index 9c14d92483..0d4e7787ab 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjustments\sto\s#ifdefs\sso\sthat\sthe\s#include\sof\s\sis\snot\sincluded\ntwice,\sbecause\sthat\sconfuses\sthe\samalgamation\sbuilder. -D 2010-03-05T13:53:23 +C Modify\sthe\svdbe\sso\sthat\sthe\scomparison\soperator\sopcodes\sdo\snot\smodify\sthe\sdata\stype\sof\soperands.\sFix\sfor\s[aa92c76cd4]. +D 2010-03-05T16:32:12 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -118,7 +118,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ceb247eb31620bba66a94c3f697db489a1652353 F src/date.c 485a4409a384310e6d93fd1104a9d0a8658becd9 F src/delete.c 610dc008e88a9599f905f5cbe9577ac9c36e0581 -F src/expr.c d0a345e1d8995e142bc5d9f39a97b9981d7d8f23 +F src/expr.c 6baed2a0448d494233d9c0a610eea018ab386a32 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e2116672a6bd610dc888e27df292ebc7999c9bb0 F src/func.c 5dca069d98eca0ff70c9a8fb8ab9e1d6467187b5 @@ -131,7 +131,7 @@ F src/journal.c b0ea6b70b532961118ab70301c00a33089f9315c F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e F src/loadext.c 1c7a61ce1281041f437333f366a96aa0d29bb581 -F src/main.c 5e4a918c068b9d6c87fb4721b0b5c21cd52f0f4e +F src/main.c 7d89bb6dcc6993a8d32f4f22dae3e57c50a41399 F src/malloc.c 5fa175797f982b178eaf38afba9c588a866be729 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 89d4ea8d5cdd55635cbaa48ad53132af6294cbb2 @@ -159,7 +159,7 @@ F src/pcache.c 4956b41d6ba913f7a8a56fbf32be78caed0e45c2 F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 F src/pcache1.c 2bb2261190b42a348038f5b1c285c8cef415fcc8 F src/pragma.c 56d95f76154a5f873c32eae485bb625f3c70be46 -F src/prepare.c c80630169d82945070a50ebf298611fd9f1485f1 +F src/prepare.c 18292e5f365655cd5c5693e09508e90668f7d547 F src/printf.c 5f5b65a83e63f2096a541a340722a509fa0240a7 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c a1648d98e869937b29f4f697461fe4d60f220a7b @@ -168,7 +168,7 @@ F src/select.c 4113ef360430ed4e7533690ef46d06c20204adce F src/shell.c c40427c7245535a04a9cb4a417b6cc05c022e6a4 F src/sqlite.h.in 08a2d9a278ff0dfd65055a7ec9c599f7ae1a3c18 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89 -F src/sqliteInt.h dd123c74d150078c5afc572a6bc76e0920cd9c9c +F src/sqliteInt.h 6873f7f4c24fcdceece8777f2a1cbec049df77a0 F src/sqliteLimit.h 3afab2291762b5d09ae20c18feb8e9fa935a60a6 F src/status.c d329385a2cba3ea49d9d68af0ad84b22d46b4f40 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -208,10 +208,10 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c 25ceb0f0a746ea1d0f9553787f3f0a56853cfaeb F src/trigger.c 340c9eca0fb24b1197468d96ba059f867c9834c7 F src/update.c c0dc6b75ad28b76b619042d934f337b02acee208 -F src/utf.c dad16adcc0c35ef2437dca125a4b07419d361052 +F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 F src/util.c c076b2e38134d71ed09fee62ee788ad2d4121b93 F src/vacuum.c b1d542c8919d4d11119f78069e1906a1ad07e0ee -F src/vdbe.c 4d8ff247c30d41eb96d7eb4f620baecaf887efb8 +F src/vdbe.c 8acca6dab2505e9650f6f014ada6ef30570cba99 F src/vdbe.h 471f6a3dcec4817ca33596fe7f6654d56c0e75f3 F src/vdbeInt.h ae1e6ba0dd3fb4a886898d2829d748be701b01f8 F src/vdbeapi.c 74c25680046a116b24b95393914d3669c23305dc @@ -557,7 +557,7 @@ F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 F test/select4.test 44aa6e7110592e18110b0b9cf5c024d37d23be17 F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 F test/select6.test 2b5e8500d8ec3dd4c8e0c99eb1431b3d11fcc24c -F test/select7.test 7906735805cfbee4dddc0bed4c14e68d7f5f9c5f +F test/select7.test dad6f00f0d49728a879d6eb6451d4752db0b0abe F test/select8.test 391de11bdd52339c30580dabbbbe97e3e9a3c79d F test/select9.test b4007b15396cb7ba2615cab31e1973b572e43210 F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532 @@ -792,7 +792,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 0cc981f1ccc2c99b87eb968590ad18b2d3ebf37b -R 97a48748b4b414fdba77f575c01c7ecd -U drh -Z ecb802955395b9fef6de3fc1f956d8d1 +P 27413fc8dd52b754b4be9344a66bb9e0d752d48e +R f2ab83c256285b8820ce8d6baa7f32be +U dan +Z 19b361fab49c5821c8736e06dd81041c diff --git a/manifest.uuid b/manifest.uuid index cafddba1e4..54fbd9da25 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -27413fc8dd52b754b4be9344a66bb9e0d752d48e \ No newline at end of file +8858042fa1449516a2c7dbb991dca3eb6c5794cb \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index dcadd9856a..034088fafc 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 879907fadb..c80250791a 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 c15cd13020..f1b1e00579 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 86e869663c..5720b9cf5c 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 4ea63eeddc..8312cf9337 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 c85531fa79..33dd2dac79 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; } diff --git a/test/select7.test b/test/select7.test index 3837c8822f..e8fc440006 100644 --- a/test/select7.test +++ b/test/select7.test @@ -156,4 +156,47 @@ ifcapable compound { } } +# This block of tests verifies that bug aa92c76cd4 is fixed. +# +do_test select7-7.1 { + execsql { + CREATE TABLE t3(a REAL); + INSERT INTO t3 VALUES(44.0); + INSERT INTO t3 VALUES(56.0); + } +} {} +do_test select7-7.2 { + execsql { + pragma vdbe_trace = 0; + SELECT (CASE WHEN a=0 THEN 0 ELSE (a + 25) / 50 END) AS categ, count(*) + FROM t3 GROUP BY categ + } +} {1.38 1 1.62 1} +do_test select7-7.3 { + execsql { + CREATE TABLE t4(a REAL); + INSERT INTO t4 VALUES( 2.0 ); + INSERT INTO t4 VALUES( 3.0 ); + } +} {} +do_test select7-7.4 { + execsql { + SELECT (CASE WHEN a=0 THEN 'zero' ELSE a/2 END) AS t FROM t4 GROUP BY t; + } +} {1.0 1.5} +do_test select7-7.5 { + execsql { SELECT a=0, typeof(a) FROM t4 } +} {0 real 0 real} +do_test select7-7.6 { + execsql { SELECT a=0, typeof(a) FROM t4 GROUP BY a } +} {0 real 0 real} + +do_test select7-7.7 { + execsql { + CREATE TABLE t5(a TEXT, b INT); + INSERT INTO t5 VALUES(123, 456); + SELECT typeof(a), a FROM t5 GROUP BY a HAVING a