1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

:-) (CVS 20)

FossilOrigin-Name: 01d85b35e9c4ca5619ad21a4232a8f8bf9ec3538
This commit is contained in:
drh
2000-05-31 02:27:49 +00:00
parent 7e391e1728
commit dce2cbe65f
17 changed files with 505 additions and 131 deletions

View File

@ -145,6 +145,9 @@ sqlite.html: $(TOP)/www/sqlite.tcl
c_interface.html: $(TOP)/www/c_interface.tcl c_interface.html: $(TOP)/www/c_interface.tcl
tclsh $(TOP)/www/c_interface.tcl >c_interface.html tclsh $(TOP)/www/c_interface.tcl >c_interface.html
changes.html: $(TOP)/www/changes.tcl
tclsh $(TOP)/www/changes.tcl >changes.html
# Files to be published on the website. # Files to be published on the website.
# #
PUBLISH = \ PUBLISH = \
@ -152,6 +155,7 @@ PUBLISH = \
all.tar.gz \ all.tar.gz \
index.html \ index.html \
sqlite.html \ sqlite.html \
changes.html \
c_interface.html c_interface.html
website: $(PUBLISH) website: $(PUBLISH)

View File

@ -1,25 +1,25 @@
C :-)\s(CVS\s19) C :-)\s(CVS\s20)
D 2000-05-30T20:17:49 D 2000-05-31T02:27:49
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
F Makefile.in 89921c1ee4de75275bfadfbac198396da31704d1 F Makefile.in dd79c78825935c5711ce45c372b0ac0f194b6d43
F README 6b5960603c7f8bf42fc022b4b6436f242f238dbb F README 6b5960603c7f8bf42fc022b4b6436f242f238dbb
F configure 00a5b5c82147a576fa6e82d7c1b0d55c321d6d2c x F configure 00a5b5c82147a576fa6e82d7c1b0d55c321d6d2c x
F configure.in 6ccfd5fc80517f7cfe605a7fc7e0f62d962a233c F configure.in 6ccfd5fc80517f7cfe605a7fc7e0f62d962a233c
F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47 F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47
F src/build.c 335df4b65f49d335438d3a0cd7e48d19713a1917 F src/build.c c6b500077913cde55871d1f9c0d17d4ee4a86828
F src/dbbe.c 159c39f8bf5475c34904786fad4f3f0f579d9eb6 F src/dbbe.c dc9439f839d13e633158808e352056b531f17e1b
F src/dbbe.h bedeb3a0985bb584458e7849fb59927e99e751e6 F src/dbbe.h b678e31c32fa252e6fba830ad16ed8978d1521a9
F src/main.c 25cce7bce0eb3ba10bada7c05f4b38dc6dbbc86f F src/main.c 25cce7bce0eb3ba10bada7c05f4b38dc6dbbc86f
F src/parse.y 50ca06d471132e16bb47c56f19553e4efd5b3d4a F src/parse.y 05de7dec046dd8bd11f8cc3513ff8b27624618c8
F src/shell.c 3ffa9059514cd4db3bd64e0797bf7ebbe1ea8ee3 F src/shell.c c5752d32cdeaa7d548d4f91177b697b023a00381
F src/sqlite.h 2397c17a8f4ca90c09acab0100dc7e2f8f441b69 F src/sqlite.h 2397c17a8f4ca90c09acab0100dc7e2f8f441b69
F src/sqliteInt.h 749da8b3e4ce146fd172aeb59b6db04c57726d7a F src/sqliteInt.h 9ac3f9e05bbc5913531473c86d4742343ae670c5
F src/tclsqlite.c 9efd29f79ded6a900aa3d142169c8bfe03b7affd F src/tclsqlite.c 9efd29f79ded6a900aa3d142169c8bfe03b7affd
F src/tokenize.c e176b2c1c38e11482ee3419d6b50b733860a1587 F src/tokenize.c 5b066f314646d6c5396a253315e5e95d107e1800
F src/util.c 2a0314dcc9de230526380765339071a5b304d70d F src/util.c 6b4327d7fbf684f8635155d4acb847ae991b3ebc
F src/vdbe.c 117ce5541143e3af9dccdc15c22c4920a7b9bdb4 F src/vdbe.c 74ff55bc2910e25bd811638233f6c02fb1a17fbc
F src/vdbe.h 03de26632f2e608c2a44a40262fbba21a8bdfd81 F src/vdbe.h 02b470d344caed04451c896be7a775068dbdf076
F src/where.c 2c8de69c4cf5a620ed380d3d6bb658bbbe8da5d5 F src/where.c fd9faea693083c1bde83f824b98f7eb81c4762cc
F test/all.test 66a8a5b8291a472157944edcdce51a320ebd1f35 F test/all.test 66a8a5b8291a472157944edcdce51a320ebd1f35
F test/copy.test 641bd3cfaab61c4ee32889587e21e4c70788a97a F test/copy.test 641bd3cfaab61c4ee32889587e21e4c70788a97a
F test/delete.test 814d53e3b0d2d7069fb17e005d4041454d6585d4 F test/delete.test 814d53e3b0d2d7069fb17e005d4041454d6585d4
@ -36,9 +36,10 @@ F tool/opNames.awk 2bd9071a138e4e2be13dc98fe066398a61219e1e
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9 F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9
F www/c_interface.tcl f875864edf7974157d1c257ca08de854660882a5 F www/c_interface.tcl f875864edf7974157d1c257ca08de854660882a5
F www/index.tcl 2466d1b2e26c6f354b0acedee12025309a216799 F www/changes.tcl 38ff869ccbf99388d53abd08aeea4e24e2bb23b7
F www/sqlite.tcl 947e067bcc347dc767af4c1a6e5a8d47d8404aa3 F www/index.tcl 57a97afafe04ab53d1996ba3a61ac41fa8453f5a
P 2d41caec807a6ab83b67e59c849ebbda004f2869 F www/sqlite.tcl 7deb564df188ad4523adecfe2365de6d09f6dfd9
R d274f71e9bf0807a8f2c186fb0e9f965 P 03725ce5ae871247789ece0f2c3426f74ba575e7
R bab7f299b23f92a0096c17a89a463018
U drh U drh
Z 1247bb7c9fa8cc79296726f95e563a76 Z e30b944ebaee88defeb667112902d5c8

View File

@ -1 +1 @@
03725ce5ae871247789ece0f2c3426f74ba575e7 01d85b35e9c4ca5619ad21a4232a8f8bf9ec3538

View File

@ -24,7 +24,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
** when syntax rules are reduced. ** when syntax rules are reduced.
** **
** $Id: build.c,v 1.9 2000/05/30 19:22:26 drh Exp $ ** $Id: build.c,v 1.10 2000/05/31 02:27:49 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@ -1528,3 +1528,46 @@ void sqliteCopy(
copy_cleanup: copy_cleanup:
return; return;
} }
/*
** The non-standard VACUUM command is used to clean up the database,
** collapse free space, etc. It is modelled after the VACUUM command
** in PostgreSQL.
*/
void sqliteVacuum(Parse *pParse, Token *pTableName){
char *zName;
Vdbe *v;
if( pTableName ){
zName = sqliteTableNameFromToken(pTableName);
}else{
zName = 0;
}
if( zName && sqliteFindIndex(pParse->db, zName)==0
&& sqliteFindTable(pParse->db, zName)==0 ){
sqliteSetString(&pParse->zErrMsg, "no such table or index: ", zName, 0);
pParse->nErr++;
goto vacuum_cleanup;
}
v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe);
if( v==0 ) goto vacuum_cleanup;
if( zName ){
sqliteVdbeAddOp(v, OP_Reorganize, 0, 0, zName, 0);
}else{
int h;
Table *pTab;
Index *pIdx;
for(h=0; h<N_HASH; h++){
for(pTab=pParse->db->apTblHash[h]; pTab; pTab=pTab->pHash){
sqliteVdbeAddOp(v, OP_Reorganize, 0, 0, pTab->zName, 0);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
sqliteVdbeAddOp(v, OP_Reorganize, 0, 0, pIdx->zName, 0);
}
}
}
}
vacuum_cleanup:
sqliteFree(zName);
return;
}

View File

@ -30,7 +30,7 @@
** relatively simple to convert to a different database such ** relatively simple to convert to a different database such
** as NDBM, SDBM, or BerkeleyDB. ** as NDBM, SDBM, or BerkeleyDB.
** **
** $Id: dbbe.c,v 1.2 2000/05/30 18:45:24 drh Exp $ ** $Id: dbbe.c,v 1.3 2000/05/31 02:27:49 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <gdbm.h> #include <gdbm.h>
@ -199,6 +199,22 @@ void sqliteDbbeDropTable(Dbbe *pBe, const char *zTable){
sqliteFree(zFile); sqliteFree(zFile);
} }
/*
** Reorganize a table to reduce search times and disk usage.
*/
void sqliteDbbeReorganizeTable(Dbbe *pBe, const char *zTable){
char *zFile; /* Name of the table file */
DbbeTable *pTab;
pTab = sqliteDbbeOpenTable(pBe, zTable, 1);
if( pTab && pTab->pFile && pTab->pFile->dbf ){
gdbm_reorganize(pTab->pFile->dbf);
}
if( pTab ){
sqliteDbbeCloseTable(pTab);
}
}
/* /*
** Close a table previously opened by sqliteDbbeOpenTable(). ** Close a table previously opened by sqliteDbbeOpenTable().
*/ */

View File

@ -28,7 +28,7 @@
** This library was originally designed to support the following ** This library was originally designed to support the following
** backends: GDBM, NDBM, SDBM, Berkeley DB. ** backends: GDBM, NDBM, SDBM, Berkeley DB.
** **
** $Id: dbbe.h,v 1.1 2000/05/29 14:26:01 drh Exp $ ** $Id: dbbe.h,v 1.2 2000/05/31 02:27:49 drh Exp $
*/ */
#ifndef _SQLITE_DBBE_H_ #ifndef _SQLITE_DBBE_H_
#define _SQLITE_DBBE_H_ #define _SQLITE_DBBE_H_
@ -65,6 +65,9 @@ DbbeTable *sqliteDbbeOpenTable(Dbbe*, const char *zTableName, int writeable);
/* Delete a table from the database */ /* Delete a table from the database */
void sqliteDbbeDropTable(Dbbe*, const char *zTableName); void sqliteDbbeDropTable(Dbbe*, const char *zTableName);
/* Reorganize a table to speed access or reduce its disk usage */
void sqliteDbbeReorganizeTable(Dbbe*, const char *zTableName);
/* Close a table */ /* Close a table */
void sqliteDbbeCloseTable(DbbeTable*); void sqliteDbbeCloseTable(DbbeTable*);

View File

@ -26,7 +26,7 @@
** the parser. Lemon will also generate a header file containing ** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens. ** numeric codes for all of the tokens.
** **
** @(#) $Id: parse.y,v 1.2 2000/05/30 16:27:04 drh Exp $ ** @(#) $Id: parse.y,v 1.3 2000/05/31 02:27:49 drh Exp $
*/ */
%token_prefix TK_ %token_prefix TK_
%token_type {Token} %token_type {Token}
@ -236,7 +236,7 @@ fieldlist(A) ::= ID(Y). {A = sqliteIdListAppend(0,&Y);}
%left OR. %left OR.
%left AND. %left AND.
%left EQ NE ISNULL NOTNULL IS. %left EQ NE ISNULL NOTNULL IS LIKE GLOB.
%left GT GE LT LE. %left GT GE LT LE.
%left PLUS MINUS. %left PLUS MINUS.
%left STAR SLASH PERCENT. %left STAR SLASH PERCENT.
@ -264,7 +264,9 @@ expr(A) ::= expr(X) LE expr(Y). {A = sqliteExpr(TK_LE, X, Y, 0);}
expr(A) ::= expr(X) GE expr(Y). {A = sqliteExpr(TK_GE, X, Y, 0);} expr(A) ::= expr(X) GE expr(Y). {A = sqliteExpr(TK_GE, X, Y, 0);}
expr(A) ::= expr(X) NE expr(Y). {A = sqliteExpr(TK_NE, X, Y, 0);} expr(A) ::= expr(X) NE expr(Y). {A = sqliteExpr(TK_NE, X, Y, 0);}
expr(A) ::= expr(X) EQ expr(Y). {A = sqliteExpr(TK_EQ, X, Y, 0);} expr(A) ::= expr(X) EQ expr(Y). {A = sqliteExpr(TK_EQ, X, Y, 0);}
expr(A) ::= expr(X) IS expr(Y). {A = sqliteExpr(TK_EQ, X, Y, 0);} expr(A) ::= expr(X) LIKE expr(Y). {A = sqliteExpr(TK_LIKE, X, Y, 0);}
expr(A) ::= expr(X) GLOB expr(Y). {A = sqliteExpr(TK_GLOB,X,Y,0);}
// expr(A) ::= expr(X) IS expr(Y). {A = sqliteExpr(TK_EQ, X, Y, 0);}
expr(A) ::= expr(X) PLUS expr(Y). {A = sqliteExpr(TK_PLUS, X, Y, 0);} expr(A) ::= expr(X) PLUS expr(Y). {A = sqliteExpr(TK_PLUS, X, Y, 0);}
expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);} expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);}
expr(A) ::= expr(X) STAR expr(Y). {A = sqliteExpr(TK_STAR, X, Y, 0);} expr(A) ::= expr(X) STAR expr(Y). {A = sqliteExpr(TK_STAR, X, Y, 0);}
@ -309,3 +311,6 @@ cmd ::= COPY id(X) FROM id(Y) USING DELIMITERS STRING(Z).
{sqliteCopy(pParse,&X,&Y,&Z);} {sqliteCopy(pParse,&X,&Y,&Z);}
cmd ::= COPY id(X) FROM id(Y). cmd ::= COPY id(X) FROM id(Y).
{sqliteCopy(pParse,&X,&Y,0);} {sqliteCopy(pParse,&X,&Y,0);}
cmd ::= VACUUM. {sqliteVacuum(pParse,0);}
cmd ::= VACUUM id(X). {sqliteVacuum(pParse,&X);}

View File

@ -24,7 +24,7 @@
** This file contains code to implement the "sqlite" command line ** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases. ** utility for accessing SQLite databases.
** **
** $Id: shell.c,v 1.3 2000/05/30 18:45:24 drh Exp $ ** $Id: shell.c,v 1.4 2000/05/31 02:27:49 drh Exp $
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -300,7 +300,7 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
data.showHeader = 0; data.showHeader = 0;
data.mode = MODE_List; data.mode = MODE_List;
sprintf(zSql, "SELECT name FROM sqlite_master " sprintf(zSql, "SELECT name FROM sqlite_master "
"WHERE type='index' AND tbl_name='%.00s' " "WHERE type='index' AND tbl_name LIKE '%.00s' "
"ORDER BY name", azArg[1]); "ORDER BY name", azArg[1]);
sqlite_exec(db, zSql, callback, &data, &zErrMsg); sqlite_exec(db, zSql, callback, &data, &zErrMsg);
if( zErrMsg ){ if( zErrMsg ){
@ -343,7 +343,7 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
data.showHeader = 0; data.showHeader = 0;
data.mode = MODE_List; data.mode = MODE_List;
if( nArg>1 ){ if( nArg>1 ){
sprintf(zSql, "SELECT sql FROM sqlite_master WHERE name='%.900s'", sprintf(zSql, "SELECT sql FROM sqlite_master WHERE name LIKE '%.900s'",
azArg[1]); azArg[1]);
}else{ }else{
sprintf(zSql, "SELECT sql FROM sqlite_master " sprintf(zSql, "SELECT sql FROM sqlite_master "

View File

@ -23,7 +23,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.3 2000/05/30 16:27:04 drh Exp $ ** @(#) $Id: sqliteInt.h,v 1.4 2000/05/31 02:27:49 drh Exp $
*/ */
#include "sqlite.h" #include "sqlite.h"
#include "dbbe.h" #include "dbbe.h"
@ -248,3 +248,6 @@ void sqliteExprIfTrue(Parse*, Expr*, int);
void sqliteExprIfFalse(Parse*, Expr*, int); void sqliteExprIfFalse(Parse*, Expr*, int);
Table *sqliteFindTable(sqlite*,char*); Table *sqliteFindTable(sqlite*,char*);
void sqliteCopy(Parse*, Token*, Token*, Token*); void sqliteCopy(Parse*, Token*, Token*, Token*);
void sqliteVacuum(Parse*, Token*);
int sqliteGlobCompare(const char*,const char*);
int sqliteLikeCompare(const unsigned char*,const unsigned char*);

View File

@ -27,7 +27,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.3 2000/05/30 16:27:04 drh Exp $ ** $Id: tokenize.c,v 1.4 2000/05/31 02:27:49 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@ -64,12 +64,14 @@ static Keyword aKeywordTable[] = {
{ "DROP", 0, TK_DROP, 0 }, { "DROP", 0, TK_DROP, 0 },
{ "EXPLAIN", 0, TK_EXPLAIN, 0 }, { "EXPLAIN", 0, TK_EXPLAIN, 0 },
{ "FROM", 0, TK_FROM, 0 }, { "FROM", 0, TK_FROM, 0 },
{ "GLOB", 0, TK_GLOB, 0 },
{ "INDEX", 0, TK_INDEX, 0 }, { "INDEX", 0, TK_INDEX, 0 },
{ "INSERT", 0, TK_INSERT, 0 }, { "INSERT", 0, TK_INSERT, 0 },
{ "INTO", 0, TK_INTO, 0 }, { "INTO", 0, TK_INTO, 0 },
{ "IS", 0, TK_IS, 0 }, { "IS", 0, TK_IS, 0 },
{ "ISNULL", 0, TK_ISNULL, 0 }, { "ISNULL", 0, TK_ISNULL, 0 },
{ "KEY", 0, TK_KEY, 0 }, { "KEY", 0, TK_KEY, 0 },
{ "LIKE", 0, TK_LIKE, 0 },
{ "NOT", 0, TK_NOT, 0 }, { "NOT", 0, TK_NOT, 0 },
{ "NOTNULL", 0, TK_NOTNULL, 0 }, { "NOTNULL", 0, TK_NOTNULL, 0 },
{ "NULL", 0, TK_NULL, 0 }, { "NULL", 0, TK_NULL, 0 },
@ -83,6 +85,7 @@ static Keyword aKeywordTable[] = {
{ "UNIQUE", 0, TK_UNIQUE, 0 }, { "UNIQUE", 0, TK_UNIQUE, 0 },
{ "UPDATE", 0, TK_UPDATE, 0 }, { "UPDATE", 0, TK_UPDATE, 0 },
{ "USING", 0, TK_USING, 0 }, { "USING", 0, TK_USING, 0 },
{ "VACUUM", 0, TK_VACUUM, 0 },
{ "VALUES", 0, TK_VALUES, 0 }, { "VALUES", 0, TK_VALUES, 0 },
{ "WHERE", 0, TK_WHERE, 0 }, { "WHERE", 0, TK_WHERE, 0 },
}; };

View File

@ -26,7 +26,7 @@
** This file contains functions for allocating memory, comparing ** This file contains functions for allocating memory, comparing
** strings, and stuff like that. ** strings, and stuff like that.
** **
** $Id: util.c,v 1.6 2000/05/30 16:27:04 drh Exp $ ** $Id: util.c,v 1.7 2000/05/31 02:27:49 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <stdarg.h> #include <stdarg.h>
@ -563,3 +563,138 @@ int sqliteSortCompare(const char *a, const char *b){
if( *a=='-' ) res = -res; if( *a=='-' ) res = -res;
return res; return res;
} }
/*
** Compare two strings for equality where the first string can
** potentially be a "glob" expression. Return true (1) if they
** are the same and false (0) if they are different.
**
** Globbing rules:
**
** '*' Matches any sequence of zero or more characters.
**
** '?' Matches exactly one character.
**
** [...] Matches one character from the enclosed list of
** characters.
**
** [^...] Matches one character not in the enclosed list.
**
** With the [...] and [^...] matching, a ']' character can be included
** in the list by making it the first character after '[' or '^'. A
** range of characters can be specified using '-'. Example:
** "[a-z]" matches any single lower-case letter. To match a '-', make
** it the last character in the list.
**
** This routine is usually quick, but can be N**2 in the worst case.
**
** Hints: to match '*' or '?', put them in "[]". Like this:
**
** abc[*]xyz Matches "abc*xyz" only
*/
int sqliteGlobCompare(const char *zPattern, const char *zString){
register char c;
int invert;
int seen;
char c2;
while( (c = *zPattern)!=0 ){
switch( c ){
case '*':
while( zPattern[1]=='*' ) zPattern++;
if( zPattern[1]==0 ) return 1;
c = zPattern[1];
if( c=='[' || c=='?' ){
while( *zString && sqliteGlobCompare(&zPattern[1],zString)==0 ){
zString++;
}
return *zString!=0;
}else{
while( (c2 = *zString)!=0 ){
while( c2 != 0 && c2 != c ){ c2 = *++zString; }
if( sqliteGlobCompare(&zPattern[1],zString) ) return 1;
zString++;
}
return 0;
}
case '?':
if( *zString==0 ) return 0;
break;
case '[':
seen = 0;
invert = 0;
c = *zString;
if( c==0 ) return 0;
c2 = *++zPattern;
if( c2=='^' ){ invert = 1; c2 = *++zPattern; }
if( c2==']' ){
if( c==']' ) seen = 1;
c2 = *++zPattern;
}
while( (c2 = *zPattern)!=0 && c2!=']' ){
if( c2=='-' && zPattern[1]!=']' && zPattern[1]!=0 ){
if( c>zPattern[-1] && c<zPattern[1] ) seen = 1;
}else if( c==c2 ){
seen = 1;
}
zPattern++;
}
if( c2==0 || (seen ^ invert)==0 ) return 0;
break;
default:
if( c != *zString ) return 0;
break;
}
zPattern++;
zString++;
}
return *zString==0;
}
/*
** Compare two strings for equality using the "LIKE" operator of
** SQL. The '%' character matches any sequence of 0 or more
** characters and '_' matches any single character. Case is
** not significant.
**
** This routine is just an adaptation of the sqliteGlobCompare()
** routine above.
*/
int
sqliteLikeCompare(const unsigned char *zPattern, const unsigned char *zString){
register char c;
int invert;
int seen;
char c2;
while( (c = UpperToLower[*zPattern])!=0 ){
switch( c ){
case '%':
while( zPattern[1]=='%' ) zPattern++;
if( zPattern[1]==0 ) return 1;
c = UpperToLower[0xff & zPattern[1]];
if( c=='_' ){
while( *zString && sqliteLikeCompare(&zPattern[1],zString)==0 ){
zString++;
}
return *zString!=0;
}else{
while( (c2 = UpperToLower[*zString])!=0 ){
while( c2 != 0 && c2 != c ){ c2 = UpperToLower[*++zString]; }
if( sqliteLikeCompare(&zPattern[1],zString) ) return 1;
zString++;
}
return 0;
}
case '_':
if( *zString==0 ) return 0;
break;
default:
if( c != UpperToLower[*zString] ) return 0;
break;
}
zPattern++;
zString++;
}
return *zString==0;
}

View File

@ -41,7 +41,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.2 2000/05/30 16:27:04 drh Exp $ ** $Id: vdbe.c,v 1.3 2000/05/31 02:27:50 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@ -391,23 +391,24 @@ void sqliteVdbeDelete(Vdbe *p){
** this array, then copy and paste it into this file, if you want. ** this array, then copy and paste it into this file, if you want.
*/ */
static char *zOpName[] = { 0, static char *zOpName[] = { 0,
"Open", "Close", "Destroy", "Fetch", "Open", "Close", "Fetch", "New",
"New", "Put", "Delete", "Field", "Put", "Delete", "Field", "Key",
"Key", "Rewind", "Next", "ResetIdx", "Rewind", "Next", "Destroy", "Reorganize",
"NextIdx", "PutIdx", "DeleteIdx", "ListOpen", "ResetIdx", "NextIdx", "PutIdx", "DeleteIdx",
"ListWrite", "ListRewind", "ListRead", "ListClose", "ListOpen", "ListWrite", "ListRewind", "ListRead",
"SortOpen", "SortPut", "SortMakeRec", "SortMakeKey", "ListClose", "SortOpen", "SortPut", "SortMakeRec",
"Sort", "SortNext", "SortKey", "SortCallback", "SortMakeKey", "Sort", "SortNext", "SortKey",
"SortClose", "FileOpen", "FileRead", "FileField", "SortCallback", "SortClose", "FileOpen", "FileRead",
"FileClose", "MakeRecord", "MakeKey", "Goto", "FileField", "FileClose", "MakeRecord", "MakeKey",
"If", "Halt", "ColumnCount", "ColumnName", "Goto", "If", "Halt", "ColumnCount",
"Callback", "Integer", "String", "Pop", "ColumnName", "Callback", "Integer", "String",
"Dup", "Pull", "Add", "AddImm", "Pop", "Dup", "Pull", "Add",
"Subtract", "Multiply", "Divide", "Min", "AddImm", "Subtract", "Multiply", "Divide",
"Max", "Eq", "Ne", "Lt", "Min", "Max", "Like", "Glob",
"Le", "Gt", "Ge", "IsNull", "Eq", "Ne", "Lt", "Le",
"NotNull", "Negative", "And", "Or", "Gt", "Ge", "IsNull", "NotNull",
"Not", "Concat", "Noop", "Negative", "And", "Or", "Not",
"Concat", "Noop",
}; };
/* /*
@ -997,6 +998,67 @@ int sqliteVdbeExec(
break; break;
} }
/* Opcode: Like P1 P2 *
**
** Pop the top two elements from the stack. The top-most is a
** "like" pattern -- the right operand of the SQL "LIKE" operator.
** The lower element is the string to compare against the like
** pattern. Jump to P2 if the two compare, and fall through without
** jumping if they do not. The '%' in the top-most element matches
** any sequence of zero or more characters in the lower element. The
** '_' character in the topmost matches any single character of the
** lower element. Case is ignored for this comparison.
**
** If P1 is not zero, the sense of the test is inverted and we
** have a "NOT LIKE" operator. The jump is made if the two values
** are different.
*/
case OP_Like: {
int tos = p->tos;
int nos = tos - 1;
int c;
if( nos<0 ) goto not_enough_stack;
Stringify(p, tos);
Stringify(p, nos);
c = sqliteLikeCompare(p->zStack[tos], p->zStack[nos]);
PopStack(p, 2);
if( pOp->p1 ) c = !c;
if( c ) pc = pOp->p2-1;
break;
}
/* Opcode: Glob P1 P2 *
**
** Pop the top two elements from the stack. The top-most is a
** "glob" pattern. The lower element is the string to compare
** against the glob pattern.
**
** Jump to P2 if the two compare, and fall through without
** jumping if they do not. The '*' in the top-most element matches
** any sequence of zero or more characters in the lower element. The
** '?' character in the topmost matches any single character of the
** lower element. [...] matches a range of characters. [^...]
** matches any character not in the range. Case is significant
** for globs.
**
** If P1 is not zero, the sense of the test is inverted and we
** have a "NOT GLOB" operator. The jump is made if the two values
** are different.
*/
case OP_Glob: {
int tos = p->tos;
int nos = tos - 1;
int c;
if( nos<0 ) goto not_enough_stack;
Stringify(p, tos);
Stringify(p, nos);
c = sqliteGlobCompare(p->zStack[tos], p->zStack[nos]);
PopStack(p, 2);
if( pOp->p1 ) c = !c;
if( c ) pc = pOp->p2-1;
break;
}
/* Opcode: And * * * /* Opcode: And * * *
** **
** Pop two values off the stack. Take the logical AND of the ** Pop two values off the stack. Take the logical AND of the
@ -1581,6 +1643,15 @@ int sqliteVdbeExec(
break; break;
} }
/* Opcode: Reorganize * * P3
**
** Compress, optimize, and tidy up the GDBM file named by P3.
*/
case OP_Reorganize: {
sqliteDbbeReorganizeTable(p->pBe, pOp->p3);
break;
}
/* Opcode: ListOpen P1 * * /* Opcode: ListOpen P1 * *
** **
** Open a file used for temporary storage of index numbers. P1 ** Open a file used for temporary storage of index numbers. P1

View File

@ -27,7 +27,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.2 2000/05/30 16:27:05 drh Exp $ ** $Id: vdbe.h,v 1.3 2000/05/31 02:27:50 drh Exp $
*/ */
#ifndef _SQLITE_VDBE_H_ #ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_
@ -73,81 +73,86 @@ typedef struct VdbeOp VdbeOp;
*/ */
#define OP_Open 1 #define OP_Open 1
#define OP_Close 2 #define OP_Close 2
#define OP_Destroy 3 #define OP_Fetch 3
#define OP_Fetch 4 #define OP_New 4
#define OP_New 5 #define OP_Put 5
#define OP_Put 6 #define OP_Delete 6
#define OP_Delete 7 #define OP_Field 7
#define OP_Field 8 #define OP_Key 8
#define OP_Key 9 #define OP_Rewind 9
#define OP_Rewind 10 #define OP_Next 10
#define OP_Next 11
#define OP_ResetIdx 12
#define OP_NextIdx 13
#define OP_PutIdx 14
#define OP_DeleteIdx 15
#define OP_ListOpen 16 #define OP_Destroy 11
#define OP_ListWrite 17 #define OP_Reorganize 12
#define OP_ListRewind 18
#define OP_ListRead 19
#define OP_ListClose 20
#define OP_SortOpen 21 #define OP_ResetIdx 13
#define OP_SortPut 22 #define OP_NextIdx 14
#define OP_SortMakeRec 23 #define OP_PutIdx 15
#define OP_SortMakeKey 24 #define OP_DeleteIdx 16
#define OP_Sort 25
#define OP_SortNext 26
#define OP_SortKey 27
#define OP_SortCallback 28
#define OP_SortClose 29
#define OP_FileOpen 30 #define OP_ListOpen 17
#define OP_FileRead 31 #define OP_ListWrite 18
#define OP_FileField 32 #define OP_ListRewind 19
#define OP_FileClose 33 #define OP_ListRead 20
#define OP_ListClose 21
#define OP_MakeRecord 34 #define OP_SortOpen 22
#define OP_MakeKey 35 #define OP_SortPut 23
#define OP_SortMakeRec 24
#define OP_SortMakeKey 25
#define OP_Sort 26
#define OP_SortNext 27
#define OP_SortKey 28
#define OP_SortCallback 29
#define OP_SortClose 30
#define OP_Goto 36 #define OP_FileOpen 31
#define OP_If 37 #define OP_FileRead 32
#define OP_Halt 38 #define OP_FileField 33
#define OP_FileClose 34
#define OP_ColumnCount 39 #define OP_MakeRecord 35
#define OP_ColumnName 40 #define OP_MakeKey 36
#define OP_Callback 41
#define OP_Integer 42 #define OP_Goto 37
#define OP_String 43 #define OP_If 38
#define OP_Pop 44 #define OP_Halt 39
#define OP_Dup 45
#define OP_Pull 46
#define OP_Add 47 #define OP_ColumnCount 40
#define OP_AddImm 48 #define OP_ColumnName 41
#define OP_Subtract 49 #define OP_Callback 42
#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 #define OP_Integer 43
#define OP_String 44
#define OP_Pop 45
#define OP_Dup 46
#define OP_Pull 47
#define OP_Add 48
#define OP_AddImm 49
#define OP_Subtract 50
#define OP_Multiply 51
#define OP_Divide 52
#define OP_Min 53
#define OP_Max 54
#define OP_Like 55
#define OP_Glob 56
#define OP_Eq 57
#define OP_Ne 58
#define OP_Lt 59
#define OP_Le 60
#define OP_Gt 61
#define OP_Ge 62
#define OP_IsNull 63
#define OP_NotNull 64
#define OP_Negative 65
#define OP_And 66
#define OP_Or 67
#define OP_Not 68
#define OP_Concat 69
#define OP_Noop 70
#define OP_MAX 70
/* /*
** Prototypes for the VDBE interface. See comments on the implementation ** Prototypes for the VDBE interface. See comments on the implementation

View File

@ -25,7 +25,7 @@
** the WHERE clause of SQL statements. Also found here are subroutines ** the WHERE clause of SQL statements. Also found here are subroutines
** to generate VDBE code to evaluate expressions. ** to generate VDBE code to evaluate expressions.
** **
** $Id: where.c,v 1.3 2000/05/30 20:17:49 drh Exp $ ** $Id: where.c,v 1.4 2000/05/31 02:27:50 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@ -368,12 +368,14 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
case TK_SLASH: op = OP_Divide; break; case TK_SLASH: op = OP_Divide; break;
case TK_AND: op = OP_And; break; case TK_AND: op = OP_And; break;
case TK_OR: op = OP_Or; break; case TK_OR: op = OP_Or; break;
case TK_LT: op = OP_Ge; break; case TK_LT: op = OP_Lt; break;
case TK_LE: op = OP_Gt; break; case TK_LE: op = OP_Le; break;
case TK_GT: op = OP_Le; break; case TK_GT: op = OP_Gt; break;
case TK_GE: op = OP_Lt; break; case TK_GE: op = OP_Ge; break;
case TK_NE: op = OP_Eq; break; case TK_NE: op = OP_Ne; break;
case TK_EQ: op = OP_Ne; break; case TK_EQ: op = OP_Eq; break;
case TK_LIKE: op = OP_Like; break;
case TK_GLOB: op = OP_Glob; break;
case TK_ISNULL: op = OP_IsNull; break; case TK_ISNULL: op = OP_IsNull; break;
case TK_NOTNULL: op = OP_NotNull; break; case TK_NOTNULL: op = OP_NotNull; break;
case TK_NOT: op = OP_Not; break; case TK_NOT: op = OP_Not; break;
@ -421,14 +423,16 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
case TK_GT: case TK_GT:
case TK_GE: case TK_GE:
case TK_NE: case TK_NE:
case TK_EQ: { case TK_EQ:
case TK_LIKE:
case TK_GLOB: {
int dest; int dest;
sqliteVdbeAddOp(v, OP_Integer, 0, 0, 0, 0); sqliteVdbeAddOp(v, OP_Integer, 1, 0, 0, 0);
sqliteExprCode(pParse, pExpr->pLeft); sqliteExprCode(pParse, pExpr->pLeft);
sqliteExprCode(pParse, pExpr->pRight); sqliteExprCode(pParse, pExpr->pRight);
dest = sqliteVdbeCurrentAddr(v) + 2; dest = sqliteVdbeCurrentAddr(v) + 2;
sqliteVdbeAddOp(v, op, 0, dest, 0, 0); sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
sqliteVdbeAddOp(v, OP_AddImm, 1, 0, 0, 0); sqliteVdbeAddOp(v, OP_AddImm, -1, 0, 0, 0);
break; break;
} }
case TK_NOT: case TK_NOT:
@ -466,6 +470,8 @@ void sqliteExprIfTrue(Parse *pParse, Expr *pExpr, int dest){
case TK_GE: op = OP_Ge; break; case TK_GE: op = OP_Ge; break;
case TK_NE: op = OP_Ne; break; case TK_NE: op = OP_Ne; break;
case TK_EQ: op = OP_Eq; break; case TK_EQ: op = OP_Eq; break;
case TK_LIKE: op = OP_Like; break;
case TK_GLOB: op = OP_Glob; break;
case TK_ISNULL: op = OP_IsNull; break; case TK_ISNULL: op = OP_IsNull; break;
case TK_NOTNULL: op = OP_NotNull; break; case TK_NOTNULL: op = OP_NotNull; break;
default: break; default: break;
@ -483,12 +489,18 @@ void sqliteExprIfTrue(Parse *pParse, Expr *pExpr, int dest){
sqliteExprIfTrue(pParse, pExpr->pRight, dest); sqliteExprIfTrue(pParse, pExpr->pRight, dest);
break; break;
} }
case TK_NOT: {
sqliteExprIfFalse(pParse, pExpr->pLeft, dest);
break;
}
case TK_LT: case TK_LT:
case TK_LE: case TK_LE:
case TK_GT: case TK_GT:
case TK_GE: case TK_GE:
case TK_NE: case TK_NE:
case TK_EQ: { case TK_EQ:
case TK_LIKE:
case TK_GLOB: {
sqliteExprCode(pParse, pExpr->pLeft); sqliteExprCode(pParse, pExpr->pLeft);
sqliteExprCode(pParse, pExpr->pRight); sqliteExprCode(pParse, pExpr->pRight);
sqliteVdbeAddOp(v, op, 0, dest, 0, 0); sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
@ -523,6 +535,8 @@ void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest){
case TK_GE: op = OP_Lt; break; case TK_GE: op = OP_Lt; break;
case TK_NE: op = OP_Eq; break; case TK_NE: op = OP_Eq; break;
case TK_EQ: op = OP_Ne; break; case TK_EQ: op = OP_Ne; break;
case TK_LIKE: op = OP_Like; break;
case TK_GLOB: op = OP_Glob; break;
case TK_ISNULL: op = OP_NotNull; break; case TK_ISNULL: op = OP_NotNull; break;
case TK_NOTNULL: op = OP_IsNull; break; case TK_NOTNULL: op = OP_IsNull; break;
default: break; default: break;
@ -540,6 +554,10 @@ void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest){
sqliteVdbeResolveLabel(v, d2); sqliteVdbeResolveLabel(v, d2);
break; break;
} }
case TK_NOT: {
sqliteExprIfTrue(pParse, pExpr->pLeft, dest);
break;
}
case TK_LT: case TK_LT:
case TK_LE: case TK_LE:
case TK_GT: case TK_GT:
@ -551,6 +569,13 @@ void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest){
sqliteVdbeAddOp(v, op, 0, dest, 0, 0); sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
break; break;
} }
case TK_LIKE:
case TK_GLOB: {
sqliteExprCode(pParse, pExpr->pLeft);
sqliteExprCode(pParse, pExpr->pRight);
sqliteVdbeAddOp(v, op, 1, dest, 0, 0);
break;
}
case TK_ISNULL: case TK_ISNULL:
case TK_NOTNULL: { case TK_NOTNULL: {
sqliteExprCode(pParse, pExpr->pLeft); sqliteExprCode(pParse, pExpr->pLeft);

46
www/changes.tcl Normal file
View File

@ -0,0 +1,46 @@
#
# Run this script to generated a changes.html output file
#
puts {<html>
<head>
<title>SQLite Change Log</title>
</head>
<body bgcolor="white">
<h1 align="center">Recent Changes To SQLite</h1>
<DL>
}
proc chng {date desc} {
puts "<DT><B>$date</B></DT>"
puts "<DD><P><UL>$desc</UL></P></DD>"
}
chng {2000 May 30} {
<li>Added the <b>LIKE</b> operator.</li>
<li>Added a <b>GLOB</b> operator: similar to <B>LIKE</B>
but it uses Unix shell globbing wildcards instead of the '%'
and '_' wildcards of SQL.</li>
<li>Added the <B>COPY</b> command patterned after
<a href="http://www.postgresql.org/">PostgreSQL</a> so that SQLite
can now read the output of the <b>pg_dump</b> database dump utility
of PostgreSQL.</li>
<li>Added a <B>VACUUM</B> command that that calls the
<b>gdbm_reorganize()</b> function on the underlying database
files.</li>
<li>And many, many bug fixes...</li>
}
chng {2000 May 29} {
<li>Initial Public Release of Alpha code</li>
}
puts {
</DL>
<p><hr /></p>
<p><a href="index.html"><img src="/goback.jpg" border=0 />
Back to the SQLite Home Page</a>
</p>
</body></html>}

View File

@ -1,7 +1,7 @@
# #
# Run this TCL script to generate HTML for the index.html file. # Run this TCL script to generate HTML for the index.html file.
# #
set rcsid {$Id: index.tcl,v 1.4 2000/05/30 00:05:13 drh Exp $} set rcsid {$Id: index.tcl,v 1.5 2000/05/31 02:27:50 drh Exp $}
puts {<html> puts {<html>
<head><title>SQLite: An SQL Frontend For GDBM</title></head> <head><title>SQLite: An SQL Frontend For GDBM</title></head>
@ -47,6 +47,9 @@ can be used as an example of how to interact with the SQLite C
library. For more information on the sqlite program, library. For more information on the sqlite program,
see <a href="sqlite.html">sqlite.html</a>.</p> see <a href="sqlite.html">sqlite.html</a>.</p>
<p>A history of changes to SQLite is found
<a href="changes.html">here</a>.</p>
<p>SQLite does not try to implement every feature of SQL. But it <p>SQLite does not try to implement every feature of SQL. But it
does strive to implement to most commonly used features. SQLite does strive to implement to most commonly used features. SQLite
currently understands the following SQL commands:</p> currently understands the following SQL commands:</p>
@ -71,7 +74,6 @@ implement are as follows:</p>
<ul> <ul>
<li>ALTER TABLE</li> <li>ALTER TABLE</li>
<li>The GROUP BY or HAVING clauses of a SELECT</li> <li>The GROUP BY or HAVING clauses of a SELECT</li>
<li>The LIKE or IN operators</li>
<li>The COUNT(), MAX(), MIN(), and AVG() functions</li> <li>The COUNT(), MAX(), MIN(), and AVG() functions</li>
<li>Constraints</li> <li>Constraints</li>
<li>Nested queries</li> <li>Nested queries</li>

View File

@ -1,7 +1,7 @@
# #
# Run this Tcl script to generate the sqlite.html file. # Run this Tcl script to generate the sqlite.html file.
# #
set rcsid {$Id: sqlite.tcl,v 1.3 2000/05/29 18:50:16 drh Exp $} set rcsid {$Id: sqlite.tcl,v 1.4 2000/05/31 02:27:50 drh Exp $}
puts {<html> puts {<html>
<head> <head>
@ -354,6 +354,18 @@ SELECT sql FROM sqlite_master
ORDER BY tbl_name, type DESC, name ORDER BY tbl_name, type DESC, name
</pre></blockquote> </pre></blockquote>
<p>Of, if you give an argument to ".schema" because you only
one the schema for a single table, the query looks like this:</p>
<blockquote><pre>
SELECT sql FROM sqlite_master
WHERE tbl_name LIKE '%s'
ORDER BY type DESC, name
</pre></blockquote>
<p>The <b>%s</b> in the query above is replaced by the argument
to ".schema", of course.</p>
<h2>Other Dot Commands</h2> <h2>Other Dot Commands</h2>
<p>The ".explain" dot command can be used to set the output mode <p>The ".explain" dot command can be used to set the output mode