1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Change the SQLITE_MASTER format to version 2 in preparation for adding views. (CVS 386)

FossilOrigin-Name: b2a9807fed544e83002366149b9a363759338c5d
This commit is contained in:
drh
2002-02-21 12:01:27 +00:00
parent 2af0b2d78f
commit 17f7193434
11 changed files with 304 additions and 184 deletions

View File

@@ -1,5 +1,5 @@
C Do\snot\sallow\sdot-commands\sto\soccur\sin\sthe\smiddle\sof\sa\sreal\sSQL\scommand.\s(CVS\s385) C Change\sthe\sSQLITE_MASTER\sformat\sto\sversion\s2\sin\spreparation\sfor\sadding\sviews.\s(CVS\s386)
D 2002-02-21T02:25:03 D 2002-02-21T12:01:27
F Makefile.in 9fa4277413bf1d9cf91365f07d4108d7d87ed2af F Makefile.in 9fa4277413bf1d9cf91365f07d4108d7d87ed2af
F Makefile.template 3372d45f8853afdb70bd30cc6fb50a3cd9069834 F Makefile.template 3372d45f8853afdb70bd30cc6fb50a3cd9069834
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
@@ -21,13 +21,13 @@ F sqlite.1 2e2bb0529ef468ade9e4322bd609d0695fb9ded9
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6 F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
F src/btree.c 495275fe14f3b718cf2f691dce979d4c0e1f8e5d F src/btree.c 495275fe14f3b718cf2f691dce979d4c0e1f8e5d
F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3 F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
F src/build.c 088acf87a92b00edda1206ccafac3518660b1b3b F src/build.c 4e10d8e61971fe900317d00a98f49dd7ceb27c20
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 eae5aa2e9ac68c4d465e71b2ad34bcbb882979cf F src/insert.c eae5aa2e9ac68c4d465e71b2ad34bcbb882979cf
F src/main.c fada622b468c54fb211372f38a27ee636915e2ee F src/main.c abc0732d4caa676ff8337f278b01f1f1b57538f5
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
@@ -36,22 +36,22 @@ F src/pager.h b28f004e2f5541dc60cc32db01bf80cf4d056283
F src/parse.y b82278917959eefd05bd08c90e07a4fa5917ea51 F src/parse.y b82278917959eefd05bd08c90e07a4fa5917ea51
F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
F src/select.c 282f37b2fdb9367f0230811e1cf7bba48665fb72 F src/select.c f0cbfd2d9059e0f33837797ee326fbe964a35f09
F src/shell.c cbf48bf0ca35c4e0d8a7d2a86f7724f52c525cd7 F src/shell.c cbf48bf0ca35c4e0d8a7d2a86f7724f52c525cd7
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 e19efd5b1c6accfb3418cbb5c0e8c143fc1d18d7 F src/sqliteInt.h 338cd586b9322105080a2a31122446e504ac1fc4
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
F src/test2.c d410dbd8a90faa466c3ab694fa0aa57f5a773aa6 F src/test2.c d410dbd8a90faa466c3ab694fa0aa57f5a773aa6
F src/test3.c 4e52fff8b01f08bd202f7633feda5639b7ba2b5e F src/test3.c 4e52fff8b01f08bd202f7633feda5639b7ba2b5e
F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f
F src/tokenize.c 9e98f94469694a763992860596137e78dbae0cc0 F src/tokenize.c 777b734f9d06f5a9055b6808e5baec18936a4fd9
F src/update.c 95459f94a061860bf8e5716b3426a5ba85c79103 F src/update.c 95459f94a061860bf8e5716b3426a5ba85c79103
F src/util.c f31f3d6198a0d1296a16f5a6ceec423a932cbbf6 F src/util.c f31f3d6198a0d1296a16f5a6ceec423a932cbbf6
F src/vdbe.c 18b6e9ed3bcdd76ae74d60a977a6d8a3a1b0f797 F src/vdbe.c 44832d804e109248e9e2abd40daee5f8ac735450
F src/vdbe.h b4d35e159fbb80a74728b4a96e5b789fffce6f57 F src/vdbe.h 002bb8cf884034bea25a9fe901a9c5e9d29bc045
F src/where.c f79bc3179379b46b131a67ab10713779368dceee F src/where.c f79bc3179379b46b131a67ab10713779368dceee
F test/all.test 7a8a8a7a579ed2bb4d8976d55402f21eacd58049 F test/all.test 7a8a8a7a579ed2bb4d8976d55402f21eacd58049
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
@@ -89,7 +89,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 b8be4d3d3ff6b4858516fa274d38075ba06b5004 F test/table.test 17b0b6eafa3faaee5545b7a94e6c1ff73f0880f3
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
@@ -110,7 +110,7 @@ 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 63efc40f09e2f0d8fea43d174103248b160fdf0e F www/c_interface.tcl 63efc40f09e2f0d8fea43d174103248b160fdf0e
F www/changes.tcl e9ac5ffc030ad355fb5973bc2c68e622c3bc9ae2 F www/changes.tcl 4aee975940a59d43736cdd4cd352c51e1e6426ba
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
@@ -125,7 +125,7 @@ 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 953928537c350e6c9df157553114c6d9d44712d5 P ffb00bf36a9a5851ea4a69f9c7dd7ce412553e3b
R 9ed6435fa0cf461ec879e5b28166d8d6 R 827e990a5d306ede002baf12f96964e4
U drh U drh
Z a1b5da6dd8cc3bb5ba9dca0ec016a36c Z 93dfb9234ed5554b3f3a0a3a7b0ddf3a

View File

@@ -1 +1 @@
ffb00bf36a9a5851ea4a69f9c7dd7ce412553e3b b2a9807fed544e83002366149b9a363759338c5d

View File

@@ -25,7 +25,7 @@
** ROLLBACK ** ROLLBACK
** PRAGMA ** PRAGMA
** **
** $Id: build.c,v 1.77 2002/02/19 13:39:22 drh Exp $ ** $Id: build.c,v 1.78 2002/02/21 12:01:27 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -473,12 +473,25 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName, int isTemp){
pTable->isTemp = isTemp; pTable->isTemp = isTemp;
if( pParse->pNewTable ) sqliteDeleteTable(db, pParse->pNewTable); if( pParse->pNewTable ) sqliteDeleteTable(db, pParse->pNewTable);
pParse->pNewTable = pTable; pParse->pNewTable = pTable;
/* Begin generating the code that will insert the table record into
** the SQLITE_MASTER table. Note in particular that we must go ahead
** and allocate the record number for the table entry now. Before any
** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause
** indices to be created and the table record must come before the
** indices. Hence, the record number for the table must be allocated
** now.
*/
if( !pParse->initFlag && (v = sqliteGetVdbe(pParse))!=0 ){ if( !pParse->initFlag && (v = sqliteGetVdbe(pParse))!=0 ){
sqliteBeginWriteOperation(pParse); sqliteBeginWriteOperation(pParse);
if( !isTemp ){ if( !isTemp ){
sqliteVdbeAddOp(v, OP_SetCookie, db->file_format, 1); sqliteVdbeAddOp(v, OP_SetCookie, db->file_format, 1);
sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2); sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2);
sqliteVdbeChangeP3(v, -1, MASTER_NAME, P3_STATIC); sqliteVdbeChangeP3(v, -1, MASTER_NAME, P3_STATIC);
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
sqliteVdbeAddOp(v, OP_String, 0, 0);
sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
} }
} }
} }
@@ -657,10 +670,11 @@ static void changeCookie(sqlite *db){
*/ */
static int identLength(const char *z){ static int identLength(const char *z){
int n; int n;
for(n=2; *z; n++, z++){ int needQuote = 0;
if( *z=='\'' ){ n++; } for(n=0; *z; n++, z++){
if( *z=='\'' ){ n++; needQuote=1; }
} }
return n; return n + needQuote*2;
} }
/* /*
@@ -668,14 +682,19 @@ static int identLength(const char *z){
** quote characters as needed. ** quote characters as needed.
*/ */
static void identPut(char *z, int *pIdx, char *zIdent){ static void identPut(char *z, int *pIdx, char *zIdent){
int i, j; int i, j, needQuote;
i = *pIdx; i = *pIdx;
z[i++] = '\''; for(j=0; zIdent[j]; j++){
if( !isalnum(zIdent[j]) && zIdent[j]!='_' ) break;
}
needQuote = zIdent[j]!=0 || isdigit(zIdent[0])
|| sqliteKeywordCode(zIdent, j)!=TK_ID;
if( needQuote ) z[i++] = '\'';
for(j=0; zIdent[j]; j++){ for(j=0; zIdent[j]; j++){
z[i++] = zIdent[j]; z[i++] = zIdent[j];
if( zIdent[j]=='\'' ) z[i++] = '\''; if( zIdent[j]=='\'' ) z[i++] = '\'';
} }
z[i++] = '\''; if( needQuote ) z[i++] = '\'';
z[i] = 0; z[i] = 0;
*pIdx = i; *pIdx = i;
} }
@@ -769,6 +788,7 @@ void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){
*/ */
if( pSelect ){ if( pSelect ){
Table *pSelTab = sqliteResultSetOfSelect(pParse, 0, pSelect); Table *pSelTab = sqliteResultSetOfSelect(pParse, 0, pSelect);
if( pSelTab==0 ) return;
assert( p->aCol==0 ); assert( p->aCol==0 );
p->nCol = pSelTab->nCol; p->nCol = pSelTab->nCol;
p->aCol = pSelTab->aCol; p->aCol = pSelTab->aCol;
@@ -788,7 +808,8 @@ void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){
} }
/* If not initializing, then create a record for the new table /* If not initializing, then create a record for the new table
** in the SQLITE_MASTER table of the database. ** in the SQLITE_MASTER table of the database. The record number
** for the new table entry should already be on the stack.
** **
** If this is a TEMPORARY table, then just create the table. Do not ** If this is a TEMPORARY table, then just create the table. Do not
** make an entry in SQLITE_MASTER. ** make an entry in SQLITE_MASTER.
@@ -803,7 +824,7 @@ void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){
sqliteVdbeChangeP3(v, addr, (char *)&p->tnum, P3_POINTER); sqliteVdbeChangeP3(v, addr, (char *)&p->tnum, P3_POINTER);
p->tnum = 0; p->tnum = 0;
if( !p->isTemp ){ if( !p->isTemp ){
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0); sqliteVdbeAddOp(v, OP_Pull, 1, 0);
sqliteVdbeAddOp(v, OP_String, 0, 0); sqliteVdbeAddOp(v, OP_String, 0, 0);
sqliteVdbeChangeP3(v, -1, "table", P3_STATIC); sqliteVdbeChangeP3(v, -1, "table", P3_STATIC);
sqliteVdbeAddOp(v, OP_String, 0, 0); sqliteVdbeAddOp(v, OP_String, 0, 0);

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.60 2002/02/19 22:42:05 drh Exp $ ** $Id: main.c,v 1.61 2002/02/21 12:01:27 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "os.h" #include "os.h"
@@ -51,13 +51,14 @@ static int sqliteOpenCb(void *pDb, int argc, char **argv, char **azColName){
db->next_cookie = db->schema_cookie; db->next_cookie = db->schema_cookie;
break; break;
} }
case 'v':
case 'i': case 'i':
case 't': { /* CREATE TABLE and CREATE INDEX statements */ case 't': { /* CREATE TABLE, CREATE INDEX, or CREATE VIEW statements */
if( argv[3] && argv[3][0] ){ if( argv[3] && argv[3][0] ){
/* Call the parser to process a CREATE TABLE or CREATE INDEX statement. /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
** But because sParse.initFlag is set to 1, no VDBE code is generated ** But because sParse.initFlag is set to 1, no VDBE code is generated
** or executed. All the parser does is build the internal data ** or executed. All the parser does is build the internal data
** structures that describe the table or index. ** structures that describe the table, index, or view.
*/ */
memset(&sParse, 0, sizeof(sParse)); memset(&sParse, 0, sizeof(sParse));
sParse.db = db; sParse.db = db;
@@ -149,10 +150,15 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
** was created to fulfill a PRIMARY KEY or UNIQUE constraint on a table, ** was created to fulfill a PRIMARY KEY or UNIQUE constraint on a table,
** then the "sql" column is NULL. ** then the "sql" column is NULL.
** **
** If the "type" column has the value "meta", then the "sql" column ** In format 1, entries in the sqlite_master table are in a random
** contains extra information about the database, such as the ** order. Two passes must be made through the table to initialize
** file format version number. All meta information must be processed ** internal data structures. The first pass reads table definitions
** before any tables or indices are constructed. ** and the second pass read index definitions. Having two passes
** insures that indices appear after their tables.
**
** In format 2, entries appear in chronological order. Only a single
** pass needs to be made through the table since everything will be
** in the write order. VIEWs may only occur in format 2.
** **
** The following program invokes its callback on the SQL for each ** The following program invokes its callback on the SQL for each
** table then goes back and invokes the callback on the ** table then goes back and invokes the callback on the
@@ -161,38 +167,70 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
** database scheme. ** database scheme.
*/ */
static VdbeOp initProg[] = { static VdbeOp initProg[] = {
/* Send the file format to the callback routine
*/
{ OP_Open, 0, 2, 0}, { OP_Open, 0, 2, 0},
{ OP_String, 0, 0, "file-format"}, { OP_String, 0, 0, "file-format"},
{ OP_String, 0, 0, 0}, { OP_String, 0, 0, 0},
{ OP_String, 0, 0, 0}, { OP_String, 0, 0, 0},
{ OP_ReadCookie, 0, 1, 0}, { OP_ReadCookie, 0, 1, 0},
{ OP_Callback, 4, 0, 0}, { OP_Callback, 4, 0, 0},
/* Send the initial schema cookie to the callback
*/
{ OP_String, 0, 0, "schema_cookie"}, { OP_String, 0, 0, "schema_cookie"},
{ OP_String, 0, 0, 0}, { OP_String, 0, 0, 0},
{ OP_String, 0, 0, 0}, { OP_String, 0, 0, 0},
{ OP_ReadCookie, 0, 0, 0}, { OP_ReadCookie, 0, 0, 0},
{ OP_Callback, 4, 0, 0}, { OP_Callback, 4, 0, 0},
{ OP_Rewind, 0, 31, 0},
{ OP_Column, 0, 0, 0}, /* 12 */ /* Check the file format. If the format number is 2 or more,
** then do a single pass through the SQLITE_MASTER table. For
** a format number of less than 2, jump forward to a different
** algorithm that makes two passes through the SQLITE_MASTER table,
** once for tables and a second time for indices.
*/
{ OP_ReadCookie, 0, 1, 0},
{ OP_Integer, 2, 0, 0},
{ OP_Lt, 0, 23, 0},
/* This is the code for doing a single scan through the SQLITE_MASTER
** table. This code runs for format 2 and greater.
*/
{ OP_Rewind, 0, 21, 0},
{ OP_Column, 0, 0, 0}, /* 15 */
{ OP_Column, 0, 1, 0},
{ OP_Column, 0, 3, 0},
{ OP_Column, 0, 4, 0},
{ OP_Callback, 4, 0, 0},
{ OP_Next, 0, 15, 0},
{ OP_Close, 0, 0, 0}, /* 21 */
{ OP_Halt, 0, 0, 0},
/* This is the code for doing two passes through SQLITE_MASTER. This
** code runs for file format 1.
*/
{ OP_Rewind, 0, 43, 0}, /* 23 */
{ OP_Column, 0, 0, 0}, /* 24 */
{ OP_String, 0, 0, "table"}, { OP_String, 0, 0, "table"},
{ OP_Ne, 0, 20, 0}, { OP_Ne, 0, 32, 0},
{ OP_Column, 0, 0, 0}, { OP_Column, 0, 0, 0},
{ OP_Column, 0, 1, 0}, { OP_Column, 0, 1, 0},
{ OP_Column, 0, 3, 0}, { OP_Column, 0, 3, 0},
{ OP_Column, 0, 4, 0}, { OP_Column, 0, 4, 0},
{ OP_Callback, 4, 0, 0}, { OP_Callback, 4, 0, 0},
{ OP_Next, 0, 12, 0}, /* 20 */ { OP_Next, 0, 24, 0}, /* 32 */
{ OP_Rewind, 0, 31, 0}, /* 21 */ { OP_Rewind, 0, 43, 0}, /* 33 */
{ OP_Column, 0, 0, 0}, /* 22 */ { OP_Column, 0, 0, 0}, /* 34 */
{ OP_String, 0, 0, "index"}, { OP_String, 0, 0, "index"},
{ OP_Ne, 0, 30, 0}, { OP_Ne, 0, 42, 0},
{ OP_Column, 0, 0, 0}, { OP_Column, 0, 0, 0},
{ OP_Column, 0, 1, 0}, { OP_Column, 0, 1, 0},
{ OP_Column, 0, 3, 0}, { OP_Column, 0, 3, 0},
{ OP_Column, 0, 4, 0}, { OP_Column, 0, 4, 0},
{ OP_Callback, 4, 0, 0}, { OP_Callback, 4, 0, 0},
{ OP_Next, 0, 22, 0}, /* 30 */ { OP_Next, 0, 34, 0}, /* 42 */
{ OP_Close, 0, 0, 0}, /* 31 */ { OP_Close, 0, 0, 0}, /* 43 */
{ OP_Halt, 0, 0, 0}, { OP_Halt, 0, 0, 0},
}; };
@@ -209,9 +247,9 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
db->pBusyArg, db->xBusyCallback); db->pBusyArg, db->xBusyCallback);
sqliteVdbeDelete(vdbe); sqliteVdbeDelete(vdbe);
if( rc==SQLITE_OK && db->nTable==0 ){ if( rc==SQLITE_OK && db->nTable==0 ){
db->file_format = FILE_FORMAT; db->file_format = 2;
} }
if( rc==SQLITE_OK && db->file_format>FILE_FORMAT ){ if( rc==SQLITE_OK && db->file_format>2 ){
sqliteSetString(pzErrMsg, "unsupported file format", 0); sqliteSetString(pzErrMsg, "unsupported file format", 0);
rc = SQLITE_ERROR; rc = SQLITE_ERROR;
} }

View File

@@ -12,7 +12,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 in SQLite. ** to handle SELECT statements in SQLite.
** **
** $Id: select.c,v 1.63 2002/02/19 22:42:05 drh Exp $ ** $Id: select.c,v 1.64 2002/02/21 12:01:27 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -760,7 +760,10 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
pTab = p->pSrc->a[0].pTab; pTab = p->pSrc->a[0].pTab;
/* If we get to here, it means the query is of the correct form. /* If we get to here, it means the query is of the correct form.
** Check to make sure we have an index. ** Check to make sure we have an index and make pIdx point to the
** appropriate index. If the min() or max() is on an INTEGER PRIMARY
** key column, no index is necessary so set pIdx to NULL. If no
** usable index is found, return 0.
*/ */
if( iCol<0 ){ if( iCol<0 ){
pIdx = 0; pIdx = 0;
@@ -772,7 +775,7 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
if( pIdx==0 ) return 0; if( pIdx==0 ) return 0;
} }
/* Identify column names if we will be using in the callback. This /* Identify column names if we will be using the callback. This
** step is skipped if the output is going to a table or a memory cell. ** step is skipped if the output is going to a table or a memory cell.
*/ */
v = sqliteGetVdbe(pParse); v = sqliteGetVdbe(pParse);
@@ -781,7 +784,10 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
generateColumnNames(pParse, p->pSrc, p->pEList); generateColumnNames(pParse, p->pSrc, p->pEList);
} }
/* Begin generating code /* Generating code to find the min or the max. Basically all we have
** to do is find the first or the last entry in the chosen index. If
** the min() or max() is on the INTEGER PRIMARY KEY, then find the first
** or last entry in the main table.
*/ */
if( !pParse->schemaVerified && (pParse->db->flags & SQLITE_InTrans)==0 ){ if( !pParse->schemaVerified && (pParse->db->flags & SQLITE_InTrans)==0 ){
sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0); sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0);

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.88 2002/02/19 22:42:05 drh Exp $ ** @(#) $Id: sqliteInt.h,v 1.89 2002/02/21 12:01:27 drh Exp $
*/ */
#include "sqlite.h" #include "sqlite.h"
#include "hash.h" #include "hash.h"
@@ -30,11 +30,6 @@
#define MAX_PAGES 100 #define MAX_PAGES 100
#define TEMP_PAGES 25 #define TEMP_PAGES 25
/*
** File format version number
*/
#define FILE_FORMAT 1
/* /*
** Integers of known sizes. These typedefs might change for architectures ** Integers of known sizes. These typedefs might change for architectures
** where the sizes very. Preprocessor macros are available so that the ** where the sizes very. Preprocessor macros are available so that the
@@ -555,6 +550,7 @@ void sqliteRealToSortable(double r, char *);
void sqliteSetString(char **, const char *, ...); void sqliteSetString(char **, const char *, ...);
void sqliteSetNString(char **, ...); void sqliteSetNString(char **, ...);
void sqliteDequote(char*); void sqliteDequote(char*);
int sqliteKeywordCode(const char*, int);
int sqliteRunParser(Parse*, const char*, char **); int sqliteRunParser(Parse*, const char*, char **);
void sqliteExec(Parse*); void sqliteExec(Parse*);
Expr *sqliteExpr(int, Expr*, Expr*, Token*); Expr *sqliteExpr(int, Expr*, Expr*, Token*);

View File

@@ -15,7 +15,7 @@
** individual tokens and sends those tokens one-by-one over to the ** individual tokens and sends those tokens one-by-one over to the
** parser for analysis. ** parser for analysis.
** **
** $Id: tokenize.c,v 1.36 2002/02/17 00:30:36 drh Exp $ ** $Id: tokenize.c,v 1.37 2002/02/21 12:01:27 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "os.h" #include "os.h"
@@ -116,7 +116,7 @@ static Keyword *apHashTable[KEY_HASH_SIZE];
** keyword. If it is a keyword, the token code of that keyword is ** keyword. If it is a keyword, the token code of that keyword is
** returned. If the input is not a keyword, TK_ID is returned. ** returned. If the input is not a keyword, TK_ID is returned.
*/ */
static int sqliteKeywordCode(const char *z, int n){ int sqliteKeywordCode(const char *z, int n){
int h; int h;
Keyword *p; Keyword *p;
if( aKeywordTable[0].len==0 ){ if( aKeywordTable[0].len==0 ){

View File

@@ -30,7 +30,7 @@
** But other routines are also provided to help in building up ** But other routines are also provided to help in building up
** a program instruction by instruction. ** a program instruction by instruction.
** **
** $Id: vdbe.c,v 1.120 2002/02/19 22:42:05 drh Exp $ ** $Id: vdbe.c,v 1.121 2002/02/21 12:01:27 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -72,6 +72,7 @@ struct Cursor {
Bool keyAsData; /* The OP_Column command works on key instead of data */ Bool keyAsData; /* The OP_Column command works on key instead of data */
Bool atFirst; /* True if pointing to first entry */ Bool atFirst; /* True if pointing to first entry */
Bool useRandomRowid; /* Generate new record numbers semi-randomly */ Bool useRandomRowid; /* Generate new record numbers semi-randomly */
Bool nullRow; /* True if pointing to a row with no data */
Btree *pBt; /* Separate file holding temporary table */ Btree *pBt; /* Separate file holding temporary table */
}; };
typedef struct Cursor Cursor; typedef struct Cursor Cursor;
@@ -867,30 +868,30 @@ static char *zOpName[] = { 0,
"Close", "MoveTo", "NewRecno", "PutIntKey", "Close", "MoveTo", "NewRecno", "PutIntKey",
"PutStrKey", "Distinct", "Found", "NotFound", "PutStrKey", "Distinct", "Found", "NotFound",
"IsUnique", "NotExists", "Delete", "Column", "IsUnique", "NotExists", "Delete", "Column",
"KeyAsData", "Recno", "FullKey", "Last", "KeyAsData", "Recno", "FullKey", "NullRow",
"Rewind", "Next", "Destroy", "Clear", "Last", "Rewind", "Next", "Destroy",
"CreateIndex", "CreateTable", "IntegrityCk", "IdxPut", "Clear", "CreateIndex", "CreateTable", "IntegrityCk",
"IdxDelete", "IdxRecno", "IdxGT", "IdxGE", "IdxPut", "IdxDelete", "IdxRecno", "IdxGT",
"MemLoad", "MemStore", "ListWrite", "ListRewind", "IdxGE", "MemLoad", "MemStore", "ListWrite",
"ListRead", "ListReset", "SortPut", "SortMakeRec", "ListRewind", "ListRead", "ListReset", "SortPut",
"SortMakeKey", "Sort", "SortNext", "SortCallback", "SortMakeRec", "SortMakeKey", "Sort", "SortNext",
"SortReset", "FileOpen", "FileRead", "FileColumn", "SortCallback", "SortReset", "FileOpen", "FileRead",
"AggReset", "AggFocus", "AggIncr", "AggNext", "FileColumn", "AggReset", "AggFocus", "AggIncr",
"AggSet", "AggGet", "SetInsert", "SetFound", "AggNext", "AggSet", "AggGet", "SetInsert",
"SetNotFound", "MakeRecord", "MakeKey", "MakeIdxKey", "SetFound", "SetNotFound", "MakeRecord", "MakeKey",
"IncrKey", "Goto", "If", "Halt", "MakeIdxKey", "IncrKey", "Goto", "If",
"ColumnCount", "ColumnName", "Callback", "NullCallback", "Halt", "ColumnCount", "ColumnName", "Callback",
"Integer", "String", "Pop", "Dup", "NullCallback", "Integer", "String", "Pop",
"Pull", "Push", "MustBeInt", "Add", "Dup", "Pull", "Push", "MustBeInt",
"AddImm", "Subtract", "Multiply", "Divide", "Add", "AddImm", "Subtract", "Multiply",
"Remainder", "BitAnd", "BitOr", "BitNot", "Divide", "Remainder", "BitAnd", "BitOr",
"ShiftLeft", "ShiftRight", "AbsValue", "Precision", "BitNot", "ShiftLeft", "ShiftRight", "AbsValue",
"Min", "Max", "Like", "Glob", "Precision", "Min", "Max", "Like",
"Eq", "Ne", "Lt", "Le", "Glob", "Eq", "Ne", "Lt",
"Gt", "Ge", "IsNull", "NotNull", "Le", "Gt", "Ge", "IsNull",
"Negative", "And", "Or", "Not", "NotNull", "Negative", "And", "Or",
"Concat", "Noop", "Strlen", "Substr", "Not", "Concat", "Noop", "Strlen",
"Limit", "Substr", "Limit",
}; };
/* /*
@@ -2591,6 +2592,7 @@ case OP_Open: {
} }
cleanupCursor(&p->aCsr[i]); cleanupCursor(&p->aCsr[i]);
memset(&p->aCsr[i], 0, sizeof(Cursor)); memset(&p->aCsr[i], 0, sizeof(Cursor));
p->aCsr[i].nullRow = 1;
do{ do{
rc = sqliteBtreeCursor(pX, p2, wrFlag, &p->aCsr[i].pCursor); rc = sqliteBtreeCursor(pX, p2, wrFlag, &p->aCsr[i].pCursor);
switch( rc ){ switch( rc ){
@@ -2648,6 +2650,7 @@ case OP_OpenTemp: {
pCx = &p->aCsr[i]; pCx = &p->aCsr[i];
cleanupCursor(pCx); cleanupCursor(pCx);
memset(pCx, 0, sizeof(*pCx)); memset(pCx, 0, sizeof(*pCx));
pCx->nullRow = 1;
rc = sqliteBtreeOpen(0, 0, TEMP_PAGES, &pCx->pBt); rc = sqliteBtreeOpen(0, 0, TEMP_PAGES, &pCx->pBt);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = sqliteBtreeBeginTrans(pCx->pBt); rc = sqliteBtreeBeginTrans(pCx->pBt);
@@ -2708,6 +2711,7 @@ case OP_MoveTo: {
sqliteBtreeMoveto(pC->pCursor, zStack[tos], aStack[tos].n, &res); sqliteBtreeMoveto(pC->pCursor, zStack[tos], aStack[tos].n, &res);
pC->recnoIsValid = 0; pC->recnoIsValid = 0;
} }
pC->nullRow = 0;
sqlite_search_count++; sqlite_search_count++;
if( res<0 ){ if( res<0 ){
sqliteBtreeNext(pC->pCursor, &res); sqliteBtreeNext(pC->pCursor, &res);
@@ -2892,8 +2896,12 @@ case OP_NotExists: {
assert( aStack[tos].flags & STK_Int ); assert( aStack[tos].flags & STK_Int );
iKey = intToKey(aStack[tos].i); iKey = intToKey(aStack[tos].i);
rx = sqliteBtreeMoveto(pCrsr, (char*)&iKey, sizeof(int), &res); rx = sqliteBtreeMoveto(pCrsr, (char*)&iKey, sizeof(int), &res);
p->aCsr[i].lastRecno = aStack[tos].i;
p->aCsr[i].recnoIsValid = res==0;
p->aCsr[i].nullRow = 0;
if( rx!=SQLITE_OK || res!=0 ){ if( rx!=SQLITE_OK || res!=0 ){
pc = pOp->p2 - 1; pc = pOp->p2 - 1;
p->aCsr[i].recnoIsValid = 0;
} }
} }
POPSTACK; POPSTACK;
@@ -2982,6 +2990,7 @@ case OP_NewRecno: {
goto abort_due_to_error; goto abort_due_to_error;
} }
} }
pC->recnoIsValid = 0;
} }
VERIFY( NeedStack(p, p->tos+1); ) VERIFY( NeedStack(p, p->tos+1); )
p->tos++; p->tos++;
@@ -3044,6 +3053,7 @@ case OP_PutStrKey: {
} }
rc = sqliteBtreeInsert(p->aCsr[i].pCursor, zKey, nKey, rc = sqliteBtreeInsert(p->aCsr[i].pCursor, zKey, nKey,
zStack[tos], aStack[tos].n); zStack[tos], aStack[tos].n);
p->aCsr[i].recnoIsValid = 0;
} }
POPSTACK; POPSTACK;
POPSTACK; POPSTACK;
@@ -3113,7 +3123,9 @@ case OP_Column: {
** is coming from the key or the data of the record. ** is coming from the key or the data of the record.
*/ */
pCrsr = pC->pCursor; pCrsr = pC->pCursor;
if( pC->keyAsData ){ if( pC->nullRow ){
payloadSize = 0;
}else if( pC->keyAsData ){
sqliteBtreeKeySize(pCrsr, &payloadSize); sqliteBtreeKeySize(pCrsr, &payloadSize);
xRead = sqliteBtreeKey; xRead = sqliteBtreeKey;
}else{ }else{
@@ -3199,6 +3211,9 @@ case OP_Recno: {
int v; int v;
if( p->aCsr[i].recnoIsValid ){ if( p->aCsr[i].recnoIsValid ){
v = p->aCsr[i].lastRecno; v = p->aCsr[i].lastRecno;
}else if( p->aCsr[i].nullRow ){
aStack[tos].flags = STK_Null;
break;
}else{ }else{
sqliteBtreeKey(pCrsr, 0, sizeof(u32), (char*)&v); sqliteBtreeKey(pCrsr, 0, sizeof(u32), (char*)&v);
v = keyToInt(v); v = keyToInt(v);
@@ -3248,6 +3263,22 @@ case OP_FullKey: {
break; break;
} }
/* Opcode: NullRow P1 * *
**
** Move the cursor P1 to a null row. Any OP_Column operations
** that occur while the cursor is on the null row will always push
** a NULL onto the stack.
*/
case OP_NullRow: {
int i = pOp->p1;
BtCursor *pCrsr;
if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
p->aCsr[i].nullRow = 1;
}
break;
}
/* Opcode: Last P1 P2 * /* Opcode: Last P1 P2 *
** **
** The next use of the Recno or Column or Next instruction for P1 ** The next use of the Recno or Column or Next instruction for P1
@@ -3263,7 +3294,7 @@ case OP_Last: {
if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){ if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
int res; int res;
sqliteBtreeLast(pCrsr, &res); sqliteBtreeLast(pCrsr, &res);
p->aCsr[i].atFirst = res==0; p->aCsr[i].nullRow = res;
if( res && pOp->p2>0 ){ if( res && pOp->p2>0 ){
pc = pOp->p2 - 1; pc = pOp->p2 - 1;
} }
@@ -3287,6 +3318,7 @@ case OP_Rewind: {
int res; int res;
sqliteBtreeFirst(pCrsr, &res); sqliteBtreeFirst(pCrsr, &res);
p->aCsr[i].atFirst = res==0; p->aCsr[i].atFirst = res==0;
p->aCsr[i].nullRow = res;
if( res && pOp->p2>0 ){ if( res && pOp->p2>0 ){
pc = pOp->p2 - 1; pc = pOp->p2 - 1;
} }
@@ -3308,6 +3340,7 @@ case OP_Next: {
if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){ if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
int res; int res;
rc = sqliteBtreeNext(pCrsr, &res); rc = sqliteBtreeNext(pCrsr, &res);
p->aCsr[i].nullRow = res;
if( res==0 ){ if( res==0 ){
pc = pOp->p2 - 1; pc = pOp->p2 - 1;
sqlite_search_count++; sqlite_search_count++;

View File

@@ -15,7 +15,7 @@
** or VDBE. The VDBE implements an abstract machine that runs a ** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database. ** simple program to access and modify the underlying database.
** **
** $Id: vdbe.h,v 1.43 2002/02/19 15:00:08 drh Exp $ ** $Id: vdbe.h,v 1.44 2002/02/21 12:01:28 drh Exp $
*/ */
#ifndef _SQLITE_VDBE_H_ #ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_
@@ -97,113 +97,114 @@ typedef struct VdbeOp VdbeOp;
#define OP_KeyAsData 25 #define OP_KeyAsData 25
#define OP_Recno 26 #define OP_Recno 26
#define OP_FullKey 27 #define OP_FullKey 27
#define OP_Last 28 #define OP_NullRow 28
#define OP_Rewind 29 #define OP_Last 29
#define OP_Next 30 #define OP_Rewind 30
#define OP_Next 31
#define OP_Destroy 31 #define OP_Destroy 32
#define OP_Clear 32 #define OP_Clear 33
#define OP_CreateIndex 33 #define OP_CreateIndex 34
#define OP_CreateTable 34 #define OP_CreateTable 35
#define OP_IntegrityCk 35 #define OP_IntegrityCk 36
#define OP_IdxPut 36 #define OP_IdxPut 37
#define OP_IdxDelete 37 #define OP_IdxDelete 38
#define OP_IdxRecno 38 #define OP_IdxRecno 39
#define OP_IdxGT 39 #define OP_IdxGT 40
#define OP_IdxGE 40 #define OP_IdxGE 41
#define OP_MemLoad 41 #define OP_MemLoad 42
#define OP_MemStore 42 #define OP_MemStore 43
#define OP_ListWrite 43 #define OP_ListWrite 44
#define OP_ListRewind 44 #define OP_ListRewind 45
#define OP_ListRead 45 #define OP_ListRead 46
#define OP_ListReset 46 #define OP_ListReset 47
#define OP_SortPut 47 #define OP_SortPut 48
#define OP_SortMakeRec 48 #define OP_SortMakeRec 49
#define OP_SortMakeKey 49 #define OP_SortMakeKey 50
#define OP_Sort 50 #define OP_Sort 51
#define OP_SortNext 51 #define OP_SortNext 52
#define OP_SortCallback 52 #define OP_SortCallback 53
#define OP_SortReset 53 #define OP_SortReset 54
#define OP_FileOpen 54 #define OP_FileOpen 55
#define OP_FileRead 55 #define OP_FileRead 56
#define OP_FileColumn 56 #define OP_FileColumn 57
#define OP_AggReset 57 #define OP_AggReset 58
#define OP_AggFocus 58 #define OP_AggFocus 59
#define OP_AggIncr 59 #define OP_AggIncr 60
#define OP_AggNext 60 #define OP_AggNext 61
#define OP_AggSet 61 #define OP_AggSet 62
#define OP_AggGet 62 #define OP_AggGet 63
#define OP_SetInsert 63 #define OP_SetInsert 64
#define OP_SetFound 64 #define OP_SetFound 65
#define OP_SetNotFound 65 #define OP_SetNotFound 66
#define OP_MakeRecord 66 #define OP_MakeRecord 67
#define OP_MakeKey 67 #define OP_MakeKey 68
#define OP_MakeIdxKey 68 #define OP_MakeIdxKey 69
#define OP_IncrKey 69 #define OP_IncrKey 70
#define OP_Goto 70 #define OP_Goto 71
#define OP_If 71 #define OP_If 72
#define OP_Halt 72 #define OP_Halt 73
#define OP_ColumnCount 73 #define OP_ColumnCount 74
#define OP_ColumnName 74 #define OP_ColumnName 75
#define OP_Callback 75 #define OP_Callback 76
#define OP_NullCallback 76 #define OP_NullCallback 77
#define OP_Integer 77 #define OP_Integer 78
#define OP_String 78 #define OP_String 79
#define OP_Pop 79 #define OP_Pop 80
#define OP_Dup 80 #define OP_Dup 81
#define OP_Pull 81 #define OP_Pull 82
#define OP_Push 82 #define OP_Push 83
#define OP_MustBeInt 83 #define OP_MustBeInt 84
#define OP_Add 84 #define OP_Add 85
#define OP_AddImm 85 #define OP_AddImm 86
#define OP_Subtract 86 #define OP_Subtract 87
#define OP_Multiply 87 #define OP_Multiply 88
#define OP_Divide 88 #define OP_Divide 89
#define OP_Remainder 89 #define OP_Remainder 90
#define OP_BitAnd 90 #define OP_BitAnd 91
#define OP_BitOr 91 #define OP_BitOr 92
#define OP_BitNot 92 #define OP_BitNot 93
#define OP_ShiftLeft 93 #define OP_ShiftLeft 94
#define OP_ShiftRight 94 #define OP_ShiftRight 95
#define OP_AbsValue 95 #define OP_AbsValue 96
#define OP_Precision 96 #define OP_Precision 97
#define OP_Min 97 #define OP_Min 98
#define OP_Max 98 #define OP_Max 99
#define OP_Like 99 #define OP_Like 100
#define OP_Glob 100 #define OP_Glob 101
#define OP_Eq 101 #define OP_Eq 102
#define OP_Ne 102 #define OP_Ne 103
#define OP_Lt 103 #define OP_Lt 104
#define OP_Le 104 #define OP_Le 105
#define OP_Gt 105 #define OP_Gt 106
#define OP_Ge 106 #define OP_Ge 107
#define OP_IsNull 107 #define OP_IsNull 108
#define OP_NotNull 108 #define OP_NotNull 109
#define OP_Negative 109 #define OP_Negative 110
#define OP_And 110 #define OP_And 111
#define OP_Or 111 #define OP_Or 112
#define OP_Not 112 #define OP_Not 113
#define OP_Concat 113 #define OP_Concat 114
#define OP_Noop 114 #define OP_Noop 115
#define OP_Strlen 115 #define OP_Strlen 116
#define OP_Substr 116 #define OP_Substr 117
#define OP_Limit 117 #define OP_Limit 118
#define OP_MAX 117 #define OP_MAX 118
/* /*
** Prototypes for the VDBE interface. See comments on the implementation ** Prototypes for the VDBE interface. See comments on the implementation

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.14 2002/02/18 18:30:33 drh Exp $ # $Id: table.test,v 1.15 2002/02/21 12:01:28 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@@ -282,8 +282,8 @@ do_test table-7.1 {
desc text, desc text,
asc text, asc text,
explain int, explain int,
vacuum boolean, [14_vac] boolean,
delimiters varchar(10), fuzzy_dog_12 varchar(10),
begin blob, begin blob,
end clob end clob
) )
@@ -300,7 +300,7 @@ do_test table-7.3 {
execsql2 { execsql2 {
SELECT * FROM weird; SELECT * FROM weird;
} }
} {desc a asc b explain 9 vacuum 0 delimiters xyz begin hi end y'all} } {desc a asc b explain 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
# Try out the CREATE TABLE AS syntax # Try out the CREATE TABLE AS syntax
# #
@@ -309,7 +309,20 @@ do_test table-8.1 {
CREATE TABLE t2 AS SELECT * FROM weird; CREATE TABLE t2 AS SELECT * FROM weird;
SELECT * FROM t2; SELECT * FROM t2;
} }
} {desc a asc b explain 9 vacuum 0 delimiters xyz begin hi end y'all} } {desc a asc b explain 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
do_test table-8.1.1 {
execsql {
SELECT sql FROM sqlite_master WHERE name='t2';
}
} {{CREATE TABLE t2(
'desc',
'asc',
'explain',
'14_vac',
fuzzy_dog_12,
'begin',
'end'
)}}
do_test table-8.2 { do_test table-8.2 {
execsql { execsql {
CREATE TABLE 't3''xyz'(a,b,c); CREATE TABLE 't3''xyz'(a,b,c);
@@ -319,10 +332,15 @@ do_test table-8.2 {
} {1 2 3} } {1 2 3}
do_test table-8.3 { do_test table-8.3 {
execsql2 { execsql2 {
CREATE TABLE [t4'abc] AS SELECT count(*), min(a), max(b+c) FROM [t3'xyz]; CREATE TABLE [t4'abc] AS SELECT count(*) as cnt, max(b+c) FROM [t3'xyz];
SELECT * FROM [t4'abc]; SELECT * FROM [t4'abc];
} }
} {count(*) 1 min(a) 1 max(b+c) 5} } {cnt 1 max(b+c) 5}
do_test table-8.3.1 {
execsql {
SELECT sql FROM sqlite_master WHERE name='t4''abc'
}
} {{CREATE TABLE 't4''abc'(cnt,'max(b+c)')}}
do_test table-8.4 { do_test table-8.4 {
execsql2 { execsql2 {
CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3'xyz]; CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3'xyz];
@@ -335,16 +353,21 @@ do_test table-8.5 {
execsql2 { execsql2 {
SELECT * FROM [t4'abc]; SELECT * FROM [t4'abc];
} }
} {count(*) 1 min(a) 1 max(b+c) 5} } {cnt 1 max(b+c) 5}
do_test table-8.6 { do_test table-8.6 {
execsql2 { execsql2 {
SELECT * FROM t2; SELECT * FROM t2;
} }
} {desc a asc b explain 9 vacuum 0 delimiters xyz begin hi end y'all} } {desc a asc b explain 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
do_test table-8.7 { do_test table-8.7 {
catchsql { catchsql {
SELECT * FROM t5; SELECT * FROM t5;
} }
} {1 {no such table: t5}} } {1 {no such table: t5}}
do_test table-8.8 {
catchsql {
CREATE TABLE t5 AS SELECT * FROM no_such_table;
}
} {1 {no such table: no_such_table}}
finish_test finish_test

View File

@@ -23,6 +23,8 @@ chng {2002 Feb * (2.3.4)} {
<li>SELECT min() or max() of an indexed column with no WHERE or GROUP BY <li>SELECT min() or max() of an indexed column with no WHERE or GROUP BY
clause is handled as a special case which avoids a complete table scan.</li> clause is handled as a special case which avoids a complete table scan.</li>
<li>Automatically generated ROWIDs are now sequential.</li> <li>Automatically generated ROWIDs are now sequential.</li>
<li>Do not allow dot-commands of the command-line shell to occur in the
middle of a real SQL command.</li>
} }
chng {2002 Feb 18 (2.3.3)} { chng {2002 Feb 18 (2.3.3)} {