Index: src/func.c ================================================================== --- src/func.c +++ src/func.c @@ -14,15 +14,15 @@ ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.110 2005/09/08 20:37:43 drh Exp $ +** $Id: func.c,v 1.111 2005/10/13 02:09:50 drh Exp $ */ #include "sqliteInt.h" #include -#include +/* #include */ #include #include #include "vdbeInt.h" #include "os.h" Index: src/printf.c ================================================================== --- src/printf.c +++ src/printf.c @@ -118,14 +118,16 @@ { 'c', 0, 0, etCHARX, 0, 0 }, { 'o', 8, 0, etRADIX, 0, 2 }, { 'u', 10, 0, etRADIX, 0, 0 }, { 'x', 16, 0, etRADIX, 16, 1 }, { 'X', 16, 0, etRADIX, 0, 4 }, +#ifndef SQLITE_OMIT_FLOATING_POINT { 'f', 0, 1, etFLOAT, 0, 0 }, { 'e', 0, 1, etEXP, 30, 0 }, { 'E', 0, 1, etEXP, 14, 0 }, { 'G', 0, 1, etGENERIC, 14, 0 }, +#endif { 'i', 10, 1, etRADIX, 0, 0 }, { 'n', 0, 0, etSIZE, 0, 0 }, { '%', 0, 0, etPERCENT, 0, 0 }, { 'p', 16, 0, etPOINTER, 0, 1 }, { 'T', 0, 2, etTOKEN, 0, 0 }, @@ -132,14 +134,14 @@ { 'S', 0, 2, etSRCLIST, 0, 0 }, }; #define etNINFO (sizeof(fmtinfo)/sizeof(fmtinfo[0])) /* -** If NOFLOATINGPOINT is defined, then none of the floating point +** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point ** conversions will work. */ -#ifndef etNOFLOATINGPOINT +#ifndef SQLITE_OMIT_FLOATING_POINT /* ** "*val" is a double such that 0.1 <= *val < 10.0 ** Return the ascii code for the leading digit of *val, then ** multiply "*val" by 10.0 to renormalize. ** @@ -159,11 +161,11 @@ d = digit; digit += '0'; *val = (*val - d)*10.0; return digit; } -#endif +#endif /* SQLITE_OMIT_FLOATING_POINT */ /* ** On machines with a small stack size, you can redefine the ** SQLITE_PRINT_BUF_SIZE to be less than 350. But beware - for ** smaller values some %f conversions may go into an infinite loop. @@ -232,11 +234,11 @@ etByte xtype; /* Conversion paradigm */ char *zExtra; /* Extra memory used for etTCLESCAPE conversions */ static const char spaces[] = " "; #define etSPACESIZE (sizeof(spaces)-1) -#ifndef etNOFLOATINGPOINT +#ifndef SQLITE_OMIT_FLOATING_POINT int exp, e2; /* exponent of real numbers */ double rounder; /* Used for rounding floating point values */ etByte flag_dp; /* True if decimal point should be shown */ etByte flag_rtz; /* True if trailing zeros should be removed */ etByte flag_exp; /* True to force display of the exponent */ @@ -423,11 +425,11 @@ break; case etFLOAT: case etEXP: case etGENERIC: realvalue = va_arg(ap,double); -#ifndef etNOFLOATINGPOINT +#ifndef SQLITE_OMIT_FLOATING_POINT if( precision<0 ) precision = 6; /* Set default precision */ if( precision>etBUFSIZE/2-10 ) precision = etBUFSIZE/2-10; if( realvalue<0.0 ){ realvalue = -realvalue; prefix = '-'; Index: src/sqlite.h.in ================================================================== --- src/sqlite.h.in +++ src/sqlite.h.in @@ -10,11 +10,11 @@ ** ************************************************************************* ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.141 2005/09/08 10:58:52 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.142 2005/10/13 02:09:50 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include /* Needed for the definition of va_list */ @@ -84,10 +84,17 @@ #else typedef long long int sqlite_int64; typedef unsigned long long int sqlite_uint64; #endif +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite_int64 +#endif /* ** A function to close the database. ** ** Call this function with a pointer to a structure that was previously @@ -1267,9 +1274,17 @@ ** the first argument to the sqlite3_prepare() that was used to create ** the statement in the first place. */ sqlite3 *sqlite3_db_handle(sqlite3_stmt*); +/* +** Undo the hack that converts floating point types to integer for +** builds on processors without floating point support. +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# undef double +#endif + #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif #endif Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -9,11 +9,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.422 2005/10/06 16:53:15 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.423 2005/10/13 02:09:50 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* @@ -57,10 +57,22 @@ #include #include #include #include +/* +** If compiling for a processor that lacks floating point support, +** substitute integer for floating-point +*/ +#ifdef SQLITE_OMIT_FLOATING_POINT +# define double sqlite_int64 +# define LONGDOUBLE_TYPE sqlite_int64 +# define SQLITE_BIG_DBL (0x7fffffffffffffff) +# define SQLITE_OMIT_DATETIME_FUNCS 1 +# define SQLITE_OMIT_TRACE 1 +#endif + /* ** The maximum number of in-memory pages to use for the main database ** table and for temporary tables. Internally, the MAX_PAGES and ** TEMP_PAGES macros are used. To override the default values at ** compilation time, the SQLITE_DEFAULT_CACHE_SIZE and @@ -126,24 +138,10 @@ /* ** The maximum value of a ?nnn wildcard that the parser will accept. */ #define SQLITE_MAX_VARIABLE_NUMBER 999 -/* -** When building SQLite for embedded systems where memory is scarce, -** you can define one or more of the following macros to omit extra -** features of the library and thus keep the size of the library to -** a minimum. -*/ -/* #define SQLITE_OMIT_AUTHORIZATION 1 */ -/* #define SQLITE_OMIT_MEMORYDB 1 */ -/* #define SQLITE_OMIT_VACUUM 1 */ -/* #define SQLITE_OMIT_DATETIME_FUNCS 1 */ -/* #define SQLITE_OMIT_PROGRESS_CALLBACK 1 */ -/* #define SQLITE_OMIT_AUTOVACUUM */ -/* #define SQLITE_OMIT_ALTERTABLE */ - /* ** Provide a default value for TEMP_STORE in case it is not specified ** on the command-line */ #ifndef TEMP_STORE Index: src/util.c ================================================================== --- src/util.c +++ src/util.c @@ -12,11 +12,11 @@ ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.146 2005/09/17 18:34:11 drh Exp $ +** $Id: util.c,v 1.147 2005/10/13 02:09:50 drh Exp $ */ #include "sqliteInt.h" #include #include @@ -604,10 +604,11 @@ ** the library atof() might want to use "," as the decimal point instead ** of "." depending on how locale is set. But that would cause problems ** for SQL. So this routine always uses "." regardless of locale. */ int sqlite3AtoF(const char *z, double *pResult){ +#ifndef SQLITE_OMIT_FLOATING_POINT int sign = 1; const char *zBegin = z; LONGDOUBLE_TYPE v1 = 0.0; if( *z=='-' ){ sign = -1; @@ -654,10 +655,13 @@ v1 *= scale; } } *pResult = sign<0 ? -v1 : v1; return z - zBegin; +#else + return sqlite3atoi64(z, pResult); +#endif /* SQLITE_OMIT_FLOATING_POINT */ } /* ** Return TRUE if zNum is a 64-bit signed integer and write ** the value of the integer into *pNum. If zNum is not an integer Index: src/where.c ================================================================== --- src/where.c +++ src/where.c @@ -14,11 +14,11 @@ ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: where.c,v 1.179 2005/09/20 17:42:23 drh Exp $ +** $Id: where.c,v 1.180 2005/10/13 02:09:50 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". @@ -38,10 +38,20 @@ # define TRACE(X) if(sqlite3_where_trace) sqlite3DebugPrintf X #else # define TRACE(X) #endif +/* +** A large value which is the maximum cost of using an index. +** By default this is a large floating point value. When compiling +** SQLite for a processor that lacks floating point support, simply +** redefine this constant to a large integer. +*/ +#ifndef SQLITE_BIG_DBL +# define SQLITE_BIG_DBL (1.0e+99) +#endif + /* Forward reference */ typedef struct WhereClause WhereClause; /* @@ -852,14 +862,14 @@ ** the total cost of performing operatings with O(logN) or O(NlogN) ** complexity. Because N is just a guess, it is no great tragedy if ** logN is a little off. */ static double estLog(double N){ - double logN = 1.0; - double x = 10.0; + double logN = 1; + double x = 10; while( N>x ){ - logN += 1.0; + logN += 1; x *= 10; } return logN; } @@ -891,11 +901,11 @@ int *pFlags, /* Put flags describing this choice in *pFlags */ int *pnEq /* Put the number of == or IN constraints here */ ){ WhereTerm *pTerm; Index *bestIdx = 0; /* Index that gives the lowest cost */ - double lowestCost = 1.0e99; /* The cost of using bestIdx */ + double lowestCost; /* The cost of using bestIdx */ int bestFlags = 0; /* Flags associated with bestIdx */ int bestNEq = 0; /* Best value for nEq */ int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */ Index *pProbe; /* An index we are evaluating */ int rev; /* True to scan in reverse order */ @@ -902,10 +912,11 @@ int flags; /* Flags associated with pProbe */ int nEq; /* Number of == or IN constraints */ double cost; /* Cost of using pProbe */ TRACE(("bestIndex: tbl=%s notReady=%x\n", pSrc->pTab->zName, notReady)); + lowestCost = SQLITE_BIG_DBL; /* Check for a rowid=EXPR or rowid IN (...) constraints */ pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0); if( pTerm ){ @@ -926,34 +937,34 @@ lowestCost *= estLog(lowestCost); }else{ /* Rowid IN (SELECT): cost is NlogN where N is the number of rows ** in the result of the inner select. We have no way to estimate ** that value so make a wild guess. */ - lowestCost = 200.0; + lowestCost = 200; } TRACE(("... rowid IN cost: %.9g\n", lowestCost)); } /* Estimate the cost of a table scan. If we do not know how many ** entries are in the table, use 1 million as a guess. */ pProbe = pSrc->pTab->pIndex; - cost = pProbe ? pProbe->aiRowEst[0] : 1000000.0; + cost = pProbe ? pProbe->aiRowEst[0] : 1000000; TRACE(("... table scan base cost: %.9g\n", cost)); flags = WHERE_ROWID_RANGE; /* Check for constraints on a range of rowids in a table scan. */ pTerm = findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE|WO_GT|WO_GE, 0); if( pTerm ){ if( findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0) ){ flags |= WHERE_TOP_LIMIT; - cost *= 0.333; /* Guess that rowidEXPR eliminates two-thirds of rows */ + cost /= 3; /* Guess that rowid>EXPR eliminates two-thirds of rows */ } TRACE(("... rowid range reduces cost to %.9g\n", cost)); }else{ flags = 0; } @@ -978,11 +989,11 @@ /* Look at each index. */ for(; pProbe; pProbe=pProbe->pNext){ int i; /* Loop counter */ - double inMultiplier = 1.0; + double inMultiplier = 1; TRACE(("... index %s:\n", pProbe->zName)); /* Count the number of columns in the index that are satisfied ** by x=EXPR constraints or x IN (...) constraints. @@ -995,13 +1006,13 @@ flags |= WHERE_COLUMN_EQ; if( pTerm->operator & WO_IN ){ Expr *pExpr = pTerm->pExpr; flags |= WHERE_COLUMN_IN; if( pExpr->pSelect!=0 ){ - inMultiplier *= 100.0; + inMultiplier *= 100; }else if( pExpr->pList!=0 ){ - inMultiplier *= pExpr->pList->nExpr + 1.0; + inMultiplier *= pExpr->pList->nExpr + 1; } } } cost = pProbe->aiRowEst[i] * inMultiplier * estLog(inMultiplier); nEq = i; @@ -1018,15 +1029,15 @@ pTerm = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pProbe); if( pTerm ){ flags |= WHERE_COLUMN_RANGE; if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pProbe) ){ flags |= WHERE_TOP_LIMIT; - cost *= 0.333; + cost /= 3; } if( findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pProbe) ){ flags |= WHERE_BTM_LIMIT; - cost *= 0.333; + cost /= 3; } TRACE(("...... range reduces cost to %.9g\n", cost)); } } @@ -1061,11 +1072,11 @@ m &= ~(((Bitmask)1)<a[j]; jnSrc; j++, pTabItem++){ m = getMask(&maskSet, pTabItem->iCursor); if( (m & notReady)==0 ){ if( j==iFrom ) iFrom++; continue;