-C Fix\stypos\sin\sdocumentation\sfor\spragma\sshort_column_names.\sTicket\s#1130.\s(CVS\s2350)
-D 2005-02-18T01:15:23
+C Support\sfor\sa\sfuture\sfile\sformat\sthat\sincludes\s'short'\srecords.\s(CVS\s2351)
+D 2005-02-19T08:18:06
F Makefile.in 76443a83549d1539105e12d13bd0054a05ab2214
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
F src/auth.c 18c5a0befe20f3a58a41e3ddd78f372faeeefe1f
F src/btree.c 5c6e81855deec3d1eac5ae03e4c8db6c2595421f
F src/btree.h 2e2cc923224649337d7217df0dd32b06673ca180
-F src/build.c 7db7f593093caeb223c849a0fd7ca428dcda631e
+F src/build.c a8792b2f866c1ccc32f4977f4ff61d787d60ddfb
F src/date.c f3d1f5cd1503dabf426a198f3ebef5afbc122a7f
F src/delete.c 4b94395b52a8f7785acd71135c2ce54f3f5550b3
F src/experimental.c 8cc66b2be6a011055d75ef19ed2584bcfbb585ad
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
F src/insert.c 0456649d4d48396f918e7ea1fecbf3d66ed90816
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
-F src/main.c 981099f5f73a71e54b0858b01e03d29b83168f7b
+F src/main.c 9f0716fcee245c275a04b42c778c921483dcf868
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
F src/os.h ae44064dc118b20d39450cb331409a775e8bb1c6
F src/os_common.h 0e7f428ba0a6c40a61bc56c4e96f493231301b73
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
F src/util.c 1b7b9a127b66743ab6cba8d44597aeb570723c99
F src/vacuum.c 5cf598003191bd91c17a64742bad8e46241698a8
-F src/vdbe.c 40de3ba927a8a99b582d9cd554a2f9eca1c7a025
+F src/vdbe.c 26b085c3a64a8d7a50f9a4ef116481b6afce80b9
F src/vdbe.h bb9186484f749a839c6c43953e79a6530253f7cd
F src/vdbeInt.h e80721cd8ff611789e20743eec43363a9fb5a48e
F src/vdbeapi.c 467caa6e6fb9247528b1c7ab9132ae1b4748e8ac
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
F test/alter.test 3a20ce14c3989f7e2e75da50797065c2e56f838b
+F test/alter2.test cd4204a4f5e11c5abfe8abbdf880538c994f3b47
F test/attach.test 5147d531ca5fc5c2539fd20ce3b07a00420e1fbb
F test/attach2.test 6f3a3a3a7f5be40388dd4d805e0e0712718dca9d
F test/attach3.test c05c70b933afbde0901dab9da3e66ee842c09f38
F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
F test/btree7.test a6d3b842db22af97dd14b989e90a2fd96066b72f
F test/capi2.test 2bd71f573b32e3ac5b97441a55873eae14eeab0d
-F test/capi3.test f50dd4666deba96275f9927fe8ec089a3d8c0efa
+F test/capi3.test 39143488ac6aeddb35fa76557d0a25f54081cebc
F test/capi3b.test 5b6a66f9f295f79f443b5d3f33187fa5ef6cf336
F test/collate1.test f79736d2ebf5492167ee4d1f4ab4c09dda776b03
F test/collate2.test 224a632ba04907c049804b08162efd234aa7871f
F test/collate5.test 581775b94604b7435dc6a5c6e72fbbf7d69e3830
F test/collate6.test 6c9470d1606ee3e564675b229653e320c49ec638
F test/conflict.test c5b849b01cfbe0a4f63a90cba6f68e2fe3a75f87
-F test/corrupt.test c34304baf2f027e05942af2efeb26844adca9a53
+F test/corrupt.test 18c7a995b1af76a8c8600b996257f2c7b7bff083
F test/corrupt2.test 88342570828f2b8cbbd8369eff3891f5c0bdd5ba
F test/crash.test f38b980a0508655d08c957a6dd27d66bca776504
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl 3e522a06ad41992023c80ca29a048ae2331ca5bd
-P c5366deaf5beca9c99558c0f375ba73f817acd92
-R b75a67c7136a5c5600c1249b41513257
+P fac56fa1e06e15ffd738cb9b780d422a73a743ae
+R 9d7f7d2d11da73519486c2d9ff0d66a6
U danielk1977
-Z 6cb6073f29d2f0c0fa8b11d17ae22e19
+Z 26acc87d20c627eefd55cc96ad30a1f6
-fac56fa1e06e15ffd738cb9b780d422a73a743ae
\ No newline at end of file
+173aeb256e2c09098a4392874f8623e8a760d951
\ No newline at end of file
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.311 2005/02/15 20:47:57 drh Exp $
+** $Id: build.c,v 1.312 2005/02/19 08:18:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
** now.
*/
if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
+ int lbl;
sqlite3BeginWriteOperation(pParse, 0, iDb);
- /* Every time a new table is created the file-format
- ** and encoding meta-values are set in the database, in
- ** case this is the first table created.
+ /* If the file format and encoding in the database have not been set,
+ ** set them now.
*/
+ sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); /* file_format */
+ lbl = sqlite3VdbeMakeLabel(v);
+ sqlite3VdbeAddOp(v, OP_If, 0, lbl);
sqlite3VdbeAddOp(v, OP_Integer, db->file_format, 0);
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0);
sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
+ sqlite3VdbeResolveLabel(v, lbl);
/* This just creates a place-holder record in the sqlite_master table.
** The record created does not contain anything yet. It will be replaced
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.280 2005/02/06 02:45:42 drh Exp $
+** $Id: main.c,v 1.281 2005/02/19 08:18:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
/* This happens if the database was initially empty */
db->file_format = 1;
}
+
+ if( db->file_format==2 ){
+ /* File format 2 is treated exactly as file format 1. New
+ ** databases are created with file format 1.
+ */
+ db->file_format = 1;
+ }
}
/*
- ** file_format==1 Version 3.0.0.
+ ** file_format==1 Version 3.0.0.
+ ** file_format==2 Version 3.1.3.
+ **
+ ** Version 3.0 can only use files with file_format==1. Version 3.1.3
+ ** can read and write files with file_format==1 or file_format==2.
*/
- if( meta[1]>1 ){
+ if( meta[1]>2 ){
sqlite3BtreeCloseCursor(curMain);
sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
return SQLITE_ERROR;
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.455 2005/02/17 00:03:07 drh Exp $
+** $Id: vdbe.c,v 1.456 2005/02/19 08:18:06 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction. (See the MakeRecord opcode for additional
** information about the format of the data.) Push onto the stack the value
-** of the P2-th column contained in the data.
+** of the P2-th column contained in the data. If there are less that (P2+1)
+** values in the record, push a NULL onto the stack.
**
** If the KeyAsData opcode has previously executed on this cursor, then the
** field might be extracted from the key rather than the data.
** of the record to the start of the data for the i-th column
*/
offset = szHdr;
+ assert( offset>0 );
i = 0;
while( idx<szHdr && i<nField && offset<=payloadSize ){
aOffset[i] = offset;
Release(&sMem);
sMem.flags = MEM_Null;
+ /* If i is less that nField, then there are less fields in this
+ ** record than SetNumColumns indicated there are columns in the
+ ** table. Set the offset for any extra columns not present in
+ ** the record to 0. This tells code below to push a NULL onto the
+ ** stack instead of deserializing a value from the record.
+ */
+ while( i<nField ){
+ aOffset[i++] = 0;
+ }
+
/* The header should end at the start of data and the data should
** end at last byte of the record. If this is not the case then
** we are dealing with a malformed record.
}
}
- /* Get the column information.
+ /* Get the column information. If aOffset[p2] is non-zero, then
+ ** deserialize the value from the record. If aOffset[p2] is zero,
+ ** then there are not enough fields in the record to satisfy the
+ ** request. The value is NULL in this case.
*/
- assert( rc==SQLITE_OK );
- if( zRec ){
- zData = &zRec[aOffset[p2]];
- }else{
- len = sqlite3VdbeSerialTypeLen(aType[p2]);
- rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->keyAsData, &sMem);
- if( rc!=SQLITE_OK ){
- goto op_column_out;
+ if( aOffset[p2] ){
+ assert( rc==SQLITE_OK );
+ if( zRec ){
+ zData = &zRec[aOffset[p2]];
+ }else{
+ len = sqlite3VdbeSerialTypeLen(aType[p2]);
+ rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len,pC->keyAsData,&sMem);
+ if( rc!=SQLITE_OK ){
+ goto op_column_out;
+ }
+ zData = sMem.z;
}
- zData = sMem.z;
+ sqlite3VdbeSerialGet(zData, aType[p2], pTos);
+ pTos->enc = db->enc;
+ }else{
+ pTos->flags = MEM_Null;
}
- sqlite3VdbeSerialGet(zData, aType[p2], pTos);
- pTos->enc = db->enc;
/* If we dynamically allocated space to hold the data (in the
** sqlite3VdbeMemFromBtree() call above) then transfer control of that
--- /dev/null
+# 2005 February 18
+#
+# 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.
+#
+#*************************************************************************
+# This file implements regression tests for SQLite library. The
+# focus of this script is testing that SQLite can handle a subtle
+# file format change that may be used in the future to implement
+# "ALTER TABLE ... ADD COLUMN".
+#
+# $Id: alter2.test,v 1.1 2005/02/19 08:18:06 danielk1977 Exp $
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# The file format change affects the way row-records stored in tables (but
+# not indices) are interpreted. Before version 3.1.3, a row-record for a
+# table with N columns was guaranteed to contain exactly N fields. As
+# of version 3.1.3, the record may contain up to N fields. In this case
+# the M fields that are present are the values for the left-most M
+# columns. The (N-M) rightmost columns contain NULL.
+#
+# If any records in the database contain less fields than their table
+# has columns, then the file-format meta value should be set to (at least) 2.
+#
+
+# This procedure sets the value of the file-format in file 'test.db'
+# to $newval. Also, the schema cookie is incremented.
+#
+proc set_file_format {newval} {
+ set bt [btree_open test.db 10 0]
+ btree_begin_transaction $bt
+ set meta [btree_get_meta $bt]
+ lset meta 2 $newval ;# File format
+ lset meta 1 [expr [lindex $meta 1]+1] ;# Schema cookie
+ eval "btree_update_meta $bt $meta"
+ btree_commit $bt
+ btree_close $bt
+}
+
+# This procedure returns the value of the file-format in file 'test.db'.
+#
+proc get_file_format {{fname test.db}} {
+ set bt [btree_open $fname 10 0]
+ set meta [btree_get_meta $bt]
+ btree_close $bt
+ lindex $meta 2
+}
+
+# This procedure sets the SQL statement stored for table $tbl in the
+# sqlite_master table of file 'test.db' to $sql.
+#
+proc alter_table {tbl sql} {
+ sqlite3 dbat test.db
+ dbat eval {
+ PRAGMA writable_schema = 1;
+ UPDATE sqlite_master SET sql = $sql WHERE name = $tbl AND type = 'table';
+ PRAGMA writable_schema = 0;
+ }
+ dbat close
+ set_file_format 2
+}
+
+#-----------------------------------------------------------------------
+# Some basic tests to make sure short rows are handled.
+#
+do_test alter2-1.1 {
+ execsql {
+ CREATE TABLE abc(a, b);
+ INSERT INTO abc VALUES(1, 2);
+ INSERT INTO abc VALUES(3, 4);
+ INSERT INTO abc VALUES(5, 6);
+ }
+} {}
+do_test alter2-1.2 {
+ # ALTER TABLE abc ADD COLUMN c;
+ alter_table abc {CREATE TABLE abc(a, b, c);}
+} {}
+do_test alter2-1.3 {
+ execsql {
+ SELECT * FROM abc;
+ }
+} {1 2 {} 3 4 {} 5 6 {}}
+do_test alter2-1.4 {
+ execsql {
+ UPDATE abc SET c = 10 WHERE a = 1;
+ SELECT * FROM abc;
+ }
+} {1 2 10 3 4 {} 5 6 {}}
+do_test alter2-1.5 {
+ execsql {
+ CREATE INDEX abc_i ON abc(c);
+ }
+} {}
+do_test alter2-1.6 {
+ execsql {
+ SELECT c FROM abc ORDER BY c;
+ }
+} {{} {} 10}
+do_test alter2-1.7 {
+ execsql {
+ SELECT * FROM abc WHERE c = 10;
+ }
+} {1 2 10}
+do_test alter2-1.8 {
+ execsql {
+ SELECT sum(a), c FROM abc GROUP BY c;
+ }
+} {8.0 {} 1.0 10}
+do_test alter2-1.9 {
+ # ALTER TABLE abc ADD COLUMN d;
+ alter_table abc {CREATE TABLE abc(a, b, c, d);}
+ execsql { SELECT * FROM abc; }
+ execsql {
+ UPDATE abc SET d = 11 WHERE c IS NULL AND a<4;
+ SELECT * FROM abc;
+ }
+} {1 2 10 {} 3 4 {} 11 5 6 {} {}}
+do_test alter2-1.10 {
+ execsql {
+ SELECT typeof(d) FROM abc;
+ }
+} {null integer null}
+do_test alter2-1.99 {
+ execsql {
+ DROP TABLE abc;
+ }
+} {}
+
+#-----------------------------------------------------------------------
+# Test that views work when the underlying table structure is changed.
+#
+ifcapable view {
+ do_test alter2-2.1 {
+ execsql {
+ CREATE TABLE abc2(a, b, c);
+ INSERT INTO abc2 VALUES(1, 2, 10);
+ INSERT INTO abc2 VALUES(3, 4, NULL);
+ INSERT INTO abc2 VALUES(5, 6, NULL);
+ CREATE VIEW abc2_v AS SELECT * FROM abc2;
+ SELECT * FROM abc2_v;
+ }
+ } {1 2 10 3 4 {} 5 6 {}}
+ do_test alter2-2.2 {
+ # ALTER TABLE abc ADD COLUMN d;
+ alter_table abc2 {CREATE TABLE abc2(a, b, c, d);}
+ execsql {
+ SELECT * FROM abc2_v;
+ }
+ } {1 2 10 {} 3 4 {} {} 5 6 {} {}}
+ do_test alter2-2.3 {
+ execsql {
+ DROP TABLE abc2;
+ DROP VIEW abc2_v;
+ }
+ } {}
+}
+
+#-----------------------------------------------------------------------
+# Test that triggers work when a short row is copied to the old.*
+# trigger pseudo-table.
+#
+ifcapable trigger {
+ do_test alter2-3.1 {
+ execsql {
+ CREATE TABLE abc3(a, b);
+ CREATE TABLE blog(o, n);
+ CREATE TRIGGER abc3_t AFTER UPDATE OF b ON abc3 BEGIN
+ INSERT INTO blog VALUES(old.b, new.b);
+ END;
+ }
+ } {}
+ do_test alter2-3.2 {
+ execsql {
+ INSERT INTO abc3 VALUES(1, 4);
+ UPDATE abc3 SET b = 2 WHERE b = 4;
+ SELECT * FROM blog;
+ }
+ } {4 2}
+ do_test alter2-3.3 {
+ execsql {
+ INSERT INTO abc3 VALUES(3, 4);
+ INSERT INTO abc3 VALUES(5, 6);
+ }
+ alter_table abc3 {CREATE TABLE abc3(a, b, c);}
+ execsql {
+ SELECT * FROM abc3;
+ }
+ } {1 2 {} 3 4 {} 5 6 {}}
+ do_test alter2-3.4 {
+ execsql {
+ UPDATE abc3 SET b = b*2 WHERE a<4;
+ SELECT * FROM abc3;
+ }
+ } {1 4 {} 3 8 {} 5 6 {}}
+ do_test alter2-3.5 {
+ execsql {
+ SELECT * FROM blog;
+ }
+ } {4 2 2 4 4 8}
+
+ do_test alter2-3.6 {
+ execsql {
+ CREATE TABLE clog(o, n);
+ CREATE TRIGGER abc3_t2 AFTER UPDATE OF c ON abc3 BEGIN
+ INSERT INTO clog VALUES(old.c, new.c);
+ END;
+ UPDATE abc3 SET c = a*2;
+ SELECT * FROM clog;
+ }
+ } {{} 2 {} 6 {} 10}
+}
+
+#---------------------------------------------------------------------
+# Check that an error occurs if the database is upgraded to a file
+# format that SQLite does not support (in this case 3). Note: The
+# file format is checked each time the schema is read, so changing the
+# file format requires incrementing the schema cookie.
+#
+do_test alter2-4.1 {
+ set_file_format 3
+} {}
+do_test alter2-4.2 {
+ catchsql {
+ SELECT * FROM sqlite_master;
+ }
+} {1 {unsupported file format}}
+do_test alter2-4.3 {
+ sqlite3_errcode $::DB
+} {SQLITE_ERROR}
+do_test alter2-4.4 {
+ db close
+ set ::DB [sqlite3 db test.db]
+ catchsql {
+ SELECT * FROM sqlite_master;
+ }
+} {1 {unsupported file format}}
+do_test alter2-4.5 {
+ sqlite3_errcode $::DB
+} {SQLITE_ERROR}
+
+#---------------------------------------------------------------------
+# Check that executing VACUUM on a file with file-format version 2
+# resets the file format to 1.
+#
+do_test alter2-5.1 {
+ set_file_format 2
+ get_file_format
+} {2}
+do_test alter2-5.2 {
+ execsql {
+ VACUUM;
+ }
+} {}
+do_test alter2-5.3 {
+ get_file_format
+} {1}
+
+#---------------------------------------------------------------------
+# Test that when a database with file-format 2 is opened, new
+# databases are still created with file-format 1.
+#
+do_test alter2-6.1 {
+ db close
+ set_file_format 2
+ set ::DB [sqlite3 db test.db]
+ get_file_format
+} {2}
+do_test alter2-6.2 {
+ file delete -force test2.db-journal
+ file delete -force test2.db
+ execsql {
+ ATTACH 'test2.db' AS aux;
+ CREATE TABLE aux.t1(a, b);
+ }
+ get_file_format test2.db
+} {1}
+do_test alter2-6.3 {
+ execsql {
+ CREATE TABLE t1(a, b);
+ }
+ get_file_format
+} {2}
+
+finish_test
+
# This file implements regression tests for SQLite library. The
# focus of this script testing the callback-free C/C++ API.
#
-# $Id: capi3.test,v 1.29 2005/01/24 10:26:00 danielk1977 Exp $
+# $Id: capi3.test,v 1.30 2005/02/19 08:18:06 danielk1977 Exp $
#
set testdir [file dirname $argv0]
set ::bt [btree_open test.db 10 0]
btree_begin_transaction $::bt
set meta [btree_get_meta $::bt]
- lset meta 2 2
+ lset meta 2 3
eval [concat btree_update_meta $::bt [lrange $meta 0 end]]
btree_commit $::bt
btree_close $::bt
# This file implements tests to make sure SQLite does not crash or
# segfault if it sees a corrupt database file.
#
-# $Id: corrupt.test,v 1.7 2005/02/05 12:48:49 danielk1977 Exp $
+# $Id: corrupt.test,v 1.8 2005/02/19 08:18:06 danielk1977 Exp $
catch {file delete -force test.db}
catch {file delete -force test.db-journal}
execsql {
BEGIN;
CREATE TABLE t1(x);
- INSERT INTO t1 VALUES(randstr(10,100));
- INSERT INTO t1 VALUES(randstr(10,100));
- INSERT INTO t1 VALUES(randstr(10,100));
- INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
- INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
- INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
- INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
- INSERT INTO t1 VALUES(randstr(2100,3000));
- INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
- INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
- INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
- INSERT INTO t1 SELECT x || randstr(5,10) FROM t1;
+ INSERT INTO t1 VALUES(randstr(100,100));
+ INSERT INTO t1 VALUES(randstr(90,90));
+ INSERT INTO t1 VALUES(randstr(80,80));
+ INSERT INTO t1 SELECT x || randstr(5,5) FROM t1;
+ INSERT INTO t1 SELECT x || randstr(6,6) FROM t1;
+ INSERT INTO t1 SELECT x || randstr(7,7) FROM t1;
+ INSERT INTO t1 SELECT x || randstr(8,8) FROM t1;
+ INSERT INTO t1 VALUES(randstr(3000,3000));
+ INSERT INTO t1 SELECT x || randstr(9,9) FROM t1;
+ INSERT INTO t1 SELECT x || randstr(10,10) FROM t1;
+ INSERT INTO t1 SELECT x || randstr(11,11) FROM t1;
+ INSERT INTO t1 SELECT x || randstr(12,12) FROM t1;
CREATE INDEX t1i1 ON t1(x);
CREATE TABLE t2 AS SELECT * FROM t1;
DELETE FROM t2 WHERE rowid%5!=0;