From b37df7b928122d1632573f577522e6fa36538102 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Oct 2005 02:09:49 +0000 Subject: [PATCH] Attempt to fix the SQLite core so that no floating point operations are used anywhere if SQLITE_OMIT_FLOATING_POINT is defined at compile-time. This is useful to people who use SQLite on embedded processors that lack floating point support. (CVS 2749) FossilOrigin-Name: a0bdb584680ce6400d9e8c57db9d91197cc7b776 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/func.c | 4 ++-- src/printf.c | 12 +++++++----- src/sqlite.h.in | 17 ++++++++++++++++- src/sqliteInt.h | 28 +++++++++++++--------------- src/util.c | 6 +++++- src/where.c | 44 ++++++++++++++++++++++++++++---------------- 8 files changed, 83 insertions(+), 52 deletions(-) diff --git a/manifest b/manifest index 48492a4064..f00d36ce50 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sdefault\sTEMP_STORE=1\s(TEMP\stables\sstored\son\sdisk)\sin\sthe\sconfigure\nscript.\s(CVS\s2748) -D 2005-10-10T00:05:51 +C Attempt\sto\sfix\sthe\sSQLite\score\sso\sthat\sno\sfloating\spoint\soperations\sare\sused\nanywhere\sif\sSQLITE_OMIT_FLOATING_POINT\sis\sdefined\sat\scompile-time.\s\sThis\nis\suseful\sto\speople\swho\suse\sSQLite\son\sembedded\sprocessors\sthat\slack\nfloating\spoint\ssupport.\s(CVS\s2749) +D 2005-10-13T02:09:50 F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -42,7 +42,7 @@ F src/date.c 7444b0900a28da77e57e3337a636873cff0ae940 F src/delete.c 29dac493f4d83b05f91233b116827c133bcdab72 F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d F src/expr.c 6881c8dfe363c1ee5a5dcb463b880704acb77709 -F src/func.c f63d417248808ff2632a3b576536abffcc21d858 +F src/func.c 7d81dccd9c440c6c4e761056333e629192814af0 F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84 F src/insert.c 1f51566d7cf4b243a2792f5fda37343d6e9377fa @@ -62,12 +62,12 @@ F src/pager.h e7b41ce8e7b5f629d456708b7ad9a8c8ede37140 F src/parse.y 5602d5cb894dda2932bf50b7e88782a4440ae3ae F src/pragma.c 9ec219dc4ee2d4e78f4ec5c9d1422089758af13f F src/prepare.c fc098db25d2a121affb08686cf04833fd50452d4 -F src/printf.c bd421c1ad5e01013c89af63c60eab02852ccd15e +F src/printf.c 3ea3a17d25d7ac498efc18007c70371a42c968f8 F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4 F src/select.c 80c95f3cebd6f7096cdcad1968316e4bb96b18b2 F src/shell.c 3596c1e559b82663057940d19ba533ad421c7dd3 -F src/sqlite.h.in 461b2535550cf77aedfd44385da11ef7d63e57a2 -F src/sqliteInt.h c9afda257c9649aef17f9ddb67ae443b800e2bae +F src/sqlite.h.in a9c3e9797c6f2657f2096630af6240a602ff8622 +F src/sqliteInt.h 403552a7770a5c5a376af9bdc956f0c78e524b9c F src/table.c e03b60eaabaeb54a00d7e931566d77302dfc19b0 F src/tclsqlite.c 4f274fae3d4a1863451a553dd8e5015747a5d91d F src/test1.c 0f1a66f65a54fba029f7e93b7500d49443dc959b @@ -79,7 +79,7 @@ F src/tokenize.c e1faf5637f3f4f90933785a0ecf64595f3ac3530 F src/trigger.c f51dec15921629591cb98bf2e350018e268b109a F src/update.c ac506fb7400158f826ec6c3a0dbe65e7ed3928d5 F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c -F src/util.c 55caaffbb2716f9928ab452d20f3e9cbbeab872d +F src/util.c e10e28d410aa49ea9c318cf7f285ab8c8a567154 F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c F src/vdbe.c c9aca7cc6dc381c4ce5a59c97ac148ed0659fb3c F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13 @@ -88,7 +88,7 @@ F src/vdbeapi.c 85bbe1d0243a89655433d60711b4bd71979b59cd F src/vdbeaux.c eb1ce3a40d37a1a7e92749e0ef72e3224fa5e55f F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5 F src/vdbemem.c ff426ff6e72aa3f0300a56ec8c7f18099be96b43 -F src/where.c 3ed72ca029b3010a76e3a41b7b02ec1bdf849f00 +F src/where.c 5252bf20257fb8630959ae7a145fc20076f30543 F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42 F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3 F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6 @@ -315,7 +315,7 @@ F www/tclsqlite.tcl ddcf912ea48695603c8ed7efb29f0812ef8d1b49 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P edca8913ca012fc0c17343a27f819de95147b1bd -R 4311fd59747207ae5450fbdb06f917f3 +P 9753af53494a14f7300f92f3d94e4ceb55619529 +R a6df4c45cb7278a0ea91b4f127858f77 U drh -Z 4013be90cb59b45ffcbc0935306d8882 +Z 0352737aa28a9b0c5a1c2ec1286f6536 diff --git a/manifest.uuid b/manifest.uuid index 88b5687281..8407bf9dbd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9753af53494a14f7300f92f3d94e4ceb55619529 \ No newline at end of file +a0bdb584680ce6400d9e8c57db9d91197cc7b776 \ No newline at end of file diff --git a/src/func.c b/src/func.c index ed9133c350..6071aa452b 100644 --- a/src/func.c +++ b/src/func.c @@ -16,11 +16,11 @@ ** 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" diff --git a/src/printf.c b/src/printf.c index a669eb8d44..539455a00a 100644 --- a/src/printf.c +++ b/src/printf.c @@ -120,10 +120,12 @@ static const et_info fmtinfo[] = { { '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 }, @@ -134,10 +136,10 @@ static const et_info fmtinfo[] = { #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 @@ -161,7 +163,7 @@ static int et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ *val = (*val - d)*10.0; return digit; } -#endif +#endif /* SQLITE_OMIT_FLOATING_POINT */ /* ** On machines with a small stack size, you can redefine the @@ -234,7 +236,7 @@ static int vxprintf( 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 */ @@ -425,7 +427,7 @@ static int vxprintf( 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 ){ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index a5015dbce1..5b0ead4be6 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** 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_ @@ -86,6 +86,13 @@ typedef struct sqlite3 sqlite3; 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. @@ -1269,6 +1276,14 @@ int sqlite3_get_autocommit(sqlite3*); */ 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 diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9d172a227a..7b4f360b62 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** 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_ @@ -59,6 +59,18 @@ #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 @@ -128,20 +140,6 @@ */ #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 diff --git a/src/util.c b/src/util.c index ba37e0c8a0..1601234447 100644 --- a/src/util.c +++ b/src/util.c @@ -14,7 +14,7 @@ ** 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 @@ -606,6 +606,7 @@ int sqlite3IsNumber(const char *z, int *realnum, u8 enc){ ** 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; @@ -656,6 +657,9 @@ int sqlite3AtoF(const char *z, double *pResult){ } *pResult = sign<0 ? -v1 : v1; return z - zBegin; +#else + return sqlite3atoi64(z, pResult); +#endif /* SQLITE_OMIT_FLOATING_POINT */ } /* diff --git a/src/where.c b/src/where.c index e3b0e19a0a..21958bf6c3 100644 --- a/src/where.c +++ b/src/where.c @@ -16,7 +16,7 @@ ** 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" @@ -40,6 +40,16 @@ int sqlite3_where_trace = 0; # 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; @@ -854,10 +864,10 @@ static int sortableByRowid( ** 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; @@ -893,7 +903,7 @@ static double bestIndex( ){ 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 */ @@ -904,6 +914,7 @@ static double bestIndex( 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 */ @@ -928,7 +939,7 @@ static double bestIndex( /* 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)); } @@ -937,7 +948,7 @@ static double bestIndex( ** 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; @@ -947,11 +958,11 @@ static double bestIndex( 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{ @@ -980,7 +991,7 @@ static double bestIndex( */ for(; pProbe; pProbe=pProbe->pNext){ int i; /* Loop counter */ - double inMultiplier = 1.0; + double inMultiplier = 1; TRACE(("... index %s:\n", pProbe->zName)); @@ -997,9 +1008,9 @@ static double bestIndex( 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; } } } @@ -1020,11 +1031,11 @@ static double bestIndex( 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)); } @@ -1063,7 +1074,7 @@ static double bestIndex( } if( m==0 ){ flags |= WHERE_IDX_ONLY; - cost *= 0.5; + cost /= 2; TRACE(("...... idx-only reduces cost to %.9g\n", cost)); } } @@ -1464,10 +1475,11 @@ WhereInfo *sqlite3WhereBegin( Index *pBest = 0; /* The best index seen so far */ int bestFlags = 0; /* Flags associated with pBest */ int bestNEq = 0; /* nEq associated with pBest */ - double lowestCost = 1.0e99; /* Cost of the pBest */ + double lowestCost; /* Cost of the pBest */ int bestJ; /* The value of j */ Bitmask m; /* Bitmask value for j or bestJ */ + lowestCost = SQLITE_BIG_DBL; for(j=iFrom, pTabItem=&pTabList->a[j]; jnSrc; j++, pTabItem++){ m = getMask(&maskSet, pTabItem->iCursor); if( (m & notReady)==0 ){