diff --git a/manifest b/manifest index a19528f384..572b46b673 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C :-)\s(CVS\s6) -D 2000-05-29T20:41:50 +C :-)\s(CVS\s7) +D 2000-05-29T23:30:51 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4 F Makefile.in f5e807375d080405b757239762db8f3b4124e08a F README 0200f7787a68917ac55c07b97e3c3a982bccd0bc F configure 00a5b5c82147a576fa6e82d7c1b0d55c321d6d2c x F configure.in 6ccfd5fc80517f7cfe605a7fc7e0f62d962a233c F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47 -F src/build.c 45dc91016e13dec70620b049a53ba785b4a0c76b +F src/build.c 56fd0763b19fa5aa3bdeb4acb4566b17305428a8 F src/dbbe.c ab05293e89525041eaab8b4aca10516db3648792 F src/dbbe.h bedeb3a0985bb584458e7849fb59927e99e751e6 F src/main.c 25cce7bce0eb3ba10bada7c05f4b38dc6dbbc86f @@ -16,11 +16,12 @@ F src/sqlite.h 2397c17a8f4ca90c09acab0100dc7e2f8f441b69 F src/sqliteInt.h 0365970442441b5e9b74e1e828afdeac7b0662be F src/tclsqlite.c 30f4317e1fc9119b130f29ee5dac4ab9121de68b F src/tokenize.c ab578d90ec6ab117b7ade6e6cfbcb5b0f9cad500 -F src/util.c b2e2a4dc55f7cbd41a7d9e0a8473eedd3b2691c8 +F src/util.c 171dc6334fde23ccdf6e058d98c23eaa88445944 F src/vdbe.c 80132b6bb9a744d1990a1c16666d54baaff2dbc3 F src/vdbe.h e721ad308f2e6ca805cebc4dd0a196ce4419d030 F src/where.c 67ffea57920e16b33c580e9a9b9855b3ec9dea7b -F test/crttbl.test 49a73b927ad85bf8edae7e5311fde34bf5b2c1fb +F test/crtidx.test 56de1628220deafe33037c40369229eb02c1907d +F test/crttbl.test 45889cb39e3c3de9e10d79057f424a38ecebe93f F test/tester.tcl 31a9077926a5eb54dcae11b2c92abc1263dd675c F tool/gdbmdump.c 529e67c78d920606ba196326ea55b57b75fcc82b F tool/lemon.c cff35578b3c4d1491021b6418016639ebe21b1a5 @@ -31,7 +32,7 @@ F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9 F www/c_interface.tcl f875864edf7974157d1c257ca08de854660882a5 F www/index.tcl 67b2bee04077377eacede2b11e21fe37ef7e10c6 F www/sqlite.tcl 947e067bcc347dc767af4c1a6e5a8d47d8404aa3 -P 9fd0628af897c54c122fdef02f79788385ece39c -R b39dfec9006cd0b187aa3d6ee1e9799f +P 1517f85243b63511c2ceb73a10453c5ae56d3428 +R 57cc33953bef9654e813c3a2624d0bb4 U drh -Z ad70bffed13ea99cad14d2118369d246 +Z b4846e605fc44b608a9e06c083145b56 diff --git a/manifest.uuid b/manifest.uuid index e2c8ab7a08..8f309adba2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1517f85243b63511c2ceb73a10453c5ae56d3428 \ No newline at end of file +fdf4b31a18fcbbcd358bf92c91fccbf94a79bc26 \ No newline at end of file diff --git a/src/build.c b/src/build.c index ad0fec58c5..aadc3326b9 100644 --- a/src/build.c +++ b/src/build.c @@ -24,7 +24,7 @@ ** This file contains C code routines that are called by the parser ** when syntax rules are reduced. ** -** $Id: build.c,v 1.2 2000/05/29 17:44:25 drh Exp $ +** $Id: build.c,v 1.3 2000/05/29 23:30:51 drh Exp $ */ #include "sqliteInt.h" @@ -243,7 +243,7 @@ void sqliteAddColumn(Parse *pParse, Token *pName){ char **pz; if( (p = pParse->pNewTable)==0 ) return; if( (p->nCol & 0x7)==0 ){ - p->azCol = sqliteRealloc( p->azCol, (p->nCol+8)*sizeof(p->azCol[0])); + p->azCol = sqliteRealloc( p->azCol, (p->nCol+9)*sizeof(p->azCol[0])); } if( p->azCol==0 ){ p->nCol = 0; @@ -319,8 +319,8 @@ static Table *sqliteTableFromToken(Parse *pParse, Token *pTok){ Table *pTab = sqliteFindTable(pParse->db, zName); sqliteFree(zName); if( pTab==0 ){ - sqliteSetNString(&pParse->zErrMsg, "no such table: \"", 0, - pTok->z, pTok->n, "\"", 1, 0); + sqliteSetNString(&pParse->zErrMsg, "no such table: ", 0, + pTok->z, pTok->n, 0); pParse->nErr++; } return pTab; @@ -430,8 +430,8 @@ void sqliteCreateIndex( } if( pTab==0 || pParse->nErr ) goto exit_create_index; if( pTab->readOnly ){ - sqliteSetString(&pParse->zErrMsg, "table \"", pTab->zName, - "\" may not have new indices added", 0); + sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, + " may not have new indices added", 0); pParse->nErr++; goto exit_create_index; } @@ -495,8 +495,8 @@ void sqliteCreateIndex( if( sqliteStrICmp(pList->a[i].zName, pTab->azCol[j])==0 ) break; } if( j>=pTab->nCol ){ - sqliteSetString(&pParse->zErrMsg, "table being indexed has no field " - "named \"", pList->a[i].zName, "\"", 0); + sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, + " has no field named ", pList->a[i].zName, 0); pParse->nErr++; sqliteFree(pIndex); goto exit_create_index; @@ -530,9 +530,9 @@ void sqliteCreateIndex( { OP_Open, 0, 0, MASTER_NAME}, { OP_New, 0, 0, 0}, { OP_String, 0, 0, "index"}, - { OP_String, 0, 0, 0}, /* 2 */ { OP_String, 0, 0, 0}, /* 3 */ { OP_String, 0, 0, 0}, /* 4 */ + { OP_String, 0, 0, 0}, /* 5 */ { OP_MakeRecord, 4, 0, 0}, { OP_Put, 0, 0, 0}, { OP_Close, 0, 0, 0}, @@ -550,9 +550,9 @@ void sqliteCreateIndex( int base; n = (int)pEnd->z - (int)pStart->z + 1; base = sqliteVdbeAddOpList(v, ArraySize(addTable), addTable); - sqliteVdbeChangeP3(v, base+2, pIndex->zName, 0); - sqliteVdbeChangeP3(v, base+3, pTab->zName, 0); - sqliteVdbeChangeP3(v, base+4, pStart->z, n); + sqliteVdbeChangeP3(v, base+3, pIndex->zName, 0); + sqliteVdbeChangeP3(v, base+4, pTab->zName, 0); + sqliteVdbeChangeP3(v, base+5, pStart->z, n); } sqliteVdbeAddOp(v, OP_Open, 0, 0, pTab->zName, 0); sqliteVdbeAddOp(v, OP_Open, 1, 0, pIndex->zName, 0); diff --git a/src/util.c b/src/util.c index 78fadd2fea..a621080da4 100644 --- a/src/util.c +++ b/src/util.c @@ -26,7 +26,7 @@ ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.2 2000/05/29 17:44:25 drh Exp $ +** $Id: util.c,v 1.3 2000/05/29 23:30:51 drh Exp $ */ #include "sqliteInt.h" #include @@ -67,6 +67,7 @@ void *sqliteRealloc(void *p, int n){ sqliteFree(p); return 0; } + /* printf("realloc 0x%x size: %d bytes\n", (int)p, n); */ return realloc(p, n); } diff --git a/test/crtidx.test b/test/crtidx.test new file mode 100644 index 0000000000..1da3cf1fd6 --- /dev/null +++ b/test/crtidx.test @@ -0,0 +1,204 @@ +# Copyright (c) 1999, 2000 D. Richard Hipp +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +# +# Author contact information: +# drh@hwaci.com +# http://www.hwaci.com/drh/ +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing the CREATE INDEX statement. +# +# $Id: crtidx.test,v 1.1 2000/05/29 23:30:51 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Create a basic index and verify it is added to sqlite_master +# +do_test crtidx-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} +} {index1 test1} +do_test crtidx-1.1b { + execsql {SELECT name, sql, tbl_name, type FROM sqlite_master + WHERE name='index1'} +} {index1 {CREATE INDEX index1 ON test1(f1)} test1 index} +do_test crtidx-1.1c { + db close + sqlite db testdb + execsql {SELECT name, sql, tbl_name, type FROM sqlite_master + WHERE name='index1'} +} {index1 {CREATE INDEX index1 ON test1(f1)} test1 index} +do_test crtidx-1.1d { + db close + sqlite db testdb + execsql {SELECT name FROM sqlite_master ORDER BY name} +} {index1 test1} + +# Verify that the index dies with the table +# +do_test crtidx-1.2 { + execsql {DROP TABLE test1} + execsql {SELECT name FROM sqlite_master ORDER BY name} +} {} + +# Try adding an index to a table that does not exist +# +do_test crtidx-2.1 { + set v [catch {execsql {CREATE INDEX index1 ON test1(f1)}} msg] + lappend v $msg +} {1 {no such table: test1}} + +# Try adding an index on a field of a table where the table +# exists but the field does not. +# +do_test crtidx-2.1 { + execsql {CREATE TABLE test1(f1 int, f2 int, f3 int)} + set v [catch {execsql {CREATE INDEX index1 ON test1(f4)}} msg] + lappend v $msg +} {1 {table test1 has no field named f4}} + +# Try an index with some fields that match and others that do now. +# +do_test crtidx-2.2 { + set v [catch {execsql {CREATE INDEX index1 ON test1(f1, f2, f4, f3)}} msg] + execsql {DROP TABLE test1} + lappend v $msg +} {1 {table test1 has no field named f4}} + +# Try creating a bunch of indices on the same table +# +set r {} +for {set i 1} {$i<100} {incr i} { + lappend r index$i +} +do_test crtidx-3.1 { + execsql {CREATE TABLE test1(f1 int, f2 int, f3 int, f4 int, f5 int)} + for {set i 1} {$i<100} {incr i} { + set sql "CREATE INDEX index$i ON test1(f[expr {($i%5)+1}])" + execsql $sql + } + execsql {SELECT name FROM sqlite_master + WHERE type='index' AND tbl_name='test1' + ORDER BY name} +} $r + +# Add a single entry to the table. Verify that files are created +# for every index. +# +set r {} +for {set i 1} {$i<100} {incr i} { + lappend r testdb/index$i.tbl +} +do_test crtidx-3.2 { + execsql {INSERT INTO test1 VALUES(1,2,3,4,5)} + lsort -dictionary [glob testdb/index*.tbl] +} $r + +# Verify that all the indices go away when we drop the table. +# +do_test crtidx-3.3 { + execsql {DROP TABLE test1} + execsql {SELECT name FROM sqlite_master + WHERE type='index' AND tbl_name='test1' + ORDER BY name} +} {} +do_test crtidx-3.4 { + lsort -dictionary [glob -nocomplain testdb/index*.tbl] +} {} + +# Create a table and insert values into that table. Then create +# an index on that table. Verify that we can select values +# from the table correctly using the index. +# +do_test crtidx-4.1 { + execsql {CREATE TABLE test1(cnt int, power int)} + for {set i 1} {$i<20} {incr i} { + execsql "INSERT INTO test1 VALUES($i,[expr {int(pow(2,$i))}])" + } + execsql {CREATE INDEX index1 ON test1(cnt)} + execsql {CREATE INDEX index2 ON test1(cnt)} + execsql {SELECT name FROM sqlite_master ORDER BY name} +} {index1 index2 test1} +do_test crtidx-4.2 { + execsql {SELECT cnt FROM test1 WHERE power=4} +} {2} +do_test crtidx-4.3 { + execsql {SELECT cnt FROM test1 WHERE power=1024} +} {10} +do_test crtidx-4.4 { + execsql {SELECT power FROM test1 WHERE cnt=6} +} {64} +do_test crtidx-4.5 { + execsql {DROP TABLE test1} +} {} + +# Do not allow indices to be added to sqlite_master +# +do_test crtidx-5.1 { + set v [catch {execsql {CREATE INDEX index1 ON sqlite_master(name)}} msg] + lappend v $msg +} {1 {table sqlite_master may not have new indices added}} +do_test crtidx-5.2 { + execsql {SELECT name FROM sqlite_master} +} {} + +# Do not allow indices with duplicate names to be added +# +do_test crtidx-6.1 { + execsql {CREATE TABLE test1(f1 int, f2 int)} + execsql {CREATE TABLE test2(g1 real, g2 real)} + execsql {CREATE INDEX index1 ON test1(f1)} + set v [catch {execsql {CREATE INDEX index1 ON test2(g1)}} msg] + lappend v $msg +} {1 {index "index1" already exists}} +do_test crtidx-6.1b { + execsql {SELECT name FROM sqlite_master ORDER BY name} +} {index1 test1 test2} +do_test crtidx-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 crtidx-6.2b { + execsql {SELECT name FROM sqlite_master ORDER BY name} +} {index1 test1 test2} +do_test crtidx-6.3 { + execsql {DROP TABLE test1} + execsql {DROP TABLE test2} + execsql {SELECT name FROM sqlite_master ORDER BY name} +} {} + +# Create a primary key +# +do_test crtidx-7.1 { + execsql {CREATE TABLE test1(f1 int, f2 int primary key)} + for {set i 1} {$i<20} {incr i} { + execsql "INSERT INTO test1 VALUES($i,[expr {int(pow(2,$i))}])" + } + lsort -dictionary [glob testdb/test1*.tbl] +} {testdb/test1.tbl testdb/test1__primary_key.tbl} +do_test crtidx-7.2 { + execsql {SELECT f1 FROM test1 WHERE f2=65536} +} {16} +do_test crtidx-7.3 { + set code [execsql {EXPLAIN SELECT f1 FROM test1 WHERE f2=65536}] + expr {[lsearch $code test1__primary_key]>0} +} {1} + +finish_test diff --git a/test/crttbl.test b/test/crttbl.test index 93f1eb4c28..7c70056185 100644 --- a/test/crttbl.test +++ b/test/crttbl.test @@ -23,7 +23,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the CREATE TABLE statement. # -# $Id: crttbl.test,v 1.1 2000/05/29 20:41:51 drh Exp $ +# $Id: crttbl.test,v 1.2 2000/05/29 23:30:51 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -89,4 +89,151 @@ do_test crttbl-1.6 { execsql {SELECT name FROM sqlite_master} } {} + +# Verify that we cannot make two tables with the same name +# +do_test crttbl-2.1 { + execsql {CREATE TABLE test2(one text)} + set v [catch {execsql {CREATE TABLE test2(two text)}} msg] + lappend v $msg +} {1 {table "test2" already exists}} +do_test crttbl-2.1b { + set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg] + lappend v $msg +} {1 {table "sqlite_master" already exists}} +do_test crttbl-2.1c { + db close + sqlite db testdb + set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg] + lappend v $msg +} {1 {table "sqlite_master" already exists}} +do_test crttbl-2.1d { + execsql {DROP TABLE test2; SELECT name FROM sqlite_master} +} {} + +# Verify that we cannot make a table with the same name as an index +# +do_test crttbl-2.2 { + execsql {CREATE TABLE test2(one text); CREATE INDEX test3 ON test2(one)} + set v [catch {execsql {CREATE TABLE test3(two text)}} msg] + lappend v $msg +} {1 {there is already an index named "test3"}} +do_test crttbl-2.2b { + db close + sqlite db testdb + set v [catch {execsql {CREATE TABLE test3(two text)}} msg] + lappend v $msg +} {1 {there is already an index named "test3"}} +do_test crttbl-2.2c { + execsql {DROP INDEX test3} + set v [catch {execsql {CREATE TABLE test3(two text)}} msg] + lappend v $msg +} {0 {}} +do_test crttbl-2.2d { + execsql {SELECT name FROM sqlite_master ORDER BY name} +} {test2 test3} +do_test crttbl-2.2e { + execsql {DROP TABLE test2; DROP TABLE test3} + execsql {SELECT name FROM sqlite_master ORDER BY name} +} {} + +# Create a table with many field names +# +set big_table \ +{CREATE TABLE big( + f1 varchar(20), + f2 char(10), + f3 varchar(30), + f4 text, + f5 text, + f6 text, + f7 text, + f8 text, + f9 text, + f10 text, + f11 text, + f12 text, + f13 text, + f14 text, + f15 text, + f16 text, + f17 text, + f18 text, + f19 text, + f20 text +)} +do_test crttbl-3.1 { + execsql $big_table + execsql {SELECT sql FROM sqlite_master} +} \{$big_table\} +do_test crttbl-3.2 { + set v [catch {execsql {CREATE TABLE BIG(xyz foo)}} msg] + lappend v $msg +} {1 {table "BIG" already exists}} +do_test crttbl-3.3 { + set v [catch {execsql {CREATE TABLE biG(xyz foo)}} msg] + lappend v $msg +} {1 {table "biG" already exists}} +do_test crttbl-3.4 { + set v [catch {execsql {CREATE TABLE bIg(xyz foo)}} msg] + lappend v $msg +} {1 {table "bIg" already exists}} +do_test crttbl-3.5 { + db close + sqlite db testdb + set v [catch {execsql {CREATE TABLE Big(xyz foo)}} msg] + lappend v $msg +} {1 {table "Big" already exists}} +do_test crttbl-3.6 { + execsql {DROP TABLE big} + execsql {SELECT name FROM sqlite_master} +} {} + +# Try creating large numbers of tables +# +set r {} +for {set i 1} {$i<=100} {incr i} { + lappend r test$i +} +do_test crttbl-4.1 { + for {set i 1} {$i<=100} {incr i} { + set sql "CREATE TABLE test$i (" + for {set k 1} {$k<$i} {incr k} { + append sql "field$k text," + } + append sql "last_field text)" + execsql $sql + } + execsql {SELECT name FROM sqlite_master ORDER BY name} +} $r +do_test crttbl-4.1b { + db close + sqlite db testdb + execsql {SELECT name FROM sqlite_master ORDER BY name} +} $r + +# Drop the even number tables +# +set r {} +for {set i 1} {$i<=100} {incr i 2} { + lappend r test$i +} +do_test crttbl-4.2 { + for {set i 2} {$i<=100} {incr i 2} { + set sql "DROP TABLE TEST$i" + execsql $sql + } + execsql {SELECT name FROM sqlite_master ORDER BY name} +} $r + +# Drop the odd number tables +# +do_test crttbl-4.3 { + for {set i 1} {$i<=100} {incr i 2} { + set sql "DROP TABLE test$i" + execsql $sql + } + execsql {SELECT name FROM sqlite_master ORDER BY name} +} {} + finish_test