Additional test cases and documentation updates. (CVS 717)
FossilOrigin-Name: 048b16c111693727482642e2a19a74a91458fc80
This commit is contained in:
parent
3d037a91a5
commit
310ae7be1e
20
manifest
20
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
|
||||
|
@ -1 +1 @@
|
||||
66a0f6a8e25e3eeed78eba4b63b097f921c79d99
|
||||
048b16c111693727482642e2a19a74a91458fc80
|
@ -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
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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 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 {
|
||||
|
94
www/faq.tcl
94
www/faq.tcl
@ -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
|
||||
);
|
||||
<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>
|
||||
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);
|
||||
</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>As of version 2.7.0, it doesn't.</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>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>
|
||||
|
||||
<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>
|
||||
<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 {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user