-C file\sformat\schange\s(CVS\s121)
-D 2000-08-02T12:37:18
+C file\sformat\schange\s(CVS\s122)
+D 2000-08-02T13:47:42
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
F Makefile.in 670aa9413cb2cdcded23b328a9e255c845c41a1e
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
F configure 51063d594190fa085f909cefc9427241088bec4f x
F configure.in a04f02ba61ed09a00e862b4f78b91b06a559e0b5
F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47
-F src/build.c ecb8ec724914780efed01d1739e6dd398d75af46
+F src/build.c afdbf21315526902577ebeb690737a27ab73c2a1
F src/dbbe.c 5c69d68fe8d9461e56d066f9a7f693636c02d0c7
F src/dbbe.h 8718b718b36d37584e9bbdfccec10588fa91271f
F src/delete.c 4d491eaf61b515516749c7ed68fa3b2ee8a09065
F src/expr.c 2fa63f086707176d09092e71832f9bbdc6a8ac85
F src/insert.c f146f149ad2422a1dc3bfa7a1651a25940f98958
-F src/main.c c4b6678af8326cc602f61de51d451697451fd177
+F src/main.c ba16b81890d962821bb90f0a4de9a29b0e495eb2
F src/parse.y 5d199034de5d29ebedb42c1c51f34db4df40cbe5
F src/select.c d382e96c2221d08367cc87976f2b574537c9de97
-F src/shell.c a5eb8ee9d5f90e735900a92e7fc364a54deb2cfb
+F src/shell.c 2fd370838742afa068cfcdd05b667ff89bab25b6
F src/sqlite.h 82ae53028e27919250f886ff9d7c4927de81978a
-F src/sqliteInt.h cbb973ffcbbefdfb59438fa5c1df0be768cc490c
+F src/sqliteInt.h f6d1e139b3bfa4ceff2136684e19d76b53178ec0
F src/tclsqlite.c 9f358618ae803bedf4fb96da5154fd45023bc1f7
F src/tokenize.c 77ff8164a8751994bc9926ce282847f653ac0c16
F src/update.c 51b9ef7434b15e31096155da920302e9db0d27fc
F test/delete.test 402ee3ccb6e544582d24c573ef70b34d09583ae7
F test/expr.test 09b55ccf81cb8cc2f9cd83d592a2ba187ee48ba8
F test/in.test 2c560c0f55fb777029fd9bb5378f2997582aa603
-F test/index.test e5f4e7ad41e1709ef4426a3a4ce1bafe1afe1ee4
+F test/index.test 950be6116122c6e2db7c2c345eabcdb854ced1d0
F test/insert.test 66f4c3bd600fec8eb1e733b928cbe6fa885eff0c
F test/insert2.test 732405e30331635af8d159fccabe835eea5cd0c6
F test/lock.test 42a2d171eba1078cf3fd58ab64241eb8f1b08d69
F test/select5.test e2b9d51d88cbd6c307c2c05b0ef55fe7ba811ac2
F test/sort.test d582086c4bb7df3fbf50aa72e69d7e235e9f8e31
F test/subselect.test bf8b251a92fb091973c1c469ce499dc9648a41d5
-F test/table.test d3e01e4916a99ade7d8f1d534ee1b36d57c00490
+F test/table.test 620cd72a6c29da3b9153d15c9e94abbbb282373b
F test/tester.tcl 95b286791e6256bb6db0165f9342c70fff549a62
F test/update.test 62f6ce99ff31756aab0ca832ff6d34c5a87b6250
F test/vacuum.test 8becf5cfeb897108b35cdd996793e7f1df2f28fd
F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
F www/sqlite.tcl 69781eaffb02e17aa4af28b76a2bedb19baa8e9f
F www/vdbe.tcl bcbfc33bcdd0ebad95eab31286adb9e1bc289520
-P 67f8af377c8a92ac155f55afc75e9957bec4e787
-R 123e192ab64d207d4ac341998bf97433
+P 4110936f112092b3bbc134f0717b899aad6502ad
+R 27068e8e66b0ad6baca5a9255d7bc1a0
U drh
-Z 1c32c9d74ea685fb114555df3a32fc58
+Z b61a3a088aa89de6d6b88a94a54cc74a
-4110936f112092b3bbc134f0717b899aad6502ad
\ No newline at end of file
+b7b90237945d3577caba3a2f5595e52b25027297
\ No newline at end of file
** COPY
** VACUUM
**
-** $Id: build.c,v 1.21 2000/07/29 13:06:59 drh Exp $
+** $Id: build.c,v 1.22 2000/08/02 13:47:42 drh Exp $
*/
#include "sqliteInt.h"
void sqliteEndTable(Parse *pParse, Token *pEnd){
Table *p;
int h;
+ int addVersion; /* True to insert a "file format" meta record */
if( pParse->nErr ) return;
+ p = pParse->pNewTable;
+ addVersion = p!=0 && pParse->db->nTable==1;
/* Add the table to the in-memory representation of the database
*/
- if( (p = pParse->pNewTable)!=0 && pParse->explain==0 ){
+ if( p!=0 && pParse->explain==0 ){
h = sqliteHashNoCase(p->zName, 0) % N_HASH;
p->pHash = pParse->db->apTblHash[h];
pParse->db->apTblHash[h] = p;
pParse->pNewTable = 0;
+ pParse->db->nTable++;
}
/* If not initializing, then create the table on disk.
{ OP_String, 0, 0, 0}, /* 5 */
{ OP_MakeRecord, 4, 0, 0},
{ OP_Put, 0, 0, 0},
- { OP_Close, 0, 0, 0},
+ };
+ static VdbeOp addVersion[] = {
+ { OP_New, 0, 0, 0},
+ { OP_String, 0, 0, "meta" },
+ { OP_String, 0, 0, "" },
+ { OP_String, 0, 0, "" },
+ { OP_String, 0, 0, "file format 2" },
+ { OP_MakeRecord, 4, 0, 0},
+ { OP_Put, 0, 0, 0},
};
int n, base;
Vdbe *v;
sqliteVdbeChangeP3(v, base+3, p->zName, 0);
sqliteVdbeChangeP3(v, base+4, p->zName, 0);
sqliteVdbeChangeP3(v, base+5, pParse->sFirstToken.z, n);
+ if( addVersion ){
+ sqliteVdbeAddOpList(v, ArraySize(addVersion), addVersion);
+ }
+ sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0);
}
}
p->pHash = pTable->pHash;
}
}
+ pParse->db->nTable--;
sqliteDeleteTable(pParse->db, pTable);
}
}
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.15 2000/07/31 13:38:26 drh Exp $
+** $Id: main.c,v 1.16 2000/08/02 13:47:42 drh Exp $
*/
#include "sqliteInt.h"
** database. Each callback contains text of a CREATE TABLE or
** CREATE INDEX statement that must be parsed to yield the internal
** structures that describe the tables.
+**
+** This callback is also called with argc==2 when there is meta
+** information in the sqlite_master file. The meta information is
+** contained in argv[1]. Typical meta information is the file format
+** version.
*/
static int sqliteOpenCb(void *pDb, int argc, char **argv, char **azColName){
sqlite *db = (sqlite*)pDb;
Parse sParse;
int nErr;
+ if( argc==2 ){
+ if( sscanf(argv[1],"file format %d",&db->file_format)==1 ){
+ return 0;
+ }
+ /* Unknown meta information. Ignore it. */
+ return 0;
+ }
if( argc!=1 ) return 0;
memset(&sParse, 0, sizeof(sParse));
sParse.db = db;
** defined as follows:
**
** CREATE TABLE sqlite_master (
- ** type text, -- Either "table" or "index"
+ ** type text, -- Either "table" or "index" or "meta"
** name text, -- Name of table or index
** tbl_name text, -- Associated table
** sql text -- The CREATE statement for this object
** the CREATE TABLE or CREATE INDEX statement that originally created
** the table or index.
**
+ ** If the "type" column has the value "meta", then the "sql" column
+ ** contains extra information about the database, such as the
+ ** file format version number. All meta information must be processed
+ ** before any tables or indices are constructed.
+ **
** The following program invokes its callback on the SQL for each
** table then goes back and invokes the callback on the
** SQL for each index. The callback will invoke the
*/
static VdbeOp initProg[] = {
{ OP_Open, 0, 0, MASTER_NAME},
- { OP_Next, 0, 8, 0}, /* 1 */
+ { OP_Next, 0, 9, 0}, /* 1 */
{ OP_Field, 0, 0, 0},
- { OP_String, 0, 0, "table"},
+ { OP_String, 0, 0, "meta"},
{ OP_Ne, 0, 1, 0},
+ { OP_Field, 0, 0, 0},
{ OP_Field, 0, 3, 0},
- { OP_Callback, 1, 0, 0},
+ { OP_Callback, 2, 0, 0},
{ OP_Goto, 0, 1, 0},
- { OP_Rewind, 0, 0, 0}, /* 8 */
- { OP_Next, 0, 16, 0}, /* 9 */
+ { OP_Rewind, 0, 0, 0}, /* 9 */
+ { OP_Next, 0, 17, 0}, /* 10 */
+ { OP_Field, 0, 0, 0},
+ { OP_String, 0, 0, "table"},
+ { OP_Ne, 0, 10, 0},
+ { OP_Field, 0, 3, 0},
+ { OP_Callback, 1, 0, 0},
+ { OP_Goto, 0, 10, 0},
+ { OP_Rewind, 0, 0, 0}, /* 17 */
+ { OP_Next, 0, 25, 0}, /* 18 */
{ OP_Field, 0, 0, 0},
{ OP_String, 0, 0, "index"},
- { OP_Ne, 0, 9, 0},
+ { OP_Ne, 0, 18, 0},
{ OP_Field, 0, 3, 0},
{ OP_Callback, 1, 0, 0},
- { OP_Goto, 0, 9, 0},
- { OP_Halt, 0, 0, 0}, /* 16 */
+ { OP_Goto, 0, 18, 0},
+ { OP_Halt, 0, 0, 0}, /* 25 */
};
/* Create a virtual machine to run the initialization program. Run
rc = sqliteVdbeExec(vdbe, sqliteOpenCb, db, pzErrMsg,
db->pBusyArg, db->xBusyCallback);
sqliteVdbeDelete(vdbe);
+ if( rc==SQLITE_OK && db->file_format<2 && db->nTable>0 ){
+ sqliteSetString(pzErrMsg, "obsolete file format", 0);
+ rc = SQLITE_ERROR;
+ }
if( rc==SQLITE_OK ){
Table *pTab;
char *azArg[2];
return 0;
}
+ /* Assume file format 1 unless the database says otherwise */
+ db->file_format = 1;
+
/* Attempt to read the schema */
rc = sqliteInit(db, pzErrMsg);
if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
-** $Id: shell.c,v 1.18 2000/07/31 11:57:37 drh Exp $
+** $Id: shell.c,v 1.19 2000/08/02 13:47:42 drh Exp $
*/
#include <stdlib.h>
#include <string.h>
char zSql[1000];
if( nArg==1 ){
sprintf(zSql, "SELECT name, type, sql FROM sqlite_master "
+ "WHERE type!='meta' "
"ORDER BY tbl_name, type DESC, name");
sqlite_exec(db, zSql, dump_callback, p, &zErrMsg);
}else{
int i;
for(i=1; i<nArg && zErrMsg==0; i++){
sprintf(zSql, "SELECT name, type, sql FROM sqlite_master "
- "WHERE tbl_name LIKE '%.800s'"
+ "WHERE tbl_name LIKE '%.800s' AND type!='meta' "
"ORDER BY type DESC, name", azArg[i]);
sqlite_exec(db, zSql, dump_callback, p, &zErrMsg);
data.mode = MODE_List;
if( nArg>1 ){
sprintf(zSql, "SELECT sql FROM sqlite_master "
- "WHERE tbl_name LIKE '%.800s'"
+ "WHERE tbl_name LIKE '%.800s' AND type!='meta'"
"ORDER BY type DESC, name",
azArg[1]);
}else{
sprintf(zSql, "SELECT sql FROM sqlite_master "
+ "WHERE type!='meta' "
"ORDER BY tbl_name, type DESC, name");
}
sqlite_exec(db, zSql, callback, &data, &zErrMsg);
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.28 2000/08/02 12:26:29 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.29 2000/08/02 13:47:42 drh Exp $
*/
#include "sqlite.h"
#include "dbbe.h"
struct sqlite {
Dbbe *pBe; /* The backend driver */
int flags; /* Miscellanous flags */
+ int file_format; /* What file format version is this database? */
+ int nTable; /* Number of tables in the database */
void *pBusyArg; /* 1st Argument to the busy callback */
int (*xBusyCallback)(void *,const char*,int); /* The busy callback */
Table *apTblHash[N_HASH]; /* All tables of the database */
#define SQLITE_VdbeTrace 0x00000001
#define SQLITE_Initialized 0x00000002
+/*
+** Current file format version
+*/
+#define SQLITE_FileFormat 2
+
/*
** information about each column of an SQL table is held in an instance
** of this structure.
# This file implements regression tests for SQLite library. The
# focus of this file is testing the CREATE INDEX statement.
#
-# $Id: index.test,v 1.6 2000/08/02 12:26:30 drh Exp $
+# $Id: index.test,v 1.7 2000/08/02 13:47:42 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_test index-1.1 {
execsql {CREATE TABLE test1(f1 int, f2 int, f3 int)}
execsql {CREATE INDEX index1 ON test1(f1)}
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {index1 test1}
do_test index-1.1b {
execsql {SELECT name, sql, tbl_name, type FROM sqlite_master
do_test index-1.1d {
db close
sqlite db testdb
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {index1 test1}
# Verify that the index dies with the table
#
do_test index-1.2 {
execsql {DROP TABLE test1}
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {}
# Try adding an index to a table that does not exist
}
execsql {CREATE INDEX index9 ON test1(cnt)}
execsql {CREATE INDEX indext ON test1(power)}
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {index9 indext test1}
do_test index-4.2 {
execsql {SELECT cnt FROM test1 WHERE power=4}
} {10}
do_test index-4.13 {
execsql {DROP TABLE test1}
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {}
# Do not allow indices to be added to sqlite_master
lappend v $msg
} {1 {table sqlite_master may not have new indices added}}
do_test index-5.2 {
- execsql {SELECT name FROM sqlite_master}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {}
# Do not allow indices with duplicate names to be added
lappend v $msg
} {1 {index index1 already exists}}
do_test index-6.1b {
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {index1 test1 test2}
do_test index-6.2 {
set v [catch {execsql {CREATE INDEX test1 ON test2(g1)}} msg]
lappend v $msg
} {1 {there is already a table named test1}}
do_test index-6.2b {
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {index1 test1 test2}
do_test index-6.3 {
execsql {DROP TABLE test1}
execsql {DROP TABLE test2}
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {}
# Create a primary key
} {1}
do_test index-7.4 {
execsql {DROP table test1}
- execsql {SELECT name FROM sqlite_master}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {}
# Make sure we cannot drop a non-existant index.
# This file implements regression tests for SQLite library. The
# focus of this file is testing the CREATE TABLE statement.
#
-# $Id: table.test,v 1.5 2000/06/08 15:10:48 drh Exp $
+# $Id: table.test,v 1.6 2000/08/02 13:47:43 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
)
}
execsql {
- SELECT sql FROM sqlite_master
+ SELECT sql FROM sqlite_master WHERE type!='meta'
}
} {{CREATE TABLE test1 (
one varchar(10),
# Verify the other fields of the sqlite_master file.
#
do_test table-1.3 {
- execsql {SELECT name, tbl_name, type FROM sqlite_master}
+ execsql {SELECT name, tbl_name, type FROM sqlite_master WHERE type!='meta'}
} {test1 test1 table}
# Close and reopen the database. Verify that everything is
do_test table-1.4 {
db close
sqlite db testdb
- execsql {SELECT name, tbl_name, type from sqlite_master}
+ execsql {SELECT name, tbl_name, type from sqlite_master WHERE type!='meta'}
} {test1 test1 table}
# Drop the database and make sure it disappears.
#
do_test table-1.5 {
execsql {DROP TABLE test1}
- execsql {SELECT * FROM sqlite_master}
+ execsql {SELECT * FROM sqlite_master WHERE type!='meta'}
} {}
# Verify that the file associated with the database is gone.
do_test table-1.6 {
db close
sqlite db testdb
- execsql {SELECT name FROM sqlite_master}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {}
# Repeat the above steps, but this time quote the table name.
#
do_test table-1.10 {
execsql {CREATE TABLE "create" (f1 int)}
- execsql {SELECT name FROM sqlite_master}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {create}
do_test table-1.11 {
execsql {DROP TABLE "create"}
- execsql {SELECT name FROM "sqlite_master"}
+ execsql {SELECT name FROM "sqlite_master" WHERE type!='meta'}
} {}
do_test table-1.12 {
execsql {CREATE TABLE test1("f1 ho" int)}
- execsql {SELECT name as "X" FROM sqlite_master}
+ execsql {SELECT name as "X" FROM sqlite_master WHERE type!='meta'}
} {test1}
do_test table-1.13 {
execsql {DROP TABLE "TEST1"}
- execsql {SELECT name FROM "sqlite_master"}
+ execsql {SELECT name FROM "sqlite_master" WHERE type!='meta'}
} {}
lappend v $msg
} {1 {table sqlite_master already exists}}
do_test table-2.1d {
- execsql {DROP TABLE test2; SELECT name FROM sqlite_master}
+ execsql {DROP TABLE test2; SELECT name FROM sqlite_master WHERE type!='meta'}
} {}
# Verify that we cannot make a table with the same name as an index
lappend v $msg
} {0 {}}
do_test table-2.2d {
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {test2 test3}
do_test table-2.2e {
execsql {DROP TABLE test2; DROP TABLE test3}
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {}
# Create a table with many field names
)}
do_test table-3.1 {
execsql $big_table
- execsql {SELECT sql FROM sqlite_master}
+ execsql {SELECT sql FROM sqlite_master WHERE type!='meta'}
} \{$big_table\}
do_test table-3.2 {
set v [catch {execsql {CREATE TABLE BIG(xyz foo)}} msg]
} {1 {table Big already exists}}
do_test table-3.6 {
execsql {DROP TABLE big}
- execsql {SELECT name FROM sqlite_master}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {}
# Try creating large numbers of tables
append sql "last_field text)"
execsql $sql
}
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} $r
do_test table-4.1b {
db close
sqlite db testdb
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} $r
# Drop the even number tables
set sql "DROP TABLE TEST$i"
execsql $sql
}
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} $r
# Drop the odd number tables
set sql "DROP TABLE test$i"
execsql $sql
}
- execsql {SELECT name FROM sqlite_master ORDER BY name}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {}
# Try to drop a table that does not exist
#
do_test table-5.3 {
execsql {EXPLAIN CREATE TABLE test1(f1 int)}
- execsql {SELECT name FROM sqlite_master}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {}
# Make sure an EXPLAIN does not really drop an existing table
do_test table-5.4 {
execsql {CREATE TABLE test1(f1 int)}
execsql {EXPLAIN DROP TABLE test1}
- execsql {SELECT name FROM sqlite_master}
+ execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {test1}
# Create a table with a goofy name