]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Additional test cases and documentation updates. (CVS 717)
authordrh <drh@noemail.net>
Thu, 15 Aug 2002 11:48:13 +0000 (11:48 +0000)
committerdrh <drh@noemail.net>
Thu, 15 Aug 2002 11:48:13 +0000 (11:48 +0000)
FossilOrigin-Name: 048b16c111693727482642e2a19a74a91458fc80

manifest
manifest.uuid
test/misc1.test
www/c_interface.tcl
www/datatypes.tcl
www/faq.tcl
www/lang.tcl

index 8af6e9e72c46da2f69adb7b5f83581f71b713940..f4c80bfb4e35a15bbd7c6967e857abd39a0fbfa5 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fixes\sand\stest\simprovements\sresulting\sfrom\scode\scoverage\stesting.\s(CVS\s716)
-D 2002-08-15T01:26:09
+C Additional\stest\scases\sand\sdocumentation\supdates.\s(CVS\s717)
+D 2002-08-15T11:48:13
 F Makefile.in 6291a33b87d2a395aafd7646ee1ed562c6f2c28c
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -77,7 +77,7 @@ F test/lock.test f1b55dc61632e99d241643cc8e7c03774f09f623
 F test/main.test c66b564554b770ee7fdbf6a66c0cd90329bc2c85
 F test/malloc.test 7ba32a9ebd3aeed52ae4aaa6d42ca37e444536fd
 F test/minmax.test 29bc5727c3e4c792d5c4745833dd4b505905819e
-F test/misc1.test 064d7fbbe41285a381ce21832fed41ed245a6a2e
+F test/misc1.test 834dce8b6db65c4921d59a4d449b87f40442ab87
 F test/misuse.test a3aa2b18a97e4c409a1fcaff5151a4dd804a0162
 F test/notnull.test b1f3e42fc475b0b5827b27b2e9b562081995ff30
 F test/null.test 5c2b57307e4b6178aae825eb65ddbee01e76b0fd
@@ -127,17 +127,17 @@ F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
 F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
 F www/arch.tcl 679a0c48817f71bc91d5911ef386e5ef35d4f178
 F www/audit.tcl 90e09d580f79c7efec0c7d6f447b7ec5c2dce5c0
-F www/c_interface.tcl fb87b825b9032b9aa941694c5c9c5aee9424467e
+F www/c_interface.tcl 70548ff5f73c6adcdb7aeced929ebb30a99f5807
 F www/changes.tcl df6f06b1aa97ef285c744bf19ec3efddf707b05f
 F www/conflict.tcl 81dd21f9a679e60aae049e9dd8ab53d59570cda2
 F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
-F www/datatypes.tcl ac58cd17bd96cbf1dc228dfb965f88e3e8d45c6b
+F www/datatypes.tcl a555ff9f5121aab9d7cffcec4c1d8c86ad79c4ee
 F www/download.tcl 29aa6679ca29621d10613f60ebbbda18f4b91c49
 F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
-F www/faq.tcl 234cd80a771f63c778b0a86784589f4eaae2b381
+F www/faq.tcl 9262ad6f7f25ab253a9771ab1fbd48a1a14f2957
 F www/formatchng.tcl b4449e065d2da38b6563bdf12cf46cfe1d4d765e
 F www/index.tcl 9af69527a26895ec56ad920d4c51541c3e5643a6
-F www/lang.tcl 902f677258ee63dd8f6677b54118f354a1d824b6
+F www/lang.tcl a2785964e80627381e953849e227a3ff2a38cb09
 F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc
 F www/omitted.tcl 7a6d6598e6a6a09bf54a02e0aff0f29e407d9f11
 F www/opcode.tcl 33c5f2061a05c5d227c72b84c080b3bf74c74f8b
@@ -145,7 +145,7 @@ F www/speed.tcl 7fc83f1b018e1ecc451838449542c3079ed12425
 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 07f6020bb56d6d1bffdd936017f61cfae5bd134b
-R 9cedd757d76753c6b434284c8a29f442
+P 66a0f6a8e25e3eeed78eba4b63b097f921c79d99
+R cf9944ebe55162967e3e3ce76c6f7260
 U drh
-Z 60f9f150ddc50216dbbd17469130080e
+Z 8cc0e2bc226abcbf418a7651cce9d7b1
index 3e7370fe97fa7354c1212b98373ecf1c82a2ab4b..d58a3b8ec2d2c924d591836901e3cfd5baae71e0 100644 (file)
@@ -1 +1 @@
-66a0f6a8e25e3eeed78eba4b63b097f921c79d99
\ No newline at end of file
+048b16c111693727482642e2a19a74a91458fc80
\ No newline at end of file
index d779605787979399ce77433badf3c185421f6b75..9ea6ae1dacd8bb4bab78d0f8c9ce802e08b9264c 100644 (file)
@@ -13,7 +13,7 @@
 # This file implements tests for miscellanous features that were
 # left out of other test files.
 #
-# $Id: misc1.test,v 1.12 2002/08/13 23:02:58 drh Exp $
+# $Id: misc1.test,v 1.13 2002/08/15 11:48:13 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -320,4 +320,47 @@ do_test misc1-11.2 {
   lappend rc $msg
 } {0 3}
 
+# Make sure string comparisons really do compare strings in format4+.
+# Similar tests in the format3.test file show that for format3 and earlier
+# all comparisions where numeric if either operand looked like a number.
+#
+do_test misc1-12.1 {
+  execsql {SELECT '0'=='0.0'}
+} {0}
+do_test misc1-12.2 {
+  execsql {SELECT '0'==0.0}
+} {1}
+do_test misc1-12.3 {
+  execsql {SELECT '12345678901234567890'=='12345678901234567891'}
+} {0}
+do_test misc1-12.4 {
+  execsql {
+    CREATE TABLE t6(a INT UNIQUE, b TEXT UNIQUE);
+    INSERT INTO t6 VALUES('0','0.0');
+    SELECT * FROM t6;
+  }
+} {0 0.0}
+do_test misc1-12.5 {
+  execsql {
+    INSERT OR IGNORE INTO t6 VALUES(0.0,'x');
+    SELECT * FROM t6;
+  }
+} {0 0.0}
+do_test misc1-12.6 {
+  execsql {
+    INSERT OR IGNORE INTO t6 VALUES('y',0);
+    SELECT * FROM t6;
+  }
+} {0 0.0 y 0}
+do_test misc1-12.7 {
+  execsql {
+    CREATE TABLE t7(x INTEGER, y TEXT, z);
+    INSERT INTO t7 VALUES(0,0,1);
+    INSERT INTO t7 VALUES(0.0,0,2);
+    INSERT INTO t7 VALUES(0,0.0,3);
+    INSERT INTO t7 VALUES(0.0,0.0,4);
+    SELECT DISTINCT x, y FROM t7 ORDER BY z;
+  }
+} {0 0 0 0.0}
+
 finish_test
index 1b260292d2112534164bcc3a777f238daabf0a9b..1066a760bb76deb90b077813dcd2078cfbd2e5d2 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this Tcl script to generate the sqlite.html file.
 #
-set rcsid {$Id: c_interface.tcl,v 1.33 2002/08/02 10:36:10 drh Exp $}
+set rcsid {$Id: c_interface.tcl,v 1.34 2002/08/15 11:48:14 drh Exp $}
 
 puts {<html>
 <head>
@@ -410,7 +410,7 @@ for the most recent INSERT statement using the
 <p>The <b>sqlite_changes()</b> API function returns the number of rows
 that were inserted, deleted, or modified during the most recent
 <b>sqlite_exec()</b> call.  The number reported includes any changes
-that were later undo by a ROLLBACK or ABORT.  But rows that are
+that were later undone by a ROLLBACK or ABORT.  But rows that are
 deleted because of a DROP TABLE are <em>not</em> counted.</p>
 
 <p>SQLite implements the command "<b>DELETE FROM table</b>" (without
@@ -425,7 +425,7 @@ is necessary, use "<b>DELETE FROM table WHERE 1</b>" instead.</p>
 
 <p>The <b>sqlite_get_table()</b> function is a wrapper around
 <b>sqlite_exec()</b> that collects all the information from successive
-callbacks and write it into memory obtained from malloc().  This
+callbacks and writes it into memory obtained from malloc().  This
 is a convenience function that allows the application to get the
 entire result of a database query with a single function call.</p>
 
@@ -433,7 +433,7 @@ entire result of a database query with a single function call.</p>
 to strings.  There is one element in this array for each column of
 each row in the result.  NULL results are represented by a NULL
 pointer. In addition to the regular data, there is an added row at the 
-beginning of the array that contains the names of each column of the
+beginning of the array that contains the name of each column of the
 result.</p>
 
 <p>As an example, consider the following query:</p>
@@ -619,7 +619,7 @@ additional arguments are attached to the end of the function call.</p>
 functions instead of <b>sprintf()</b>.  First of all, with the
 SQLite printf routines, there is never a danger of overflowing a
 static buffer as there is with <b>sprintf()</b>.  The SQLite
-printf routines automatically allocate (and later free)
+printf routines automatically allocate (and later frees)
 as much memory as is 
 necessary to hold the SQL statements generated.</p>
 
index 5623d44cc976027294c34b00fb77a2f98916f7a1..b3db49c3eddd996c6747c8ab3b98f28fe1546ca0 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this script to generated a datatypes.html output file
 #
-set rcsid {$Id: datatypes.tcl,v 1.2 2002/08/14 03:03:58 drh Exp $}
+set rcsid {$Id: datatypes.tcl,v 1.3 2002/08/15 11:48:14 drh Exp $}
 
 puts {<html>
 <head>
@@ -184,10 +184,70 @@ TEXT
 <p>
 The search for these strings in the type declaration is case insensitive,
 of course.  If any of the above strings occur anywhere in the type
-declaration, then the datatype of the column is text.  Otherwise the
-datatype is numeric.  Note in particular that the datatype for columns
+declaration, then the datatype of the column is text.  Notice that
+the type "VARCHAR" contains "CHAR" as a substring so it is considered
+text.</p>
+
+<p>If none of the strings above occur anywhere in the type declaration,
+then the datatype is numeric.  Note in particular that the datatype for columns
 with an empty type declaration is numeric.
 </p>
+
+<h2>5.0 &nbsp; Examples</h2>
+
+<p>
+Consider the following two command sequences:
+</p>
+
+<blockquote><pre>
+CREATE TABLE t1(a INTEGER UNIQUE);        CREATE TABLE t2(b TEXT UNIQUE);
+INSERT INTO t1 VALUES('0');               INSERT INTO t2 VALUES(0);
+INSERT INTO t1 VALUES('0.0');             INSERT INTO t2 VALUES(0.0);
+</pre></blockquote>
+
+<p>In the sequence on the left, the second insert will fail.  In this case,
+the strings '0' and '0.0' are treated as numbers since they are being 
+inserted into a numeric column but 0==0.0 which violates the uniqueness
+constraint.  However, the second insert in the right-hand sequence works.  In
+this case, the constants 0 and 0.0 are treated a strings which means that
+they are distinct.</p>
+
+<p>SQLite always converts numbers into double-precision (64-bit) floats
+for comparison purposes.  This means that a long sequence of digits that
+differ only in digits of far to the right will compare equal if they
+are in a numeric column but will compare unequal if they are in a text
+column.  We have:</p>
+
+<blockquote><pre>
+INSERT INTO t1                            INSERT INTO t2
+   VALUES('12345678901234567890');           VALUES(12345678901234567890);
+INSERT INTO t1                            INSERT INTO t2
+   VALUES('12345678901234567891');           VALUES(12345678901234567891);
+</pre></blockquote>
+
+<p>As before, the second insert on the left will fail because the comparison
+will convert both strings into floating-point number first and the only
+difference in the strings is in the 20-th digit which exceeds the resolution
+of a 64-bit float.  In contrast, the second insert on the right will work
+because in that case, the numbers being inserted are strings and are
+compared using memcmp().</p>
+
+<p>
+Numeric and text types make a difference for the DISTINCT keyword too:
+</p>
+
+<blockquote><pre>
+CREATE TABLE t3(a INTEGER);               CREATE TABLE t4(b TEXT);
+INSERT INTO t3 VALUES('0');               INSERT INTO t4 VALUES(0);
+INSERT INTO t3 VALUES('0.0');             INSERT INTO t4 VALUES(0.0);
+SELECT DISTINCT * FROM t3;                SELECT DISTINCT * FROM t4;
+</pre></blockquote>
+
+<p>
+The SELECT statement on the left returns a single row since '0' and '0.0'
+are treated as numbers and are therefore indistinct.  But the SELECT 
+statement on the right returns two rows since 0 and 0.0 are treated
+a strings which are different.</p>
 }
 
 puts {
index d8447bd5ccd796f70ecd52b13dac02113c8d86c8..ecd7249159d0c32daa2e7f4bd145c9a644b2984b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this script to generated a faq.html output file
 #
-set rcsid {$Id: faq.tcl,v 1.16 2002/08/14 12:56:56 drh Exp $}
+set rcsid {$Id: faq.tcl,v 1.17 2002/08/15 11:48:14 drh Exp $}
 
 puts {<html>
 <head>
@@ -79,6 +79,9 @@ faq {
   <p>An exception to this rule is a column of type INTEGER PRIMARY KEY.
   Such columns must hold an integer.  An attempt to put a non-integer
   value into an INTEGER PRIMARY KEY column will generate an error.</p>
+
+  <p>There is a page on <a href="datatypes.html">datatypes in SQLite</a>
+  that explains this concept further.</p>
 }
 
 faq {
@@ -88,65 +91,78 @@ faq {
   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
+  CREATE TABLE command does not restrict what data can be put into
+  that column.  Every column is able to hold
   an arbitrary length string.  (There is one exception: Columns of
   type INTEGER PRIMARY KEY may only hold an integer.  An error will result
   if you try to put anything other than an integer into an
   INTEGER PRIMARY KEY column.)</p>
 
-  <p>Because SQLite ignores data types, you can omit the data type definition
-  from columns in CREATE TABLE statements.  For example, instead of saying
-<blockquote><pre>
-CREATE TABLE t1(
-  f1 int,
-  f2 varchar(10),
-  f3 boolean
-);
-</pre></blockquote>
-  You can save yourself a lot of typing and formatting by omitting the
-  data type declarations, like this:
-<blockquote><pre>
-CREATE TABLE t1(f1,f2,f3);
+  <p>The datatype does effect how values are compared, however.  For
+  columns with a numeric type (such as "integer") any string that looks
+  like a number is treated as a number for comparison and sorting purposes.
+  Consider these two command sequences:</p>
+
+  <blockquote><pre>
+CREATE TABLE t1(a INTEGER UNIQUE);        CREATE TABLE t2(b TEXT UNIQUE);
+INSERT INTO t1 VALUES('0');               INSERT INTO t2 VALUES(0);
+INSERT INTO t1 VALUES('0.0');             INSERT INTO t2 VALUES(0.0);
 </pre></blockquote>
-  </p>
+
+  <p>In the sequence on the left, the second insert will fail.  In this case,
+  the strings '0' and '0.0' are treated as numbers since they are being 
+  inserted into a numeric column and 0==0.0 which violates the uniqueness
+  constraint.  But the second insert in the right-hand sequence works.  In
+  this case, the constants 0 and 0.0 are treated a strings which means that
+  they are distinct.</p>
+
+  <p>There is a page on <a href="datatypes.html">datatypes in SQLite</a>
+  that explains this concept further.</p>
 }
 
 faq {
   Why does SQLite think that the expression '0'=='00' is TRUE?
 } {
-  <p>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.</p>
-
-  <p>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 <b>atof()</b> and the results
-  are compared.  The results of <b>atof("0")</b> and <b>atof("00")</b>
-  are both 0.0, so those two strings are considered to be equal.</p>
-
-  <p>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 <b>strcmp()</b> is used for the comparison.</p>
+  <p>As of version 2.7.0, it doesn't.</p>
+
+  <p>But if one of the two values being compared is stored in a column that
+  has a numeric type, the the other value is treated as a number, not a
+  string and the result succeeds.  For example:</p>
+
+<blockquote><pre>
+CREATE TABLE t3(a INTEGER, b TEXT);
+INSERT INTO t3 VALUES(0,0);
+SELECT count(*) FROM t3 WHERE a=='00';
+</pre></blockquote>
+
+  <p>The SELECT in the above series of commands returns 1.  The "a" column
+  is numeric so in the WHERE clause the string '00' is converted into a
+  number for comparison against "a".  0==00 so the test is true.  Now
+  consider a different SELECT:</p>
+
+<blockquote><pre>
+SELECT count(*) FROM t3 WHERE b=='00';
+</pre></blockquote>
+
+  <p>In this case the answer is 0.  B is a text column so a text comparison
+  is done against '00'.  '0'!='00' so the WHERE clause returns FALSE and
+  the count is zero.</p>
+
+  <p>There is a page on <a href="datatypes.html">datatypes in SQLite</a>
+  that explains this concept further.</p>
 }
 
 faq {
   Why doesn't SQLite allow me to use '0' and '0.0' as the primary
   key on two different rows of the same table?
 } {
-  <p>Every row much have a unique primary key.
-  But SQLite thinks that <b>'0'</b> and <b>'0.0'</b> are the
+  <p>Your primary key must have a numeric type.  Change the datatype of
+  your primary key to TEXT and it should work.</p>
+
+  <p>Every row must have a unique primary key.  For a column with a
+  numeric type, SQLite thinks that <b>'0'</b> and <b>'0.0'</b> are the
   same value because they compare equal to one another numerically.
   (See the previous question.)  Hence the values are not unique.</p>
-
-  <p>You can work around this issue in two ways:</p>
-  <ol>
-  <li><p>Remove the <b>primary key</b> clause from the CREATE TABLE.</p></li>
-  <li><p>Prepend a space to the beginning of every value you use for
-      the primary key.  The initial
-     space will mean that the entries are not pure numerics and hence
-     will be compared as strings using <b>strcmp()</b>.</p></li>
-  </ol>
 }
         
 faq {
index cc0099d76e4f481b9c8dd9361b4ed5fa3f5aa39e..72a55ceee162b37fbf634015d4f4452759cb6f9b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this Tcl script to generate the sqlite.html file.
 #
-set rcsid {$Id: lang.tcl,v 1.42 2002/08/14 00:08:13 drh Exp $}
+set rcsid {$Id: lang.tcl,v 1.43 2002/08/15 11:48:14 drh Exp $}
 
 puts {<html>
 <head>
@@ -283,7 +283,7 @@ for use by the engine.</p>
 <p>Each column definition is the name of the column followed by the
 datatype for that column, then one or more optional column constraints.
 SQLite is <a href="datatypes.html">typeless</a>.
-The datatype for the column does not constraint what data may be put
+The datatype for the column does not restrict what data may be put
 in that column.
 All information is stored as null-terminated strings.
 The UNIQUE constraint causes an index to be created on the specified