Add additional test cases and requirements evidence marks for WITHOUT ROWID.

FossilOrigin-Name: b408d788105efd007e3546f45d5dd15a5dc5688d
This commit is contained in:
drh 2013-11-27 00:45:49 +00:00
parent bbbb0e8053
commit ef1bd970ef
6 changed files with 259 additions and 12 deletions

View File

@ -1,5 +1,5 @@
C Make\ssure\sthe\supdate\shook\sis\snot\sinvoked\sfor\sWITHOUT\sROWID\stables,\sas\nthe\sdocumentation\sspecifies.\s\sThis\sbug\swas\sfound\swhile\sadding\srequirements\nmarks,\sso\sa\sfew\sextraneous\srequirements\smarks\sare\sincluded\sin\sthis\ncheck-in.
D 2013-11-26T23:27:07.055
C Add\sadditional\stest\scases\sand\srequirements\sevidence\smarks\sfor\sWITHOUT\sROWID.
D 2013-11-27T00:45:49.889
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -587,7 +587,7 @@ F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36
F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536
F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
F test/hook.test 8b24a1a8a1ddf0883c6824825e7577f2636918dc
F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f
F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4
F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
@ -643,7 +643,7 @@ F test/jrnlmode.test 9ee3a78f53d52cca737db69293d15dc41c0cbd36
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05
F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/like.test 935fb4f608e3ea126891496a6e99b9468372bf5c
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
@ -756,7 +756,7 @@ F test/releasetest.tcl 06d289d8255794073a58d2850742f627924545ce
F test/resolver01.test 33abf37ff8335e6bf98f2b45a0af3e06996ccd9a
F test/rollback.test e9504a009a202c3ed711da2e6879ff60c5a4669c
F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81
F test/rowid.test f777404492adb0e00868fd706a3721328fd3af48
F test/rowid.test b78b30afb9537a73788ca1233a23a32190a3bb1f
F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798
F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09
F test/savepoint.test 6c53f76dffe5df0dd87646efe3e7aa159c36e07b
@ -1091,6 +1091,7 @@ F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
F test/without_rowid5.test b4a639a367f04d382d20e8f44fc1be4f2d57d107
F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda
F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688
F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd
@ -1143,7 +1144,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P 838654e56304a5788ac384ca506c1938f48af488
R e178483a3ba4d2f533907e57553db5a6
P 0978bac6b8aee229d7a0d148546f50d380d06a06
R c5e238577bf88ba62aaf207d6ba68ed5
U drh
Z 51c7e3abc8471c6679ba39e030a2dca2
Z 6729df1882fbf26a3a642e6e52bb3ce5

View File

@ -1 +1 @@
0978bac6b8aee229d7a0d148546f50d380d06a06
b408d788105efd007e3546f45d5dd15a5dc5688d

View File

@ -127,23 +127,52 @@ db2 close
# depopulation of indices, to make sure the update-hook is not
# invoked incorrectly.
#
# EVIDENCE-OF: R-21999-45122 The sqlite3_update_hook() interface
# registers a callback function with the database connection identified
# by the first argument to be invoked whenever a row is updated,
# inserted or deleted in a rowid table.
# Simple tests
do_test hook-4.1.1 {
do_test hook-4.1.1a {
catchsql {
DROP TABLE t1;
}
unset -nocomplain ::update_hook
set ::update_hook {}
db update_hook [list lappend ::update_hook]
#
# EVIDENCE-OF: R-52223-27275 The update hook is not invoked when
# internal system tables are modified (i.e. sqlite_master and
# sqlite_sequence).
#
execsql {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
CREATE TABLE t1w(a INT PRIMARY KEY, b) WITHOUT ROWID;
}
set ::update_hook
} {}
do_test hook-4.1.1b {
execsql {
INSERT INTO t1 VALUES(1, 'one');
INSERT INTO t1 VALUES(2, 'two');
INSERT INTO t1 VALUES(3, 'three');
INSERT INTO t1w SELECT * FROM t1;
}
db update_hook [list lappend ::update_hook]
} {}
# EVIDENCE-OF: R-15506-57666 The second callback argument is one of
# SQLITE_INSERT, SQLITE_DELETE, or SQLITE_UPDATE, depending on the
# operation that caused the callback to be invoked.
#
# EVIDENCE-OF: R-29213-61195 The third and fourth arguments to the
# callback contain pointers to the database and table name containing
# the affected row.
#
# EVIDENCE-OF: R-30809-57812 The final callback parameter is the rowid
# of the row.
#
do_test hook-4.1.2 {
set ::update_hook {}
execsql {
INSERT INTO t1 VALUES(4, 'four');
DELETE FROM t1 WHERE b = 'two';
@ -164,6 +193,9 @@ do_test hook-4.1.2 {
# EVIDENCE-OF: R-61808-14344 The sqlite3_update_hook() interface does
# not fire callbacks for changes to a WITHOUT ROWID table.
#
# EVIDENCE-OF: R-33257-44249 The update hook is not invoked when WITHOUT
# ROWID tables are modified.
#
do_test hook-4.1.2w {
set ::update_hook {}
execsql {

View File

@ -36,6 +36,17 @@ do_test lastinsert-1.1 {
}
} {0 3}
# EVIDENCE-OF: R-47220-63683 The sqlite3_last_insert_rowid() function
# does not work for WITHOUT ROWID tables.
#
do_test lastinsert-1.1w {
catchsql {
create table t1w (k integer primary key) WITHOUT ROWID;
insert into t1w values (123456);
select last_insert_rowid(); -- returns 3 from above.
}
} {0 3}
# LIRID unchanged after an update on a table
do_test lastinsert-1.2 {
catchsql {

View File

@ -12,7 +12,9 @@
# focus of this file is testing the magic ROWID column that is
# found on all tables.
#
# $Id: rowid.test,v 1.21 2009/06/26 15:14:55 drh Exp $
# EVIDENCE-OF: R-36924-43758 By default, every row in SQLite has a
# special column, usually called the "rowid", that uniquely identifies
# that row within the table.
set testdir [file dirname $argv0]
source $testdir/tester.tcl

201
test/without_rowid5.test Normal file
View File

@ -0,0 +1,201 @@
# 2013-11-26
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Requirements testing for WITHOUT ROWID tables.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# EVIDENCE-OF: R-36924-43758 By default, every row in SQLite has a
# special column, usually called the "rowid", that uniquely identifies
# that row within the table.
#
# EVIDENCE-OF: R-32341-39358 However if the phrase "WITHOUT ROWID" is
# added to the end of a CREATE TABLE statement, then the special "rowid"
# column is omitted.
#
do_execsql_test without_rowid5-1.1 {
CREATE TABLE t1(a PRIMARY KEY,b,c);
CREATE TABLE t1w(a PRIMARY KEY,b,c) WITHOUT ROWID;
INSERT INTO t1 VALUES(1565,681,1148),(1429,1190,1619),(425,358,1306);
INSERT INTO t1w SELECT a,b,c FROM t1;
SELECT rowid, _rowid_, oid FROM t1 ORDER BY a DESC;
} {1 1 1 2 2 2 3 3 3}
do_catchsql_test without_rowid5-1.2 {
SELECT rowid FROM t1w;
} {1 {no such column: rowid}}
do_catchsql_test without_rowid5-1.3 {
SELECT _rowid_ FROM t1w;
} {1 {no such column: _rowid_}}
do_catchsql_test without_rowid5-1.4 {
SELECT oid FROM t1w;
} {1 {no such column: oid}}
# EVIDENCE-OF: R-00217-01605 To create a WITHOUT ROWID table, simply add
# the keywords "WITHOUT ROWID" to the end of the CREATE TABLE statement.
# For example: CREATE TABLE IF NOT EXISTS wordcount( word TEXT PRIMARY
# KEY, cnt INTEGER ) WITHOUT ROWID;
#
do_execsql_test without_rowid5-2.1 {
CREATE TABLE IF NOT EXISTS wordcount(
word TEXT PRIMARY KEY,
cnt INTEGER
) WITHOUT ROWID;
INSERT INTO wordcount VALUES('one',1);
} {}
do_catchsql_test without_rowid5-2.2 {
SELECT rowid FROM wordcount;
} {1 {no such column: rowid}}
# EVIDENCE-OF: R-24770-17719 As with all SQL syntax, the case of the
# keywords does not matter. One can write "WITHOUT rowid" or "without
# rowid" or "WiThOuT rOwId" and it will mean the same thing.
#
do_execsql_test without_rowid5-2.3 {
CREATE TABLE IF NOT EXISTS wordcount_b(
word TEXT PRIMARY KEY,
cnt INTEGER
) WITHOUT rowid;
INSERT INTO wordcount_b VALUES('one',1);
} {}
do_catchsql_test without_rowid5-2.4 {
SELECT rowid FROM wordcount_b;
} {1 {no such column: rowid}}
do_execsql_test without_rowid5-2.5 {
CREATE TABLE IF NOT EXISTS wordcount_c(
word TEXT PRIMARY KEY,
cnt INTEGER
) without rowid;
INSERT INTO wordcount_c VALUES('one',1);
} {}
do_catchsql_test without_rowid5-2.6 {
SELECT rowid FROM wordcount_c;
} {1 {no such column: rowid}}
do_execsql_test without_rowid5-2.7 {
CREATE TABLE IF NOT EXISTS wordcount_d(
word TEXT PRIMARY KEY,
cnt INTEGER
) WITHOUT rowid;
INSERT INTO wordcount_d VALUES('one',1);
} {}
do_catchsql_test without_rowid5-2.8 {
SELECT rowid FROM wordcount_d;
} {1 {no such column: rowid}}
# EVIDENCE-OF: R-01418-51310 However, only "rowid" works as the keyword
# in the CREATE TABLE statement.
#
do_catchsql_test without_rowid5-3.1 {
CREATE TABLE IF NOT EXISTS error1(
word TEXT PRIMARY KEY,
cnt INTEGER
) WITHOUT _rowid_;
} {1 {unknown table option: _rowid_}}
do_catchsql_test without_rowid5-3.2 {
CREATE TABLE IF NOT EXISTS error2(
word TEXT PRIMARY KEY,
cnt INTEGER
) WITHOUT oid;
} {1 {unknown table option: oid}}
# EVIDENCE-OF: R-58033-17334 An error is raised if a CREATE TABLE
# statement with the WITHOUT ROWID clause lacks a PRIMARY KEY.
#
# EVIDENCE-OF: R-63443-09418 Every WITHOUT ROWID table must have a
# PRIMARY KEY.
#
# EVIDENCE-OF: R-27966-31616 An attempt to create a WITHOUT ROWID table
# without a PRIMARY KEY results in an error.
#
do_catchsql_test without_rowid5-4.1 {
CREATE TABLE IF NOT EXISTS error3(
word TEXT UNIQUE,
cnt INTEGER
) WITHOUT ROWID;
} {1 {PRIMARY KEY missing on table error3}}
# EVIDENCE-OF: R-48230-36247 The special behaviors associated "INTEGER
# PRIMARY KEY" do not apply on WITHOUT ROWID tables.
#
do_execsql_test without_rowid5-5.1 {
CREATE TABLE ipk(key INTEGER PRIMARY KEY, val TEXT) WITHOUT ROWID;
INSERT INTO ipk VALUES('rival','bonus'); -- ok to insert non-integer key
SELECT * FROM ipk;
} {rival bonus}
do_catchsql_test without_rowid5-5.2 {
INSERT INTO ipk VALUES(NULL,'sample'); -- no automatic generation of keys
} {1 {NOT NULL constraint failed: ipk.key}}
# EVIDENCE-OF: R-33142-02092 AUTOINCREMENT does not work on WITHOUT
# ROWID tables.
#
# EVIDENCE-OF: R-53084-07740 An error is raised if the "AUTOINCREMENT"
# keyword is used in the CREATE TABLE statement for a WITHOUT ROWID
# table.
#
do_catchsql_test without_rowid5-5.3 {
CREATE TABLE ipk2(key INTEGER PRIMARY KEY AUTOINCREMENT, val TEXT)WITHOUT ROWID;
} {1 {AUTOINCREMENT not allowed on WITHOUT ROWID tables}}
# EVIDENCE-OF: R-27831-00579 NOT NULL is enforced on every column of the
# PRIMARY KEY in a WITHOUT ROWID table.
#
# EVIDENCE-OF: R-29781-51289 So, ordinary rowid tables in SQLite violate
# the SQL standard and allow NULL values in PRIMARY KEY fields.
#
# EVIDENCE-OF: R-27472-62612 But WITHOUT ROWID tables do follow the
# standard and will throw an error on any attempt to insert a NULL into
# a PRIMARY KEY column.
#
do_execsql_test without_rowid5-5.4 {
CREATE TABLE nn(a, b, c, d, e, PRIMARY KEY(c,a,e));
CREATE TABLE nnw(a, b, c, d, e, PRIMARY KEY(c,a,e)) WITHOUT ROWID;
INSERT INTO nn VALUES(1,2,3,4,5);
INSERT INTO nnw VALUES(1,2,3,4,5);
} {}
do_execsql_test without_rowid5-5.5 {
INSERT INTO nn VALUES(NULL, 3,4,5,6);
INSERT INTO nn VALUES(3,4,NULL,7,8);
INSERT INTO nn VALUES(4,5,6,7,NULL);
SELECT count(*) FROM nn;
} {4}
do_catchsql_test without_rowid5-5.6 {
INSERT INTO nnw VALUES(NULL, 3,4,5,6);
} {1 {NOT NULL constraint failed: nnw.a}}
do_catchsql_test without_rowid5-5.7 {
INSERT INTO nnw VALUES(3,4,NULL,7,8)
} {1 {NOT NULL constraint failed: nnw.c}}
do_catchsql_test without_rowid5-5.8 {
INSERT INTO nnw VALUES(4,5,6,7,NULL)
} {1 {NOT NULL constraint failed: nnw.e}}
do_execsql_test without_rowid5-5.9 {
SELECT count(*) FROM nnw;
} {1}
# EVIDENCE-OF: R-12643-30541 The incremental blob I/O mechanism does not
# work for WITHOUT ROWID tables.
#
# EVIDENCE-OF: R-25760-33257 The sqlite3_blob_open() interface will fail
# for a WITHOUT ROWID table.
#
do_execsql_test without_rowid5-6.1 {
CREATE TABLE b1(a INTEGER PRIMARY KEY, b BLOB) WITHOUT ROWID;
INSERT INTO b1 VALUES(1,x'0102030405060708090a0b0c0d0e0f');
} {}
do_test without_rowid5-6.2 {
set rc [catch {db incrblob b1 b 1} msg]
lappend rc $msg
} {1 {cannot open table without rowid: b1}}
finish_test