/ Check-in [bd7aeeb6]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:When an arithmetic operation with two integer operands must give a floating-point answer due to overflow, make sure the answer is not rounded back to integer by affinity.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: bd7aeeb691fee69dd6a562138a7aba8e8e192272
User & Date: drh 2012-12-10 22:19:14
Context
2012-12-11
19:10
Fix a typo in a comment that is used to generate documentation. No changes to code. check-in: e38adb60 user: drh tags: trunk
2012-12-10
22:19
When an arithmetic operation with two integer operands must give a floating-point answer due to overflow, make sure the answer is not rounded back to integer by affinity. check-in: bd7aeeb6 user: drh tags: trunk
10:22
Modify releasetest.tcl so that it runs the "checksymbols" test on a build without SQLITE_DEBUG defined. If SQLITE_DEBUG is defined, the sqlite3WhereTrace variable causes the test to fail. check-in: 75e545a9 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

  1266   1266   ** If either operand is NULL, the result is NULL.
  1267   1267   */
  1268   1268   case OP_Add:                   /* same as TK_PLUS, in1, in2, out3 */
  1269   1269   case OP_Subtract:              /* same as TK_MINUS, in1, in2, out3 */
  1270   1270   case OP_Multiply:              /* same as TK_STAR, in1, in2, out3 */
  1271   1271   case OP_Divide:                /* same as TK_SLASH, in1, in2, out3 */
  1272   1272   case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
         1273  +  char bIntint;   /* Started out as two integer operands */
  1273   1274     int flags;      /* Combined MEM_* flags from both inputs */
  1274   1275     i64 iA;         /* Integer value of left operand */
  1275   1276     i64 iB;         /* Integer value of right operand */
  1276   1277     double rA;      /* Real value of left operand */
  1277   1278     double rB;      /* Real value of right operand */
  1278   1279   
  1279   1280     pIn1 = &aMem[pOp->p1];
................................................................................
  1282   1283     applyNumericAffinity(pIn2);
  1283   1284     pOut = &aMem[pOp->p3];
  1284   1285     flags = pIn1->flags | pIn2->flags;
  1285   1286     if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
  1286   1287     if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
  1287   1288       iA = pIn1->u.i;
  1288   1289       iB = pIn2->u.i;
         1290  +    bIntint = 1;
  1289   1291       switch( pOp->opcode ){
  1290   1292         case OP_Add:       if( sqlite3AddInt64(&iB,iA) ) goto fp_math;  break;
  1291   1293         case OP_Subtract:  if( sqlite3SubInt64(&iB,iA) ) goto fp_math;  break;
  1292   1294         case OP_Multiply:  if( sqlite3MulInt64(&iB,iA) ) goto fp_math;  break;
  1293   1295         case OP_Divide: {
  1294   1296           if( iA==0 ) goto arithmetic_result_is_null;
  1295   1297           if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math;
................................................................................
  1302   1304           iB %= iA;
  1303   1305           break;
  1304   1306         }
  1305   1307       }
  1306   1308       pOut->u.i = iB;
  1307   1309       MemSetTypeFlag(pOut, MEM_Int);
  1308   1310     }else{
         1311  +    bIntint = 0;
  1309   1312   fp_math:
  1310   1313       rA = sqlite3VdbeRealValue(pIn1);
  1311   1314       rB = sqlite3VdbeRealValue(pIn2);
  1312   1315       switch( pOp->opcode ){
  1313   1316         case OP_Add:         rB += rA;       break;
  1314   1317         case OP_Subtract:    rB -= rA;       break;
  1315   1318         case OP_Multiply:    rB *= rA;       break;
................................................................................
  1333   1336       MemSetTypeFlag(pOut, MEM_Int);
  1334   1337   #else
  1335   1338       if( sqlite3IsNaN(rB) ){
  1336   1339         goto arithmetic_result_is_null;
  1337   1340       }
  1338   1341       pOut->r = rB;
  1339   1342       MemSetTypeFlag(pOut, MEM_Real);
  1340         -    if( (flags & MEM_Real)==0 ){
         1343  +    if( (flags & MEM_Real)==0 && !bIntint ){
  1341   1344         sqlite3VdbeIntegerAffinity(pOut);
  1342   1345       }
  1343   1346   #endif
  1344   1347     }
  1345   1348     break;
  1346   1349   
  1347   1350   arithmetic_result_is_null: