:-) (CVS 20)
FossilOrigin-Name: 01d85b35e9c4ca5619ad21a4232a8f8bf9ec3538
This commit is contained in:
parent
7e391e1728
commit
dce2cbe65f
@ -145,6 +145,9 @@ sqlite.html: $(TOP)/www/sqlite.tcl
|
||||
c_interface.html: $(TOP)/www/c_interface.tcl
|
||||
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.
|
||||
#
|
||||
PUBLISH = \
|
||||
@ -152,6 +155,7 @@ PUBLISH = \
|
||||
all.tar.gz \
|
||||
index.html \
|
||||
sqlite.html \
|
||||
changes.html \
|
||||
c_interface.html
|
||||
|
||||
website: $(PUBLISH)
|
||||
|
39
manifest
39
manifest
@ -1,25 +1,25 @@
|
||||
C :-)\s(CVS\s19)
|
||||
D 2000-05-30T20:17:49
|
||||
C :-)\s(CVS\s20)
|
||||
D 2000-05-31T02:27:49
|
||||
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
||||
F Makefile.in 89921c1ee4de75275bfadfbac198396da31704d1
|
||||
F Makefile.in dd79c78825935c5711ce45c372b0ac0f194b6d43
|
||||
F README 6b5960603c7f8bf42fc022b4b6436f242f238dbb
|
||||
F configure 00a5b5c82147a576fa6e82d7c1b0d55c321d6d2c x
|
||||
F configure.in 6ccfd5fc80517f7cfe605a7fc7e0f62d962a233c
|
||||
F doc/lemon.html e233a3e97a779c7a87e1bc4528c664a58e49dd47
|
||||
F src/build.c 335df4b65f49d335438d3a0cd7e48d19713a1917
|
||||
F src/dbbe.c 159c39f8bf5475c34904786fad4f3f0f579d9eb6
|
||||
F src/dbbe.h bedeb3a0985bb584458e7849fb59927e99e751e6
|
||||
F src/build.c c6b500077913cde55871d1f9c0d17d4ee4a86828
|
||||
F src/dbbe.c dc9439f839d13e633158808e352056b531f17e1b
|
||||
F src/dbbe.h b678e31c32fa252e6fba830ad16ed8978d1521a9
|
||||
F src/main.c 25cce7bce0eb3ba10bada7c05f4b38dc6dbbc86f
|
||||
F src/parse.y 50ca06d471132e16bb47c56f19553e4efd5b3d4a
|
||||
F src/shell.c 3ffa9059514cd4db3bd64e0797bf7ebbe1ea8ee3
|
||||
F src/parse.y 05de7dec046dd8bd11f8cc3513ff8b27624618c8
|
||||
F src/shell.c c5752d32cdeaa7d548d4f91177b697b023a00381
|
||||
F src/sqlite.h 2397c17a8f4ca90c09acab0100dc7e2f8f441b69
|
||||
F src/sqliteInt.h 749da8b3e4ce146fd172aeb59b6db04c57726d7a
|
||||
F src/sqliteInt.h 9ac3f9e05bbc5913531473c86d4742343ae670c5
|
||||
F src/tclsqlite.c 9efd29f79ded6a900aa3d142169c8bfe03b7affd
|
||||
F src/tokenize.c e176b2c1c38e11482ee3419d6b50b733860a1587
|
||||
F src/util.c 2a0314dcc9de230526380765339071a5b304d70d
|
||||
F src/vdbe.c 117ce5541143e3af9dccdc15c22c4920a7b9bdb4
|
||||
F src/vdbe.h 03de26632f2e608c2a44a40262fbba21a8bdfd81
|
||||
F src/where.c 2c8de69c4cf5a620ed380d3d6bb658bbbe8da5d5
|
||||
F src/tokenize.c 5b066f314646d6c5396a253315e5e95d107e1800
|
||||
F src/util.c 6b4327d7fbf684f8635155d4acb847ae991b3ebc
|
||||
F src/vdbe.c 74ff55bc2910e25bd811638233f6c02fb1a17fbc
|
||||
F src/vdbe.h 02b470d344caed04451c896be7a775068dbdf076
|
||||
F src/where.c fd9faea693083c1bde83f824b98f7eb81c4762cc
|
||||
F test/all.test 66a8a5b8291a472157944edcdce51a320ebd1f35
|
||||
F test/copy.test 641bd3cfaab61c4ee32889587e21e4c70788a97a
|
||||
F test/delete.test 814d53e3b0d2d7069fb17e005d4041454d6585d4
|
||||
@ -36,9 +36,10 @@ F tool/opNames.awk 2bd9071a138e4e2be13dc98fe066398a61219e1e
|
||||
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
|
||||
F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9
|
||||
F www/c_interface.tcl f875864edf7974157d1c257ca08de854660882a5
|
||||
F www/index.tcl 2466d1b2e26c6f354b0acedee12025309a216799
|
||||
F www/sqlite.tcl 947e067bcc347dc767af4c1a6e5a8d47d8404aa3
|
||||
P 2d41caec807a6ab83b67e59c849ebbda004f2869
|
||||
R d274f71e9bf0807a8f2c186fb0e9f965
|
||||
F www/changes.tcl 38ff869ccbf99388d53abd08aeea4e24e2bb23b7
|
||||
F www/index.tcl 57a97afafe04ab53d1996ba3a61ac41fa8453f5a
|
||||
F www/sqlite.tcl 7deb564df188ad4523adecfe2365de6d09f6dfd9
|
||||
P 03725ce5ae871247789ece0f2c3426f74ba575e7
|
||||
R bab7f299b23f92a0096c17a89a463018
|
||||
U drh
|
||||
Z 1247bb7c9fa8cc79296726f95e563a76
|
||||
Z e30b944ebaee88defeb667112902d5c8
|
||||
|
@ -1 +1 @@
|
||||
03725ce5ae871247789ece0f2c3426f74ba575e7
|
||||
01d85b35e9c4ca5619ad21a4232a8f8bf9ec3538
|
45
src/build.c
45
src/build.c
@ -24,7 +24,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** 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"
|
||||
|
||||
@ -1528,3 +1528,46 @@ void sqliteCopy(
|
||||
copy_cleanup:
|
||||
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;
|
||||
}
|
||||
|
18
src/dbbe.c
18
src/dbbe.c
@ -30,7 +30,7 @@
|
||||
** relatively simple to convert to a different database such
|
||||
** 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 <gdbm.h>
|
||||
@ -199,6 +199,22 @@ void sqliteDbbeDropTable(Dbbe *pBe, const char *zTable){
|
||||
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().
|
||||
*/
|
||||
|
@ -28,7 +28,7 @@
|
||||
** This library was originally designed to support the following
|
||||
** 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_
|
||||
#define _SQLITE_DBBE_H_
|
||||
@ -65,6 +65,9 @@ DbbeTable *sqliteDbbeOpenTable(Dbbe*, const char *zTableName, int writeable);
|
||||
/* Delete a table from the database */
|
||||
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 */
|
||||
void sqliteDbbeCloseTable(DbbeTable*);
|
||||
|
||||
|
11
src/parse.y
11
src/parse.y
@ -26,7 +26,7 @@
|
||||
** the parser. Lemon will also generate a header file containing
|
||||
** 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_type {Token}
|
||||
@ -236,7 +236,7 @@ fieldlist(A) ::= ID(Y). {A = sqliteIdListAppend(0,&Y);}
|
||||
|
||||
%left OR.
|
||||
%left AND.
|
||||
%left EQ NE ISNULL NOTNULL IS.
|
||||
%left EQ NE ISNULL NOTNULL IS LIKE GLOB.
|
||||
%left GT GE LT LE.
|
||||
%left PLUS MINUS.
|
||||
%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) 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) 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) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, 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);}
|
||||
cmd ::= COPY id(X) FROM id(Y).
|
||||
{sqliteCopy(pParse,&X,&Y,0);}
|
||||
|
||||
cmd ::= VACUUM. {sqliteVacuum(pParse,0);}
|
||||
cmd ::= VACUUM id(X). {sqliteVacuum(pParse,&X);}
|
||||
|
@ -24,7 +24,7 @@
|
||||
** This file contains code to implement the "sqlite" command line
|
||||
** 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 <string.h>
|
||||
@ -300,7 +300,7 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
|
||||
data.showHeader = 0;
|
||||
data.mode = MODE_List;
|
||||
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]);
|
||||
sqlite_exec(db, zSql, callback, &data, &zErrMsg);
|
||||
if( zErrMsg ){
|
||||
@ -343,7 +343,7 @@ static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
|
||||
data.showHeader = 0;
|
||||
data.mode = MODE_List;
|
||||
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]);
|
||||
}else{
|
||||
sprintf(zSql, "SELECT sql FROM sqlite_master "
|
||||
|
@ -23,7 +23,7 @@
|
||||
*************************************************************************
|
||||
** 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 "dbbe.h"
|
||||
@ -248,3 +248,6 @@ void sqliteExprIfTrue(Parse*, Expr*, int);
|
||||
void sqliteExprIfFalse(Parse*, Expr*, int);
|
||||
Table *sqliteFindTable(sqlite*,char*);
|
||||
void sqliteCopy(Parse*, Token*, Token*, Token*);
|
||||
void sqliteVacuum(Parse*, Token*);
|
||||
int sqliteGlobCompare(const char*,const char*);
|
||||
int sqliteLikeCompare(const unsigned char*,const unsigned char*);
|
||||
|
@ -27,7 +27,7 @@
|
||||
** individual tokens and sends those tokens one-by-one over to the
|
||||
** 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 <ctype.h>
|
||||
@ -64,12 +64,14 @@ static Keyword aKeywordTable[] = {
|
||||
{ "DROP", 0, TK_DROP, 0 },
|
||||
{ "EXPLAIN", 0, TK_EXPLAIN, 0 },
|
||||
{ "FROM", 0, TK_FROM, 0 },
|
||||
{ "GLOB", 0, TK_GLOB, 0 },
|
||||
{ "INDEX", 0, TK_INDEX, 0 },
|
||||
{ "INSERT", 0, TK_INSERT, 0 },
|
||||
{ "INTO", 0, TK_INTO, 0 },
|
||||
{ "IS", 0, TK_IS, 0 },
|
||||
{ "ISNULL", 0, TK_ISNULL, 0 },
|
||||
{ "KEY", 0, TK_KEY, 0 },
|
||||
{ "LIKE", 0, TK_LIKE, 0 },
|
||||
{ "NOT", 0, TK_NOT, 0 },
|
||||
{ "NOTNULL", 0, TK_NOTNULL, 0 },
|
||||
{ "NULL", 0, TK_NULL, 0 },
|
||||
@ -83,6 +85,7 @@ static Keyword aKeywordTable[] = {
|
||||
{ "UNIQUE", 0, TK_UNIQUE, 0 },
|
||||
{ "UPDATE", 0, TK_UPDATE, 0 },
|
||||
{ "USING", 0, TK_USING, 0 },
|
||||
{ "VACUUM", 0, TK_VACUUM, 0 },
|
||||
{ "VALUES", 0, TK_VALUES, 0 },
|
||||
{ "WHERE", 0, TK_WHERE, 0 },
|
||||
};
|
||||
|
137
src/util.c
137
src/util.c
@ -26,7 +26,7 @@
|
||||
** This file contains functions for allocating memory, comparing
|
||||
** 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 <stdarg.h>
|
||||
@ -563,3 +563,138 @@ int sqliteSortCompare(const char *a, const char *b){
|
||||
if( *a=='-' ) res = -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;
|
||||
}
|
||||
|
107
src/vdbe.c
107
src/vdbe.c
@ -41,7 +41,7 @@
|
||||
** But other routines are also provided to help in building up
|
||||
** 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"
|
||||
|
||||
@ -391,23 +391,24 @@ void sqliteVdbeDelete(Vdbe *p){
|
||||
** this array, then copy and paste it into this file, if you want.
|
||||
*/
|
||||
static char *zOpName[] = { 0,
|
||||
"Open", "Close", "Destroy", "Fetch",
|
||||
"New", "Put", "Delete", "Field",
|
||||
"Key", "Rewind", "Next", "ResetIdx",
|
||||
"NextIdx", "PutIdx", "DeleteIdx", "ListOpen",
|
||||
"ListWrite", "ListRewind", "ListRead", "ListClose",
|
||||
"SortOpen", "SortPut", "SortMakeRec", "SortMakeKey",
|
||||
"Sort", "SortNext", "SortKey", "SortCallback",
|
||||
"SortClose", "FileOpen", "FileRead", "FileField",
|
||||
"FileClose", "MakeRecord", "MakeKey", "Goto",
|
||||
"If", "Halt", "ColumnCount", "ColumnName",
|
||||
"Callback", "Integer", "String", "Pop",
|
||||
"Dup", "Pull", "Add", "AddImm",
|
||||
"Subtract", "Multiply", "Divide", "Min",
|
||||
"Max", "Eq", "Ne", "Lt",
|
||||
"Le", "Gt", "Ge", "IsNull",
|
||||
"NotNull", "Negative", "And", "Or",
|
||||
"Not", "Concat", "Noop",
|
||||
"Open", "Close", "Fetch", "New",
|
||||
"Put", "Delete", "Field", "Key",
|
||||
"Rewind", "Next", "Destroy", "Reorganize",
|
||||
"ResetIdx", "NextIdx", "PutIdx", "DeleteIdx",
|
||||
"ListOpen", "ListWrite", "ListRewind", "ListRead",
|
||||
"ListClose", "SortOpen", "SortPut", "SortMakeRec",
|
||||
"SortMakeKey", "Sort", "SortNext", "SortKey",
|
||||
"SortCallback", "SortClose", "FileOpen", "FileRead",
|
||||
"FileField", "FileClose", "MakeRecord", "MakeKey",
|
||||
"Goto", "If", "Halt", "ColumnCount",
|
||||
"ColumnName", "Callback", "Integer", "String",
|
||||
"Pop", "Dup", "Pull", "Add",
|
||||
"AddImm", "Subtract", "Multiply", "Divide",
|
||||
"Min", "Max", "Like", "Glob",
|
||||
"Eq", "Ne", "Lt", "Le",
|
||||
"Gt", "Ge", "IsNull", "NotNull",
|
||||
"Negative", "And", "Or", "Not",
|
||||
"Concat", "Noop",
|
||||
};
|
||||
|
||||
/*
|
||||
@ -997,6 +998,67 @@ int sqliteVdbeExec(
|
||||
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 * * *
|
||||
**
|
||||
** Pop two values off the stack. Take the logical AND of the
|
||||
@ -1581,6 +1643,15 @@ int sqliteVdbeExec(
|
||||
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 * *
|
||||
**
|
||||
** Open a file used for temporary storage of index numbers. P1
|
||||
|
139
src/vdbe.h
139
src/vdbe.h
@ -27,7 +27,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.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_
|
||||
#define _SQLITE_VDBE_H_
|
||||
@ -73,81 +73,86 @@ typedef struct VdbeOp VdbeOp;
|
||||
*/
|
||||
#define OP_Open 1
|
||||
#define OP_Close 2
|
||||
#define OP_Destroy 3
|
||||
#define OP_Fetch 4
|
||||
#define OP_New 5
|
||||
#define OP_Put 6
|
||||
#define OP_Delete 7
|
||||
#define OP_Field 8
|
||||
#define OP_Key 9
|
||||
#define OP_Rewind 10
|
||||
#define OP_Next 11
|
||||
#define OP_ResetIdx 12
|
||||
#define OP_NextIdx 13
|
||||
#define OP_PutIdx 14
|
||||
#define OP_DeleteIdx 15
|
||||
#define OP_Fetch 3
|
||||
#define OP_New 4
|
||||
#define OP_Put 5
|
||||
#define OP_Delete 6
|
||||
#define OP_Field 7
|
||||
#define OP_Key 8
|
||||
#define OP_Rewind 9
|
||||
#define OP_Next 10
|
||||
|
||||
#define OP_ListOpen 16
|
||||
#define OP_ListWrite 17
|
||||
#define OP_ListRewind 18
|
||||
#define OP_ListRead 19
|
||||
#define OP_ListClose 20
|
||||
#define OP_Destroy 11
|
||||
#define OP_Reorganize 12
|
||||
|
||||
#define OP_SortOpen 21
|
||||
#define OP_SortPut 22
|
||||
#define OP_SortMakeRec 23
|
||||
#define OP_SortMakeKey 24
|
||||
#define OP_Sort 25
|
||||
#define OP_SortNext 26
|
||||
#define OP_SortKey 27
|
||||
#define OP_SortCallback 28
|
||||
#define OP_SortClose 29
|
||||
#define OP_ResetIdx 13
|
||||
#define OP_NextIdx 14
|
||||
#define OP_PutIdx 15
|
||||
#define OP_DeleteIdx 16
|
||||
|
||||
#define OP_FileOpen 30
|
||||
#define OP_FileRead 31
|
||||
#define OP_FileField 32
|
||||
#define OP_FileClose 33
|
||||
#define OP_ListOpen 17
|
||||
#define OP_ListWrite 18
|
||||
#define OP_ListRewind 19
|
||||
#define OP_ListRead 20
|
||||
#define OP_ListClose 21
|
||||
|
||||
#define OP_MakeRecord 34
|
||||
#define OP_MakeKey 35
|
||||
#define OP_SortOpen 22
|
||||
#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_If 37
|
||||
#define OP_Halt 38
|
||||
#define OP_FileOpen 31
|
||||
#define OP_FileRead 32
|
||||
#define OP_FileField 33
|
||||
#define OP_FileClose 34
|
||||
|
||||
#define OP_ColumnCount 39
|
||||
#define OP_ColumnName 40
|
||||
#define OP_Callback 41
|
||||
#define OP_MakeRecord 35
|
||||
#define OP_MakeKey 36
|
||||
|
||||
#define OP_Integer 42
|
||||
#define OP_String 43
|
||||
#define OP_Pop 44
|
||||
#define OP_Dup 45
|
||||
#define OP_Pull 46
|
||||
#define OP_Goto 37
|
||||
#define OP_If 38
|
||||
#define OP_Halt 39
|
||||
|
||||
#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_ColumnCount 40
|
||||
#define OP_ColumnName 41
|
||||
#define OP_Callback 42
|
||||
|
||||
#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
|
||||
|
47
src/where.c
47
src/where.c
@ -25,7 +25,7 @@
|
||||
** the WHERE clause of SQL statements. Also found here are subroutines
|
||||
** 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"
|
||||
|
||||
@ -368,12 +368,14 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
||||
case TK_SLASH: op = OP_Divide; break;
|
||||
case TK_AND: op = OP_And; break;
|
||||
case TK_OR: op = OP_Or; break;
|
||||
case TK_LT: op = OP_Ge; break;
|
||||
case TK_LE: op = OP_Gt; break;
|
||||
case TK_GT: op = OP_Le; break;
|
||||
case TK_GE: op = OP_Lt; break;
|
||||
case TK_NE: op = OP_Eq; break;
|
||||
case TK_EQ: op = OP_Ne; break;
|
||||
case TK_LT: op = OP_Lt; break;
|
||||
case TK_LE: op = OP_Le; break;
|
||||
case TK_GT: op = OP_Gt; break;
|
||||
case TK_GE: op = OP_Ge; break;
|
||||
case TK_NE: 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_NOTNULL: op = OP_NotNull; break;
|
||||
case TK_NOT: op = OP_Not; break;
|
||||
@ -421,14 +423,16 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
|
||||
case TK_GT:
|
||||
case TK_GE:
|
||||
case TK_NE:
|
||||
case TK_EQ: {
|
||||
case TK_EQ:
|
||||
case TK_LIKE:
|
||||
case TK_GLOB: {
|
||||
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->pRight);
|
||||
dest = sqliteVdbeCurrentAddr(v) + 2;
|
||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AddImm, 1, 0, 0, 0);
|
||||
sqliteVdbeAddOp(v, OP_AddImm, -1, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
case TK_NOT:
|
||||
@ -466,6 +470,8 @@ void sqliteExprIfTrue(Parse *pParse, Expr *pExpr, int dest){
|
||||
case TK_GE: op = OP_Ge; break;
|
||||
case TK_NE: 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_NOTNULL: op = OP_NotNull; break;
|
||||
default: break;
|
||||
@ -483,12 +489,18 @@ void sqliteExprIfTrue(Parse *pParse, Expr *pExpr, int dest){
|
||||
sqliteExprIfTrue(pParse, pExpr->pRight, dest);
|
||||
break;
|
||||
}
|
||||
case TK_NOT: {
|
||||
sqliteExprIfFalse(pParse, pExpr->pLeft, dest);
|
||||
break;
|
||||
}
|
||||
case TK_LT:
|
||||
case TK_LE:
|
||||
case TK_GT:
|
||||
case TK_GE:
|
||||
case TK_NE:
|
||||
case TK_EQ: {
|
||||
case TK_EQ:
|
||||
case TK_LIKE:
|
||||
case TK_GLOB: {
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
sqliteExprCode(pParse, pExpr->pRight);
|
||||
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_NE: op = OP_Eq; 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_NOTNULL: op = OP_IsNull; break;
|
||||
default: break;
|
||||
@ -540,6 +554,10 @@ void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest){
|
||||
sqliteVdbeResolveLabel(v, d2);
|
||||
break;
|
||||
}
|
||||
case TK_NOT: {
|
||||
sqliteExprIfTrue(pParse, pExpr->pLeft, dest);
|
||||
break;
|
||||
}
|
||||
case TK_LT:
|
||||
case TK_LE:
|
||||
case TK_GT:
|
||||
@ -551,6 +569,13 @@ void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest){
|
||||
sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
|
||||
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_NOTNULL: {
|
||||
sqliteExprCode(pParse, pExpr->pLeft);
|
||||
|
46
www/changes.tcl
Normal file
46
www/changes.tcl
Normal 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>}
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# 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>
|
||||
<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,
|
||||
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
|
||||
does strive to implement to most commonly used features. SQLite
|
||||
currently understands the following SQL commands:</p>
|
||||
@ -71,7 +74,6 @@ implement are as follows:</p>
|
||||
<ul>
|
||||
<li>ALTER TABLE</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>Constraints</li>
|
||||
<li>Nested queries</li>
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# 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>
|
||||
<head>
|
||||
@ -354,6 +354,18 @@ SELECT sql FROM sqlite_master
|
||||
ORDER BY tbl_name, type DESC, name
|
||||
</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>
|
||||
|
||||
<p>The ".explain" dot command can be used to set the output mode
|
||||
|
Loading…
Reference in New Issue
Block a user