From 5974a30f1a3c5d738df85add6a8b594f982f0c28 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 7 Jun 2000 14:42:26 +0000 Subject: [PATCH] :-) (CVS 1697) FossilOrigin-Name: 5d773b5d4e9c23b81f53afd0cef7bd2300fff329 --- manifest | 28 ++++----- manifest.uuid | 2 +- src/dbbe.c | 4 +- src/insert.c | 142 ++++++++++++++++++++++++++++------------------ src/main.c | 3 +- src/parse.y | 6 +- src/select.c | 13 ++++- src/sqliteInt.h | 5 +- test/dbbe.test | 122 +++++++++++++++++++++++++++++++++++++++ test/insert.test | 13 +++-- test/insert2.test | 73 ++++++++++++++++++++++++ test/select1.test | 6 +- 12 files changed, 330 insertions(+), 87 deletions(-) create mode 100644 test/dbbe.test create mode 100644 test/insert2.test diff --git a/manifest b/manifest index 3d72138362..ecaf63bf88 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C :-)\s(CVS\s68) -D 2000-06-07T02:04:23 +C :-)\s(CVS\s1697) +D 2000-06-07T14:42:26 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4 F Makefile.in 17ba1ccf8d2d40c627796bba8f72952365d6d644 F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958 @@ -7,17 +7,17 @@ F configure 00a5b5c82147a576fa6e82d7c1b0d55c321d6d2c x F configure.in 6ccfd5fc80517f7cfe605a7fc7e0f62d962a233c F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47 F src/build.c 6c9454b2e2b866979527fb41b19ad8bc49c27a20 -F src/dbbe.c ae8b5d2cdb4fa7dd11313059984be9457fa77f63 +F src/dbbe.c 9b191b16ff01ec5bc0af436558501d07938ba4f0 F src/dbbe.h a8a46f71238e0f09f3ec08fd9d1c8c7f4cdc49bf F src/delete.c 8c733bb82a1b84126116d03dcdccf433c0856f5d F src/expr.c d350fe393e1753aaa733a5d21f0830a23e547400 -F src/insert.c 5e69dd70c3f91cf5ec5090f39fd6cd8e135af9bf -F src/main.c 93a7ad14bb5a82ad13ad59da23ef674a94b0c3d6 -F src/parse.y 8b632f4c4ff2f4400f15592ca9d8fda27d97d0c4 -F src/select.c 74fa3af62bfa2e6e29f43153f883fd28c295b853 +F src/insert.c 8bd762bb6aa7bf0e6abda03699c88db7736bf7dd +F src/main.c 48440ddd39783ac379c746804e3424e06cdf7138 +F src/parse.y 4a2e6b14177c97f61fc3e21d4570f5a9c541c1e1 +F src/select.c 4834ab68a3308871f17fe8e22d903fcdf1b42420 F src/shell.c 3f4afc39a36e4824e8aa262623fd03568874799e F src/sqlite.h 58da0a8590133777b741f9836beaef3d58f40268 -F src/sqliteInt.h 3cca846df0a8b5f811cf4f8021303547cd8f21fd +F src/sqliteInt.h a593cb946ea81f24c8a79f996d6597184ab40053 F src/tclsqlite.c 9f358618ae803bedf4fb96da5154fd45023bc1f7 F src/tokenize.c 900af9479d0feaa76b0225680196aa81afec930a F src/update.c 18746f920f989b3d19d96c08263c92584823cd35 @@ -27,12 +27,14 @@ F src/vdbe.h 8f79f57c66ce1030f6371ff067b326d627a52c6d F src/where.c c9b90e7672f4662a83ef9a27a193020d69fe034c F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7 F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb +F test/dbbe.test 3978ab21ff2a0531a85618c538d27047d560fc5d F test/delete.test 30451333f89479d2deb5410edd3f3cce67339944 F test/expr.test 52be5592143a88479e0006dfd7e2023e43294636 F test/in.test 17cd46a9ca0e5d4a804483e6fb496458494858e6 F test/index.test 9f99dca2d904b8de330863a978587f136e2df65a -F test/insert.test b4c186ffa4b97a231643726f3bcee29815b24eaf -F test/select1.test 2311bddd40bca257c27a7d141ed2a359bbdbc906 +F test/insert.test 66f4c3bd600fec8eb1e733b928cbe6fa885eff0c +F test/insert2.test 2d529bc4acf33dcf554a8c2e4593aab270fa6faf +F test/select1.test 55af6d31c778022ac3eecd051a66e9df3573c46f F test/select2.test 3cd3c0f9d67e98b1b54af5853679b4a111224410 F test/select3.test 73ae8c7b80c4e03a9c29d12f2ea1782e28b8e61f F test/sort.test d582086c4bb7df3fbf50aa72e69d7e235e9f8e31 @@ -51,7 +53,7 @@ F www/c_interface.tcl 9ac800854272db5fe439e07b7435b243a5422293 F www/changes.tcl 04e66b4257589ff78a7e1de93e9dda4725fb03d6 F www/index.tcl 52e29a4eeda8d59e91af43c61fef177c5f2ffd53 F www/sqlite.tcl 2f933ce18cffd34a0a020a82435ab937137970fd -P 8bff1bee63b77353b4cfe5aa0c662187a7bf93da -R 66723773907deae85c622c6e494a06db +P fc8d25ea1fffa115fad15b9eb8bb0b0aaaff0431 +R 57fdc174a06c58f4d8c32ca7ec794547 U drh -Z 03e9a47b962f6283d6dab7f071f9c9ae +Z 6ab7c0c87e13b9e4938e70912c15eacc diff --git a/manifest.uuid b/manifest.uuid index 87b75f8514..3c93d6eb6b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc8d25ea1fffa115fad15b9eb8bb0b0aaaff0431 \ No newline at end of file +5d773b5d4e9c23b81f53afd0cef7bd2300fff329 \ No newline at end of file diff --git a/src/dbbe.c b/src/dbbe.c index ece4f4ff67..cce7b3c37d 100644 --- a/src/dbbe.c +++ b/src/dbbe.c @@ -30,7 +30,7 @@ ** relatively simple to convert to a different database such ** as NDBM, SDBM, or BerkeleyDB. ** -** $Id: dbbe.c,v 1.11 2000/06/02 13:27:59 drh Exp $ +** $Id: dbbe.c,v 1.12 2000/06/07 14:42:26 drh Exp $ */ #include "sqliteInt.h" #include @@ -161,7 +161,7 @@ Dbbe *sqliteDbbeOpen( return 0; } zMaster = 0; - sqliteSetString(&zMaster, zName, "/" MASTER_NAME, 0); + sqliteSetString(&zMaster, zName, "/" MASTER_NAME ".tbl", 0); if( stat(zMaster, &statbuf)==0 && access(zMaster, writeFlag ? (W_OK|R_OK) : R_OK)!=0 ){ sqliteSetString(pzErrMsg, "access permission denied for ", zMaster, 0); diff --git a/src/insert.c b/src/insert.c index 112ba3386c..40178a9d25 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.6 2000/06/05 18:54:46 drh Exp $ +** $Id: insert.c,v 1.7 2000/06/07 14:42:27 drh Exp $ */ #include "sqliteInt.h" @@ -39,12 +39,18 @@ void sqliteInsert( Parse *pParse, /* Parser context */ Token *pTableName, /* Name of table into which we are inserting */ ExprList *pList, /* List of values to be inserted */ + Select *pSelect, /* A SELECT statement to use as the data source */ IdList *pField /* Field name corresponding to pList. Might be NULL */ ){ - Table *pTab; - char *zTab; - int i, j, idx; - Vdbe *v; + Table *pTab; /* The table to insert into */ + char *zTab; /* Name of the table into which we are inserting */ + int i, j, idx; /* Loop counters */ + Vdbe *v; /* Generate code into this virtual machine */ + Index *pIdx; /* For looping over indices of the table */ + int srcTab; /* Date comes from this temporary cursor if >=0 */ + int nField; /* Number of columns in the data */ + int base; /* First available cursor */ + int iCont, iBreak; /* Beginning and end of the loop over srcTab */ zTab = sqliteTableNameFromToken(pTableName); pTab = sqliteFindTable(pParse->db, zTab); @@ -61,10 +67,28 @@ void sqliteInsert( pParse->nErr++; goto insert_cleanup; } - if( pField==0 && pList->nExpr!=pTab->nCol ){ + v = pParse->pVdbe; + if( v==0 ){ + v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe); + } + if( v==0 ) goto insert_cleanup; + if( pSelect ){ + int rc; + srcTab = pParse->nTab++; + sqliteVdbeAddOp(v, OP_Open, srcTab, 1, 0, 0); + rc = sqliteSelect(pParse, pSelect, SRT_Table, srcTab); + if( rc ) goto insert_cleanup; + assert( pSelect->pEList ); + nField = pSelect->pEList->nExpr; + }else{ + srcTab = -1; + assert( pList ); + nField = pList->nExpr; + } + if( pField==0 && nField!=pTab->nCol ){ char zNum1[30]; char zNum2[30]; - sprintf(zNum1,"%d", pList->nExpr); + sprintf(zNum1,"%d", nField); sprintf(zNum2,"%d", pTab->nCol); sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, " has ", zNum2, " columns but ", @@ -72,10 +96,10 @@ void sqliteInsert( pParse->nErr++; goto insert_cleanup; } - if( pField!=0 && pList->nExpr!=pField->nId ){ + if( pField!=0 && nField!=pField->nId ){ char zNum1[30]; char zNum2[30]; - sprintf(zNum1,"%d", pList->nExpr); + sprintf(zNum1,"%d", nField); sprintf(zNum2,"%d", pField->nId); sqliteSetString(&pParse->zErrMsg, zNum1, " values for ", zNum2, " columns", 0); @@ -101,73 +125,81 @@ void sqliteInsert( } } } - v = pParse->pVdbe; - if( v==0 ){ - v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe); + base = pParse->nTab; + sqliteVdbeAddOp(v, OP_Open, base, 1, pTab->zName, 0); + for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ + sqliteVdbeAddOp(v, OP_Open, idx+base, 1, pIdx->zName, 0); } - if( v ){ - Index *pIdx; - sqliteVdbeAddOp(v, OP_Open, 0, 1, pTab->zName, 0); - for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ - sqliteVdbeAddOp(v, OP_Open, idx, 1, pIdx->zName, 0); + if( srcTab>=0 ){ + sqliteVdbeAddOp(v, OP_Rewind, srcTab, 0, 0, 0); + iBreak = sqliteVdbeMakeLabel(v); + iCont = sqliteVdbeAddOp(v, OP_Next, srcTab, iBreak, 0, 0); + } + sqliteVdbeAddOp(v, OP_New, 0, 0, 0, 0); + if( pTab->pIndex ){ + sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0); + } + for(i=0; inCol; i++){ + if( pField==0 ){ + j = i; + }else{ + for(j=0; jnId; j++){ + if( pField->a[j].idx==i ) break; + } } - sqliteVdbeAddOp(v, OP_New, 0, 0, 0, 0); - if( pTab->pIndex ){ + if( pField && j>=pField->nId ){ + char *zDflt = pTab->aCol[i].zDflt; + if( zDflt==0 ){ + sqliteVdbeAddOp(v, OP_Null, 0, 0, 0, 0); + }else{ + sqliteVdbeAddOp(v, OP_String, 0, 0, zDflt, 0); + } + }else if( srcTab>=0 ){ + sqliteVdbeAddOp(v, OP_Field, srcTab, i, 0, 0); + }else{ + sqliteExprCode(pParse, pList->a[j].pExpr); + } + } + sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0); + sqliteVdbeAddOp(v, OP_Put, base, 0, 0, 0); + /* sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0); */ + for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ + if( pIdx->pNext ){ sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0); } - for(i=0; inCol; i++){ + for(i=0; inField; i++){ + int idx = pIdx->aiField[i]; if( pField==0 ){ - j = i; + j = idx; }else{ for(j=0; jnId; j++){ - if( pField->a[j].idx==i ) break; + if( pField->a[j].idx==idx ) break; } } if( pField && j>=pField->nId ){ - char *zDflt = pTab->aCol[i].zDflt; + char *zDflt = pTab->aCol[idx].zDflt; if( zDflt==0 ){ sqliteVdbeAddOp(v, OP_Null, 0, 0, 0, 0); }else{ sqliteVdbeAddOp(v, OP_String, 0, 0, zDflt, 0); } + }else if( srcTab>=0 ){ + sqliteVdbeAddOp(v, OP_Field, srcTab, i, 0, 0); }else{ sqliteExprCode(pParse, pList->a[j].pExpr); } } - sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0); - sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0); - sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0); - for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ - if( pIdx->pNext ){ - sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0); - } - for(i=0; inField; i++){ - int idx = pIdx->aiField[i]; - if( pField==0 ){ - j = idx; - }else{ - for(j=0; jnId; j++){ - if( pField->a[j].idx==idx ) break; - } - } - if( pField && j>=pField->nId ){ - char *zDflt = pTab->aCol[idx].zDflt; - if( zDflt==0 ){ - sqliteVdbeAddOp(v, OP_Null, 0, 0, 0, 0); - }else{ - sqliteVdbeAddOp(v, OP_String, 0, 0, zDflt, 0); - } - }else{ - sqliteExprCode(pParse, pList->a[j].pExpr); - } - } - sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0); - sqliteVdbeAddOp(v, OP_PutIdx, idx, 0, 0, 0); - sqliteVdbeAddOp(v, OP_Close, idx, 0, 0, 0); - } + sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0); + sqliteVdbeAddOp(v, OP_PutIdx, idx+base, 0, 0, 0); + /* sqliteVdbeAddOp(v, OP_Close, idx, 0, 0, 0); */ + } + if( srcTab>=0 ){ + sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0); + sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, iBreak); } insert_cleanup: - sqliteExprListDelete(pList); + if( pList ) sqliteExprListDelete(pList); + if( pSelect ) sqliteSelectDelete(pSelect); sqliteIdListDelete(pField); } diff --git a/src/main.c b/src/main.c index 317c08ce61..8f0c561e03 100644 --- a/src/main.c +++ b/src/main.c @@ -26,7 +26,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.9 2000/06/05 16:01:39 drh Exp $ +** $Id: main.c,v 1.10 2000/06/07 14:42:27 drh Exp $ */ #include "sqliteInt.h" @@ -174,6 +174,7 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){ /* Open the backend database driver */ db->pBe = sqliteDbbeOpen(zFilename, (mode&0222)!=0, mode!=0, pzErrMsg); if( db->pBe==0 ){ + sqliteStrRealloc(pzErrMsg); sqliteFree(db); return 0; } diff --git a/src/parse.y b/src/parse.y index e42adedd81..049a631734 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.14 2000/06/06 21:56:08 drh Exp $ +** @(#) $Id: parse.y,v 1.15 2000/06/07 14:42:27 drh Exp $ */ %token_prefix TK_ %token_type {Token} @@ -256,7 +256,9 @@ setlist(A) ::= ID(X) EQ expr(Y) COMMA setlist(Z). setlist(A) ::= ID(X) EQ expr(Y). {A = sqliteExprListAppend(0,Y,&X);} cmd ::= INSERT INTO ID(X) fieldlist_opt(F) VALUES LP itemlist(Y) RP. - {sqliteInsert(pParse, &X, Y, F);} + {sqliteInsert(pParse, &X, Y, 0, F);} +cmd ::= INSERT INTO ID(X) fieldlist_opt(F) select(S). + {sqliteInsert(pParse, &X, 0, S, F);} %type itemlist {ExprList*} diff --git a/src/select.c b/src/select.c index 46bdb42894..1992612e4b 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.14 2000/06/06 22:13:55 drh Exp $ +** $Id: select.c,v 1.15 2000/06/07 14:42:27 drh Exp $ */ #include "sqliteInt.h" @@ -156,6 +156,15 @@ static int selectInnerLoop( sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0); }else + /* Store the result as data using a unique key. + */ + if( eDest==SRT_Table ){ + sqliteVdbeAddOp(v, OP_MakeRecord, nField, 0, 0, 0); + sqliteVdbeAddOp(v, OP_New, iParm, 0, 0, 0); + sqliteVdbeAddOp(v, OP_Pull, 1, 0, 0, 0); + sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0); + }else + /* Construct a record from the query result, but instead of ** saving that record, use it as a key to delete elements from ** the temporary table iParm. @@ -215,7 +224,7 @@ static void generateColumnNames(Vdbe *v, IdList *pTabList, ExprList *pEList){ p = pEList->a[i].pExpr; if( p->op!=TK_FIELD || pTabList==0 ){ char zName[30]; - sprintf(zName, "field%d", i+1); + sprintf(zName, "column%d", i+1); sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0); }else{ if( pTabList->nId>1 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ebe04dfb54..7d26bd16ca 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -23,7 +23,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.19 2000/06/06 21:56:08 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.20 2000/06/07 14:42:27 drh Exp $ */ #include "sqlite.h" #include "dbbe.h" @@ -240,6 +240,7 @@ struct Select { #define SRT_Set 3 /* Store result as unique keys in a table */ #define SRT_Union 5 /* Store result as keys in a table */ #define SRT_Except 6 /* Remove result from a UNION table */ +#define SRT_Table 7 /* Store result as data with a unique key */ /* ** When a SELECT uses aggregate functions (like "count(*)" or "avg(f1)") @@ -325,7 +326,7 @@ void sqliteAddDefaultValue(Parse*,Token*,int); void sqliteEndTable(Parse*,Token*); void sqliteDropTable(Parse*, Token*); void sqliteDeleteTable(sqlite*, Table*); -void sqliteInsert(Parse*, Token*, ExprList*, IdList*); +void sqliteInsert(Parse*, Token*, ExprList*, Select*, IdList*); IdList *sqliteIdListAppend(IdList*, Token*); void sqliteIdListAddAlias(IdList*, Token*); void sqliteIdListDelete(IdList*); diff --git a/test/dbbe.test b/test/dbbe.test new file mode 100644 index 0000000000..c93b8bec1a --- /dev/null +++ b/test/dbbe.test @@ -0,0 +1,122 @@ +# 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 exercising the code in dbbe.c. +# +# $Id: dbbe.test,v 1.1 2000/06/07 14:42:27 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Try to open a database that does not exist. +# +do_test dbbe-1.1 { + catch {db close} + file delete -force testdb + set v [catch {sqlite db testdb 0444} msg] + lappend v $msg +} {1 {can't find directory "testdb"}} +do_test dbbe-1.2 { + catch {db close} + file delete -force testdb + set v [catch {sqlite db testdb/dummy 0666} msg] + lappend v $msg +} {1 {can't find or create directory "testdb/dummy"}} + +# Try to open a database for writing in a directory that +# doesn't exist but for which the parent directory does +# exist. This should work! +# +do_test dbbe-1.3 { + catch {db close} + file delete -force testdb + set v [catch {sqlite db testdb 0666} msg] + lappend v $msg +} {0 {}} + +# Try to open a file instead of a directory. +# +do_test dbbe-1.4 { + catch {db close} + file delete -force testdb + set fd [open testdb w] + puts $fd hi! + close $fd + set v [catch {sqlite db testdb 0666} msg] + lappend v $msg +} {1 {not a directory: "testdb"}} + +# Access permission denied on the directory. +# +do_test dbbe-1.5 { + catch {db close} + file delete -force testdb + file mkdir testdb + file attributes testdb -permissions 0 + set v [catch {sqlite db testdb 0666} msg] + lappend v $msg +} {1 {access permission denied}} + +# Access permission denied on the master file +# +do_test dbbe-1.6 { + catch {db close} + file delete -force testdb + sqlite db testdb 0666 + execsql {CREATE TABLE t1(x int)} + db close + file attributes testdb/sqlite_master.tbl -permission 0444 + set v [catch {sqlite db testdb 0666} msg] + lappend v $msg +} {1 {access permission denied for testdb/sqlite_master.tbl}} +do_test dbbe-1.6b { + catch {db close} + file delete -force testdb + sqlite db testdb 0666 + execsql {CREATE TABLE t1(x int)} + db close + file attributes testdb/sqlite_master.tbl -permission 0444 + set v [catch {sqlite db testdb 0444} msg] + lappend v $msg +} {0 {}} + +# Make sure a table can be accessed by either uppercase or lowercase +# names +# +do_test dbbe-2.1 { + catch {db close} + file delete -force testdb + sqlite db testdb 0666 + execsql { + CREATE TABLE t1(x int); + INSERT INTO t1 VALUES(1); + } + db close + sqlite db testdb 0444 + set r [execsql {SELECT * FROM T1}] + db close + sqlite db testdb 0666 + lappend r [execsql {SELECT * FROM t1}] +} {1 1} + +finish_test diff --git a/test/insert.test b/test/insert.test index 45a642ed6e..25988903d6 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.3 2000/06/03 18:06:53 drh Exp $ +# $Id: insert.test,v 1.4 2000/06/07 14:42:27 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -126,12 +126,13 @@ do_test insert-2.3 { # 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} + execsql { + DELETE FROM test2; + CREATE INDEX index9 ON test2(f1,f2); + CREATE INDEX indext ON test2(f4,f5); + SELECT * from test2; + } } {} do_test insert-3.2 { execsql {INSERT INTO test2(f2,f4) VALUES(-3.33,'hum')} diff --git a/test/insert2.test b/test/insert2.test new file mode 100644 index 0000000000..de87a75b92 --- /dev/null +++ b/test/insert2.test @@ -0,0 +1,73 @@ +# 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 INSERT statement that takes is +# result from a SELECT. +# +# $Id: insert2.test,v 1.1 2000/06/07 14:42:27 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Create some tables with data that we can select against +# +do_test insert2-1.0 { + execsql {CREATE TABLE d1(n int, log int);} + for {set i 1} {$i<=20} {incr i} { + for {set j 0} {pow(2,$j)<$i} {incr j} {} + execsql "INSERT INTO d1 VALUES($i,$j)" + } + execsql {SELECT * FROM d1 ORDER BY n} +} {1 0 2 1 3 2 4 2 5 3 6 3 7 3 8 3 9 4 10 4 11 4 12 4 13 4 14 4 15 4 16 4 17 5 18 5 19 5 20 5} + +# Insert into a new table from the old one. +# +do_test insert2-1.1 { + execsql { + CREATE TABLE t1(log int, cnt int); + INSERT INTO t1 SELECT log, count(*) FROM d1 GROUP BY log; + } + execsql {SELECT * FROM t1 ORDER BY log} +} {0 1 1 1 2 2 3 4 4 8 5 4} +do_test insert2-1.2 { + catch {execsql {DROP TABLE t1}} + execsql { + CREATE TABLE t1(log int, cnt int); + INSERT INTO t1 + SELECT log, count(*) FROM d1 GROUP BY log + EXCEPT SELECT n-1,log FROM d1; + SELECT * FROM t1 ORDER BY log; + } +} {0 1 3 4 4 8 5 4} +do_test insert2-1.3 { + catch {execsql {DROP TABLE t1}} + execsql { + CREATE TABLE t1(log int, cnt int); + INSERT INTO t1 + SELECT log, count(*) FROM d1 GROUP BY log + INTERSECT SELECT n-1,log FROM d1; + SELECT * FROM t1 ORDER BY log; + } +} {1 1 2 2} + +finish_test diff --git a/test/select1.test b/test/select1.test index c3cd08dd88..235d4b5f18 100644 --- a/test/select1.test +++ b/test/select1.test @@ -23,7 +23,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the SELECT statement. # -# $Id: select1.test,v 1.3 2000/06/06 17:27:06 drh Exp $ +# $Id: select1.test,v 1.4 2000/06/07 14:42:27 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -265,12 +265,12 @@ do_test select1-6.4 { do_test select1-6.5 { set v [catch {execsql2 {SELECT test1.f1+F2 FROM test1 ORDER BY f2}} msg] lappend v $msg -} {0 {field1 33 field1 77}} +} {0 {column1 33 column1 77}} do_test select1-6.6 { set v [catch {execsql2 {SELECT test1.f1+F2, t1 FROM test1, test2 ORDER BY f2}} msg] lappend v $msg -} {0 {field1 33 test2.t1 abc field1 77 test2.t1 abc}} +} {0 {column1 33 test2.t1 abc column1 77 test2.t1 abc}} do_test select1-6.7 { set v [catch {execsql2 {SELECT A.f1, t1 FROM test1 as A, test2 ORDER BY f2}} msg]