-C :-)\s(CVS\s14)
-D 2000-05-30T13:44:19
+C :-)\s(CVS\s15)
+D 2000-05-30T16:27:04
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
F Makefile.in 89921c1ee4de75275bfadfbac198396da31704d1
F README 6b5960603c7f8bf42fc022b4b6436f242f238dbb
F configure 00a5b5c82147a576fa6e82d7c1b0d55c321d6d2c x
F configure.in 6ccfd5fc80517f7cfe605a7fc7e0f62d962a233c
F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47
-F src/build.c bc81ec2f7c3296c1f784f7c94d2d8afea9f787e7
+F src/build.c 971796c068b8ae25b476f924e5e0da0b57adb9e6
F src/dbbe.c ab05293e89525041eaab8b4aca10516db3648792
F src/dbbe.h bedeb3a0985bb584458e7849fb59927e99e751e6
F src/main.c 25cce7bce0eb3ba10bada7c05f4b38dc6dbbc86f
-F src/parse.y 265c8596598afba0a94b94acd9c866d01603dfe5
+F src/parse.y 50ca06d471132e16bb47c56f19553e4efd5b3d4a
F src/shell.c 125f84ea5f8b725ba474d4702b575d062cc94d92
F src/sqlite.h 2397c17a8f4ca90c09acab0100dc7e2f8f441b69
-F src/sqliteInt.h 562760efc29cf5b37a9029de04a5a8bca156f025
+F src/sqliteInt.h 749da8b3e4ce146fd172aeb59b6db04c57726d7a
F src/tclsqlite.c 9efd29f79ded6a900aa3d142169c8bfe03b7affd
-F src/tokenize.c 948b8897ba211b58069d4a4465be23a2c639cf18
-F src/util.c dc1e1814cf69587e6ed58b82dd880ddb2165f3ce
-F src/vdbe.c 80132b6bb9a744d1990a1c16666d54baaff2dbc3
-F src/vdbe.h e721ad308f2e6ca805cebc4dd0a196ce4419d030
+F src/tokenize.c e176b2c1c38e11482ee3419d6b50b733860a1587
+F src/util.c 2a0314dcc9de230526380765339071a5b304d70d
+F src/vdbe.c 117ce5541143e3af9dccdc15c22c4920a7b9bdb4
+F src/vdbe.h 03de26632f2e608c2a44a40262fbba21a8bdfd81
F src/where.c be3973952e9bb5d2bb0bc5523b03f5d1f9e9d6f9
F test/all.test 66a8a5b8291a472157944edcdce51a320ebd1f35
F test/delete.test 814d53e3b0d2d7069fb17e005d4041454d6585d4
F test/expr.test 11e00880d2de0f60ff1ba7fdd4e09a0d72a01910
F test/index.test 8d4f26901a5582daa353fe3c8266cbf4a53af830
F test/insert.test 161bc67a4189738c559e3569323ceae31f4d49d6
-F test/table.test 2d6b3ba1024032d341aec0d3c48272c8407485b4
+F test/table.test 85d6f410d127ec508c6640f02d7c40d218414e81
F test/tester.tcl 70d25b7ced0a958bc377c72399b3dc6bf6a2d09e
F test/update.test 69459302ea75cafac1479e60b0e36efb88123c0e
F tool/gdbmdump.c 529e67c78d920606ba196326ea55b57b75fcc82b
F www/c_interface.tcl f875864edf7974157d1c257ca08de854660882a5
F www/index.tcl 2466d1b2e26c6f354b0acedee12025309a216799
F www/sqlite.tcl 947e067bcc347dc767af4c1a6e5a8d47d8404aa3
-P 191a7f484e0a10839e7e1c8eb6658536643e4756
-R 0c03c3a3c9ac1b3b825b1193112ad5a4
+P 1bb8ee8d9f1d3c409a11910e7552e4bb5e7f5f87
+R 0bda635e569bcbbf1f49ce4a3f5d3df9
U drh
-Z df606080358f2355e3007d65ffed4f54
+Z 1c759b788ddf2200404a81ace8a2be6e
-1bb8ee8d9f1d3c409a11910e7552e4bb5e7f5f87
\ No newline at end of file
+8d66c7355de1d87b25c4fb92d0ef3603da72899a
\ No newline at end of file
** This file contains C code routines that are called by the parser
** when syntax rules are reduced.
**
-** $Id: build.c,v 1.6 2000/05/30 13:44:19 drh Exp $
+** $Id: build.c,v 1.7 2000/05/30 16:27:04 drh Exp $
*/
#include "sqliteInt.h"
static char *sqliteTableNameFromToken(Token *pName){
char *zName = 0;
sqliteSetNString(&zName, pName->z, pName->n, 0);
+ sqliteDequote(zName);
return zName;
}
pz = &p->azCol[p->nCol++];
*pz = 0;
sqliteSetNString(pz, pName->z, pName->n, 0);
+ sqliteDequote(*pz);
}
/*
pList->a[i].zName = 0;
if( pName ){
sqliteSetNString(&pList->a[i].zName, pName->z, pName->n, 0);
+ sqliteDequote(pList->a[i].zName);
}
return pList;
}
memset(&pList->a[pList->nId], 0, sizeof(pList->a[0]));
if( pToken ){
sqliteSetNString(&pList->a[pList->nId].zName, pToken->z, pToken->n, 0);
+ sqliteDequote(pList->a[pList->nId].zName);
}
pList->nId++;
return pList;
if( pList && pList->nId>0 ){
int i = pList->nId - 1;
sqliteSetNString(&pList->a[i].zAlias, pToken->z, pToken->n, 0);
+ sqliteDequote(pList->a[i].zAlias);
}
}
sqliteExprDelete(pWhere);
return;
}
+
+/*
+** The COPY command is for compatibility with PostgreSQL and specificially
+** for the ability to read the output of pg_dump. The format is as
+** follows:
+**
+** COPY table FROM file [USING DELIMITERS string]
+**
+** "table" is an existing table name. We will read lines of code from
+** file to fill this table with data. File might be "stdin". The optional
+** delimiter string identifies the field separators. The default is a tab.
+*/
+void sqliteCopy(
+ Parse *pParse, /* The parser context */
+ Token *pTableName, /* The name of the table into which we will insert */
+ Token *pFilename, /* The file from which to obtain information */
+ Token *pDelimiter /* Use this as the field delimiter */
+){
+ Table *pTab;
+ char *zTab;
+ int i, j;
+ Vdbe *v;
+ int addr, end;
+ Index *pIdx;
+
+ zTab = sqliteTableNameFromToken(pTableName);
+ pTab = sqliteFindTable(pParse->db, zTab);
+ sqliteFree(zTab);
+ if( pTab==0 ){
+ sqliteSetNString(&pParse->zErrMsg, "no such table: ", 0,
+ pTableName->z, pTableName->n, 0);
+ pParse->nErr++;
+ goto copy_cleanup;
+ }
+ if( pTab->readOnly ){
+ sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
+ " may not be modified", 0);
+ pParse->nErr++;
+ goto copy_cleanup;
+ }
+ v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe);
+ if( v ){
+ addr = sqliteVdbeAddOp(v, OP_FileOpen, 0, 0, 0, 0);
+ sqliteVdbeChangeP3(v, addr, pFilename->z, pFilename->n);
+ sqliteVdbeAddOp(v, OP_Open, 0, 0, pTab->zName, 0);
+ for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ sqliteVdbeAddOp(v, OP_Open, i, 0, pIdx->zName, 0);
+ }
+ end = sqliteVdbeMakeLabel(v);
+ addr = sqliteVdbeAddOp(v, OP_FileRead, pTab->nCol, end, 0, 0);
+ if( pDelimiter ){
+ sqliteVdbeChangeP3(v, addr, pDelimiter->z, pDelimiter->n);
+ sqliteVdbeDequoteP3(v, addr);
+ }else{
+ sqliteVdbeChangeP3(v, addr, "\t", 1);
+ }
+ sqliteVdbeAddOp(v, OP_New, 0, 0, 0, 0);
+ if( pTab->pIndex ){
+ sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
+ }
+ for(i=0; i<pTab->nCol; i++){
+ sqliteVdbeAddOp(v, OP_FileField, i, 0, 0, 0);
+ }
+ sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0);
+ sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0);
+ for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ if( pIdx->pNext ){
+ sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
+ }
+ for(j=0; j<pIdx->nField; j++){
+ sqliteVdbeAddOp(v, OP_FileField, pIdx->aiField[j], 0, 0, 0);
+ }
+ sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
+ sqliteVdbeAddOp(v, OP_PutIdx, i, 0, 0, 0);
+ }
+ sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
+ sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, end);
+ }
+
+copy_cleanup:
+ return;
+}
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
-** @(#) $Id: parse.y,v 1.1 2000/05/29 20:42:06 drh Exp $
+** @(#) $Id: parse.y,v 1.2 2000/05/30 16:27:04 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
// The first form of a command is a CREATE TABLE statement.
//
cmd ::= create_table create_table_args.
-create_table ::= CREATE(X) TABLE ID(Y). {sqliteStartTable(pParse,&X,&Y);}
+create_table ::= CREATE(X) TABLE id(Y). {sqliteStartTable(pParse,&X,&Y);}
create_table_args ::= LP columnlist conslist_opt RP(X).
{sqliteEndTable(pParse,&X);}
columnlist ::= columnlist COMMA column.
// an elaborate typename. Perhaps someday we'll do something with it.
//
column ::= columnid type carglist.
-columnid ::= ID(X). {sqliteAddColumn(pParse,&X);}
+columnid ::= id(X). {sqliteAddColumn(pParse,&X);}
+%type id {Token}
+id(A) ::= ID(X). {A = X;}
+id(A) ::= STRING(X). {A = X;}
type ::= typename.
type ::= typename LP signed RP.
type ::= typename LP signed COMMA signed RP.
{sqliteCreateIndex(pParse,0,0,X,0,0);}
tcons2 ::= UNIQUE LP idlist RP.
tcons2 ::= CHECK expr.
-idlist ::= idlist COMMA ID.
-idlist ::= ID.
+idlist ::= idlist COMMA id.
+idlist ::= id.
// The next command format is dropping tables.
//
-cmd ::= DROP TABLE ID(X). {sqliteDropTable(pParse,&X);}
+cmd ::= DROP TABLE id(X). {sqliteDropTable(pParse,&X);}
// The select statement
//
from(A) ::= FROM seltablist(X). {A = X;}
stl_prefix(A) ::= seltablist(X) COMMA. {A = X;}
stl_prefix(A) ::= . {A = 0;}
-seltablist(A) ::= stl_prefix(X) ID(Y). {A = sqliteIdListAppend(X,&Y);}
-seltablist(A) ::= stl_prefix(X) ID(Y) AS ID(Z).
+seltablist(A) ::= stl_prefix(X) id(Y). {A = sqliteIdListAppend(X,&Y);}
+seltablist(A) ::= stl_prefix(X) id(Y) AS id(Z).
{A = sqliteIdListAppend(X,&Y);
sqliteIdListAddAlias(A,&Z);}
{A = sqliteIdListAppend(0,&Y);}
idxitem(A) ::= ID(X). {A = X;}
-cmd ::= DROP INDEX ID(X). {sqliteDropIndex(pParse, &X);}
+cmd ::= DROP INDEX id(X). {sqliteDropIndex(pParse, &X);}
+
+cmd ::= COPY id(X) FROM id(Y) USING DELIMITERS STRING(Z).
+ {sqliteCopy(pParse,&X,&Y,&Z);}
+cmd ::= COPY id(X) FROM id(Y).
+ {sqliteCopy(pParse,&X,&Y,0);}
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.2 2000/05/30 13:44:20 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.3 2000/05/30 16:27:04 drh Exp $
*/
#include "sqlite.h"
#include "dbbe.h"
int sqliteGetToken(const char*, int *);
void sqliteSetString(char **, const char *, ...);
void sqliteSetNString(char **, ...);
+void sqliteDequote(char*);
int sqliteRunParser(Parse*, char*, char **);
void sqliteExec(Parse*);
Expr *sqliteExpr(int, Expr*, Expr*, Token*);
void sqliteExprIfTrue(Parse*, Expr*, int);
void sqliteExprIfFalse(Parse*, Expr*, int);
Table *sqliteFindTable(sqlite*,char*);
+void sqliteCopy(Parse*, Token*, Token*, Token*);
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
-** $Id: tokenize.c,v 1.2 2000/05/30 13:44:20 drh Exp $
+** $Id: tokenize.c,v 1.3 2000/05/30 16:27:04 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
{ "BY", 0, TK_BY, 0 },
{ "CHECK", 0, TK_CHECK, 0 },
{ "CONSTRAINT", 0, TK_CONSTRAINT, 0 },
+ { "COPY", 0, TK_COPY, 0 },
{ "CREATE", 0, TK_CREATE, 0 },
{ "DEFAULT", 0, TK_DEFAULT, 0 },
{ "DELETE", 0, TK_DELETE, 0 },
+ { "DELIMITERS", 0, TK_DELIMITERS, 0 },
{ "DESC", 0, TK_DESC, 0 },
{ "DROP", 0, TK_DROP, 0 },
{ "EXPLAIN", 0, TK_EXPLAIN, 0 },
{ "TABLE", 0, TK_TABLE, 0 },
{ "UNIQUE", 0, TK_UNIQUE, 0 },
{ "UPDATE", 0, TK_UPDATE, 0 },
+ { "USING", 0, TK_USING, 0 },
{ "VALUES", 0, TK_VALUES, 0 },
{ "WHERE", 0, TK_WHERE, 0 },
};
extern void sqliteParserTrace(FILE*, char *);
i = 0;
- pEngine = sqliteParserAlloc((void(*)())malloc);
+ pEngine = sqliteParserAlloc((void*(*)(int))malloc);
if( pEngine==0 ){
sqliteSetString(pzErrMsg, "out of memory", 0);
return 1;
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.5 2000/05/30 13:44:20 drh Exp $
+** $Id: util.c,v 1.6 2000/05/30 16:27:04 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
va_end(ap);
}
+/*
+** Convert an SQL-style quoted string into a normal string by removing
+** the quote characters. The conversion is done in-place. If the
+** input does not begin with a quote character, then this routine
+** is a no-op.
+*/
+void sqliteDequote(char *z){
+ int quote;
+ int i, j;
+ quote = z[0];
+ if( quote!='\'' && quote!='"' ) return;
+ for(i=1, j=0; z[i]; i++){
+ if( z[i]==quote ){
+ if( z[i+1]==quote ){
+ z[j++] = quote;
+ i++;
+ }else{
+ z[j++] = 0;
+ break;
+ }
+ }else{
+ z[j++] = z[i];
+ }
+ }
+}
+
/* An array to map all upper-case characters into their corresponding
** lower-case character.
*/
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
-** $Id: vdbe.c,v 1.1 2000/05/29 14:26:02 drh Exp $
+** $Id: vdbe.c,v 1.2 2000/05/30 16:27:04 drh Exp $
*/
#include "sqliteInt.h"
FILE **apList; /* An open file for each list */
int nSort; /* Number of slots in apSort[] */
Sorter **apSort; /* An open sorter list */
+ FILE *pFile; /* At most one open file handler */
+ int nField; /* Number of file fields */
+ char **azField; /* Data for each file field */
+ char *zLine; /* A single line from the input file */
+ int nLineAlloc; /* Number of spaces allocated for zLine */
};
/*
** resolve to be a single actual quote character within the string.
*/
void sqliteVdbeDequoteP3(Vdbe *p, int addr){
- int quote;
- int i, j;
char *z;
if( addr<0 || addr>=p->nOp ) return;
z = p->aOp[addr].p3;
- quote = z[0];
- if( quote!='\'' && quote!='"' ) return;
- for(i=1, j=0; z[i]; i++){
- if( z[i]==quote ){
- if( z[i+1]==quote ){
- z[j++] = quote;
- i++;
- }else{
- z[j++] = 0;
- break;
- }
- }else{
- z[j++] = z[i];
- }
- }
+ sqliteDequote(z);
}
/*
sqliteFree(p->apSort);
p->apSort = 0;
p->nSort = 0;
+ if( p->pFile ){
+ if( p->pFile!=stdin ) fclose(p->pFile);
+ p->pFile = 0;
+ }
+ if( p->azField ){
+ sqliteFree(p->azField);
+ p->azField = 0;
+ }
+ p->nField = 0;
+ if( p->zLine ){
+ sqliteFree(p->zLine);
+ p->zLine = 0;
+ }
+ p->nLineAlloc = 0;
}
/*
"ListWrite", "ListRewind", "ListRead", "ListClose",
"SortOpen", "SortPut", "SortMakeRec", "SortMakeKey",
"Sort", "SortNext", "SortKey", "SortCallback",
- "SortClose", "MakeRecord", "MakeKey", "Goto",
+ "SortClose", "FileOpen", "FileRead", "FileField",
+ "FileClose", "MakeRecord", "MakeKey", "Goto",
"If", "Halt", "ColumnCount", "ColumnName",
"Callback", "Integer", "String", "Pop",
"Dup", "Pull", "Add", "AddImm",
break;
}
+ /* Opcode: FileOpen * * P3
+ **
+ ** Open the file named by P3 for reading using the FileRead opcode.
+ ** If P3 is "stdin" then output standard input for reading.
+ */
+ case OP_FileOpen: {
+ if( pOp->p3==0 ) goto bad_instruction;
+ if( p->pFile ){
+ if( p->pFile!=stdin ) fclose(p->pFile);
+ p->pFile = 0;
+ }
+ if( sqliteStrICmp(pOp->p3,"stdin")==0 ){
+ p->pFile = stdin;
+ }else{
+ p->pFile = fopen(pOp->p3, "r");
+ }
+ if( p->pFile==0 ){
+ sqliteSetString(pzErrMsg,"unable to open file: ", pOp->p3, 0);
+ rc = 1;
+ goto cleanup;
+ }
+ break;
+ }
+
+ /* Opcode: FileClose * * *
+ **
+ ** Close a file previously opened using FileOpen. This is a no-op
+ ** if there is no prior FileOpen call.
+ */
+ case OP_FileClose: {
+ if( p->pFile ){
+ if( p->pFile!=stdin ) fclose(p->pFile);
+ p->pFile = 0;
+ }
+ if( p->azField ){
+ sqliteFree(p->azField);
+ p->azField = 0;
+ }
+ p->nField = 0;
+ if( p->zLine ){
+ sqliteFree(p->zLine);
+ p->zLine = 0;
+ }
+ p->nLineAlloc = 0;
+ break;
+ }
+
+ /* Opcode: FileRead P1 P2 P3
+ **
+ ** Read a single line of input the open file (the file opened using
+ ** FileOpen). If we reach end-of-file, jump immediately to P2. If
+ ** we are able to get another line, split the line apart using P3 as
+ ** a delimiter. There should be exactly P1 fields. Throw an exception
+ ** if the number of fields is different from P1.
+ */
+ case OP_FileRead: {
+ int n, eol, nField, i, c, nDelim;
+ char *zDelim, *z;
+ if( p->pFile==0 ) goto fileread_jump;
+ nField = pOp->p1;
+ if( nField<=0 ) goto fileread_jump;
+ if( nField!=p->nField || p->azField==0 ){
+ p->azField = sqliteRealloc(p->azField, sizeof(char*)*nField+1);
+ if( p->azField==0 ){
+ p->nField = 0;
+ goto fileread_jump;
+ }
+ p->nField = nField;
+ }
+ n = 0;
+ eol = 0;
+ while( eol==0 ){
+ if( p->zLine==0 || n+200>p->nLineAlloc ){
+ p->nLineAlloc = p->nLineAlloc*2 + 300;
+ p->zLine = sqliteRealloc(p->zLine, p->nLineAlloc);
+ if( p->zLine==0 ){
+ p->nLineAlloc = 0;
+ goto fileread_jump;
+ }
+ }
+ if( fgets(&p->zLine[n], p->nLineAlloc-n, p->pFile)==0 ){
+ eol = 1;
+ p->zLine[n] = 0;
+ }else{
+ while( p->zLine[n] ){ n++; }
+ if( n>0 && p->zLine[n-1]=='\n' ){
+ n--;
+ p->zLine[n] = 0;
+ eol = 1;
+ }
+ }
+ }
+ if( n==0 ) goto fileread_jump;
+ z = p->zLine;
+ if( z[0]=='\\' && z[1]=='.' && z[2]==0 ){
+ goto fileread_jump;
+ }
+ zDelim = pOp->p3;
+ if( zDelim==0 ) zDelim = "\t";
+ c = zDelim[0];
+ nDelim = strlen(zDelim);
+ p->azField[0] = z;
+ for(i=1; *z!=0 && i<nField; i++){
+ while( *z && (*z!=c || strncmp(z,zDelim,nDelim)) ){ z++; }
+ if( *z ){
+ *z = 0;
+ z += nDelim;
+ p->azField[i] = z;
+ }
+ }
+ while( i<nField ){
+ p->azField[i++] = "";
+ }
+ break;
+
+ /* If we reach end-of-file, or if anything goes wrong, jump here.
+ ** This code will cause a jump to P2 */
+ fileread_jump:
+ pc = pOp->p2;
+ if( pc<0 || pc>p->nOp ){
+ sqliteSetString(pzErrMsg, "jump destination out of range", 0);
+ rc = 1;
+ }
+ pc--;
+ break;
+ }
+
+ /* Opcode: FileField P1 * *
+ **
+ ** Push onto the stack the P1-th field of the most recently read line
+ ** from the file.
+ */
+ case OP_FileField: {
+ int i = pOp->p1;
+ char *z;
+ if( NeedStack(p, p->tos+1) ) goto no_mem;
+ if( i>=0 && i<p->nField && p->azField ){
+ z = p->azField[i];
+ }else{
+ z = 0;
+ }
+ if( z==0 ) z = "";
+ p->tos++;
+ p->iStack[p->tos] = strlen(z) + 1;
+ sqliteSetString(&p->zStack[p->tos], z, 0);
+ break;
+ }
+
/* An other opcode is illegal...
*/
default: {
** 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.1 2000/05/29 14:26:02 drh Exp $
+** $Id: vdbe.h,v 1.2 2000/05/30 16:27:05 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#define OP_SortCallback 28
#define OP_SortClose 29
-#define OP_MakeRecord 30
-#define OP_MakeKey 31
-
-#define OP_Goto 32
-#define OP_If 33
-#define OP_Halt 34
-
-#define OP_ColumnCount 35
-#define OP_ColumnName 36
-#define OP_Callback 37
-
-#define OP_Integer 38
-#define OP_String 39
-#define OP_Pop 40
-#define OP_Dup 41
-#define OP_Pull 42
-
-#define OP_Add 43
-#define OP_AddImm 44
-#define OP_Subtract 45
-#define OP_Multiply 46
-#define OP_Divide 47
-#define OP_Min 48
-#define OP_Max 49
-#define OP_Eq 50
-#define OP_Ne 51
-#define OP_Lt 52
-#define OP_Le 53
-#define OP_Gt 54
-#define OP_Ge 55
-#define OP_IsNull 56
-#define OP_NotNull 57
-#define OP_Negative 58
-#define OP_And 59
-#define OP_Or 60
-#define OP_Not 61
-#define OP_Concat 62
-#define OP_Noop 63
-
-#define OP_MAX 63
+#define OP_FileOpen 30
+#define OP_FileRead 31
+#define OP_FileField 32
+#define OP_FileClose 33
+
+#define OP_MakeRecord 34
+#define OP_MakeKey 35
+
+#define OP_Goto 36
+#define OP_If 37
+#define OP_Halt 38
+
+#define OP_ColumnCount 39
+#define OP_ColumnName 40
+#define OP_Callback 41
+
+#define OP_Integer 42
+#define OP_String 43
+#define OP_Pop 44
+#define OP_Dup 45
+#define OP_Pull 46
+
+#define OP_Add 47
+#define OP_AddImm 48
+#define OP_Subtract 49
+#define OP_Multiply 50
+#define OP_Divide 51
+#define OP_Min 52
+#define OP_Max 53
+#define OP_Eq 54
+#define OP_Ne 55
+#define OP_Lt 56
+#define OP_Le 57
+#define OP_Gt 58
+#define OP_Ge 59
+#define OP_IsNull 60
+#define OP_NotNull 61
+#define OP_Negative 62
+#define OP_And 63
+#define OP_Or 64
+#define OP_Not 65
+#define OP_Concat 66
+#define OP_Noop 67
+
+#define OP_MAX 67
/*
** Prototypes for the VDBE interface. See comments on the implementation
# This file implements regression tests for SQLite library. The
# focus of this file is testing the CREATE TABLE statement.
#
-# $Id: table.test,v 1.3 2000/05/30 13:44:20 drh Exp $
+# $Id: table.test,v 1.4 2000/05/30 16:27:05 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
execsql {SELECT name FROM sqlite_master}
} {}
+# Repeat the above steps, but this time quote the table name.
+#
+do_test table-1.10 {
+ execsql {CREATE TABLE "create" (f1 int)}
+ execsql {SELECT name FROM sqlite_master}
+} {create}
+do_test table-1.11 {
+ execsql {DROP TABLE "create"}
+ execsql {SELECT name FROM "sqlite_master"}
+} {}
+do_test table-1.12 {
+ execsql {CREATE TABLE test1("f1 ho" int)}
+ execsql {SELECT name as "X" FROM sqlite_master}
+} {test1}
+do_test table-1.13 {
+ execsql {DROP TABLE "TEST1"}
+ execsql {SELECT name FROM "sqlite_master"}
+} {}
+
+
# Verify that we cannot make two tables with the same name
#