From 7020f6516cdf9789de324f4eb2eeb5f3bb0ec042 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 3 Jun 2000 18:06:52 +0000 Subject: [PATCH] added default values (CVS 46) FossilOrigin-Name: 27c0678623de37f3166cb9952989fd03484cdb8d --- manifest | 33 ++++++++++---------- manifest.uuid | 2 +- src/build.c | 41 +++++++++++++++++++------ src/expr.c | 6 ++-- src/insert.c | 12 +++++--- src/parse.y | 24 +++++++++++++-- src/select.c | 6 ++-- src/sqliteInt.h | 17 ++++++++-- src/update.c | 4 +-- test/copy.test | 28 ++++++++++++++++- test/delete.test | 25 ++++++++++++++- test/index.test | 55 +++++++++++++++++++++++++++++---- test/insert.test | 49 ++++++++++++++++++++++++++++- test/vacuum.test | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ 14 files changed, 330 insertions(+), 52 deletions(-) create mode 100644 test/vacuum.test diff --git a/manifest b/manifest index ca062d1daa..1f9f9f627a 100644 --- a/manifest +++ b/manifest @@ -1,41 +1,42 @@ -C :-)\s(CVS\s45) -D 2000-06-02T23:22:40 +C added\sdefault\svalues\s(CVS\s46) +D 2000-06-03T18:06:52 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4 F Makefile.in 3d367d6699f6fb987d0041a9d3b4dbf4308c8983 F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958 F configure 00a5b5c82147a576fa6e82d7c1b0d55c321d6d2c x F configure.in 6ccfd5fc80517f7cfe605a7fc7e0f62d962a233c F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47 -F src/build.c 44a99167e5aebd04a65c607dc8556c13d9bccdb0 +F src/build.c 15c4f3844774baa882435223119a18c33810ee94 F src/dbbe.c ae8b5d2cdb4fa7dd11313059984be9457fa77f63 F src/dbbe.h a8a46f71238e0f09f3ec08fd9d1c8c7f4cdc49bf F src/delete.c e11433c14ed5cc8553cba14296b3baa3c23054bc -F src/expr.c fb0972a54cc0230b6d4ce02c80ae07d0e1876e01 -F src/insert.c 747aad76e48a811c6fd30336514df84104587c3f +F src/expr.c baab49f0db860d27fdc41e6cd0bde1c437189ac8 +F src/insert.c 62951015437a96d388f43b591437d489719872fb F src/main.c ed15e0132659ace7f44ea2dbcdd21c232af3dbd5 -F src/parse.y 16322c46ec117082ef745715f7a4761f2491a0b2 -F src/select.c ce21eb2db2c621c097f03c21ff8d18804fb9897d +F src/parse.y 64d9e4808993e9384ba9557f7168ac3dab6cb89f +F src/select.c 2f4ae48deae2c5c94a89b3bc4fef2fe96c575e9f F src/shell.c bd658f9208bc20ce565c3f687836155772ca939a F src/sqlite.h 58da0a8590133777b741f9836beaef3d58f40268 -F src/sqliteInt.h 0b7a533a389ccead699ea149ff3f8d61831d0c0a +F src/sqliteInt.h 606a1614000f4e1cf208fe656bfabc5bd2957c7e F src/tclsqlite.c 10c00c460246cfba375b768c90b22bfe3c774c8f F src/tokenize.c 15c229fee77325334c6814652e429b0930eba6c1 -F src/update.c 1f7284e00921352c3ae699fb60f2c2fbf8098212 +F src/update.c 3f05d5082fd2c34f15d1e4a4db17355ad8807a78 F src/util.c c22846f23b9311ca0e68f076686493bac7b20d5d F src/vdbe.c a584da66af8b44b0236bece378c4dc8ef333f814 F src/vdbe.h ab574c91c6328c5795f68b84074fbcf860eae70e F src/where.c bed9a8360cbfbf712bdc397c8e22216a5e5f9800 F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7 -F test/copy.test 641bd3cfaab61c4ee32889587e21e4c70788a97a -F test/delete.test 814d53e3b0d2d7069fb17e005d4041454d6585d4 +F test/copy.test 6b218a41dc6469491049b50ee105f76282f2547d +F test/delete.test 9b2515aa621fb5df46c640fdef39c876b9a5fc4b F test/expr.test f3fc925935533082911dfa5fde9b22e382b3132f -F test/index.test 8d4f26901a5582daa353fe3c8266cbf4a53af830 -F test/insert.test 161bc67a4189738c559e3569323ceae31f4d49d6 +F test/index.test 9f99dca2d904b8de330863a978587f136e2df65a +F test/insert.test b4c186ffa4b97a231643726f3bcee29815b24eaf F test/select1.test a0b00df77e85adff75c338e487718c5d31f69e3a F test/select2.test ebb5497babf02982304841f2eacc985bcc17691e F test/table.test 85d6f410d127ec508c6640f02d7c40d218414e81 F test/tester.tcl 44690d463c1dc83a4c76ccde07cc146a988600f6 F test/update.test 69459302ea75cafac1479e60b0e36efb88123c0e +F test/vacuum.test 8becf5cfeb897108b35cdd996793e7f1df2f28fd F tool/gdbmdump.c 529e67c78d920606ba196326ea55b57b75fcc82b F tool/lemon.c 1f0e96515c12e9e413f5b8fdebc79ddcf18ddc9d F tool/lempar.c a1eec94d6eacc12332368660ec65f3b248853833 @@ -46,7 +47,7 @@ F www/c_interface.tcl 8867d76ddd416d2fbd41e4cb3de8efa9cef105a5 F www/changes.tcl 7d6ed774362dea0c9687d4efbafd939c1c48fd81 F www/index.tcl 0096a3e00b1364fb2c3e06941aa8c31454b6d06a F www/sqlite.tcl 2f933ce18cffd34a0a020a82435ab937137970fd -P cd83d3cfeb26ebf0d33e7113d0ee549c9cfd55c5 -R 5705bb5aa8e116fe9b24a61fe0df9e9a +P 3e88142e908de02b5c8243c47dc9ca237cb7f011 +R 75efbb82189fa0b34c50ac1e66e30b8e U drh -Z 34ab52e330faf4fc4a55a2f7524e8453 +Z c2845300f99ec90b3961e47b3598d5e7 diff --git a/manifest.uuid b/manifest.uuid index 79181fc567..e140eb122b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e88142e908de02b5c8243c47dc9ca237cb7f011 \ No newline at end of file +27c0678623de37f3166cb9952989fd03484cdb8d \ No newline at end of file diff --git a/src/build.c b/src/build.c index 0c7904d348..5144f13310 100644 --- a/src/build.c +++ b/src/build.c @@ -33,7 +33,7 @@ ** COPY ** VACUUM ** -** $Id: build.c,v 1.13 2000/06/02 13:27:59 drh Exp $ +** $Id: build.c,v 1.14 2000/06/03 18:06:52 drh Exp $ */ #include "sqliteInt.h" @@ -181,13 +181,14 @@ void sqliteDeleteTable(sqlite *db, Table *pTable){ Index *pIndex, *pNext; if( pTable==0 ) return; for(i=0; inCol; i++){ - if( pTable->azCol[i] ) sqliteFree(pTable->azCol[i]); + sqliteFree(pTable->aCol[i].zName); + sqliteFree(pTable->aCol[i].zDflt); } for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){ pNext = pIndex->pNext; sqliteDeleteIndex(db, pIndex); } - sqliteFree(pTable->azCol); + sqliteFree(pTable->aCol); sqliteFree(pTable); } @@ -239,7 +240,7 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName){ pTable->zName = zName; pTable->pHash = 0; pTable->nCol = 0; - pTable->azCol = 0; + pTable->aCol = 0; pTable->pIndex = 0; if( pParse->pNewTable ) sqliteDeleteTable(pParse->db, pParse->pNewTable); pParse->pNewTable = pTable; @@ -253,18 +254,38 @@ 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->aCol = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0])); } - if( p->azCol==0 ){ + if( p->aCol==0 ){ p->nCol = 0; return; } - pz = &p->azCol[p->nCol++]; - *pz = 0; + memset(&p->aCol[p->nCol], 0, sizeof(p->aCol[0])); + pz = &p->aCol[p->nCol++].zName; sqliteSetNString(pz, pName->z, pName->n, 0); sqliteDequote(*pz); } +/* +** The given token is the default value for the last column added to +** the table currently under construction. If "minusFlag" is true, it +** means the value token was preceded by a minus sign. +*/ +void sqliteAddDefaultValue(Parse *pParse, Token *pVal, int minusFlag){ + Table *p; + int i; + char **pz; + if( (p = pParse->pNewTable)==0 ) return; + i = p->nCol-1; + pz = &p->aCol[i].zDflt; + if( minusFlag ){ + sqliteSetNString(pz, "-", 1, pVal->z, pVal->n, 0); + }else{ + sqliteSetNString(pz, pVal->z, pVal->n, 0); + } + sqliteDequote(*pz); +} + /* ** This routine is called to report the final ")" that terminates ** a CREATE TABLE statement. @@ -475,7 +496,7 @@ void sqliteCreateIndex( ** So create a fake list to simulate this. */ if( pList==0 ){ - nullId.z = pTab->azCol[pTab->nCol-1]; + nullId.z = pTab->aCol[pTab->nCol-1].zName; nullId.n = strlen(nullId.z); pList = sqliteIdListAppend(0, &nullId); if( pList==0 ) goto exit_create_index; @@ -503,7 +524,7 @@ void sqliteCreateIndex( */ for(i=0; inId; i++){ for(j=0; jnCol; j++){ - if( sqliteStrICmp(pList->a[i].zName, pTab->azCol[j])==0 ) break; + if( sqliteStrICmp(pList->a[i].zName, pTab->aCol[j].zName)==0 ) break; } if( j>=pTab->nCol ){ sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, diff --git a/src/expr.c b/src/expr.c index 73478feb6f..1efd74ea60 100644 --- a/src/expr.c +++ b/src/expr.c @@ -23,7 +23,7 @@ ************************************************************************* ** This file contains C code routines used for processing expressions ** -** $Id: expr.c,v 1.2 2000/06/02 13:27:59 drh Exp $ +** $Id: expr.c,v 1.3 2000/06/03 18:06:53 drh Exp $ */ #include "sqliteInt.h" @@ -52,7 +52,7 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){ Table *pTab = pTabList->a[i].pTab; if( pTab==0 ) continue; for(j=0; jnCol; j++){ - if( sqliteStrICmp(pTab->azCol[j], z)==0 ){ + if( sqliteStrICmp(pTab->aCol[j].zName, z)==0 ){ cnt++; pExpr->iTable = i; pExpr->iField = j; @@ -102,7 +102,7 @@ int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){ } if( sqliteStrICmp(zTab, zLeft)!=0 ) continue; for(j=0; jnCol; j++){ - if( sqliteStrICmp(pTab->azCol[j], zRight)==0 ){ + if( sqliteStrICmp(pTab->aCol[j].zName, zRight)==0 ){ cnt++; pExpr->iTable = i; pExpr->iField = j; diff --git a/src/insert.c b/src/insert.c index 3edd78b7cc..f947820320 100644 --- a/src/insert.c +++ b/src/insert.c @@ -24,7 +24,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements. ** -** $Id: insert.c,v 1.3 2000/06/02 13:27:59 drh Exp $ +** $Id: insert.c,v 1.4 2000/06/03 18:06:53 drh Exp $ */ #include "sqliteInt.h" @@ -88,7 +88,7 @@ void sqliteInsert( } for(i=0; inId; i++){ for(j=0; jnCol; j++){ - if( sqliteStrICmp(pField->a[i].zName, pTab->azCol[j])==0 ){ + if( sqliteStrICmp(pField->a[i].zName, pTab->aCol[j].zName)==0 ){ pField->a[i].idx = j; break; } @@ -121,7 +121,9 @@ void sqliteInsert( } } if( pField && j>=pField->nId ){ - sqliteVdbeAddOp(v, OP_String, 0, 0, "", 0); + char *zDflt = pTab->aCol[i].zDflt; + if( zDflt==0 ) zDflt = ""; + sqliteVdbeAddOp(v, OP_String, 0, 0, zDflt, 0); }else{ sqliteExprCode(pParse, pList->a[j].pExpr); } @@ -143,7 +145,9 @@ void sqliteInsert( } } if( pField && j>=pField->nId ){ - sqliteVdbeAddOp(v, OP_String, 0, 0, "", 0); + char *zDflt = pTab->aCol[idx].zDflt; + if( zDflt==0 ) zDflt = ""; + sqliteVdbeAddOp(v, OP_String, 0, 0, zDflt, 0); }else{ sqliteExprCode(pParse, pList->a[j].pExpr); } diff --git a/src/parse.y b/src/parse.y index 7ae7dbf7d2..41b276bc9a 100644 --- a/src/parse.y +++ b/src/parse.y @@ -26,7 +26,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.6 2000/05/31 20:00:52 drh Exp $ +** @(#) $Id: parse.y,v 1.7 2000/06/03 18:06:53 drh Exp $ */ %token_prefix TK_ %token_type {Token} @@ -92,7 +92,15 @@ carglist ::= carglist carg. carglist ::= . carg ::= CONSTRAINT ID ccons. carg ::= ccons. -carg ::= DEFAULT expr. +carg ::= DEFAULT STRING(X). {sqliteAddDefaultValue(pParse,&X,0);} +carg ::= DEFAULT ID(X). {sqliteAddDefaultValue(pParse,&X,0);} +carg ::= DEFAULT INTEGER(X). {sqliteAddDefaultValue(pParse,&X,0);} +carg ::= DEFAULT PLUS INTEGER(X). {sqliteAddDefaultValue(pParse,&X,0);} +carg ::= DEFAULT MINUS INTEGER(X). {sqliteAddDefaultValue(pParse,&X,1);} +carg ::= DEFAULT FLOAT(X). {sqliteAddDefaultValue(pParse,&X,0);} +carg ::= DEFAULT PLUS FLOAT(X). {sqliteAddDefaultValue(pParse,&X,0);} +carg ::= DEFAULT MINUS FLOAT(X). {sqliteAddDefaultValue(pParse,&X,1);} +carg ::= DEFAULT NULL. // In addition to the type name, we also care about the primary key. // @@ -220,7 +228,19 @@ cmd ::= INSERT INTO ID(X) fieldlist_opt(F) VALUES LP itemlist(Y) RP. itemlist(A) ::= itemlist(X) COMMA item(Y). {A = sqliteExprListAppend(X,Y,0);} itemlist(A) ::= item(X). {A = sqliteExprListAppend(0,X,0);} item(A) ::= INTEGER(X). {A = sqliteExpr(TK_INTEGER, 0, 0, &X);} +item(A) ::= PLUS INTEGER(X). {A = sqliteExpr(TK_INTEGER, 0, 0, &X);} +item(A) ::= MINUS INTEGER(X). { + A = sqliteExpr(TK_INTEGER, 0, 0, 0); + A->token.z = 0; + sqliteSetNString(&A->token.z, "-", 1, X.z, X.n, 0); +} item(A) ::= FLOAT(X). {A = sqliteExpr(TK_FLOAT, 0, 0, &X);} +item(A) ::= PLUS FLOAT(X). {A = sqliteExpr(TK_FLOAT, 0, 0, &X);} +item(A) ::= MINUS FLOAT(X). { + A = sqliteExpr(TK_FLOAT, 0, 0, 0); + A->token.z = 0; + sqliteSetNString(&A->token.z, "-", 1, X.z, X.n, 0); +} item(A) ::= STRING(X). {A = sqliteExpr(TK_STRING, 0, 0, &X);} %type fieldlist_opt {IdList*} diff --git a/src/select.c b/src/select.c index f0a1e94b0b..561a5fb8ae 100644 --- a/src/select.c +++ b/src/select.c @@ -24,7 +24,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements. ** -** $Id: select.c,v 1.4 2000/06/02 01:51:20 drh Exp $ +** $Id: select.c,v 1.5 2000/06/03 18:06:53 drh Exp $ */ #include "sqliteInt.h" @@ -165,12 +165,12 @@ void sqliteSelect( zTab = pTabList->a[p->iTable].zAlias; if( zTab==0 ) zTab = pTab->zName; - sqliteSetString(&zName, zTab, ".", pTab->azCol[p->iField], 0); + sqliteSetString(&zName, zTab, ".", pTab->aCol[p->iField].zName, 0); sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0); sqliteFree(zName); }else{ Table *pTab = pTabList->a[0].pTab; - sqliteVdbeAddOp(v, OP_ColumnName, i, 0, pTab->azCol[p->iField], 0); + sqliteVdbeAddOp(v, OP_ColumnName, i, 0, pTab->aCol[p->iField].zName, 0); } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index bfabcc3793..f59fdbf0d4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -23,7 +23,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.10 2000/06/02 13:28:00 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.11 2000/06/03 18:06:53 drh Exp $ */ #include "sqlite.h" #include "dbbe.h" @@ -77,6 +77,7 @@ /* ** Forward references to structures */ +typedef struct Column Column; typedef struct Table Table; typedef struct Index Index; typedef struct Instruction Instruction; @@ -103,6 +104,16 @@ struct sqlite { #define SQLITE_VdbeTrace 0x00000001 #define SQLITE_Initialized 0x00000002 +/* +** information about each column of a table is held in an instance +** of this structure. +*/ +struct Column { + char *zName; /* Name of this column */ + char *zDflt; /* Default value of this column */ + int notNull; /* True if there is a NOT NULL constraing */ +}; + /* ** Each table is represented in memory by ** an instance of the following structure @@ -111,8 +122,8 @@ struct Table { char *zName; /* Name of the table */ Table *pHash; /* Next table with same hash on zName */ int nCol; /* Number of columns in this table */ + Column *aCol; /* Information about each column */ int readOnly; /* True if this table should not be written by the user */ - char **azCol; /* Name of each column */ Index *pIndex; /* List of indices on this table. */ }; @@ -126,6 +137,7 @@ struct Index { int nField; /* Number of fields in the table indexed by this index */ int *aiField; /* Indices of fields used by this index. 1st is 0 */ Table *pTable; /* The table being indexed */ + int isUnique; /* True if keys must all be unique */ Index *pNext; /* The next index associated with the same table */ }; @@ -244,6 +256,7 @@ ExprList *sqliteExprListAppend(ExprList*,Expr*,Token*); void sqliteExprListDelete(ExprList*); void sqliteStartTable(Parse*,Token*,Token*); void sqliteAddColumn(Parse*,Token*); +void sqliteAddDefaultValue(Parse*,Token*,int); void sqliteEndTable(Parse*,Token*); void sqliteDropTable(Parse*, Token*); void sqliteDeleteTable(sqlite*, Table*); diff --git a/src/update.c b/src/update.c index 8bd2e5dd0a..323c4254ae 100644 --- a/src/update.c +++ b/src/update.c @@ -24,7 +24,7 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.2 2000/06/02 01:17:38 drh Exp $ +** $Id: update.c,v 1.3 2000/06/03 18:06:53 drh Exp $ */ #include "sqliteInt.h" @@ -96,7 +96,7 @@ void sqliteUpdate( goto update_cleanup; } for(j=0; jnCol; j++){ - if( strcmp(pTab->azCol[j], pChanges->a[i].zName)==0 ){ + if( strcmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){ pChanges->a[i].idx = j; aXRef[j] = i; break; diff --git a/test/copy.test b/test/copy.test index fa9df9922b..37740e008e 100644 --- a/test/copy.test +++ b/test/copy.test @@ -23,7 +23,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the COPY statement. # -# $Id: copy.test,v 1.1 2000/05/30 17:30:36 drh Exp $ +# $Id: copy.test,v 1.2 2000/06/03 18:06:53 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -94,6 +94,32 @@ do_test copy-1.6 { execsql {COPY test1 FROM 'data5.txt' USING DELIMITERS '|'} execsql {SELECT * FROM test1 ORDER BY one} } {11 22 33 22 33 11} +do_test copy-1.7 { + execsql {DELETE FROM test1} + execsql {COPY test1 FROM 'data4.txt' USING DELIMITERS '|'} + execsql {SELECT * FROM test1 ORDER BY one} +} {{11 } { 22 } { 33} {22 } { 33 } { 11}} + +# Try copying into a table that has one or more indices. +# +execsql {DELETE FROM test1} +execsql {CREATE INDEX index1 ON test1(one)} +execsql {CREATE INDEX index2 ON test1(two)} +execsql {CREATE INDEX index3 ON test1(three)} +do_test copy-1.8 { + execsql {COPY test1 from 'data1.txt'} + execsql {SELECT * FROM test1 WHERE one=11} +} {11 22 33} +do_test copy-1.8b { + execsql {SELECT * FROM test1 WHERE one=22} +} {22 33 11} +do_test copy-1.8c { + execsql {SELECT * FROM test1 WHERE two=22} +} {11 22 33} +do_test copy-1.8d { + execsql {SELECT * FROM test1 WHERE three=11} +} {22 33 11} + # Try inserting really long data # diff --git a/test/delete.test b/test/delete.test index c745afa155..5ed8e8d922 100644 --- a/test/delete.test +++ b/test/delete.test @@ -23,7 +23,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the DELETE FROM statement. # -# $Id: delete.test,v 1.2 2000/05/30 03:12:22 drh Exp $ +# $Id: delete.test,v 1.3 2000/06/03 18:06:53 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -42,6 +42,29 @@ do_test delete-2.1 { lappend v $msg } {1 {table sqlite_master may not be modified}} +# Delete selected entries from a table with and without an index. +# +do_test delete-3.1a { + execsql {CREATE TABLE table1(f1 int, f2 int)} + execsql {INSERT INTO table1 VALUES(1,2)} + execsql {INSERT INTO table1 VALUES(2,4)} + execsql {INSERT INTO table1 VALUES(3,8)} + execsql {INSERT INTO table1 VALUES(4,16)} + execsql {SELECT * FROM table1 ORDER BY f1} +} {1 2 2 4 3 8 4 16} +do_test delete-3.1b { + execsql {DELETE FROM table1 WHERE f1=3} + execsql {SELECT * FROM table1 ORDER BY f1} +} {1 2 2 4 4 16} +do_test delete-3.1c { + execsql {CREATE INDEX index1 ON table1(f1)} + execsql {DELETE FROM table1 WHERE f1=3} + execsql {SELECT * FROM table1 ORDER BY f1} +} {1 2 2 4 4 16} +do_test delete-3.1d { + execsql {DELETE FROM table1 WHERE f1=2} + execsql {SELECT * FROM table1 ORDER BY f1} +} {1 2 4 16} finish_test diff --git a/test/index.test b/test/index.test index e760fe0192..9db1d89c00 100644 --- a/test/index.test +++ b/test/index.test @@ -23,7 +23,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the CREATE INDEX statement. # -# $Id: index.test,v 1.2 2000/05/30 03:12:22 drh Exp $ +# $Id: index.test,v 1.3 2000/06/03 18:06:53 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -127,15 +127,18 @@ do_test index-3.4 { # an index on that table. Verify that we can select values # from the table correctly using the index. # +# Note that the index names "index9" and "indext" are chosen because +# they both have the same hash. +# do_test index-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 {CREATE INDEX index9 ON test1(cnt)} + execsql {CREATE INDEX indext ON test1(power)} execsql {SELECT name FROM sqlite_master ORDER BY name} -} {index1 index2 test1} +} {index9 indext test1} do_test index-4.2 { execsql {SELECT cnt FROM test1 WHERE power=4} } {2} @@ -146,7 +149,36 @@ do_test index-4.4 { execsql {SELECT power FROM test1 WHERE cnt=6} } {64} do_test index-4.5 { + execsql {DROP INDEX indext} + execsql {SELECT power FROM test1 WHERE cnt=6} +} {64} +do_test index-4.6 { + execsql {SELECT cnt FROM test1 WHERE power=1024} +} {10} +do_test index-4.7 { + execsql {CREATE INDEX indext ON test1(cnt)} + execsql {SELECT power FROM test1 WHERE cnt=6} +} {64} +do_test index-4.8 { + execsql {SELECT cnt FROM test1 WHERE power=1024} +} {10} +do_test index-4.9 { + execsql {DROP INDEX index9} + execsql {SELECT power FROM test1 WHERE cnt=6} +} {64} +do_test index-4.10 { + execsql {SELECT cnt FROM test1 WHERE power=1024} +} {10} +do_test index-4.11 { + execsql {DROP INDEX indext} + execsql {SELECT power FROM test1 WHERE cnt=6} +} {64} +do_test index-4.12 { + execsql {SELECT cnt FROM test1 WHERE power=1024} +} {10} +do_test index-4.13 { execsql {DROP TABLE test1} + execsql {SELECT name FROM sqlite_master ORDER BY name} } {} # Do not allow indices to be added to sqlite_master @@ -205,13 +237,24 @@ do_test index-7.4 { execsql {SELECT name FROM sqlite_master} } {} -# Make sure we cannot drop a non-existant table. +# Make sure we cannot drop a non-existant index. # do_test index-8.1 { set v [catch {execsql {DROP INDEX index1}} msg] lappend v $msg } {1 {no such index: index1}} - +# Make sure we don't actually create an index when the EXPLAIN keyword +# is used. +# +do_test index-9.1 { + execsql {CREATE TABLE tab1(a int)} + execsql {EXPLAIN CREATE INDEX idx1 ON tab1(a)} + execsql {SELECT name FROM sqlite_master WHERE tbl_name='tab1'} +} {tab1} +do_test index-9.2 { + execsql {CREATE INDEX idx1 ON tab1(a)} + execsql {SELECT name FROM sqlite_master WHERE tbl_name='tab1' ORDER BY name} +} {idx1 tab1} finish_test diff --git a/test/insert.test b/test/insert.test index 2bb4c6d001..45a642ed6e 100644 --- a/test/insert.test +++ b/test/insert.test @@ -23,7 +23,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the INSERT statement. # -# $Id: insert.test,v 1.2 2000/05/30 03:12:22 drh Exp $ +# $Id: insert.test,v 1.3 2000/06/03 18:06:53 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -98,4 +98,51 @@ do_test insert-1.6c { execsql {SELECT * FROM test1 ORDER BY one} } {{} 5 6 1 2 {} 8 {} 7} +# A table to use for testing default values +# +execsql { + CREATE TABLE test2( + f1 int default 111, + f2 real default -4.32, + f3 text default hi, + f4 text default 'abc-123', + f5 varchar(10) + ) +} + +do_test insert-2.1 { + execsql {SELECT * from test2} +} {} +do_test insert-2.2 { + execsql {INSERT INTO test2(f2,f4) VALUES(-2.22,'hi!')} + execsql {SELECT * FROM test2} +} {111 -2.22 hi hi! {}} +do_test insert-2.3 { + execsql {INSERT INTO test2(f1,f5) VALUES(1,'xyzzy')} + execsql {SELECT * FROM test2 ORDER BY f1} +} {1 -4.32 hi abc-123 xyzzy 111 -2.22 hi hi! {}} + +# Do additional inserts with default values, but this time +# on a table that has indices. In particular we want to verify +# that the correct default values are inserted into the indices. +# +execsql {DELETE FROM test2} +execsql {CREATE INDEX index9 ON test2(f1,f2)} +execsql {CREATE INDEX indext ON test2(f4,f5)} + +do_test insert-3.1 { + execsql {SELECT * from test2} +} {} +do_test insert-3.2 { + execsql {INSERT INTO test2(f2,f4) VALUES(-3.33,'hum')} + execsql {SELECT * FROM test2 WHERE f1=111 AND f2=-3.33} +} {111 -3.33 hi hum {}} +do_test insert-3.3 { + execsql {INSERT INTO test2(f1,f2,f5) VALUES(22,-4.44,'wham')} + execsql {SELECT * FROM test2 WHERE f1=111 AND f2=-3.33} +} {111 -3.33 hi hum {}} +do_test insert-3.4 { + execsql {SELECT * FROM test2 WHERE f1=22 AND f2=-4.44} +} {22 -4.44 hi abc-123 wham} + finish_test diff --git a/test/vacuum.test b/test/vacuum.test new file mode 100644 index 0000000000..565994e31e --- /dev/null +++ b/test/vacuum.test @@ -0,0 +1,80 @@ +# 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 VACUUM statement. +# +# $Id: vacuum.test,v 1.1 2000/06/03 18:06:54 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Try to vacuum a non-existant table. +# +do_test vacuum-1.1 { + set v [catch {execsql {VACUUM dummy1}} msg] + lappend v $msg +} {1 {no such table or index: dummy1}} + +# It is OK to vacuum sqlite_master... +# +do_test vacuum-1.2 { + set v [catch {execsql {VACUUM sqlite_master}} msg] + lappend v $msg +} {0 {}} + +# Create some tables and indices to test against. +# +execsql {CREATE TABLE test1(a int)} +execsql {CREATE TABLE test2(b int)} +execsql {CREATE INDEX index1 ON test1(a)} +execsql {INSERT INTO test1 VALUES(1)} +execsql {INSERT INTO test1 VALUES(1)} +execsql {INSERT INTO test1 VALUES(2)} +execsql {INSERT INTO test1 VALUES(3)} +execsql {INSERT INTO test2 VALUES(4)} + +do_test vacuum-1.3 { + set b1 [file mtime testdb/test1.tbl] + set b2 [file mtime testdb/test2.tbl] + set b3 [file mtime testdb/index1.tbl] + after 1000 + execsql {VACUUM test1} + set a1 [file mtime testdb/test1.tbl] + set a2 [file mtime testdb/test2.tbl] + set a3 [file mtime testdb/index1.tbl] + expr {$a1>$b1 && $a2==$b2 && $a3==$b3} +} {1} +do_test vacuum-1.4 { + set b1 [file mtime testdb/test1.tbl] + set b2 [file mtime testdb/test2.tbl] + set b3 [file mtime testdb/index1.tbl] + after 1000 + execsql {VACUUM} + set a1 [file mtime testdb/test1.tbl] + set a2 [file mtime testdb/test2.tbl] + set a3 [file mtime testdb/index1.tbl] + expr {$a1>$b1 && $a2>$b2 && $a3>$b3} +} {1} + + +finish_test