From: drh Date: Sat, 24 Nov 2001 00:31:46 +0000 (+0000) Subject: Fix comparison functions so that they are consistent with the order X-Git-Tag: version-3.6.10~5716 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7a7c73905d0c881368787ebe70816c2e99039587;p=thirdparty%2Fsqlite.git Fix comparison functions so that they are consistent with the order of elements in indices. Fix the handling of large integers. (CVS 317) FossilOrigin-Name: fc2aae04578c305304a45ec6b76d3ab216cc7526 --- diff --git a/Makefile.in b/Makefile.in index 3840766f80..d43b85453f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -270,6 +270,9 @@ tclsqlite.html: $(TOP)/www/tclsqlite.tcl speed.html: $(TOP)/www/speed.tcl tclsh $(TOP)/www/speed.tcl >speed.html +faq.html: $(TOP)/www/faq.tcl + tclsh $(TOP)/www/faq.tcl >faq.html + download.html: $(TOP)/www/download.tcl tclsh $(TOP)/www/download.tcl >download.html @@ -290,7 +293,8 @@ DOC = \ mingw.html \ tclsqlite.html \ download.html \ - speed.html + speed.html \ + faq.html doc: $(DOC) mkdir -p doc diff --git a/Makefile.template b/Makefile.template index e9486371dc..ae3cd7c2ad 100644 --- a/Makefile.template +++ b/Makefile.template @@ -329,6 +329,9 @@ tclsqlite.html: $(TOP)/www/tclsqlite.tcl speed.html: $(TOP)/www/speed.tcl tclsh $(TOP)/www/speed.tcl >speed.html +faq.html: $(TOP)/www/faq.tcl + tclsh $(TOP)/www/faq.tcl >faq.html + download.html: $(TOP)/www/download.tcl tclsh $(TOP)/www/download.tcl >download.html @@ -349,7 +352,8 @@ DOC = \ mingw.html \ tclsqlite.html \ download.html \ - speed.html + speed.html \ + faq.html doc: $(DOC) mkdir -p doc diff --git a/VERSION b/VERSION index eca07e4c1a..ac2cdeba01 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1.2 +2.1.3 diff --git a/manifest b/manifest index b8ea46634f..2c5187780a 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Version\s2.1.2\s(CVS\s459) -D 2001-11-23T00:30:00 -F Makefile.in 6801df952cb1df64aa32e4de85fed24511d28efd -F Makefile.template 1fdb891f14083ee0b63cf7282f91529634438e7a +C Fix\scomparison\sfunctions\sso\sthat\sthey\sare\sconsistent\swith\sthe\sorder\nof\selements\sin\sindices.\s\sFix\sthe\shandling\sof\slarge\sintegers.\s(CVS\s317) +D 2001-11-24T00:31:46 +F Makefile.in 352fed589f09dd94347e0bb391d047118ebd6105 +F Makefile.template b6c3d3ba089e97e3a721e967f3151350f36cb42b F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0 -F VERSION c5cc20339d1ecb09a252aeef3d5417cd4d802473 +F VERSION e6864ec01e9107b1044207a2556c4e96c3457007 F aclocal.m4 11faa843caa38fd451bc6aeb43e248d1723a269d F config.guess f38b1e93d1e0fa6f5a6913e9e7b12774b9232588 F config.log 6a73d03433669b10a3f0c221198c3f26b9413914 @@ -23,7 +23,7 @@ F src/btree.c d40fa46c8c578f1d166f4ea70d7a9d365399e0f3 F src/btree.h 0250a0a577a98cc64ddf1582d50c08b8d2451650 F src/build.c 2e21d425328e7c8bd6ade235e9eef51bf6fa870f F src/delete.c 5d93a21c1388cfb1359bda01c072f25583a2f4f2 -F src/expr.c 53515a7ba787bf4f0b3f73be30eb86aadb6f1b90 +F src/expr.c 6b25c5bb1e750af2e2217c0134a7aa1fc0b11444 F src/hash.c 6f1a7712ae3aac8351662969aec5693740a2fbf7 F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac F src/insert.c 3526be771a01035198bef28d8f370cbcab94f46d @@ -37,7 +37,7 @@ F src/parse.y 5295f393f41ea89958287e5738e6c12c7cd67482 F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d F src/random.c 2a9cc2c9716d14815fd4c2accf89d87a1143e46b F src/select.c fa1c7144a9ad7ce3f16373b443bc25e764af4be7 -F src/shell.c 18e9f1cac7ec8af763f8fc71dfd81e2edee24008 +F src/shell.c 175f4e942286bcafefc5bd44346deb94394615b1 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in 934de9112747ad8d8e7d5fec44876246b24ca5a3 F src/sqliteInt.h 1d812fd1eed0008d31f7e31293f058bb6dbe3f09 @@ -48,21 +48,21 @@ F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321 F src/test3.c d6775f95fd91f5b3cf0e2382a28e5aaeb68f745b F src/tokenize.c 830e9ef684334070a26583d94770bb869e2727bf F src/update.c 365f6fafe75f6816a598e76031b0a757d91c003d -F src/util.c 265cff871a6079b95878c738bc2da3420cca1375 +F src/util.c 13dcd870ee0e424f5427e8178480ca1b1833a706 F src/vdbe.c f1afb7a82016be2cb4cea24cf98dbb5af0ea7214 F src/vdbe.h cd4c8647051a0c22c0e133c375f1cd17bb8b1e06 F src/where.c 05d27a01e53c20b8cd10589b7e789b2a64367988 F test/all.test 2a51e5395ac7c2c539689b123b9782a05e3837fe -F test/bigrow.test 1f098f85586d2117bdb3412d27eba45252bc8a6e +F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 F test/btree.test 6ab4dc5f595905a276ef588fad3c9236dc07a47b F test/btree2.test 08e9485619265cbaf5d11bd71f357cdc26bb87e0 F test/btree3.test 9caa9e22491dd8cd8aa36d7ac3b48b089817c895 F test/copy.test 768e6f1701a07d08090e1ca7f7dcce0a7a72b43e F test/delete.test c904a62129fe102b314a96111a8417f10249e4d8 -F test/expr.test b4171c84b767f7b7e94dbce4824ba8e981a1c72f +F test/expr.test d350ef5b21cc26599357fb93d15b8a5f7b524769 F test/func.test 9012f7fc5369422c890e93549aa61d762e0c8bb3 F test/in.test 9323681388be301dc73f370b4cd62c5a33f79d1e -F test/index.test c2c3088648d106a5a612a14cb346998a4ff77bfa +F test/index.test c8a471243bbf878974b99baf5badd59407237cf3 F test/insert.test a5c122aa726f1cef6f07d6767e8fd6f220994c11 F test/insert2.test d6901ca931e308fea7fca8c95ebe7dc957cc9fc2 F test/ioerr.test 57d9bffaca18b34f9e976f786eadc2591d6efc6a @@ -104,11 +104,12 @@ F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4 F www/arch.tcl 03b521d252575f93b9c52f7c8b0007011512fcfb F www/c_interface.tcl d446234c1d3ed747fcefd30e972a19f2b2fc0e05 -F www/changes.tcl f1a09dfa633183121d7d4255f4cadadc84dc034d +F www/changes.tcl 0a54872839461f49b7300b36571d342f0ef0d4fb F www/crosscompile.tcl c99efacb3aefaa550c6e80d91b240f55eb9fd33e F www/download.tcl 3e51c9ff1326b0a182846134987301310dff7d60 F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c -F www/index.tcl fa0ee4b5343fd216ee5db0285501e45484189484 +F www/faq.tcl 55c7fbb5490d045a3e8223e41b51d8b93310b52c +F www/index.tcl 7e1afccc37548b7107f666105749bfe7d99d267b F www/lang.tcl f0e953bfeaaba4c33117ec4bca639dd71ba0e13e F www/mingw.tcl fc5f4ba9d336b6e8c97347cc6496d6162461ef60 F www/opcode.tcl 7989ed328316454c7030dcdb60f09ae1e017286d @@ -116,7 +117,7 @@ F www/speed.tcl 212a91d555384e01873160d6a189f1490c791bc2 F www/sqlite.tcl 6a21242a272e9c0939a04419a51c3d50cae33e3e F www/tclsqlite.tcl 13d50723f583888fc80ae1a38247c0ab415066fa F www/vdbe.tcl eb4e1768cffa266cbbb7133488022a7a6cb278d9 -P 8a984667113564f2bac7412165b6ff8b7e3e8f70 -R c4b924c66bb520eb6ed8e5503bdf1605 +P f14835df32b4a16c840b8827f0c17f0e6d526312 +R 4107b50dd67a5b31593969d21ca32f97 U drh -Z 1a9449aaa1a79f5e52fef176b1356165 +Z 70fea61a18707bc0d908d9bbb2153332 diff --git a/manifest.uuid b/manifest.uuid index 8837d3cfdd..72d566e314 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f14835df32b4a16c840b8827f0c17f0e6d526312 \ No newline at end of file +fc2aae04578c305304a45ec6b76d3ab216cc7526 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 8e2045bf87..fc7e7f83e8 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.33 2001/11/08 00:45:21 drh Exp $ +** $Id: expr.c,v 1.34 2001/11/24 00:31:46 drh Exp $ */ #include "sqliteInt.h" @@ -511,8 +511,8 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){ break; } case TK_INTEGER: { - int i = atoi(pExpr->token.z); - sqliteVdbeAddOp(v, OP_Integer, i, 0); + sqliteVdbeAddOp(v, OP_String, 0, 0); + sqliteVdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n); break; } case TK_FLOAT: { @@ -576,11 +576,7 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){ } case TK_UMINUS: { assert( pExpr->pLeft ); - if( pExpr->pLeft->op==TK_INTEGER ){ - int i = atoi(pExpr->pLeft->token.z); - sqliteVdbeAddOp(v, OP_Integer, -i, 0); - break; - }else if( pExpr->pLeft->op==TK_FLOAT ){ + if( pExpr->pLeft->op==TK_FLOAT || pExpr->pLeft->op==TK_INTEGER ){ Token *p = &pExpr->pLeft->token; char *z = sqliteMalloc( p->n + 2 ); sprintf(z, "-%.*s", p->n, p->z); diff --git a/src/shell.c b/src/shell.c index e9fc698455..4db83d7b77 100644 --- a/src/shell.c +++ b/src/shell.c @@ -12,7 +12,7 @@ ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** -** $Id: shell.c,v 1.38 2001/11/09 22:41:45 drh Exp $ +** $Id: shell.c,v 1.39 2001/11/24 00:31:46 drh Exp $ */ #include #include @@ -556,9 +556,9 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){ p->showHeader = 1; p->colWidth[0] = 4; p->colWidth[1] = 12; - p->colWidth[2] = 5; - p->colWidth[3] = 5; - p->colWidth[4] = 40; + p->colWidth[2] = 10; + p->colWidth[3] = 10; + p->colWidth[4] = 35; }else if( c=='h' && strncmp(azArg[0], "header", n)==0 && nArg>1 ){ diff --git a/src/util.c b/src/util.c index ddb7cfa96b..166660a1e1 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.32 2001/11/21 02:21:12 drh Exp $ +** $Id: util.c,v 1.33 2001/11/24 00:31:46 drh Exp $ */ #include "sqliteInt.h" #include @@ -426,13 +426,18 @@ int sqliteStrNICmp(const char *zLeft, const char *zRight, int N){ return N<0 ? 0 : *a - *b; } -/* Notes on string comparisions. +/* +** The sortStrCmp() function below is used to order elements according +** to the ORDER BY clause of a SELECT. The sort order is a little different +** from what one might expect. This note attempts to describe what is +** going on. ** ** We want the main string comparision function used for sorting to ** sort both numbers and alphanumeric words into the correct sequence. ** The same routine should do both without prior knowledge of which ** type of text the input represents. It should even work for strings -** which are a mixture of text and numbers. +** which are a mixture of text and numbers. (It does not work for +** numeric substrings in exponential notation, however.) ** ** To accomplish this, we keep track of a state number while scanning ** the two strings. The states are as follows: @@ -525,9 +530,10 @@ static const unsigned char stateMachine[] = { }; /* This routine does a comparison of two strings. Case is used only -** if useCase!=0. Numbers compare in numerical order. +** if useCase!=0. Numeric substrings compare in numerical order for the +** most part but this routine does not understand exponential notation. */ -static int privateStrCmp(const char *atext, const char *btext, int useCase){ +static int sortStrCmp(const char *atext, const char *btext, int useCase){ register unsigned char *a, *b, *map, ca, cb; int result; register int cclass = 0; @@ -599,129 +605,69 @@ static int privateStrCmp(const char *atext, const char *btext, int useCase){ } /* -** Do a comparison of pure numerics. If either string is not a pure -** numeric, then return 0. Otherwise return 1 and set *pResult to be -** negative, zero or positive if the first string are numerially less than -** equal to, or greater than the second. +** Return TRUE if z is a pure numeric string. Return FALSE if the +** string contains any character which is not part of a number. +** +** Am empty string is considered numeric. */ -static int privateCompareNum(const char *a, const char *b, int *pResult){ - char *endPtr; - double rA, rB; - int isNumA, isNumB; - if( isdigit(*a) || ((*a=='-' || *a=='+') && isdigit(a[1])) ){ - rA = strtod(a, &endPtr); - isNumA = *endPtr==0; - }else{ - isNumA = 0; +static int isNum(const char *z){ + if( *z=='-' || *z=='+' ) z++; + if( !isdigit(*z) ){ + return *z==0; } - if( isdigit(*b) || ((*b=='-' || *b=='+') && isdigit(b[1])) ){ - rB = strtod(b, &endPtr); - isNumB = *endPtr==0; - }else{ - isNumB = 0; - } - if( isNumB==0 && isNumA==0 ) return 0; - if( isNumA!=isNumB ){ - *pResult = isNumA - isNumB; - }else if( rArB ){ - *pResult = 1; - }else{ - *pResult = 0; + z++; + while( isdigit(*z) ){ z++; } + if( *z=='.' ){ + z++; + if( !isdigit(*z) ) return 0; + while( isdigit(*z) ){ z++; } + if( *z=='e' || *z=='E' ){ + z++; + if( *z=='+' || *z=='-' ) z++; + if( !isdigit(*z) ) return 0; + while( isdigit(*z) ){ z++; } + } } - return 1; + return *z==0; } /* This comparison routine is what we use for comparison operations -** in an SQL expression. (Ex: name<'Hello' or value<5). Compare two -** strings. Use case only as a tie-breaker. Numbers compare in -** numerical order. +** in an SQL expression. (Ex: name<'Hello' or value<5). +** +** Numerical strings compare in numerical order. Numerical strings +** are always less than non-numeric strings. Non-numeric strings +** compare in lexigraphical order (the same order as strcmp()). +** +** This is NOT the comparison function used for sorting. The sort +** order is a little bit different. See sqliteSortCompare below +** for additional information. */ int sqliteCompare(const char *atext, const char *btext){ int result; - if( !privateCompareNum(atext, btext, &result) || result==0 ){ - result = privateStrCmp(atext, btext, 0); - if( result==0 ) result = privateStrCmp(atext, btext, 1); - } - return result; -} - -/* -** If you compile just this one file with the -DTEST_COMPARE=1 option, -** it generates a program to test the comparisons routines. -*/ -#ifdef TEST_COMPARE -#include -#include -int sortCmp(const char **a, const char **b){ - return sqliteCompare(*a, *b); -} -int main(int argc, char **argv){ - int i, j, k, n, cnt; - static char *azStr[] = { - "abc", "aBc", "abcd", "aBcd", - "123", "124", "1234", "-123", "-124", "-1234", "+124", - "123.45", "123.456", "123.46", "-123.45", "-123.46", "-123.456", - "x9", "x10", "x-9", "x-10", "X9", "X10", - "1.234e+02", "+123", "1.23E2", "1.2345e+2", "-1.2345e2", "+w" - }; - n = sizeof(azStr)/sizeof(azStr[0]); - qsort(azStr, n, sizeof(azStr[0]), sortCmp); - for(i=0; i0; - }else{ - success = (x2>=0 && x3>=0) || x2<0; - } - if( !success ){ - printf("Failed! \"%s\" vs \"%s\" vs \"%s\"\n", a, b, c); - i = j = k = n+1; - } - cnt++; + int isNumA = isNum(atext); + int isNumB = isNum(btext); + if( isNumA ){ + if( !isNumB ){ + result = -1; + }else{ + double rA, rB; + rA = atof(atext); + rB = atof(btext); + if( rArB ){ + result = +1; + }else{ + result = 0; } } + }else if( isNumB ){ + result = +1; + }else { + result = strcmp(atext, btext); } - if( i", and ">=" operators +** of expressions. The operators compare non-numeric strings in +** lexigraphical order. This routine does the additional processing +** to sort substrings of digits into numerical order and to use case +** only as a tie-breaker. */ int sqliteSortCompare(const char *a, const char *b){ int len; int res = 0; + int isNumA, isNumB; while( res==0 && *a && *b ){ - res = sqliteCompare(&a[1], &b[1]); - if( res==0 ){ - len = strlen(a) + 1; - a += len; - b += len; + isNumA = isNum(&a[1]); + isNumB = isNum(&b[1]); + if( isNumA ){ + double rA, rB; + if( !isNumB ){ + res = -1; + break; + } + rA = atof(&a[1]); + rB = atof(&b[1]); + if( rArB ){ + res = +1; + break; + } + }else if( isNumB ){ + res = +1; + break; + }else{ + res = sortStrCmp(&a[1],&b[1],0); + if( res==0 ){ + res = sortStrCmp(&a[1],&b[1],1); + } + if( res!=0 ){ + break; + } } + len = strlen(&a[1]) + 2; + a += len; + b += len; } if( *a=='-' ) res = -res; return res; } /* -** Some powers of 64. These numbers and their recipricals should -** all have exact representations in the floating point format. +** Some powers of 64. These constants are needed in the +** sqliteRealToSortable() routine below. */ #define _64e3 (64.0 * 64.0 * 64.0) #define _64e4 (64.0 * 64.0 * 64.0 * 64.0) diff --git a/test/bigrow.test b/test/bigrow.test index ce1150c44b..7a7d9ccaeb 100644 --- a/test/bigrow.test +++ b/test/bigrow.test @@ -12,7 +12,7 @@ # focus of this file is stressing the library by putting large amounts # of data in a single row of a table. # -# $Id: bigrow.test,v 1.3 2001/11/12 13:10:53 drh Exp $ +# $Id: bigrow.test,v 1.4 2001/11/24 00:31:47 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -90,7 +90,7 @@ do_test bigrow-1.8 { } {abc} do_test bigrow-1.9 { execsql "SELECT b FROM t1 WHERE a!='$::big1' ORDER BY a" -} {B 2} +} {2 B} # Try doing some indexing on big columns # diff --git a/test/expr.test b/test/expr.test index c275e4a4d9..23c92fa103 100644 --- a/test/expr.test +++ b/test/expr.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing expressions. # -# $Id: expr.test,v 1.16 2001/10/13 02:59:09 drh Exp $ +# $Id: expr.test,v 1.17 2001/11/24 00:31:47 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -73,6 +73,15 @@ test_expr expr-1.43 {i1=1, i2=2} {i1&i2} {0} test_expr expr-1.44 {i1=1} {~i1} {-2} test_expr expr-1.45 {i1=1, i2=3} {i1<>i2} {4} +test_expr expr-1.47 {i1=9999999999, i2=8888888888} {i1i2} 1 +test_expr expr-1.50 {i1=99999999999, i2=99999999998} {i1i2} 1 +test_expr expr-1.53 {i1=099999999999, i2=99999999999} {i1i2} 0 test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57 test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11 @@ -123,9 +132,11 @@ test_expr expr-3.22 {t1='abc', t2='xyz'} {t1!=t2} 1 test_expr expr-3.23 {t1='xyz', t2='abc'} {t1!=t2} 1 test_expr expr-3.24 {t1='abc', t2='abc'} {t1!=t2} 0 test_expr expr-3.25 {t1=NULL, t2='hi'} {t1 isnull} 1 +test_expr expr-3.25b {t1=NULL, t2='hi'} {t1 is null} 1 test_expr expr-3.26 {t1=NULL, t2='hi'} {t2 isnull} 0 test_expr expr-3.27 {t1=NULL, t2='hi'} {t1 notnull} 0 test_expr expr-3.28 {t1=NULL, t2='hi'} {t2 notnull} 1 +test_expr expr-3.28b {t1=NULL, t2='hi'} {t2 is not null} 1 test_expr expr-3.29 {t1='xyz', t2='abc'} {t1||t2} {xyzabc} test_expr expr-3.30 {t1=NULL, t2='abc'} {t1||t2} {abc} test_expr expr-3.31 {t1='xyz', t2=NULL} {t1||t2} {xyz} @@ -133,8 +144,14 @@ test_expr expr-3.32 {t1='xyz', t2='abc'} {t1||' hi '||t2} {{xyz hi abc}} test_expr expr-4.1 {t1='abc', t2='Abc'} {t1t2} 1 -test_expr expr-4.3 {t1='abc', t2='Bbc'} {t1t2} 0 +test_expr expr-4.3 {t1='abc', t2='Bbc'} {t1t2} 1 +test_expr expr-4.5 {t1='0', t2='0.0'} {t1==t2} 1 +test_expr expr-4.6 {t1='0.000', t2='0.0'} {t1==t2} 1 +test_expr expr-4.7 {t1=' 0.000', t2=' 0.0'} {t1==t2} 0 +test_expr expr-4.8 {t1='0.0', t2='abc'} {t1t2} 0 test_expr expr-5.1 {t1='abc', t2='xyz'} {t1 LIKE t2} 0 test_expr expr-5.2 {t1='abc', t2='ABC'} {t1 LIKE t2} 1 diff --git a/test/index.test b/test/index.test index 359c821d41..43a39ef15d 100644 --- a/test/index.test +++ b/test/index.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the CREATE INDEX statement. # -# $Id: index.test,v 1.16 2001/11/23 00:24:12 drh Exp $ +# $Id: index.test,v 1.17 2001/11/24 00:31:47 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -331,4 +331,54 @@ do_test index-11.1 { concat [execsql {SELECT c FROM t3 WHERE b==10}] $sqlite_search_count } {0.10 3} +# Numeric strings should compare as if they were numbers. So even if the +# strings are not character-by-character the same, if they represent the +# same number they should compare equal to one another. Verify that this +# is true in indices. +# +do_test index-12.1 { + execsql { + CREATE TABLE t4(a,b); + INSERT INTO t4 VALUES('0.0',1); + INSERT INTO t4 VALUES('0.00',2); + INSERT INTO t4 VALUES('abc',3); + INSERT INTO t4 VALUES('-1.0',4); + INSERT INTO t4 VALUES('+1.0',5); + INSERT INTO t4 VALUES('0',6); + INSERT INTO t4 VALUES('00000',7); + SELECT a FROM t4 ORDER BY b; + } +} {0.0 0.00 abc -1.0 +1.0 0 00000} +do_test index-12.2 { + execsql { + SELECT a FROM t4 WHERE a==0 ORDER BY b + } +} {0.0 0.00 0 00000} +do_test index-12.3 { + execsql { + SELECT a FROM t4 WHERE a<0.5 ORDER BY b + } +} {0.0 0.00 -1.0 0 00000} +do_test index-12.4 { + execsql { + SELECT a FROM t4 WHERE a>-0.5 ORDER BY b + } +} {0.0 0.00 abc +1.0 0 00000} +do_test index-12.5 { + execsql { + CREATE INDEX t4i1 ON t4(a); + SELECT a FROM t4 WHERE a==0 ORDER BY b + } +} {0.0 0.00 0 00000} +do_test index-12.6 { + execsql { + SELECT a FROM t4 WHERE a<0.5 ORDER BY b + } +} {0.0 0.00 -1.0 0 00000} +do_test index-12.7 { + execsql { + SELECT a FROM t4 WHERE a>-0.5 ORDER BY b + } +} {0.0 0.00 abc +1.0 0 00000} + finish_test diff --git a/www/changes.tcl b/www/changes.tcl index 9b19247fe4..c76ad91bcd 100644 --- a/www/changes.tcl +++ b/www/changes.tcl @@ -17,6 +17,14 @@ proc chng {date desc} { puts "

    $desc

" } +chng {2001 Nov 23 (2.1.3)} { +
  • Fix the behavior of comparison operators + (ex: "<", "==", etc.) + so that they are consistent with the order of entries in an index.
  • +
  • Correct handling of integers in SQL expressions that are larger than + what can be represented by the machine integer.
  • +} + chng {2001 Nov 22 (2.1.2)} {
  • Changes to support 64-bit architectures.
  • Fix a bug in the locking protocol.
  • diff --git a/www/faq.tcl b/www/faq.tcl new file mode 100644 index 0000000000..d300a7a397 --- /dev/null +++ b/www/faq.tcl @@ -0,0 +1,165 @@ +# +# Run this script to generated a faq.html output file +# +puts { + + SQLite Frequently Asked Questions + + +

    Frequently Asked Questions

    +} + +set cnt 1 +proc faq {question answer} { + set ::faq($::cnt) [list [string trim $question] [string trim $answer]] + incr ::cnt +} + +############# +# Enter questions and answers here. + +faq { + How do I create an AUTOINCREMENT field. +} { + SQLite does not support AUTOINCREMENT. If you need a unique key for + a new entry in a table, you can create an auxiliary table + with a single entry that holds the next available value for that key. + Like this: +
    +CREATE TABLE counter(cnt);
    +INSERT INTO counter VALUES(1);
    +
    + Once you have a counter set up, you can generate a unique key as follows: +
    +BEGIN TRANSACTION;
    +SELECT cnt FROM counter;
    +UPDATE counter SET cnt=cnt+1;
    +COMMIT;
    +
    + There are other ways of simulating the effect of AUTOINCREMENT but + this approach seems to be the easiest and most efficient. +} + +faq { + SQLite lets me insert a string into a database column of type integer! +} { +

    This is a feature, not a bug. SQLite is typeless. Any data can be + inserted into any column. You can put arbitrary length strings into + integer columns, floating point numbers in boolean columns, or dates + in character columns. The datatype you assign to a column in the + CREATE TABLE command is (mostly) ignored. Every column is able to hold + an arbitrary length string.

    + +

    Because SQLite ignores data types, you can omit the data type definition + from columns in CREATE TABLE statements. For example, instead of saying +

    +CREATE TABLE t1(
    +  f1 int,
    +  f2 varchar(10),
    +  f3 boolean
    +);
    +
    + You can save yourself a lot of typing and formatting by omitting the + data type declarations, like this: +
    +CREATE TABLE t1(f1,f2,f3);
    +
    +

    +} + +faq { + Why does SQLite think that the expression '0'=='00' is TRUE? +} { +

    This is a consequence of SQLite being typeless. All data is stored + internally as a null-terminated string. There is no concept of + separate data types for strings and numbers.

    + +

    When doing a comparison, SQLite looks at the string on both sides of + the comparison operator. If both strings look like pure numeric + values (with no extra punctuation or spacing) then the strings are + converted to floating point numbers using atof() and the results + are compared. The results of atof("0") and atof("00") + are both 0.0, so those two strings are considered to be equal.

    + +

    If only one string in a comparison is a pure numeric, then that string + is assumed to be less than the other. Of neither string is a pure numeric, + then strcmp() is used for the comparison.

    +} + +faq { + The second INSERT in the following sequence of commands returns with + constraint error. +
    + CREATE TABLE t(s varchar(10) primary key);
    + INSERT INTO t VALUES('0');
    + INSERT INTO t VALUES('0.0');
    +
    + Why is this? +} { +

    Because column s is a primary key, all values of s must + be unique. But SQLite thinks that '0' and '0.0' are the + same value because they compare equal to one another numerically. + (See the previous question.) Hence the values are not unique and the + constraint fails.

    + +

    You can work around this issue in several ways:

    +
      +
    1. Remove the primary key clause from the CREATE TABLE so that + s can contain more than one entry with the same value. + If you need an index on the s column then create it separately. +

    2. +
    3. Prepend a space to the beginning of every s value. The initial + space will mean that the entries are not pure numerics and hence + will be compared as strings using strcmp().

    4. +
    +} + +faq { + My linux box is not able to read an SQLite database that was created + on my SparcStation. +} { +

    The x86 processor on your windows box is little-endian (meaning that + the least signification byte of integers comes first) but the Sparc is + big-endian (the most significant bytes comes first). SQLite databases + created on a little-endian architecture cannot be used on a big-endian + machine and vice versa.

    + +

    If you need to move the database from one machine to another, you'll + have to do an ASCII dump of the database on the source machine and then + reconstruct the database at the destination machine. The following is + a typical command for transferring an SQLite databases between two + machines: +

    +echo .dump | sqlite from.db | ssh sparc 'sqlite to.db'
    +
    + The command above assumes the name of the destination machine is + sparc and that you have SSH running on both the source and + destination. An alternative approach is to save the output of the first + sqlite command in a temporary file, move the temporary file + to the destination machine, then run the second sqlite command + while redirecting input from the temporary file.

    +} + +# End of questions and answers. +############# + +puts {
    } +for {set i 1} {$i<$cnt} {incr i} { + puts "
    ($i)
    " + puts "
    [lindex $faq($i) 0]
    " +} +puts {

    } + +for {set i 1} {$i<$cnt} {incr i} { + puts "" + puts "

    ($i) [lindex $faq($i) 0]

    \n" + puts "
    [lindex $faq($i) 1]
    \n" +} + +puts { +


    +

    +Back to the SQLite Home Page +

    + +} diff --git a/www/index.tcl b/www/index.tcl index 4dd9c9b309..d7718da096 100644 --- a/www/index.tcl +++ b/www/index.tcl @@ -1,7 +1,7 @@ # # Run this TCL script to generate HTML for the index.html file. # -set rcsid {$Id: index.tcl,v 1.47 2001/11/12 12:43:22 drh Exp $} +set rcsid {$Id: index.tcl,v 1.48 2001/11/24 00:31:47 drh Exp $} puts { SQLite: An SQL Database Engine In A C Library @@ -105,6 +105,7 @@ newer versions of SQLite.

    The following documentation is currently available: