-C Avoid\sattempting\sto\smmap\smemory\sfrom\san\soffset\sthat\sis\snot\sa\smultiple\sof\sthe\ssystem\spage\ssize\son\ssystems\swith\spage\ssizes\slarger\sthan\s32KB.
-D 2014-03-24T11:23:17.736
+C Fix\sarithmetic\soperators\sso\sthat\sthey\sdo\snot\schange\sthe\saffinity\sof\stheir\ninput\soperands.\s\sTicket\s[a8a0d2996a].
+D 2014-03-24T15:00:15.271
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/utf.c 6dc9ec9f1b3db43ae8ba0365377f11df1ee4c01c
F src/util.c c46c90459ef9bdc0c6c73803cf4c55425b4771cf
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
-F src/vdbe.c 5c0feeb6c9e6a0e0cc2a9715aa6045830643809d
+F src/vdbe.c 74c7386e83eee56f921a17bb4a0396c9551f5bc7
F src/vdbe.h fb2c48c198300a7c632f09fc940011d2ad2fc2ae
F src/vdbeInt.h 2b9a6849166d0014c843ae3fd83a062be4efa325
F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
F test/tkt-9f2eb3abac.test 85bc63e749f050e6a61c8f9207f1eee65c9d3395
F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4
+F test/tkt-a8a0d2996a.test eb597379dbcefa24765763d7f682c00cb5924fa9
F test/tkt-b1d3a2e531.test 8f7576e41ca179289ee1a8fee28386fd8e4b0550
F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0
F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 641408a1395bfc911ca619ef9e5f073b913d856b e3d2be3ba47cdaafd26347620ae3bc2813203f16
-R aadeef09c98319ee1e1acbdf39605080
-U dan
-Z a7c50b19ab534dd04ee960894cca4791
+P db7d62c8d58eb1e8654a762c9b199ae4e2759038
+R c2ec5fb627231252d937ea015ddf100a
+U drh
+Z 7360db1b973f463e9c0480db05633068
-db7d62c8d58eb1e8654a762c9b199ae4e2759038
\ No newline at end of file
+221f8f944703108e47d789fa8ce6c00fe2abcbb6
\ No newline at end of file
applyAffinity((Mem *)pVal, affinity, enc);
}
+/*
+** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or
+** none.
+**
+** Unlike applyNumericAffinity(), this routine does not modify pMem->flags.
+** But it does set pMem->r and pMem->u.i appropriately.
+*/
+static u16 numericType(Mem *pMem){
+ if( pMem->flags & (MEM_Int|MEM_Real) ){
+ return pMem->flags & (MEM_Int|MEM_Real);
+ }
+ if( pMem->flags & (MEM_Str|MEM_Blob) ){
+ if( sqlite3AtoF(pMem->z, &pMem->r, pMem->n, pMem->enc)==0 ){
+ return 0;
+ }
+ if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){
+ return MEM_Int;
+ }
+ return MEM_Real;
+ }
+ return 0;
+}
+
#ifdef SQLITE_DEBUG
/*
** Write a nice string representation of the contents of cell pMem
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
char bIntint; /* Started out as two integer operands */
- int flags; /* Combined MEM_* flags from both inputs */
+ u16 flags; /* Combined MEM_* flags from both inputs */
+ u16 type1; /* Numeric type of left operand */
+ u16 type2; /* Numeric type of right operand */
i64 iA; /* Integer value of left operand */
i64 iB; /* Integer value of right operand */
double rA; /* Real value of left operand */
double rB; /* Real value of right operand */
pIn1 = &aMem[pOp->p1];
- applyNumericAffinity(pIn1);
+ type1 = numericType(pIn1);
pIn2 = &aMem[pOp->p2];
- applyNumericAffinity(pIn2);
+ type2 = numericType(pIn2);
pOut = &aMem[pOp->p3];
flags = pIn1->flags | pIn2->flags;
if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
- if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
+ if( (type1 & type2 & MEM_Int)!=0 ){
iA = pIn1->u.i;
iB = pIn2->u.i;
bIntint = 1;
}
pOut->r = rB;
MemSetTypeFlag(pOut, MEM_Real);
- if( (flags & MEM_Real)==0 && !bIntint ){
+ if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
sqlite3VdbeIntegerAffinity(pOut);
}
#endif
--- /dev/null
+# 2014-03-24
+#
+# 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.
+#
+#***********************************************************************
+#
+# Tests to verify that arithmetic operators do not change the type of
+# input operands. Ticket [a8a0d2996a]
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix tkt-a8a0d2996a
+
+do_execsql_test 1.0 {
+ CREATE TABLE t(x,y);
+ INSERT INTO t VALUES('1','1');
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x+0 AND y=='1';
+} {text text}
+do_execsql_test 1.1 {
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x-0 AND y=='1';
+} {text text}
+do_execsql_test 1.2 {
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x*1 AND y=='1';
+} {text text}
+do_execsql_test 1.3 {
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x/1 AND y=='1';
+} {text text}
+do_execsql_test 1.4 {
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x%4 AND y=='1';
+} {text text}
+
+do_execsql_test 2.0 {
+ UPDATE t SET x='1xyzzy';
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x+0 AND y=='1';
+} {text text}
+do_execsql_test 2.1 {
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x-0 AND y=='1';
+} {text text}
+do_execsql_test 2.2 {
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x*1 AND y=='1';
+} {text text}
+do_execsql_test 2.3 {
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x/1 AND y=='1';
+} {text text}
+do_execsql_test 2.4 {
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x%4 AND y=='1';
+} {text text}
+
+
+do_execsql_test 3.0 {
+ UPDATE t SET x='1.0';
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x+0 AND y=='1';
+} {text text}
+do_execsql_test 3.1 {
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x-0 AND y=='1';
+} {text text}
+do_execsql_test 3.2 {
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x*1 AND y=='1';
+} {text text}
+do_execsql_test 3.3 {
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x/1 AND y=='1';
+} {text text}
+do_execsql_test 3.4 {
+ SELECT typeof(x), typeof(y) FROM t WHERE 1=x%4 AND y=='1';
+} {text text}
+
+do_execsql_test 4.0 {
+ SELECT 1+1.;
+} {2.0}
+do_execsql_test 4.1 {
+ SELECT '1.23e64'/'1.0000e+62';
+} {123.0}
+do_execsql_test 4.2 {
+ SELECT '100x'+'-2y';
+} {98}
+do_execsql_test 4.3 {
+ SELECT '100x'+'4.5y';
+} {104.5}
+do_execsql_test 4.4 {
+ SELECT '-9223372036854775807x'-'1x';
+} {-9.22337203685478e+18}
+do_execsql_test 4.5 {
+ SELECT '9223372036854775806x'+'1x';
+} {9.22337203685478e+18}
+do_execsql_test 4.6 {
+ SELECT '1234x'/'10y';
+} {123.4}