mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Add support for CREATE TABLE AS. (CVS 377)
FossilOrigin-Name: 78a50971e9adc8739e7888201c79465a40e1a152
This commit is contained in:
26
manifest
26
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Allow\sgeneral\sexpressions\sin\sthe\sVALUES\sclause\sof\san\sINSERT\sstatement.\s(CVS\s376)
|
C Add\ssupport\sfor\sCREATE\sTABLE\sAS.\s(CVS\s377)
|
||||||
D 2002-02-18T13:56:37
|
D 2002-02-18T18:30:32
|
||||||
F Makefile.in 9fa4277413bf1d9cf91365f07d4108d7d87ed2af
|
F Makefile.in 9fa4277413bf1d9cf91365f07d4108d7d87ed2af
|
||||||
F Makefile.template 3372d45f8853afdb70bd30cc6fb50a3cd9069834
|
F Makefile.template 3372d45f8853afdb70bd30cc6fb50a3cd9069834
|
||||||
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
|
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
|
||||||
@@ -21,26 +21,26 @@ F sqlite.1 2e2bb0529ef468ade9e4322bd609d0695fb9ded9
|
|||||||
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
||||||
F src/btree.c 340254ee2ea8b3bd8b60f9768b20382b4909eec0
|
F src/btree.c 340254ee2ea8b3bd8b60f9768b20382b4909eec0
|
||||||
F src/btree.h b131caa44354d0305734d87b1c71440b4c436608
|
F src/btree.h b131caa44354d0305734d87b1c71440b4c436608
|
||||||
F src/build.c 29504057ac5e2f40c08f19cb1574bd0512353169
|
F src/build.c 6643e708b99ee801305584f81550a1e4095b5f97
|
||||||
F src/delete.c f8ad71be53cf18656b6573de65395852fe817f0c
|
F src/delete.c f8ad71be53cf18656b6573de65395852fe817f0c
|
||||||
F src/expr.c 7aff65ea0732b07d36925087ad611019103ad69a
|
F src/expr.c 7aff65ea0732b07d36925087ad611019103ad69a
|
||||||
F src/hash.c 8f7c740ef2eaaa8decfa8751f2be30680b123e46
|
F src/hash.c 8f7c740ef2eaaa8decfa8751f2be30680b123e46
|
||||||
F src/hash.h d1ce47900c7325af5e41c4feb4855c4bf2b841e7
|
F src/hash.h d1ce47900c7325af5e41c4feb4855c4bf2b841e7
|
||||||
F src/insert.c 9453cbba2a62f8a2fb37d77cbdc5c84aa24752d7
|
F src/insert.c 9453cbba2a62f8a2fb37d77cbdc5c84aa24752d7
|
||||||
F src/main.c 300320ba68d3e5b22c2c5b2c07fa884878202181
|
F src/main.c 669cfd9a8c40f6c9ff2d478e1695d1ea1fdafad1
|
||||||
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
||||||
F src/os.c f6bc9b7ab530346bb7fef2ed39f2f1f214bc14ea
|
F src/os.c f6bc9b7ab530346bb7fef2ed39f2f1f214bc14ea
|
||||||
F src/os.h a17596ecc7f38a228b83ecdb661fb03ce44726d6
|
F src/os.h a17596ecc7f38a228b83ecdb661fb03ce44726d6
|
||||||
F src/pager.c d261a3a0b4e96a400ef5432297edec09b041e9c7
|
F src/pager.c d261a3a0b4e96a400ef5432297edec09b041e9c7
|
||||||
F src/pager.h b28f004e2f5541dc60cc32db01bf80cf4d056283
|
F src/pager.h b28f004e2f5541dc60cc32db01bf80cf4d056283
|
||||||
F src/parse.y 39c336ff9ad75429205feaa704d6c1832c648c81
|
F src/parse.y 722bc0b6aacb5a8c365b187bb84e740d802cb51b
|
||||||
F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
|
F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
|
||||||
F src/random.c f6b36bec5ebd3edb3440224bf5bf811fe4ac9a1b
|
F src/random.c f6b36bec5ebd3edb3440224bf5bf811fe4ac9a1b
|
||||||
F src/select.c d2bbaf4cba97b4c40503d0dc47e8b729e7088e0b
|
F src/select.c d2bbaf4cba97b4c40503d0dc47e8b729e7088e0b
|
||||||
F src/shell.c c102dfe388c7618a668c944ff157c49cb48f28e3
|
F src/shell.c c102dfe388c7618a668c944ff157c49cb48f28e3
|
||||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||||
F src/sqlite.h.in f57074c84a2c112a5093ba7a9d9636aa9cacc87c
|
F src/sqlite.h.in f57074c84a2c112a5093ba7a9d9636aa9cacc87c
|
||||||
F src/sqliteInt.h 6c5d0415a6ff54e14fab74d5686016cc53f0be5c
|
F src/sqliteInt.h 75cf79d3d0a0ea40f43bbc2d74a4aefb2ea37ccf
|
||||||
F src/table.c c89698bd5bb4b8d14722d6ee7e9be014c383d24a
|
F src/table.c c89698bd5bb4b8d14722d6ee7e9be014c383d24a
|
||||||
F src/tclsqlite.c b9cf346e95291cb4c4f1bf5ac1d77db6b8ad023d
|
F src/tclsqlite.c b9cf346e95291cb4c4f1bf5ac1d77db6b8ad023d
|
||||||
F src/test1.c 33efd350dca27c52c58c553c04fd3a6a51f13c1f
|
F src/test1.c 33efd350dca27c52c58c553c04fd3a6a51f13c1f
|
||||||
@@ -87,7 +87,7 @@ F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
|
|||||||
F test/select6.test d9fb417d6cab75a072b547ba6303120f327fd6fd
|
F test/select6.test d9fb417d6cab75a072b547ba6303120f327fd6fd
|
||||||
F test/sort.test 3b996ce7ca385f9cd559944ac0f4027a23aa546b
|
F test/sort.test 3b996ce7ca385f9cd559944ac0f4027a23aa546b
|
||||||
F test/subselect.test 335d3dad8d585726c447dfee8d9c4f7383c76b78
|
F test/subselect.test 335d3dad8d585726c447dfee8d9c4f7383c76b78
|
||||||
F test/table.test 3ef4254d62ece31a3872ab11cdaec846f6fa8fd1
|
F test/table.test b8be4d3d3ff6b4858516fa274d38075ba06b5004
|
||||||
F test/tableapi.test 51d0c209aa6b1158cb952ec917c656d4ce66e9e4
|
F test/tableapi.test 51d0c209aa6b1158cb952ec917c656d4ce66e9e4
|
||||||
F test/tclsqlite.test ca8dd89b02ab68bd4540163c24551756a69f6783
|
F test/tclsqlite.test ca8dd89b02ab68bd4540163c24551756a69f6783
|
||||||
F test/temptable.test 0e9934283259a5e637eec756a7eefd6964c0f79b
|
F test/temptable.test 0e9934283259a5e637eec756a7eefd6964c0f79b
|
||||||
@@ -108,22 +108,22 @@ F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
|
|||||||
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
|
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
|
||||||
F www/arch.tcl 72a0c80e9054cc7025a50928d28d9c75c02c2b8b
|
F www/arch.tcl 72a0c80e9054cc7025a50928d28d9c75c02c2b8b
|
||||||
F www/c_interface.tcl 82a026b1681757f13b3f62e035f3a31407c1d353
|
F www/c_interface.tcl 82a026b1681757f13b3f62e035f3a31407c1d353
|
||||||
F www/changes.tcl e97a76943c2c4029f6ffba60c4dc6c24478e151c
|
F www/changes.tcl 46137c6e31a9b805dddaebac048177bc48fee1e7
|
||||||
F www/conflict.tcl 81dd21f9a679e60aae049e9dd8ab53d59570cda2
|
F www/conflict.tcl 81dd21f9a679e60aae049e9dd8ab53d59570cda2
|
||||||
F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
|
F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
|
||||||
F www/download.tcl a6d75b8b117cd33dcb090bef7e80d7556d28ebe0
|
F www/download.tcl a6d75b8b117cd33dcb090bef7e80d7556d28ebe0
|
||||||
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
|
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
|
||||||
F www/faq.tcl 32cbc134879871604070d4cc3a32e73fb22a35f9
|
F www/faq.tcl 32cbc134879871604070d4cc3a32e73fb22a35f9
|
||||||
F www/formatchng.tcl 2d9a35c787823b48d72a5c64bb5414a43e26d5ad
|
F www/formatchng.tcl 2d9a35c787823b48d72a5c64bb5414a43e26d5ad
|
||||||
F www/index.tcl fba075f31a9cbbf13e6adec080e4943db54dbc05
|
F www/index.tcl eacd99bcc3132d6e6b74a51422d415cc0bf7bfdf
|
||||||
F www/lang.tcl 4865287af7bb8649d8d985772a13e2f6ec639a3e
|
F www/lang.tcl 1712d94f9606b6b84982e697df0667b6a2cb1a5e
|
||||||
F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc
|
F www/mingw.tcl f1c7c0a7f53387dd9bb4f8c7e8571b7561510ebc
|
||||||
F www/opcode.tcl bdec8ef9f100dbd87bbef8976c54b88e43fd8ccc
|
F www/opcode.tcl bdec8ef9f100dbd87bbef8976c54b88e43fd8ccc
|
||||||
F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5
|
F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5
|
||||||
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
|
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
|
||||||
F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
|
F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
|
||||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||||
P a0019fce701fc858134f0a33bda9a511e41a09f8
|
P ec1f3fae6f8cd8466892cd370e1802e492a76e6e
|
||||||
R b95029b9b39abf918f39e16a59c21b3e
|
R 30ea68cf718b068f84b3b8ebb60eb037
|
||||||
U drh
|
U drh
|
||||||
Z 7c3a4a0f74cd2eb9fb88495aad858df0
|
Z 8fa30e75945f1116f95b36a95a26e476
|
||||||
|
@@ -1 +1 @@
|
|||||||
ec1f3fae6f8cd8466892cd370e1802e492a76e6e
|
78a50971e9adc8739e7888201c79465a40e1a152
|
124
src/build.c
124
src/build.c
@@ -25,7 +25,7 @@
|
|||||||
** ROLLBACK
|
** ROLLBACK
|
||||||
** PRAGMA
|
** PRAGMA
|
||||||
**
|
**
|
||||||
** $Id: build.c,v 1.74 2002/02/03 17:37:36 drh Exp $
|
** $Id: build.c,v 1.75 2002/02/18 18:30:32 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -650,6 +650,77 @@ static void changeCookie(sqlite *db){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Measure the number of characters needed to output the given
|
||||||
|
** identifier. The number returned includes any quotes used
|
||||||
|
** but does not include the null terminator.
|
||||||
|
*/
|
||||||
|
static int identLength(const char *z){
|
||||||
|
int n;
|
||||||
|
for(n=2; *z; n++, z++){
|
||||||
|
if( *z=='\'' ){ n++; }
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Write an identifier onto the end of the given string. Add
|
||||||
|
** quote characters as needed.
|
||||||
|
*/
|
||||||
|
static void identPut(char *z, int *pIdx, char *zIdent){
|
||||||
|
int i, j;
|
||||||
|
i = *pIdx;
|
||||||
|
z[i++] = '\'';
|
||||||
|
for(j=0; zIdent[j]; j++){
|
||||||
|
z[i++] = zIdent[j];
|
||||||
|
if( zIdent[j]=='\'' ) z[i++] = '\'';
|
||||||
|
}
|
||||||
|
z[i++] = '\'';
|
||||||
|
z[i] = 0;
|
||||||
|
*pIdx = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Generate a CREATE TABLE statement appropriate for the given
|
||||||
|
** table. Memory to hold the text of the statement is obtained
|
||||||
|
** from sqliteMalloc() and must be freed by the calling function.
|
||||||
|
*/
|
||||||
|
static char *createTableStmt(Table *p){
|
||||||
|
int i, k, n;
|
||||||
|
char *zStmt;
|
||||||
|
char *zSep, *zSep2, *zEnd;
|
||||||
|
n = 0;
|
||||||
|
for(i=0; i<p->nCol; i++){
|
||||||
|
n += identLength(p->aCol[i].zName);
|
||||||
|
}
|
||||||
|
n += identLength(p->zName);
|
||||||
|
if( n<40 ){
|
||||||
|
zSep = "";
|
||||||
|
zSep2 = ",";
|
||||||
|
zEnd = ")";
|
||||||
|
}else{
|
||||||
|
zSep = "\n ";
|
||||||
|
zSep2 = ",\n ";
|
||||||
|
zEnd = "\n)";
|
||||||
|
}
|
||||||
|
n += 25 + 6*p->nCol;
|
||||||
|
zStmt = sqliteMalloc( n );
|
||||||
|
if( zStmt==0 ) return 0;
|
||||||
|
assert( !p->isTemp );
|
||||||
|
strcpy(zStmt, "CREATE TABLE ");
|
||||||
|
k = strlen(zStmt);
|
||||||
|
identPut(zStmt, &k, p->zName);
|
||||||
|
zStmt[k++] = '(';
|
||||||
|
for(i=0; i<p->nCol; i++){
|
||||||
|
strcpy(&zStmt[k], zSep);
|
||||||
|
k += strlen(&zStmt[k]);
|
||||||
|
zSep = zSep2;
|
||||||
|
identPut(zStmt, &k, p->aCol[i].zName);
|
||||||
|
}
|
||||||
|
strcpy(&zStmt[k], zEnd);
|
||||||
|
return zStmt;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This routine is called to report the final ")" that terminates
|
** This routine is called to report the final ")" that terminates
|
||||||
** a CREATE TABLE statement.
|
** a CREATE TABLE statement.
|
||||||
@@ -664,12 +735,17 @@ static void changeCookie(sqlite *db){
|
|||||||
** connected to the database or because the sqlite_master table has
|
** connected to the database or because the sqlite_master table has
|
||||||
** recently changes, so the entry for this table already exists in
|
** recently changes, so the entry for this table already exists in
|
||||||
** the sqlite_master table. We do not want to create it again.
|
** the sqlite_master table. We do not want to create it again.
|
||||||
|
**
|
||||||
|
** If the pSelect argument is not NULL, it means that this routine
|
||||||
|
** was called to create a table generated from a
|
||||||
|
** "CREATE TABLE ... AS SELECT ..." statement. The column names of
|
||||||
|
** the new table will match the result set of the SELECT.
|
||||||
*/
|
*/
|
||||||
void sqliteEndTable(Parse *pParse, Token *pEnd){
|
void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){
|
||||||
Table *p;
|
Table *p;
|
||||||
sqlite *db = pParse->db;
|
sqlite *db = pParse->db;
|
||||||
|
|
||||||
if( pEnd==0 || pParse->nErr || sqlite_malloc_failed ) return;
|
if( (pEnd==0 && pSelect==0) || pParse->nErr || sqlite_malloc_failed ) return;
|
||||||
p = pParse->pNewTable;
|
p = pParse->pNewTable;
|
||||||
if( p==0 ) return;
|
if( p==0 ) return;
|
||||||
|
|
||||||
@@ -688,6 +764,19 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
|
|||||||
db->flags |= SQLITE_InternChanges;
|
db->flags |= SQLITE_InternChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If the table is generated from a SELECT, then construct the
|
||||||
|
** list of columns and the text of the table.
|
||||||
|
*/
|
||||||
|
if( pSelect ){
|
||||||
|
Table *pSelTab = sqliteResultSetOfSelect(pParse, 0, pSelect);
|
||||||
|
assert( p->aCol==0 );
|
||||||
|
p->nCol = pSelTab->nCol;
|
||||||
|
p->aCol = pSelTab->aCol;
|
||||||
|
pSelTab->nCol = 0;
|
||||||
|
pSelTab->aCol = 0;
|
||||||
|
sqliteDeleteTable(0, pSelTab);
|
||||||
|
}
|
||||||
|
|
||||||
/* If the initFlag is 1 it means we are reading the SQL off the
|
/* If the initFlag is 1 it means we are reading the SQL off the
|
||||||
** "sqlite_master" table on the disk. So do not write to the disk
|
** "sqlite_master" table on the disk. So do not write to the disk
|
||||||
** again. Extract the root page number for the table from the
|
** again. Extract the root page number for the table from the
|
||||||
@@ -710,7 +799,9 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
|
|||||||
|
|
||||||
v = sqliteGetVdbe(pParse);
|
v = sqliteGetVdbe(pParse);
|
||||||
if( v==0 ) return;
|
if( v==0 ) return;
|
||||||
n = Addr(pEnd->z) - Addr(pParse->sFirstToken.z) + 1;
|
addr = sqliteVdbeAddOp(v, OP_CreateTable, 0, p->isTemp);
|
||||||
|
sqliteVdbeChangeP3(v, addr, (char *)&p->tnum, P3_POINTER);
|
||||||
|
p->tnum = 0;
|
||||||
if( !p->isTemp ){
|
if( !p->isTemp ){
|
||||||
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
|
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
@@ -719,19 +810,30 @@ void sqliteEndTable(Parse *pParse, Token *pEnd){
|
|||||||
sqliteVdbeChangeP3(v, -1, p->zName, P3_STATIC);
|
sqliteVdbeChangeP3(v, -1, p->zName, P3_STATIC);
|
||||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeChangeP3(v, -1, p->zName, P3_STATIC);
|
sqliteVdbeChangeP3(v, -1, p->zName, P3_STATIC);
|
||||||
}
|
sqliteVdbeAddOp(v, OP_Dup, 4, 0);
|
||||||
addr = sqliteVdbeAddOp(v, OP_CreateTable, 0, p->isTemp);
|
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||||
sqliteVdbeChangeP3(v, addr, (char *)&p->tnum, P3_POINTER);
|
if( pSelect ){
|
||||||
p->tnum = 0;
|
char *z = createTableStmt(p);
|
||||||
if( !p->isTemp ){
|
n = z ? strlen(z) : 0;
|
||||||
addr = sqliteVdbeAddOp(v, OP_String, 0, 0);
|
sqliteVdbeChangeP3(v, -1, z, n);
|
||||||
sqliteVdbeChangeP3(v, addr, pParse->sFirstToken.z, n);
|
sqliteFree(z);
|
||||||
|
}else{
|
||||||
|
assert( pEnd!=0 );
|
||||||
|
n = Addr(pEnd->z) - Addr(pParse->sFirstToken.z) + 1;
|
||||||
|
sqliteVdbeChangeP3(v, -1, pParse->sFirstToken.z, n);
|
||||||
|
}
|
||||||
sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
|
sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
|
||||||
sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
|
sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
|
||||||
changeCookie(db);
|
changeCookie(db);
|
||||||
sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0);
|
sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0);
|
||||||
sqliteVdbeAddOp(v, OP_Close, 0, 0);
|
sqliteVdbeAddOp(v, OP_Close, 0, 0);
|
||||||
}
|
}
|
||||||
|
if( pSelect ){
|
||||||
|
int op = p->isTemp ? OP_OpenWrAux : OP_OpenWrite;
|
||||||
|
sqliteVdbeAddOp(v, op, 1, 0);
|
||||||
|
pParse->nTab = 2;
|
||||||
|
sqliteSelect(pParse, pSelect, SRT_Table, 1);
|
||||||
|
}
|
||||||
sqliteEndWriteOperation(pParse);
|
sqliteEndWriteOperation(pParse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,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.58 2002/02/02 15:01:16 drh Exp $
|
** $Id: main.c,v 1.59 2002/02/18 18:30:33 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
@@ -395,6 +395,13 @@ int sqlite_complete(const char *zSql){
|
|||||||
case '\f': {
|
case '\f': {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case '[': {
|
||||||
|
isComplete = 0;
|
||||||
|
zSql++;
|
||||||
|
while( *zSql && *zSql!=']' ){ zSql++; }
|
||||||
|
if( *zSql==0 ) return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case '\'': {
|
case '\'': {
|
||||||
isComplete = 0;
|
isComplete = 0;
|
||||||
zSql++;
|
zSql++;
|
||||||
|
16
src/parse.y
16
src/parse.y
@@ -14,7 +14,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.50 2002/02/18 13:56:37 drh Exp $
|
** @(#) $Id: parse.y,v 1.51 2002/02/18 18:30:33 drh Exp $
|
||||||
*/
|
*/
|
||||||
%token_prefix TK_
|
%token_prefix TK_
|
||||||
%token_type {Token}
|
%token_type {Token}
|
||||||
@@ -68,13 +68,19 @@ cmd ::= ROLLBACK trans_opt. {sqliteRollbackTransaction(pParse);}
|
|||||||
///////////////////// The CREATE TABLE statement ////////////////////////////
|
///////////////////// The CREATE TABLE statement ////////////////////////////
|
||||||
//
|
//
|
||||||
cmd ::= create_table create_table_args.
|
cmd ::= create_table create_table_args.
|
||||||
create_table ::= CREATE(X) temp(T) TABLE ids(Y).
|
create_table ::= CREATE(X) temp(T) TABLE ids(Y). {
|
||||||
{sqliteStartTable(pParse,&X,&Y,T);}
|
sqliteStartTable(pParse,&X,&Y,T);
|
||||||
|
}
|
||||||
%type temp {int}
|
%type temp {int}
|
||||||
temp(A) ::= TEMP. {A = 1;}
|
temp(A) ::= TEMP. {A = 1;}
|
||||||
temp(A) ::= . {A = 0;}
|
temp(A) ::= . {A = 0;}
|
||||||
create_table_args ::= LP columnlist conslist_opt RP(X).
|
create_table_args ::= LP columnlist conslist_opt RP(X). {
|
||||||
{sqliteEndTable(pParse,&X);}
|
sqliteEndTable(pParse,&X,0);
|
||||||
|
}
|
||||||
|
create_table_args ::= AS select(S). {
|
||||||
|
sqliteEndTable(pParse,0,S);
|
||||||
|
sqliteSelectDelete(S);
|
||||||
|
}
|
||||||
columnlist ::= columnlist COMMA column.
|
columnlist ::= columnlist COMMA column.
|
||||||
columnlist ::= column.
|
columnlist ::= column.
|
||||||
|
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.86 2002/02/18 01:17:00 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.87 2002/02/18 18:30:33 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqlite.h"
|
#include "sqlite.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
@@ -566,13 +566,14 @@ void sqliteExprListDelete(ExprList*);
|
|||||||
void sqlitePragma(Parse*,Token*,Token*,int);
|
void sqlitePragma(Parse*,Token*,Token*,int);
|
||||||
void sqliteCommitInternalChanges(sqlite*);
|
void sqliteCommitInternalChanges(sqlite*);
|
||||||
void sqliteRollbackInternalChanges(sqlite*);
|
void sqliteRollbackInternalChanges(sqlite*);
|
||||||
|
Table *sqliteResultSetOfSelect(Parse*,char*,Select*);
|
||||||
void sqliteStartTable(Parse*,Token*,Token*,int);
|
void sqliteStartTable(Parse*,Token*,Token*,int);
|
||||||
void sqliteAddColumn(Parse*,Token*);
|
void sqliteAddColumn(Parse*,Token*);
|
||||||
void sqliteAddNotNull(Parse*, int);
|
void sqliteAddNotNull(Parse*, int);
|
||||||
void sqliteAddPrimaryKey(Parse*, IdList*, int);
|
void sqliteAddPrimaryKey(Parse*, IdList*, int);
|
||||||
void sqliteAddColumnType(Parse*,Token*,Token*);
|
void sqliteAddColumnType(Parse*,Token*,Token*);
|
||||||
void sqliteAddDefaultValue(Parse*,Token*,int);
|
void sqliteAddDefaultValue(Parse*,Token*,int);
|
||||||
void sqliteEndTable(Parse*,Token*);
|
void sqliteEndTable(Parse*,Token*,Select*);
|
||||||
void sqliteDropTable(Parse*, Token*);
|
void sqliteDropTable(Parse*, Token*);
|
||||||
void sqliteDeleteTable(sqlite*, Table*);
|
void sqliteDeleteTable(sqlite*, Table*);
|
||||||
void sqliteInsert(Parse*, Token*, ExprList*, Select*, IdList*, int);
|
void sqliteInsert(Parse*, Token*, ExprList*, Select*, IdList*, int);
|
||||||
|
@@ -11,7 +11,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 CREATE TABLE statement.
|
# focus of this file is testing the CREATE TABLE statement.
|
||||||
#
|
#
|
||||||
# $Id: table.test,v 1.13 2001/09/27 15:11:55 drh Exp $
|
# $Id: table.test,v 1.14 2002/02/18 18:30:33 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@@ -302,4 +302,49 @@ do_test table-7.3 {
|
|||||||
}
|
}
|
||||||
} {desc a asc b explain 9 vacuum 0 delimiters xyz begin hi end y'all}
|
} {desc a asc b explain 9 vacuum 0 delimiters xyz begin hi end y'all}
|
||||||
|
|
||||||
|
# Try out the CREATE TABLE AS syntax
|
||||||
|
#
|
||||||
|
do_test table-8.1 {
|
||||||
|
execsql2 {
|
||||||
|
CREATE TABLE t2 AS SELECT * FROM weird;
|
||||||
|
SELECT * FROM t2;
|
||||||
|
}
|
||||||
|
} {desc a asc b explain 9 vacuum 0 delimiters xyz begin hi end y'all}
|
||||||
|
do_test table-8.2 {
|
||||||
|
execsql {
|
||||||
|
CREATE TABLE 't3''xyz'(a,b,c);
|
||||||
|
INSERT INTO [t3'xyz] VALUES(1,2,3);
|
||||||
|
SELECT * FROM [t3'xyz];
|
||||||
|
}
|
||||||
|
} {1 2 3}
|
||||||
|
do_test table-8.3 {
|
||||||
|
execsql2 {
|
||||||
|
CREATE TABLE [t4'abc] AS SELECT count(*), min(a), max(b+c) FROM [t3'xyz];
|
||||||
|
SELECT * FROM [t4'abc];
|
||||||
|
}
|
||||||
|
} {count(*) 1 min(a) 1 max(b+c) 5}
|
||||||
|
do_test table-8.4 {
|
||||||
|
execsql2 {
|
||||||
|
CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3'xyz];
|
||||||
|
SELECT * FROM t5;
|
||||||
|
}
|
||||||
|
} {y'all 1}
|
||||||
|
do_test table-8.5 {
|
||||||
|
db close
|
||||||
|
sqlite db test.db
|
||||||
|
execsql2 {
|
||||||
|
SELECT * FROM [t4'abc];
|
||||||
|
}
|
||||||
|
} {count(*) 1 min(a) 1 max(b+c) 5}
|
||||||
|
do_test table-8.6 {
|
||||||
|
execsql2 {
|
||||||
|
SELECT * FROM t2;
|
||||||
|
}
|
||||||
|
} {desc a asc b explain 9 vacuum 0 delimiters xyz begin hi end y'all}
|
||||||
|
do_test table-8.7 {
|
||||||
|
catchsql {
|
||||||
|
SELECT * FROM t5;
|
||||||
|
}
|
||||||
|
} {1 {no such table: t5}}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@@ -25,6 +25,7 @@ chng {2002 Feb * (2.3.3)} {
|
|||||||
(by Joel Luscy)</li>
|
(by Joel Luscy)</li>
|
||||||
<li>The VALUES clause of an INSERT can now contain expressions, including
|
<li>The VALUES clause of an INSERT can now contain expressions, including
|
||||||
scalar SELECT clauses.</li>
|
scalar SELECT clauses.</li>
|
||||||
|
<li>Added support for CREATE TABLE AS SELECT</li>
|
||||||
}
|
}
|
||||||
|
|
||||||
chng {2002 Feb 14 (2.3.2)} {
|
chng {2002 Feb 14 (2.3.2)} {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Run this TCL script to generate HTML for the index.html file.
|
# Run this TCL script to generate HTML for the index.html file.
|
||||||
#
|
#
|
||||||
set rcsid {$Id: index.tcl,v 1.53 2002/02/03 19:06:04 drh Exp $}
|
set rcsid {$Id: index.tcl,v 1.54 2002/02/18 18:30:33 drh Exp $}
|
||||||
|
|
||||||
puts {<html>
|
puts {<html>
|
||||||
<head><title>SQLite: An SQL Database Engine In A C Library</title></head>
|
<head><title>SQLite: An SQL Database Engine In A C Library</title></head>
|
||||||
@@ -44,7 +44,7 @@ puts {<h2>Features</h2>
|
|||||||
<li>A complete database (with multiple tables and indices) is
|
<li>A complete database (with multiple tables and indices) is
|
||||||
stored in a single disk file.</li>
|
stored in a single disk file.</li>
|
||||||
<li>Atomic commit and rollback protect data integrity.</li>
|
<li>Atomic commit and rollback protect data integrity.</li>
|
||||||
<li>Small memory footprint: about 14000 lines of C code.</li>
|
<li>Small memory footprint: less than 20K lines of C code.</li>
|
||||||
<li><a href="speed.html">Four times faster</a> than PostgreSQL.
|
<li><a href="speed.html">Four times faster</a> than PostgreSQL.
|
||||||
Twice as fast as SQLite 1.0.</li>
|
Twice as fast as SQLite 1.0.</li>
|
||||||
<li>Very simple
|
<li>Very simple
|
||||||
|
20
www/lang.tcl
20
www/lang.tcl
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Run this Tcl script to generate the sqlite.html file.
|
# Run this Tcl script to generate the sqlite.html file.
|
||||||
#
|
#
|
||||||
set rcsid {$Id: lang.tcl,v 1.23 2002/02/18 03:21:47 drh Exp $}
|
set rcsid {$Id: lang.tcl,v 1.24 2002/02/18 18:30:33 drh Exp $}
|
||||||
|
|
||||||
puts {<html>
|
puts {<html>
|
||||||
<head>
|
<head>
|
||||||
@@ -245,8 +245,10 @@ CREATE [TEMP | TEMPORARY] TABLE <table-name> (
|
|||||||
<column-def> [, <column-def>]*
|
<column-def> [, <column-def>]*
|
||||||
[, <constraint>]*
|
[, <constraint>]*
|
||||||
)
|
)
|
||||||
|
} {sql-command} {
|
||||||
|
CREATE [TEMP | TEMPORARY] TABLE <table-name> AS <select-statement>
|
||||||
} {column-def} {
|
} {column-def} {
|
||||||
<name> <type> [<column-constraint>]*
|
<name> [<type>] [<column-constraint>]*
|
||||||
} {type} {
|
} {type} {
|
||||||
<typename> |
|
<typename> |
|
||||||
<typename> ( <number> ) |
|
<typename> ( <number> ) |
|
||||||
@@ -274,8 +276,8 @@ is the name of the table that records the database schema.</p>
|
|||||||
|
|
||||||
<p>Each column definition is the name of the column followed by the
|
<p>Each column definition is the name of the column followed by the
|
||||||
datatype for that column, then one or more optional column constraints.
|
datatype for that column, then one or more optional column constraints.
|
||||||
The datatype for the column is ignored. All information
|
The datatype for the column is (usually) ignored and may be omitted.
|
||||||
is stored as null-terminated strings.
|
All information is stored as null-terminated strings.
|
||||||
The UNIQUE constraint causes an index to be created on the specified
|
The UNIQUE constraint causes an index to be created on the specified
|
||||||
columns. This index must contain unique keys.
|
columns. This index must contain unique keys.
|
||||||
The DEFAULT constraint
|
The DEFAULT constraint
|
||||||
@@ -325,11 +327,19 @@ The total amount of data in a single row is limited to about
|
|||||||
1 megabytes. (This limit can be increased to 16MB by changing
|
1 megabytes. (This limit can be increased to 16MB by changing
|
||||||
a single #define in the source code and recompiling.)</p>
|
a single #define in the source code and recompiling.)</p>
|
||||||
|
|
||||||
|
<p>The CREATE TABLE AS form defines the table to be
|
||||||
|
the result set of a query. The names of the table columns are
|
||||||
|
the names of the columns in the result.</p>
|
||||||
|
|
||||||
<p>The exact text
|
<p>The exact text
|
||||||
of each CREATE TABLE statement is stored in the <b>sqlite_master</b>
|
of each CREATE TABLE statement is stored in the <b>sqlite_master</b>
|
||||||
table. Everytime the database is opened, all CREATE TABLE statements
|
table. Everytime the database is opened, all CREATE TABLE statements
|
||||||
are read from the <b>sqlite_master</b> table and used to regenerate
|
are read from the <b>sqlite_master</b> table and used to regenerate
|
||||||
SQLite's internal representation of the table layout.</p>
|
SQLite's internal representation of the table layout.
|
||||||
|
If the original command was a CREATE TABLE AS then then an equivalent
|
||||||
|
CREATE TABLE statement is synthesized and store in <b>sqlite_master</b>
|
||||||
|
in place of the original command.
|
||||||
|
</p>
|
||||||
}
|
}
|
||||||
|
|
||||||
Section DELETE delete
|
Section DELETE delete
|
||||||
|
Reference in New Issue
Block a user