Omit the SQLITE_AFF_INTEGER type affinity.  All numeric values are now
of type real, though an integer representation is still sometimes used
internally for efficiency. (CVS 2753)

FossilOrigin-Name: e0d6f61c7de2c03b8fd17ef37cf1a0add36ee618
diff --git a/src/analyze.c b/src/analyze.c
index 67d80d5..5974970 100644
--- a/src/analyze.c
+++ b/src/analyze.c
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code associated with the ANALYZE command.
 **
-** @(#) $Id: analyze.c,v 1.9 2005/09/20 17:42:23 drh Exp $
+** @(#) $Id: analyze.c,v 1.10 2005/11/01 15:48:24 drh Exp $
 */
 #ifndef SQLITE_OMIT_ANALYZE
 #include "sqliteInt.h"
@@ -188,6 +188,7 @@
       sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
       sqlite3VdbeAddOp(v, OP_MemLoad, iMem+i+1, 0);
       sqlite3VdbeAddOp(v, OP_Divide, 0, 0);
+      sqlite3VdbeAddOp(v, OP_ToInt, 0, 0);
       if( i==nCol-1 ){
         sqlite3VdbeAddOp(v, OP_Concat, nCol*2-1, 0);
       }else{
diff --git a/src/build.c b/src/build.c
index 9857a8e..69a652b 100644
--- a/src/build.c
+++ b/src/build.c
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.351 2005/09/20 17:42:23 drh Exp $
+** $Id: build.c,v 1.352 2005/11/01 15:48:24 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -882,7 +882,7 @@
 ** found, the corresponding affinity is returned. If zType contains
 ** more than one of the substrings, entries toward the top of 
 ** the table take priority. For example, if zType is 'BLOBINT', 
-** SQLITE_AFF_INTEGER is returned.
+** SQLITE_AFF_NUMERIC is returned.
 **
 ** Substring     | Affinity
 ** --------------------------------
@@ -894,8 +894,12 @@
 **
 ** If none of the substrings in the above table are found,
 ** SQLITE_AFF_NUMERIC is returned.
+**
+** The SQLITE_AFF_INTEGER type is only returned if useIntType is true.
+** If useIntType is false, then SQLITE_AFF_INTEGER is reported back
+** as SQLITE_AFF_NUMERIC
 */
-char sqlite3AffinityType(const Token *pType){
+char sqlite3AffinityType(const Token *pType, int useIntType){
   u32 h = 0;
   char aff = SQLITE_AFF_NUMERIC;
   const unsigned char *zIn = pType->z;
@@ -914,7 +918,7 @@
         && aff==SQLITE_AFF_NUMERIC ){
       aff = SQLITE_AFF_NONE;
     }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){    /* INT */
-      aff = SQLITE_AFF_INTEGER; 
+      aff = useIntType ? SQLITE_AFF_INTEGER : SQLITE_AFF_NUMERIC; 
       break;
     }
   }
@@ -942,7 +946,7 @@
   pCol = &p->aCol[i];
   sqliteFree(pCol->zType);
   pCol->zType = sqlite3NameFromToken(pType);
-  pCol->affinity = sqlite3AffinityType(pType);
+  pCol->affinity = sqlite3AffinityType(pType, 0);
 }
 
 /*
diff --git a/src/expr.c b/src/expr.c
index f1eae86..b915059 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -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.231 2005/10/06 16:53:15 drh Exp $
+** $Id: expr.c,v 1.232 2005/11/01 15:48:24 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -43,7 +43,7 @@
   }
 #ifndef SQLITE_OMIT_CAST
   if( op==TK_CAST ){
-    return sqlite3AffinityType(&pExpr->token);
+    return sqlite3AffinityType(&pExpr->token, 0);
   }
 #endif
   return pExpr->affinity;
@@ -75,12 +75,10 @@
 char sqlite3CompareAffinity(Expr *pExpr, char aff2){
   char aff1 = sqlite3ExprAffinity(pExpr);
   if( aff1 && aff2 ){
-    /* Both sides of the comparison are columns. If one has numeric or
-    ** integer affinity, use that. Otherwise use no affinity.
+    /* Both sides of the comparison are columns. If one has numeric
+    ** affinity, use that. Otherwise use no affinity.
     */
-    if( aff1==SQLITE_AFF_INTEGER || aff2==SQLITE_AFF_INTEGER ){
-      return SQLITE_AFF_INTEGER;
-    }else if( aff1==SQLITE_AFF_NUMERIC || aff2==SQLITE_AFF_NUMERIC ){
+    if( aff1==SQLITE_AFF_NUMERIC || aff2==SQLITE_AFF_NUMERIC ){
       return SQLITE_AFF_NUMERIC;
     }else{
       return SQLITE_AFF_NONE;
@@ -89,7 +87,6 @@
     /* Neither side of the comparison is a column.  Compare the
     ** results directly.
     */
-    /* return SQLITE_AFF_NUMERIC;  // Ticket #805 */
     return SQLITE_AFF_NONE;
   }else{
     /* One side is a column, the other is not. Use the columns affinity. */
@@ -129,11 +126,7 @@
 */
 int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
   char aff = comparisonAffinity(pExpr);
-  return 
-    (aff==SQLITE_AFF_NONE) ||
-    (aff==SQLITE_AFF_NUMERIC && idx_affinity==SQLITE_AFF_INTEGER) ||
-    (aff==SQLITE_AFF_INTEGER && idx_affinity==SQLITE_AFF_NUMERIC) ||
-    (aff==idx_affinity);
+  return (aff==SQLITE_AFF_NONE) || (aff==idx_affinity);
 }
 
 /*
@@ -944,7 +937,7 @@
     if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){
       cnt = 1;
       pExpr->iColumn = -1;
-      pExpr->affinity = SQLITE_AFF_INTEGER;
+      pExpr->affinity = SQLITE_AFF_NUMERIC;
     }
 
     /*
@@ -1524,7 +1517,7 @@
       /* Expressions of the form:   CAST(pLeft AS token) */
       int aff, op;
       sqlite3ExprCode(pParse, pExpr->pLeft);
-      aff = sqlite3AffinityType(&pExpr->token);
+      aff = sqlite3AffinityType(&pExpr->token, 1);
       switch( aff ){
         case SQLITE_AFF_INTEGER:   op = OP_ToInt;      break;
         case SQLITE_AFF_NUMERIC:   op = OP_ToNumeric;  break;
diff --git a/src/insert.c b/src/insert.c
index e19aa7d..dcc57d5 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements in SQLite.
 **
-** $Id: insert.c,v 1.143 2005/09/20 17:42:23 drh Exp $
+** $Id: insert.c,v 1.144 2005/11/01 15:48:24 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -24,7 +24,6 @@
 **  Character      Column affinity
 **  ------------------------------
 **  'n'            NUMERIC
-**  'i'            INTEGER
 **  't'            TEXT
 **  'o'            NONE
 */
@@ -62,7 +61,6 @@
 **  Character      Column affinity
 **  ------------------------------
 **  'n'            NUMERIC
-**  'i'            INTEGER
 **  't'            TEXT
 **  'o'            NONE
 */
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 7b4f360..51d1ce7 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.423 2005/10/13 02:09:50 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.424 2005/11/01 15:48:24 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -585,8 +585,8 @@
 /*
 ** Column affinity types.
 */
-#define SQLITE_AFF_INTEGER  'i'
 #define SQLITE_AFF_NUMERIC  'n'
+#define SQLITE_AFF_INTEGER  'i'  /* Used for CAST operators only */
 #define SQLITE_AFF_TEXT     't'
 #define SQLITE_AFF_NONE     'o'
 
@@ -1646,7 +1646,7 @@
 void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
 const char *sqlite3TestErrorName(int);
 CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char *, int);
-char sqlite3AffinityType(const Token*);
+char sqlite3AffinityType(const Token*, int);
 void sqlite3Analyze(Parse*, Token*, Token*);
 int sqlite3InvokeBusyHandler(BusyHandler*);
 int sqlite3FindDb(sqlite3*, Token*);
diff --git a/src/vdbe.c b/src/vdbe.c
index 09cac04..30f57be 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.494 2005/10/29 15:48:31 drh Exp $
+** $Id: vdbe.c,v 1.495 2005/11/01 15:48:24 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -194,8 +194,6 @@
 ** SQLITE_AFF_NUMERIC
 ** SQLITE_AFF_TEXT
 ** SQLITE_AFF_NONE
-** SQLITE_AFF_INTEGER
-**
 */
 static void applyAffinity(Mem *pRec, char affinity, u8 enc){
   if( affinity==SQLITE_AFF_NONE ){
@@ -224,16 +222,8 @@
           Integerify(pRec);
         }
       }
-    }
-
-    if( affinity==SQLITE_AFF_INTEGER ){
-      /* For INTEGER affinity, try to convert a real value to an int */
-      if( (pRec->flags&MEM_Real) && !(pRec->flags&MEM_Int) ){
-        pRec->i = pRec->r;
-        if( ((double)pRec->i)==pRec->r ){
-          pRec->flags |= MEM_Int;
-        }
-      }
+    }else if( pRec->flags & MEM_Real ){
+      sqlite3VdbeIntegerAffinity(pRec);
     }
   }
 }
@@ -645,6 +635,7 @@
   pTos->r = sqlite3VdbeRealValue(pTos);
   pTos->flags |= MEM_Real;
   sqlite3VdbeChangeEncoding(pTos, db->enc);
+  sqlite3VdbeIntegerAffinity(pTos);
   break;
 }
 
@@ -1030,6 +1021,7 @@
       case OP_Multiply:    b *= a;       break;
       case OP_Divide: {
         if( a==0 ) goto divide_by_zero;
+        if( b%a!=0 ) goto floating_point_divide;
         b /= a;
         break;
       }
@@ -1046,6 +1038,7 @@
     pTos->flags = MEM_Int;
   }else{
     double a, b;
+    floating_point_divide:
     a = sqlite3VdbeRealValue(pTos);
     b = sqlite3VdbeRealValue(pNos);
     switch( pOp->opcode ){
@@ -1070,6 +1063,7 @@
     Release(pTos);
     pTos->r = b;
     pTos->flags = MEM_Real;
+    sqlite3VdbeIntegerAffinity(pTos);
   }
   break;
 
@@ -1267,7 +1261,7 @@
 case OP_ForceInt: {            /* no-push */
   i64 v;
   assert( pTos>=p->aStack );
-  applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
+  applyAffinity(pTos, SQLITE_AFF_NUMERIC, db->enc);
   if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){
     Release(pTos);
     pTos--;
@@ -1301,7 +1295,7 @@
 */
 case OP_MustBeInt: {            /* no-push */
   assert( pTos>=p->aStack );
-  applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
+  applyAffinity(pTos, SQLITE_AFF_NUMERIC, db->enc);
   if( (pTos->flags & MEM_Int)==0 ){
     if( pOp->p2==0 ){
       rc = SQLITE_MISMATCH;
@@ -1317,7 +1311,6 @@
   break;
 }
 
-#ifndef SQLITE_OMIT_CAST
 /* Opcode: ToInt * * *
 **
 ** Force the value on the top of the stack to be an integer.  If
@@ -1332,11 +1325,12 @@
   if( pTos->flags & MEM_Null ) break;
   assert( MEM_Str==(MEM_Blob>>3) );
   pTos->flags |= (pTos->flags&MEM_Blob)>>3;
-  applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
+  applyAffinity(pTos, SQLITE_AFF_NUMERIC, db->enc);
   sqlite3VdbeMemIntegerify(pTos);
   break;
 }
 
+#ifndef SQLITE_OMIT_CAST
 /* Opcode: ToNumeric * * *
 **
 ** Force the value on the top of the stack to be numeric (either an
@@ -1422,7 +1416,7 @@
 ** 0x200 is set but is NULL when the 0x200 bit of P1 is clear.
 **
 ** The least significant byte of P1 (mask 0xff) must be an affinity character -
-** 'n', 't', 'i' or 'o' - or 0x00. An attempt is made to coerce both values
+** 'n', 't', or 'o' - or 0x00. An attempt is made to coerce both values
 ** according to the affinity before the comparison is made. If the byte is
 ** 0x00, then numeric affinity is used.
 **
@@ -1614,11 +1608,13 @@
 case OP_AbsValue: {
   assert( pTos>=p->aStack );
   if( pTos->flags & MEM_Real ){
+    neg_abs_real_case:
     Release(pTos);
     if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
       pTos->r = -pTos->r;
     }
     pTos->flags = MEM_Real;
+    sqlite3VdbeIntegerAffinity(pTos);
   }else if( pTos->flags & MEM_Int ){
     Release(pTos);
     if( pOp->opcode==OP_Negative || pTos->i<0 ){
@@ -1629,10 +1625,7 @@
     /* Do nothing */
   }else{
     Realify(pTos);
-    if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
-      pTos->r = -pTos->r;
-    }
-    pTos->flags = MEM_Real;
+    goto neg_abs_real_case;
   }
   break;
 }
@@ -2083,7 +2076,6 @@
 **
 ** The mapping from character to affinity is as follows:
 **    'n' = NUMERIC.
-**    'i' = INTEGER.
 **    't' = TEXT.
 **    'o' = NONE.
 **
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index 1746ee5..e38f809 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -360,6 +360,7 @@
 i64 sqlite3VdbeIntValue(Mem*);
 int sqlite3VdbeMemIntegerify(Mem*);
 double sqlite3VdbeRealValue(Mem*);
+void sqlite3VdbeIntegerAffinity(Mem*);
 int sqlite3VdbeMemRealify(Mem*);
 int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*);
 void sqlite3VdbeMemRelease(Mem *p);
diff --git a/src/vdbemem.c b/src/vdbemem.c
index 0b7e193..7f40af6 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -173,11 +173,11 @@
   ** 
   ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16.
   */
-  if( fg & MEM_Real ){
-    sqlite3_snprintf(NBFS, z, "%!.15g", pMem->r);
-  }else{
-    assert( fg & MEM_Int );
+  if( fg & MEM_Int ){
     sqlite3_snprintf(NBFS, z, "%lld", pMem->i);
+  }else{
+    assert( fg & MEM_Real );
+    sqlite3_snprintf(NBFS, z, "%!.15g", pMem->r);
   }
   pMem->n = strlen(z);
   pMem->z = z;
@@ -300,13 +300,27 @@
 }
 
 /*
-** Convert pMem so that it is of type MEM_Real.  Invalidate any
-** prior representations.
+** The MEM structure is already a MEM_Real.  Try to also make it a
+** MEM_Int if we can.
+*/
+void sqlite3VdbeIntegerAffinity(Mem *pMem){
+  assert( pMem->flags & MEM_Real );
+  pMem->i = pMem->r;
+  if( ((double)pMem->i)==pMem->r ){
+    pMem->flags |= MEM_Int;
+  }
+}
+
+
+/*
+** Convert pMem so that it is of type MEM_Real and also MEM_Int if
+** possible.  Invalidate any prior representations.
 */
 int sqlite3VdbeMemRealify(Mem *pMem){
   pMem->r = sqlite3VdbeRealValue(pMem);
   sqlite3VdbeMemRelease(pMem);
   pMem->flags = MEM_Real;
+  sqlite3VdbeIntegerAffinity(pMem);
   return SQLITE_OK;
 }