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:
28
manifest
28
manifest
@@ -1,5 +1,5 @@
|
||||
C Do\snot\sallow\sdot-commands\sto\soccur\sin\sthe\smiddle\sof\sa\sreal\sSQL\scommand.\s(CVS\s385)
|
||||
D 2002-02-21T02:25:03
|
||||
C Change\sthe\sSQLITE_MASTER\sformat\sto\sversion\s2\sin\spreparation\sfor\sadding\sviews.\s(CVS\s386)
|
||||
D 2002-02-21T12:01:27
|
||||
F Makefile.in 9fa4277413bf1d9cf91365f07d4108d7d87ed2af
|
||||
F Makefile.template 3372d45f8853afdb70bd30cc6fb50a3cd9069834
|
||||
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
|
||||
@@ -21,13 +21,13 @@ F sqlite.1 2e2bb0529ef468ade9e4322bd609d0695fb9ded9
|
||||
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
|
||||
F src/btree.c 495275fe14f3b718cf2f691dce979d4c0e1f8e5d
|
||||
F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
|
||||
F src/build.c 088acf87a92b00edda1206ccafac3518660b1b3b
|
||||
F src/build.c 4e10d8e61971fe900317d00a98f49dd7ceb27c20
|
||||
F src/delete.c f8ad71be53cf18656b6573de65395852fe817f0c
|
||||
F src/expr.c 7aff65ea0732b07d36925087ad611019103ad69a
|
||||
F src/hash.c 8f7c740ef2eaaa8decfa8751f2be30680b123e46
|
||||
F src/hash.h d1ce47900c7325af5e41c4feb4855c4bf2b841e7
|
||||
F src/insert.c eae5aa2e9ac68c4d465e71b2ad34bcbb882979cf
|
||||
F src/main.c fada622b468c54fb211372f38a27ee636915e2ee
|
||||
F src/main.c abc0732d4caa676ff8337f278b01f1f1b57538f5
|
||||
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
|
||||
F src/os.c f6bc9b7ab530346bb7fef2ed39f2f1f214bc14ea
|
||||
F src/os.h a17596ecc7f38a228b83ecdb661fb03ce44726d6
|
||||
@@ -36,22 +36,22 @@ F src/pager.h b28f004e2f5541dc60cc32db01bf80cf4d056283
|
||||
F src/parse.y b82278917959eefd05bd08c90e07a4fa5917ea51
|
||||
F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
|
||||
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
|
||||
F src/select.c 282f37b2fdb9367f0230811e1cf7bba48665fb72
|
||||
F src/select.c f0cbfd2d9059e0f33837797ee326fbe964a35f09
|
||||
F src/shell.c cbf48bf0ca35c4e0d8a7d2a86f7724f52c525cd7
|
||||
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
|
||||
F src/sqlite.h.in f57074c84a2c112a5093ba7a9d9636aa9cacc87c
|
||||
F src/sqliteInt.h e19efd5b1c6accfb3418cbb5c0e8c143fc1d18d7
|
||||
F src/sqliteInt.h 338cd586b9322105080a2a31122446e504ac1fc4
|
||||
F src/table.c c89698bd5bb4b8d14722d6ee7e9be014c383d24a
|
||||
F src/tclsqlite.c b9cf346e95291cb4c4f1bf5ac1d77db6b8ad023d
|
||||
F src/test1.c 33efd350dca27c52c58c553c04fd3a6a51f13c1f
|
||||
F src/test2.c d410dbd8a90faa466c3ab694fa0aa57f5a773aa6
|
||||
F src/test3.c 4e52fff8b01f08bd202f7633feda5639b7ba2b5e
|
||||
F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f
|
||||
F src/tokenize.c 9e98f94469694a763992860596137e78dbae0cc0
|
||||
F src/tokenize.c 777b734f9d06f5a9055b6808e5baec18936a4fd9
|
||||
F src/update.c 95459f94a061860bf8e5716b3426a5ba85c79103
|
||||
F src/util.c f31f3d6198a0d1296a16f5a6ceec423a932cbbf6
|
||||
F src/vdbe.c 18b6e9ed3bcdd76ae74d60a977a6d8a3a1b0f797
|
||||
F src/vdbe.h b4d35e159fbb80a74728b4a96e5b789fffce6f57
|
||||
F src/vdbe.c 44832d804e109248e9e2abd40daee5f8ac735450
|
||||
F src/vdbe.h 002bb8cf884034bea25a9fe901a9c5e9d29bc045
|
||||
F src/where.c f79bc3179379b46b131a67ab10713779368dceee
|
||||
F test/all.test 7a8a8a7a579ed2bb4d8976d55402f21eacd58049
|
||||
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
|
||||
@@ -89,7 +89,7 @@ F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
|
||||
F test/select6.test d9fb417d6cab75a072b547ba6303120f327fd6fd
|
||||
F test/sort.test 3b996ce7ca385f9cd559944ac0f4027a23aa546b
|
||||
F test/subselect.test 335d3dad8d585726c447dfee8d9c4f7383c76b78
|
||||
F test/table.test b8be4d3d3ff6b4858516fa274d38075ba06b5004
|
||||
F test/table.test 17b0b6eafa3faaee5545b7a94e6c1ff73f0880f3
|
||||
F test/tableapi.test 51d0c209aa6b1158cb952ec917c656d4ce66e9e4
|
||||
F test/tclsqlite.test ca8dd89b02ab68bd4540163c24551756a69f6783
|
||||
F test/temptable.test 0e9934283259a5e637eec756a7eefd6964c0f79b
|
||||
@@ -110,7 +110,7 @@ F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
|
||||
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
|
||||
F www/arch.tcl 72a0c80e9054cc7025a50928d28d9c75c02c2b8b
|
||||
F www/c_interface.tcl 63efc40f09e2f0d8fea43d174103248b160fdf0e
|
||||
F www/changes.tcl e9ac5ffc030ad355fb5973bc2c68e622c3bc9ae2
|
||||
F www/changes.tcl 4aee975940a59d43736cdd4cd352c51e1e6426ba
|
||||
F www/conflict.tcl 81dd21f9a679e60aae049e9dd8ab53d59570cda2
|
||||
F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
|
||||
F www/download.tcl a6d75b8b117cd33dcb090bef7e80d7556d28ebe0
|
||||
@@ -125,7 +125,7 @@ F www/speed.tcl 83457b2bf6bb430900bd48ca3dd98264d9a916a5
|
||||
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
|
||||
F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
|
||||
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
|
||||
P 953928537c350e6c9df157553114c6d9d44712d5
|
||||
R 9ed6435fa0cf461ec879e5b28166d8d6
|
||||
P ffb00bf36a9a5851ea4a69f9c7dd7ce412553e3b
|
||||
R 827e990a5d306ede002baf12f96964e4
|
||||
U drh
|
||||
Z a1b5da6dd8cc3bb5ba9dca0ec016a36c
|
||||
Z 93dfb9234ed5554b3f3a0a3a7b0ddf3a
|
||||
|
@@ -1 +1 @@
|
||||
ffb00bf36a9a5851ea4a69f9c7dd7ce412553e3b
|
||||
b2a9807fed544e83002366149b9a363759338c5d
|
39
src/build.c
39
src/build.c
@@ -25,7 +25,7 @@
|
||||
** ROLLBACK
|
||||
** 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 <ctype.h>
|
||||
@@ -473,12 +473,25 @@ void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName, int isTemp){
|
||||
pTable->isTemp = isTemp;
|
||||
if( pParse->pNewTable ) sqliteDeleteTable(db, pParse->pNewTable);
|
||||
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 ){
|
||||
sqliteBeginWriteOperation(pParse);
|
||||
if( !isTemp ){
|
||||
sqliteVdbeAddOp(v, OP_SetCookie, db->file_format, 1);
|
||||
sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2);
|
||||
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){
|
||||
int n;
|
||||
for(n=2; *z; n++, z++){
|
||||
if( *z=='\'' ){ n++; }
|
||||
int needQuote = 0;
|
||||
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.
|
||||
*/
|
||||
static void identPut(char *z, int *pIdx, char *zIdent){
|
||||
int i, j;
|
||||
int i, j, needQuote;
|
||||
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++){
|
||||
z[i++] = zIdent[j];
|
||||
if( zIdent[j]=='\'' ) z[i++] = '\'';
|
||||
}
|
||||
z[i++] = '\'';
|
||||
if( needQuote ) z[i++] = '\'';
|
||||
z[i] = 0;
|
||||
*pIdx = i;
|
||||
}
|
||||
@@ -769,6 +788,7 @@ void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){
|
||||
*/
|
||||
if( pSelect ){
|
||||
Table *pSelTab = sqliteResultSetOfSelect(pParse, 0, pSelect);
|
||||
if( pSelTab==0 ) return;
|
||||
assert( p->aCol==0 );
|
||||
p->nCol = pSelTab->nCol;
|
||||
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
|
||||
** 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
|
||||
** 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);
|
||||
p->tnum = 0;
|
||||
if( !p->isTemp ){
|
||||
sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_Pull, 1, 0);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
sqliteVdbeChangeP3(v, -1, "table", P3_STATIC);
|
||||
sqliteVdbeAddOp(v, OP_String, 0, 0);
|
||||
|
76
src/main.c
76
src/main.c
@@ -14,7 +14,7 @@
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** 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 "os.h"
|
||||
@@ -51,13 +51,14 @@ static int sqliteOpenCb(void *pDb, int argc, char **argv, char **azColName){
|
||||
db->next_cookie = db->schema_cookie;
|
||||
break;
|
||||
}
|
||||
case 'v':
|
||||
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] ){
|
||||
/* 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
|
||||
** 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));
|
||||
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,
|
||||
** then the "sql" column is NULL.
|
||||
**
|
||||
** If the "type" column has the value "meta", then the "sql" column
|
||||
** contains extra information about the database, such as the
|
||||
** file format version number. All meta information must be processed
|
||||
** before any tables or indices are constructed.
|
||||
** In format 1, entries in the sqlite_master table are in a random
|
||||
** order. Two passes must be made through the table to initialize
|
||||
** internal data structures. The first pass reads table definitions
|
||||
** 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
|
||||
** table then goes back and invokes the callback on the
|
||||
@@ -161,38 +167,70 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
|
||||
** database scheme.
|
||||
*/
|
||||
static VdbeOp initProg[] = {
|
||||
/* Send the file format to the callback routine
|
||||
*/
|
||||
{ OP_Open, 0, 2, 0},
|
||||
{ OP_String, 0, 0, "file-format"},
|
||||
{ OP_String, 0, 0, 0},
|
||||
{ OP_String, 0, 0, 0},
|
||||
{ OP_ReadCookie, 0, 1, 0},
|
||||
{ OP_Callback, 4, 0, 0},
|
||||
|
||||
/* Send the initial schema cookie to the callback
|
||||
*/
|
||||
{ OP_String, 0, 0, "schema_cookie"},
|
||||
{ OP_String, 0, 0, 0},
|
||||
{ OP_String, 0, 0, 0},
|
||||
{ OP_ReadCookie, 0, 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_Ne, 0, 20, 0},
|
||||
{ OP_Ne, 0, 32, 0},
|
||||
{ OP_Column, 0, 0, 0},
|
||||
{ OP_Column, 0, 1, 0},
|
||||
{ OP_Column, 0, 3, 0},
|
||||
{ OP_Column, 0, 4, 0},
|
||||
{ OP_Callback, 4, 0, 0},
|
||||
{ OP_Next, 0, 12, 0}, /* 20 */
|
||||
{ OP_Rewind, 0, 31, 0}, /* 21 */
|
||||
{ OP_Column, 0, 0, 0}, /* 22 */
|
||||
{ OP_Next, 0, 24, 0}, /* 32 */
|
||||
{ OP_Rewind, 0, 43, 0}, /* 33 */
|
||||
{ OP_Column, 0, 0, 0}, /* 34 */
|
||||
{ OP_String, 0, 0, "index"},
|
||||
{ OP_Ne, 0, 30, 0},
|
||||
{ OP_Ne, 0, 42, 0},
|
||||
{ OP_Column, 0, 0, 0},
|
||||
{ OP_Column, 0, 1, 0},
|
||||
{ OP_Column, 0, 3, 0},
|
||||
{ OP_Column, 0, 4, 0},
|
||||
{ OP_Callback, 4, 0, 0},
|
||||
{ OP_Next, 0, 22, 0}, /* 30 */
|
||||
{ OP_Close, 0, 0, 0}, /* 31 */
|
||||
{ OP_Next, 0, 34, 0}, /* 42 */
|
||||
{ OP_Close, 0, 0, 0}, /* 43 */
|
||||
{ OP_Halt, 0, 0, 0},
|
||||
};
|
||||
|
||||
@@ -209,9 +247,9 @@ static int sqliteInit(sqlite *db, char **pzErrMsg){
|
||||
db->pBusyArg, db->xBusyCallback);
|
||||
sqliteVdbeDelete(vdbe);
|
||||
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);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
|
14
src/select.c
14
src/select.c
@@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** 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"
|
||||
|
||||
@@ -760,7 +760,10 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
|
||||
pTab = p->pSrc->a[0].pTab;
|
||||
|
||||
/* 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 ){
|
||||
pIdx = 0;
|
||||
@@ -772,7 +775,7 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
|
||||
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.
|
||||
*/
|
||||
v = sqliteGetVdbe(pParse);
|
||||
@@ -781,7 +784,10 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
|
||||
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 ){
|
||||
sqliteVdbeAddOp(v, OP_VerifyCookie, pParse->db->schema_cookie, 0);
|
||||
|
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** 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 "hash.h"
|
||||
@@ -30,11 +30,6 @@
|
||||
#define MAX_PAGES 100
|
||||
#define TEMP_PAGES 25
|
||||
|
||||
/*
|
||||
** File format version number
|
||||
*/
|
||||
#define FILE_FORMAT 1
|
||||
|
||||
/*
|
||||
** Integers of known sizes. These typedefs might change for architectures
|
||||
** 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 sqliteSetNString(char **, ...);
|
||||
void sqliteDequote(char*);
|
||||
int sqliteKeywordCode(const char*, int);
|
||||
int sqliteRunParser(Parse*, const char*, char **);
|
||||
void sqliteExec(Parse*);
|
||||
Expr *sqliteExpr(int, Expr*, Expr*, Token*);
|
||||
|
@@ -15,7 +15,7 @@
|
||||
** individual tokens and sends those tokens one-by-one over to the
|
||||
** 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 "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
|
||||
** 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;
|
||||
Keyword *p;
|
||||
if( aKeywordTable[0].len==0 ){
|
||||
|
87
src/vdbe.c
87
src/vdbe.c
@@ -30,7 +30,7 @@
|
||||
** But other routines are also provided to help in building up
|
||||
** 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 <ctype.h>
|
||||
@@ -72,6 +72,7 @@ struct Cursor {
|
||||
Bool keyAsData; /* The OP_Column command works on key instead of data */
|
||||
Bool atFirst; /* True if pointing to first entry */
|
||||
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 */
|
||||
};
|
||||
typedef struct Cursor Cursor;
|
||||
@@ -867,30 +868,30 @@ static char *zOpName[] = { 0,
|
||||
"Close", "MoveTo", "NewRecno", "PutIntKey",
|
||||
"PutStrKey", "Distinct", "Found", "NotFound",
|
||||
"IsUnique", "NotExists", "Delete", "Column",
|
||||
"KeyAsData", "Recno", "FullKey", "Last",
|
||||
"Rewind", "Next", "Destroy", "Clear",
|
||||
"CreateIndex", "CreateTable", "IntegrityCk", "IdxPut",
|
||||
"IdxDelete", "IdxRecno", "IdxGT", "IdxGE",
|
||||
"MemLoad", "MemStore", "ListWrite", "ListRewind",
|
||||
"ListRead", "ListReset", "SortPut", "SortMakeRec",
|
||||
"SortMakeKey", "Sort", "SortNext", "SortCallback",
|
||||
"SortReset", "FileOpen", "FileRead", "FileColumn",
|
||||
"AggReset", "AggFocus", "AggIncr", "AggNext",
|
||||
"AggSet", "AggGet", "SetInsert", "SetFound",
|
||||
"SetNotFound", "MakeRecord", "MakeKey", "MakeIdxKey",
|
||||
"IncrKey", "Goto", "If", "Halt",
|
||||
"ColumnCount", "ColumnName", "Callback", "NullCallback",
|
||||
"Integer", "String", "Pop", "Dup",
|
||||
"Pull", "Push", "MustBeInt", "Add",
|
||||
"AddImm", "Subtract", "Multiply", "Divide",
|
||||
"Remainder", "BitAnd", "BitOr", "BitNot",
|
||||
"ShiftLeft", "ShiftRight", "AbsValue", "Precision",
|
||||
"Min", "Max", "Like", "Glob",
|
||||
"Eq", "Ne", "Lt", "Le",
|
||||
"Gt", "Ge", "IsNull", "NotNull",
|
||||
"Negative", "And", "Or", "Not",
|
||||
"Concat", "Noop", "Strlen", "Substr",
|
||||
"Limit",
|
||||
"KeyAsData", "Recno", "FullKey", "NullRow",
|
||||
"Last", "Rewind", "Next", "Destroy",
|
||||
"Clear", "CreateIndex", "CreateTable", "IntegrityCk",
|
||||
"IdxPut", "IdxDelete", "IdxRecno", "IdxGT",
|
||||
"IdxGE", "MemLoad", "MemStore", "ListWrite",
|
||||
"ListRewind", "ListRead", "ListReset", "SortPut",
|
||||
"SortMakeRec", "SortMakeKey", "Sort", "SortNext",
|
||||
"SortCallback", "SortReset", "FileOpen", "FileRead",
|
||||
"FileColumn", "AggReset", "AggFocus", "AggIncr",
|
||||
"AggNext", "AggSet", "AggGet", "SetInsert",
|
||||
"SetFound", "SetNotFound", "MakeRecord", "MakeKey",
|
||||
"MakeIdxKey", "IncrKey", "Goto", "If",
|
||||
"Halt", "ColumnCount", "ColumnName", "Callback",
|
||||
"NullCallback", "Integer", "String", "Pop",
|
||||
"Dup", "Pull", "Push", "MustBeInt",
|
||||
"Add", "AddImm", "Subtract", "Multiply",
|
||||
"Divide", "Remainder", "BitAnd", "BitOr",
|
||||
"BitNot", "ShiftLeft", "ShiftRight", "AbsValue",
|
||||
"Precision", "Min", "Max", "Like",
|
||||
"Glob", "Eq", "Ne", "Lt",
|
||||
"Le", "Gt", "Ge", "IsNull",
|
||||
"NotNull", "Negative", "And", "Or",
|
||||
"Not", "Concat", "Noop", "Strlen",
|
||||
"Substr", "Limit",
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -2591,6 +2592,7 @@ case OP_Open: {
|
||||
}
|
||||
cleanupCursor(&p->aCsr[i]);
|
||||
memset(&p->aCsr[i], 0, sizeof(Cursor));
|
||||
p->aCsr[i].nullRow = 1;
|
||||
do{
|
||||
rc = sqliteBtreeCursor(pX, p2, wrFlag, &p->aCsr[i].pCursor);
|
||||
switch( rc ){
|
||||
@@ -2648,6 +2650,7 @@ case OP_OpenTemp: {
|
||||
pCx = &p->aCsr[i];
|
||||
cleanupCursor(pCx);
|
||||
memset(pCx, 0, sizeof(*pCx));
|
||||
pCx->nullRow = 1;
|
||||
rc = sqliteBtreeOpen(0, 0, TEMP_PAGES, &pCx->pBt);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqliteBtreeBeginTrans(pCx->pBt);
|
||||
@@ -2708,6 +2711,7 @@ case OP_MoveTo: {
|
||||
sqliteBtreeMoveto(pC->pCursor, zStack[tos], aStack[tos].n, &res);
|
||||
pC->recnoIsValid = 0;
|
||||
}
|
||||
pC->nullRow = 0;
|
||||
sqlite_search_count++;
|
||||
if( res<0 ){
|
||||
sqliteBtreeNext(pC->pCursor, &res);
|
||||
@@ -2892,8 +2896,12 @@ case OP_NotExists: {
|
||||
assert( aStack[tos].flags & STK_Int );
|
||||
iKey = intToKey(aStack[tos].i);
|
||||
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 ){
|
||||
pc = pOp->p2 - 1;
|
||||
p->aCsr[i].recnoIsValid = 0;
|
||||
}
|
||||
}
|
||||
POPSTACK;
|
||||
@@ -2982,6 +2990,7 @@ case OP_NewRecno: {
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
}
|
||||
pC->recnoIsValid = 0;
|
||||
}
|
||||
VERIFY( NeedStack(p, p->tos+1); )
|
||||
p->tos++;
|
||||
@@ -3044,6 +3053,7 @@ case OP_PutStrKey: {
|
||||
}
|
||||
rc = sqliteBtreeInsert(p->aCsr[i].pCursor, zKey, nKey,
|
||||
zStack[tos], aStack[tos].n);
|
||||
p->aCsr[i].recnoIsValid = 0;
|
||||
}
|
||||
POPSTACK;
|
||||
POPSTACK;
|
||||
@@ -3113,7 +3123,9 @@ case OP_Column: {
|
||||
** is coming from the key or the data of the record.
|
||||
*/
|
||||
pCrsr = pC->pCursor;
|
||||
if( pC->keyAsData ){
|
||||
if( pC->nullRow ){
|
||||
payloadSize = 0;
|
||||
}else if( pC->keyAsData ){
|
||||
sqliteBtreeKeySize(pCrsr, &payloadSize);
|
||||
xRead = sqliteBtreeKey;
|
||||
}else{
|
||||
@@ -3199,6 +3211,9 @@ case OP_Recno: {
|
||||
int v;
|
||||
if( p->aCsr[i].recnoIsValid ){
|
||||
v = p->aCsr[i].lastRecno;
|
||||
}else if( p->aCsr[i].nullRow ){
|
||||
aStack[tos].flags = STK_Null;
|
||||
break;
|
||||
}else{
|
||||
sqliteBtreeKey(pCrsr, 0, sizeof(u32), (char*)&v);
|
||||
v = keyToInt(v);
|
||||
@@ -3248,6 +3263,22 @@ case OP_FullKey: {
|
||||
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 *
|
||||
**
|
||||
** 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 ){
|
||||
int res;
|
||||
sqliteBtreeLast(pCrsr, &res);
|
||||
p->aCsr[i].atFirst = res==0;
|
||||
p->aCsr[i].nullRow = res;
|
||||
if( res && pOp->p2>0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
@@ -3287,6 +3318,7 @@ case OP_Rewind: {
|
||||
int res;
|
||||
sqliteBtreeFirst(pCrsr, &res);
|
||||
p->aCsr[i].atFirst = res==0;
|
||||
p->aCsr[i].nullRow = res;
|
||||
if( res && pOp->p2>0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
}
|
||||
@@ -3308,6 +3340,7 @@ case OP_Next: {
|
||||
if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
|
||||
int res;
|
||||
rc = sqliteBtreeNext(pCrsr, &res);
|
||||
p->aCsr[i].nullRow = res;
|
||||
if( res==0 ){
|
||||
pc = pOp->p2 - 1;
|
||||
sqlite_search_count++;
|
||||
|
185
src/vdbe.h
185
src/vdbe.h
@@ -15,7 +15,7 @@
|
||||
** or VDBE. The VDBE implements an abstract machine that runs a
|
||||
** 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_
|
||||
#define _SQLITE_VDBE_H_
|
||||
@@ -97,113 +97,114 @@ typedef struct VdbeOp VdbeOp;
|
||||
#define OP_KeyAsData 25
|
||||
#define OP_Recno 26
|
||||
#define OP_FullKey 27
|
||||
#define OP_Last 28
|
||||
#define OP_Rewind 29
|
||||
#define OP_Next 30
|
||||
#define OP_NullRow 28
|
||||
#define OP_Last 29
|
||||
#define OP_Rewind 30
|
||||
#define OP_Next 31
|
||||
|
||||
#define OP_Destroy 31
|
||||
#define OP_Clear 32
|
||||
#define OP_CreateIndex 33
|
||||
#define OP_CreateTable 34
|
||||
#define OP_IntegrityCk 35
|
||||
#define OP_Destroy 32
|
||||
#define OP_Clear 33
|
||||
#define OP_CreateIndex 34
|
||||
#define OP_CreateTable 35
|
||||
#define OP_IntegrityCk 36
|
||||
|
||||
#define OP_IdxPut 36
|
||||
#define OP_IdxDelete 37
|
||||
#define OP_IdxRecno 38
|
||||
#define OP_IdxGT 39
|
||||
#define OP_IdxGE 40
|
||||
#define OP_IdxPut 37
|
||||
#define OP_IdxDelete 38
|
||||
#define OP_IdxRecno 39
|
||||
#define OP_IdxGT 40
|
||||
#define OP_IdxGE 41
|
||||
|
||||
#define OP_MemLoad 41
|
||||
#define OP_MemStore 42
|
||||
#define OP_MemLoad 42
|
||||
#define OP_MemStore 43
|
||||
|
||||
#define OP_ListWrite 43
|
||||
#define OP_ListRewind 44
|
||||
#define OP_ListRead 45
|
||||
#define OP_ListReset 46
|
||||
#define OP_ListWrite 44
|
||||
#define OP_ListRewind 45
|
||||
#define OP_ListRead 46
|
||||
#define OP_ListReset 47
|
||||
|
||||
#define OP_SortPut 47
|
||||
#define OP_SortMakeRec 48
|
||||
#define OP_SortMakeKey 49
|
||||
#define OP_Sort 50
|
||||
#define OP_SortNext 51
|
||||
#define OP_SortCallback 52
|
||||
#define OP_SortReset 53
|
||||
#define OP_SortPut 48
|
||||
#define OP_SortMakeRec 49
|
||||
#define OP_SortMakeKey 50
|
||||
#define OP_Sort 51
|
||||
#define OP_SortNext 52
|
||||
#define OP_SortCallback 53
|
||||
#define OP_SortReset 54
|
||||
|
||||
#define OP_FileOpen 54
|
||||
#define OP_FileRead 55
|
||||
#define OP_FileColumn 56
|
||||
#define OP_FileOpen 55
|
||||
#define OP_FileRead 56
|
||||
#define OP_FileColumn 57
|
||||
|
||||
#define OP_AggReset 57
|
||||
#define OP_AggFocus 58
|
||||
#define OP_AggIncr 59
|
||||
#define OP_AggNext 60
|
||||
#define OP_AggSet 61
|
||||
#define OP_AggGet 62
|
||||
#define OP_AggReset 58
|
||||
#define OP_AggFocus 59
|
||||
#define OP_AggIncr 60
|
||||
#define OP_AggNext 61
|
||||
#define OP_AggSet 62
|
||||
#define OP_AggGet 63
|
||||
|
||||
#define OP_SetInsert 63
|
||||
#define OP_SetFound 64
|
||||
#define OP_SetNotFound 65
|
||||
#define OP_SetInsert 64
|
||||
#define OP_SetFound 65
|
||||
#define OP_SetNotFound 66
|
||||
|
||||
#define OP_MakeRecord 66
|
||||
#define OP_MakeKey 67
|
||||
#define OP_MakeIdxKey 68
|
||||
#define OP_IncrKey 69
|
||||
#define OP_MakeRecord 67
|
||||
#define OP_MakeKey 68
|
||||
#define OP_MakeIdxKey 69
|
||||
#define OP_IncrKey 70
|
||||
|
||||
#define OP_Goto 70
|
||||
#define OP_If 71
|
||||
#define OP_Halt 72
|
||||
#define OP_Goto 71
|
||||
#define OP_If 72
|
||||
#define OP_Halt 73
|
||||
|
||||
#define OP_ColumnCount 73
|
||||
#define OP_ColumnName 74
|
||||
#define OP_Callback 75
|
||||
#define OP_NullCallback 76
|
||||
#define OP_ColumnCount 74
|
||||
#define OP_ColumnName 75
|
||||
#define OP_Callback 76
|
||||
#define OP_NullCallback 77
|
||||
|
||||
#define OP_Integer 77
|
||||
#define OP_String 78
|
||||
#define OP_Pop 79
|
||||
#define OP_Dup 80
|
||||
#define OP_Pull 81
|
||||
#define OP_Push 82
|
||||
#define OP_MustBeInt 83
|
||||
#define OP_Integer 78
|
||||
#define OP_String 79
|
||||
#define OP_Pop 80
|
||||
#define OP_Dup 81
|
||||
#define OP_Pull 82
|
||||
#define OP_Push 83
|
||||
#define OP_MustBeInt 84
|
||||
|
||||
#define OP_Add 84
|
||||
#define OP_AddImm 85
|
||||
#define OP_Subtract 86
|
||||
#define OP_Multiply 87
|
||||
#define OP_Divide 88
|
||||
#define OP_Remainder 89
|
||||
#define OP_BitAnd 90
|
||||
#define OP_BitOr 91
|
||||
#define OP_BitNot 92
|
||||
#define OP_ShiftLeft 93
|
||||
#define OP_ShiftRight 94
|
||||
#define OP_AbsValue 95
|
||||
#define OP_Precision 96
|
||||
#define OP_Min 97
|
||||
#define OP_Max 98
|
||||
#define OP_Like 99
|
||||
#define OP_Glob 100
|
||||
#define OP_Eq 101
|
||||
#define OP_Ne 102
|
||||
#define OP_Lt 103
|
||||
#define OP_Le 104
|
||||
#define OP_Gt 105
|
||||
#define OP_Ge 106
|
||||
#define OP_IsNull 107
|
||||
#define OP_NotNull 108
|
||||
#define OP_Negative 109
|
||||
#define OP_And 110
|
||||
#define OP_Or 111
|
||||
#define OP_Not 112
|
||||
#define OP_Concat 113
|
||||
#define OP_Noop 114
|
||||
#define OP_Add 85
|
||||
#define OP_AddImm 86
|
||||
#define OP_Subtract 87
|
||||
#define OP_Multiply 88
|
||||
#define OP_Divide 89
|
||||
#define OP_Remainder 90
|
||||
#define OP_BitAnd 91
|
||||
#define OP_BitOr 92
|
||||
#define OP_BitNot 93
|
||||
#define OP_ShiftLeft 94
|
||||
#define OP_ShiftRight 95
|
||||
#define OP_AbsValue 96
|
||||
#define OP_Precision 97
|
||||
#define OP_Min 98
|
||||
#define OP_Max 99
|
||||
#define OP_Like 100
|
||||
#define OP_Glob 101
|
||||
#define OP_Eq 102
|
||||
#define OP_Ne 103
|
||||
#define OP_Lt 104
|
||||
#define OP_Le 105
|
||||
#define OP_Gt 106
|
||||
#define OP_Ge 107
|
||||
#define OP_IsNull 108
|
||||
#define OP_NotNull 109
|
||||
#define OP_Negative 110
|
||||
#define OP_And 111
|
||||
#define OP_Or 112
|
||||
#define OP_Not 113
|
||||
#define OP_Concat 114
|
||||
#define OP_Noop 115
|
||||
|
||||
#define OP_Strlen 115
|
||||
#define OP_Substr 116
|
||||
#define OP_Strlen 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
|
||||
|
@@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# 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]
|
||||
source $testdir/tester.tcl
|
||||
@@ -282,8 +282,8 @@ do_test table-7.1 {
|
||||
desc text,
|
||||
asc text,
|
||||
explain int,
|
||||
vacuum boolean,
|
||||
delimiters varchar(10),
|
||||
[14_vac] boolean,
|
||||
fuzzy_dog_12 varchar(10),
|
||||
begin blob,
|
||||
end clob
|
||||
)
|
||||
@@ -300,7 +300,7 @@ do_test table-7.3 {
|
||||
execsql2 {
|
||||
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
|
||||
#
|
||||
@@ -309,7 +309,20 @@ do_test table-8.1 {
|
||||
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}
|
||||
} {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 {
|
||||
execsql {
|
||||
CREATE TABLE 't3''xyz'(a,b,c);
|
||||
@@ -319,10 +332,15 @@ do_test table-8.2 {
|
||||
} {1 2 3}
|
||||
do_test table-8.3 {
|
||||
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];
|
||||
}
|
||||
} {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 {
|
||||
execsql2 {
|
||||
CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3'xyz];
|
||||
@@ -335,16 +353,21 @@ do_test table-8.5 {
|
||||
execsql2 {
|
||||
SELECT * FROM [t4'abc];
|
||||
}
|
||||
} {count(*) 1 min(a) 1 max(b+c) 5}
|
||||
} {cnt 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}
|
||||
} {desc a asc b explain 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
|
||||
do_test table-8.7 {
|
||||
catchsql {
|
||||
SELECT * FROM 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
|
||||
|
@@ -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
|
||||
clause is handled as a special case which avoids a complete table scan.</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)} {
|
||||
|
Reference in New Issue
Block a user