mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
:-) (CVS 1697)
FossilOrigin-Name: 5d773b5d4e9c23b81f53afd0cef7bd2300fff329
This commit is contained in:
28
manifest
28
manifest
@@ -1,5 +1,5 @@
|
|||||||
C :-)\s(CVS\s68)
|
C :-)\s(CVS\s1697)
|
||||||
D 2000-06-07T02:04:23
|
D 2000-06-07T14:42:26
|
||||||
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
||||||
F Makefile.in 17ba1ccf8d2d40c627796bba8f72952365d6d644
|
F Makefile.in 17ba1ccf8d2d40c627796bba8f72952365d6d644
|
||||||
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
||||||
@@ -7,17 +7,17 @@ F configure 00a5b5c82147a576fa6e82d7c1b0d55c321d6d2c x
|
|||||||
F configure.in 6ccfd5fc80517f7cfe605a7fc7e0f62d962a233c
|
F configure.in 6ccfd5fc80517f7cfe605a7fc7e0f62d962a233c
|
||||||
F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47
|
F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47
|
||||||
F src/build.c 6c9454b2e2b866979527fb41b19ad8bc49c27a20
|
F src/build.c 6c9454b2e2b866979527fb41b19ad8bc49c27a20
|
||||||
F src/dbbe.c ae8b5d2cdb4fa7dd11313059984be9457fa77f63
|
F src/dbbe.c 9b191b16ff01ec5bc0af436558501d07938ba4f0
|
||||||
F src/dbbe.h a8a46f71238e0f09f3ec08fd9d1c8c7f4cdc49bf
|
F src/dbbe.h a8a46f71238e0f09f3ec08fd9d1c8c7f4cdc49bf
|
||||||
F src/delete.c 8c733bb82a1b84126116d03dcdccf433c0856f5d
|
F src/delete.c 8c733bb82a1b84126116d03dcdccf433c0856f5d
|
||||||
F src/expr.c d350fe393e1753aaa733a5d21f0830a23e547400
|
F src/expr.c d350fe393e1753aaa733a5d21f0830a23e547400
|
||||||
F src/insert.c 5e69dd70c3f91cf5ec5090f39fd6cd8e135af9bf
|
F src/insert.c 8bd762bb6aa7bf0e6abda03699c88db7736bf7dd
|
||||||
F src/main.c 93a7ad14bb5a82ad13ad59da23ef674a94b0c3d6
|
F src/main.c 48440ddd39783ac379c746804e3424e06cdf7138
|
||||||
F src/parse.y 8b632f4c4ff2f4400f15592ca9d8fda27d97d0c4
|
F src/parse.y 4a2e6b14177c97f61fc3e21d4570f5a9c541c1e1
|
||||||
F src/select.c 74fa3af62bfa2e6e29f43153f883fd28c295b853
|
F src/select.c 4834ab68a3308871f17fe8e22d903fcdf1b42420
|
||||||
F src/shell.c 3f4afc39a36e4824e8aa262623fd03568874799e
|
F src/shell.c 3f4afc39a36e4824e8aa262623fd03568874799e
|
||||||
F src/sqlite.h 58da0a8590133777b741f9836beaef3d58f40268
|
F src/sqlite.h 58da0a8590133777b741f9836beaef3d58f40268
|
||||||
F src/sqliteInt.h 3cca846df0a8b5f811cf4f8021303547cd8f21fd
|
F src/sqliteInt.h a593cb946ea81f24c8a79f996d6597184ab40053
|
||||||
F src/tclsqlite.c 9f358618ae803bedf4fb96da5154fd45023bc1f7
|
F src/tclsqlite.c 9f358618ae803bedf4fb96da5154fd45023bc1f7
|
||||||
F src/tokenize.c 900af9479d0feaa76b0225680196aa81afec930a
|
F src/tokenize.c 900af9479d0feaa76b0225680196aa81afec930a
|
||||||
F src/update.c 18746f920f989b3d19d96c08263c92584823cd35
|
F src/update.c 18746f920f989b3d19d96c08263c92584823cd35
|
||||||
@@ -27,12 +27,14 @@ F src/vdbe.h 8f79f57c66ce1030f6371ff067b326d627a52c6d
|
|||||||
F src/where.c c9b90e7672f4662a83ef9a27a193020d69fe034c
|
F src/where.c c9b90e7672f4662a83ef9a27a193020d69fe034c
|
||||||
F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7
|
F test/all.test 0950c135cab7e60c07bd745ccfad1476211e5bd7
|
||||||
F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb
|
F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb
|
||||||
|
F test/dbbe.test 3978ab21ff2a0531a85618c538d27047d560fc5d
|
||||||
F test/delete.test 30451333f89479d2deb5410edd3f3cce67339944
|
F test/delete.test 30451333f89479d2deb5410edd3f3cce67339944
|
||||||
F test/expr.test 52be5592143a88479e0006dfd7e2023e43294636
|
F test/expr.test 52be5592143a88479e0006dfd7e2023e43294636
|
||||||
F test/in.test 17cd46a9ca0e5d4a804483e6fb496458494858e6
|
F test/in.test 17cd46a9ca0e5d4a804483e6fb496458494858e6
|
||||||
F test/index.test 9f99dca2d904b8de330863a978587f136e2df65a
|
F test/index.test 9f99dca2d904b8de330863a978587f136e2df65a
|
||||||
F test/insert.test b4c186ffa4b97a231643726f3bcee29815b24eaf
|
F test/insert.test 66f4c3bd600fec8eb1e733b928cbe6fa885eff0c
|
||||||
F test/select1.test 2311bddd40bca257c27a7d141ed2a359bbdbc906
|
F test/insert2.test 2d529bc4acf33dcf554a8c2e4593aab270fa6faf
|
||||||
|
F test/select1.test 55af6d31c778022ac3eecd051a66e9df3573c46f
|
||||||
F test/select2.test 3cd3c0f9d67e98b1b54af5853679b4a111224410
|
F test/select2.test 3cd3c0f9d67e98b1b54af5853679b4a111224410
|
||||||
F test/select3.test 73ae8c7b80c4e03a9c29d12f2ea1782e28b8e61f
|
F test/select3.test 73ae8c7b80c4e03a9c29d12f2ea1782e28b8e61f
|
||||||
F test/sort.test d582086c4bb7df3fbf50aa72e69d7e235e9f8e31
|
F test/sort.test d582086c4bb7df3fbf50aa72e69d7e235e9f8e31
|
||||||
@@ -51,7 +53,7 @@ F www/c_interface.tcl 9ac800854272db5fe439e07b7435b243a5422293
|
|||||||
F www/changes.tcl 04e66b4257589ff78a7e1de93e9dda4725fb03d6
|
F www/changes.tcl 04e66b4257589ff78a7e1de93e9dda4725fb03d6
|
||||||
F www/index.tcl 52e29a4eeda8d59e91af43c61fef177c5f2ffd53
|
F www/index.tcl 52e29a4eeda8d59e91af43c61fef177c5f2ffd53
|
||||||
F www/sqlite.tcl 2f933ce18cffd34a0a020a82435ab937137970fd
|
F www/sqlite.tcl 2f933ce18cffd34a0a020a82435ab937137970fd
|
||||||
P 8bff1bee63b77353b4cfe5aa0c662187a7bf93da
|
P fc8d25ea1fffa115fad15b9eb8bb0b0aaaff0431
|
||||||
R 66723773907deae85c622c6e494a06db
|
R 57fdc174a06c58f4d8c32ca7ec794547
|
||||||
U drh
|
U drh
|
||||||
Z 03e9a47b962f6283d6dab7f071f9c9ae
|
Z 6ab7c0c87e13b9e4938e70912c15eacc
|
||||||
|
@@ -1 +1 @@
|
|||||||
fc8d25ea1fffa115fad15b9eb8bb0b0aaaff0431
|
5d773b5d4e9c23b81f53afd0cef7bd2300fff329
|
@@ -30,7 +30,7 @@
|
|||||||
** relatively simple to convert to a different database such
|
** relatively simple to convert to a different database such
|
||||||
** as NDBM, SDBM, or BerkeleyDB.
|
** 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 "sqliteInt.h"
|
||||||
#include <gdbm.h>
|
#include <gdbm.h>
|
||||||
@@ -161,7 +161,7 @@ Dbbe *sqliteDbbeOpen(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
zMaster = 0;
|
zMaster = 0;
|
||||||
sqliteSetString(&zMaster, zName, "/" MASTER_NAME, 0);
|
sqliteSetString(&zMaster, zName, "/" MASTER_NAME ".tbl", 0);
|
||||||
if( stat(zMaster, &statbuf)==0
|
if( stat(zMaster, &statbuf)==0
|
||||||
&& access(zMaster, writeFlag ? (W_OK|R_OK) : R_OK)!=0 ){
|
&& access(zMaster, writeFlag ? (W_OK|R_OK) : R_OK)!=0 ){
|
||||||
sqliteSetString(pzErrMsg, "access permission denied for ", zMaster, 0);
|
sqliteSetString(pzErrMsg, "access permission denied for ", zMaster, 0);
|
||||||
|
142
src/insert.c
142
src/insert.c
@@ -24,7 +24,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle INSERT statements.
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -39,12 +39,18 @@ void sqliteInsert(
|
|||||||
Parse *pParse, /* Parser context */
|
Parse *pParse, /* Parser context */
|
||||||
Token *pTableName, /* Name of table into which we are inserting */
|
Token *pTableName, /* Name of table into which we are inserting */
|
||||||
ExprList *pList, /* List of values to be inserted */
|
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 */
|
IdList *pField /* Field name corresponding to pList. Might be NULL */
|
||||||
){
|
){
|
||||||
Table *pTab;
|
Table *pTab; /* The table to insert into */
|
||||||
char *zTab;
|
char *zTab; /* Name of the table into which we are inserting */
|
||||||
int i, j, idx;
|
int i, j, idx; /* Loop counters */
|
||||||
Vdbe *v;
|
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);
|
zTab = sqliteTableNameFromToken(pTableName);
|
||||||
pTab = sqliteFindTable(pParse->db, zTab);
|
pTab = sqliteFindTable(pParse->db, zTab);
|
||||||
@@ -61,10 +67,28 @@ void sqliteInsert(
|
|||||||
pParse->nErr++;
|
pParse->nErr++;
|
||||||
goto insert_cleanup;
|
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 zNum1[30];
|
||||||
char zNum2[30];
|
char zNum2[30];
|
||||||
sprintf(zNum1,"%d", pList->nExpr);
|
sprintf(zNum1,"%d", nField);
|
||||||
sprintf(zNum2,"%d", pTab->nCol);
|
sprintf(zNum2,"%d", pTab->nCol);
|
||||||
sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
|
sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
|
||||||
" has ", zNum2, " columns but ",
|
" has ", zNum2, " columns but ",
|
||||||
@@ -72,10 +96,10 @@ void sqliteInsert(
|
|||||||
pParse->nErr++;
|
pParse->nErr++;
|
||||||
goto insert_cleanup;
|
goto insert_cleanup;
|
||||||
}
|
}
|
||||||
if( pField!=0 && pList->nExpr!=pField->nId ){
|
if( pField!=0 && nField!=pField->nId ){
|
||||||
char zNum1[30];
|
char zNum1[30];
|
||||||
char zNum2[30];
|
char zNum2[30];
|
||||||
sprintf(zNum1,"%d", pList->nExpr);
|
sprintf(zNum1,"%d", nField);
|
||||||
sprintf(zNum2,"%d", pField->nId);
|
sprintf(zNum2,"%d", pField->nId);
|
||||||
sqliteSetString(&pParse->zErrMsg, zNum1, " values for ",
|
sqliteSetString(&pParse->zErrMsg, zNum1, " values for ",
|
||||||
zNum2, " columns", 0);
|
zNum2, " columns", 0);
|
||||||
@@ -101,73 +125,81 @@ void sqliteInsert(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v = pParse->pVdbe;
|
base = pParse->nTab;
|
||||||
if( v==0 ){
|
sqliteVdbeAddOp(v, OP_Open, base, 1, pTab->zName, 0);
|
||||||
v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe);
|
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
||||||
|
sqliteVdbeAddOp(v, OP_Open, idx+base, 1, pIdx->zName, 0);
|
||||||
}
|
}
|
||||||
if( v ){
|
if( srcTab>=0 ){
|
||||||
Index *pIdx;
|
sqliteVdbeAddOp(v, OP_Rewind, srcTab, 0, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Open, 0, 1, pTab->zName, 0);
|
iBreak = sqliteVdbeMakeLabel(v);
|
||||||
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
iCont = sqliteVdbeAddOp(v, OP_Next, srcTab, iBreak, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Open, idx, 1, pIdx->zName, 0);
|
}
|
||||||
|
sqliteVdbeAddOp(v, OP_New, 0, 0, 0, 0);
|
||||||
|
if( pTab->pIndex ){
|
||||||
|
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
for(i=0; i<pTab->nCol; i++){
|
||||||
|
if( pField==0 ){
|
||||||
|
j = i;
|
||||||
|
}else{
|
||||||
|
for(j=0; j<pField->nId; j++){
|
||||||
|
if( pField->a[j].idx==i ) break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_New, 0, 0, 0, 0);
|
if( pField && j>=pField->nId ){
|
||||||
if( pTab->pIndex ){
|
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);
|
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
for(i=0; i<pTab->nCol; i++){
|
for(i=0; i<pIdx->nField; i++){
|
||||||
|
int idx = pIdx->aiField[i];
|
||||||
if( pField==0 ){
|
if( pField==0 ){
|
||||||
j = i;
|
j = idx;
|
||||||
}else{
|
}else{
|
||||||
for(j=0; j<pField->nId; j++){
|
for(j=0; j<pField->nId; j++){
|
||||||
if( pField->a[j].idx==i ) break;
|
if( pField->a[j].idx==idx ) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( pField && j>=pField->nId ){
|
if( pField && j>=pField->nId ){
|
||||||
char *zDflt = pTab->aCol[i].zDflt;
|
char *zDflt = pTab->aCol[idx].zDflt;
|
||||||
if( zDflt==0 ){
|
if( zDflt==0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Null, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Null, 0, 0, 0, 0);
|
||||||
}else{
|
}else{
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0, zDflt, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0, zDflt, 0);
|
||||||
}
|
}
|
||||||
|
}else if( srcTab>=0 ){
|
||||||
|
sqliteVdbeAddOp(v, OP_Field, srcTab, i, 0, 0);
|
||||||
}else{
|
}else{
|
||||||
sqliteExprCode(pParse, pList->a[j].pExpr);
|
sqliteExprCode(pParse, pList->a[j].pExpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_PutIdx, idx+base, 0, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Close, 0, 0, 0, 0);
|
/* sqliteVdbeAddOp(v, OP_Close, idx, 0, 0, 0); */
|
||||||
for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
|
}
|
||||||
if( pIdx->pNext ){
|
if( srcTab>=0 ){
|
||||||
sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0);
|
||||||
}
|
sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, iBreak);
|
||||||
for(i=0; i<pIdx->nField; i++){
|
|
||||||
int idx = pIdx->aiField[i];
|
|
||||||
if( pField==0 ){
|
|
||||||
j = idx;
|
|
||||||
}else{
|
|
||||||
for(j=0; j<pField->nId; 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
insert_cleanup:
|
insert_cleanup:
|
||||||
sqliteExprListDelete(pList);
|
if( pList ) sqliteExprListDelete(pList);
|
||||||
|
if( pSelect ) sqliteSelectDelete(pSelect);
|
||||||
sqliteIdListDelete(pField);
|
sqliteIdListDelete(pField);
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,7 @@
|
|||||||
** other files are for internal use by SQLite and should not be
|
** other files are for internal use by SQLite and should not be
|
||||||
** accessed by users of the library.
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -174,6 +174,7 @@ sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
|
|||||||
/* Open the backend database driver */
|
/* Open the backend database driver */
|
||||||
db->pBe = sqliteDbbeOpen(zFilename, (mode&0222)!=0, mode!=0, pzErrMsg);
|
db->pBe = sqliteDbbeOpen(zFilename, (mode&0222)!=0, mode!=0, pzErrMsg);
|
||||||
if( db->pBe==0 ){
|
if( db->pBe==0 ){
|
||||||
|
sqliteStrRealloc(pzErrMsg);
|
||||||
sqliteFree(db);
|
sqliteFree(db);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,7 @@
|
|||||||
** the parser. Lemon will also generate a header file containing
|
** the parser. Lemon will also generate a header file containing
|
||||||
** numeric codes for all of the tokens.
|
** 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_prefix TK_
|
||||||
%token_type {Token}
|
%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);}
|
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.
|
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*}
|
%type itemlist {ExprList*}
|
||||||
|
13
src/select.c
13
src/select.c
@@ -24,7 +24,7 @@
|
|||||||
** This file contains C code routines that are called by the parser
|
** This file contains C code routines that are called by the parser
|
||||||
** to handle SELECT statements.
|
** 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"
|
#include "sqliteInt.h"
|
||||||
|
|
||||||
@@ -156,6 +156,15 @@ static int selectInnerLoop(
|
|||||||
sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
|
sqliteVdbeAddOp(v, OP_Put, iParm, 0, 0, 0);
|
||||||
}else
|
}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
|
/* Construct a record from the query result, but instead of
|
||||||
** saving that record, use it as a key to delete elements from
|
** saving that record, use it as a key to delete elements from
|
||||||
** the temporary table iParm.
|
** the temporary table iParm.
|
||||||
@@ -215,7 +224,7 @@ static void generateColumnNames(Vdbe *v, IdList *pTabList, ExprList *pEList){
|
|||||||
p = pEList->a[i].pExpr;
|
p = pEList->a[i].pExpr;
|
||||||
if( p->op!=TK_FIELD || pTabList==0 ){
|
if( p->op!=TK_FIELD || pTabList==0 ){
|
||||||
char zName[30];
|
char zName[30];
|
||||||
sprintf(zName, "field%d", i+1);
|
sprintf(zName, "column%d", i+1);
|
||||||
sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
|
sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
|
||||||
}else{
|
}else{
|
||||||
if( pTabList->nId>1 ){
|
if( pTabList->nId>1 ){
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** 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 "sqlite.h"
|
||||||
#include "dbbe.h"
|
#include "dbbe.h"
|
||||||
@@ -240,6 +240,7 @@ struct Select {
|
|||||||
#define SRT_Set 3 /* Store result as unique keys in a table */
|
#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_Union 5 /* Store result as keys in a table */
|
||||||
#define SRT_Except 6 /* Remove result from a UNION 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)")
|
** 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 sqliteEndTable(Parse*,Token*);
|
||||||
void sqliteDropTable(Parse*, Token*);
|
void sqliteDropTable(Parse*, Token*);
|
||||||
void sqliteDeleteTable(sqlite*, Table*);
|
void sqliteDeleteTable(sqlite*, Table*);
|
||||||
void sqliteInsert(Parse*, Token*, ExprList*, IdList*);
|
void sqliteInsert(Parse*, Token*, ExprList*, Select*, IdList*);
|
||||||
IdList *sqliteIdListAppend(IdList*, Token*);
|
IdList *sqliteIdListAppend(IdList*, Token*);
|
||||||
void sqliteIdListAddAlias(IdList*, Token*);
|
void sqliteIdListAddAlias(IdList*, Token*);
|
||||||
void sqliteIdListDelete(IdList*);
|
void sqliteIdListDelete(IdList*);
|
||||||
|
122
test/dbbe.test
Normal file
122
test/dbbe.test
Normal file
@@ -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
|
@@ -23,7 +23,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing the INSERT statement.
|
# 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]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
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
|
# on a table that has indices. In particular we want to verify
|
||||||
# that the correct default values are inserted into the indices.
|
# 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 {
|
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 {
|
do_test insert-3.2 {
|
||||||
execsql {INSERT INTO test2(f2,f4) VALUES(-3.33,'hum')}
|
execsql {INSERT INTO test2(f2,f4) VALUES(-3.33,'hum')}
|
||||||
|
73
test/insert2.test
Normal file
73
test/insert2.test
Normal file
@@ -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
|
@@ -23,7 +23,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing the SELECT statement.
|
# 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]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -265,12 +265,12 @@ do_test select1-6.4 {
|
|||||||
do_test select1-6.5 {
|
do_test select1-6.5 {
|
||||||
set v [catch {execsql2 {SELECT test1.f1+F2 FROM test1 ORDER BY f2}} msg]
|
set v [catch {execsql2 {SELECT test1.f1+F2 FROM test1 ORDER BY f2}} msg]
|
||||||
lappend v $msg
|
lappend v $msg
|
||||||
} {0 {field1 33 field1 77}}
|
} {0 {column1 33 column1 77}}
|
||||||
do_test select1-6.6 {
|
do_test select1-6.6 {
|
||||||
set v [catch {execsql2 {SELECT test1.f1+F2, t1 FROM test1, test2
|
set v [catch {execsql2 {SELECT test1.f1+F2, t1 FROM test1, test2
|
||||||
ORDER BY f2}} msg]
|
ORDER BY f2}} msg]
|
||||||
lappend v $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 {
|
do_test select1-6.7 {
|
||||||
set v [catch {execsql2 {SELECT A.f1, t1 FROM test1 as A, test2
|
set v [catch {execsql2 {SELECT A.f1, t1 FROM test1 as A, test2
|
||||||
ORDER BY f2}} msg]
|
ORDER BY f2}} msg]
|
||||||
|
Reference in New Issue
Block a user