1
0
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:
drh
2002-02-18 18:30:32 +00:00
parent e64e7b203e
commit 969fa7c128
10 changed files with 213 additions and 41 deletions

View File

@@ -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

View File

@@ -1 +1 @@
ec1f3fae6f8cd8466892cd370e1802e492a76e6e 78a50971e9adc8739e7888201c79465a40e1a152

View File

@@ -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);
} }
} }

View File

@@ -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++;

View File

@@ -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.

View File

@@ -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);

View File

@@ -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

View File

@@ -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)} {

View File

@@ -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

View File

@@ -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