Remove code for SQL cursors. (CVS 2312)

FossilOrigin-Name: 2eb90870556c90b8d85da3d5eb7554f74ec922c2
This commit is contained in:
danielk1977 2005-02-04 04:07:16 +00:00
parent 62d54916c4
commit 6a67fe8edf
18 changed files with 58 additions and 634 deletions

View File

@ -111,7 +111,7 @@ TCC += -DSQLITE_OMIT_CURSOR
# Object files for the SQLite library.
#
LIBOBJ = attach.lo auth.lo btree.lo build.lo cursor.lo date.lo \
LIBOBJ = attach.lo auth.lo btree.lo build.lo date.lo \
delete.lo expr.lo func.lo hash.lo insert.lo \
main.lo opcodes.lo os_unix.lo os_win.lo \
pager.lo parse.lo pragma.lo printf.lo random.lo \
@ -127,7 +127,6 @@ SRC = \
$(TOP)/src/btree.c \
$(TOP)/src/btree.h \
$(TOP)/src/build.c \
$(TOP)/src/cursor.c \
$(TOP)/src/date.c \
$(TOP)/src/delete.c \
$(TOP)/src/expr.c \
@ -288,9 +287,6 @@ config.h:
echo >>config.h
rm -f temp.c temp
cursor.lo: $(TOP)/src/cursor.c $(HDR)
$(LTCOMPILE) -c $(TOP)/src/cursor.c
date.lo: $(TOP)/src/date.c $(HDR)
$(LTCOMPILE) -c $(TOP)/src/date.c

View File

@ -54,7 +54,7 @@ TCCX = $(TCC) $(OPTS) $(THREADSAFE) $(USLEEP) -I. -I$(TOP)/src
# Object files for the SQLite library.
#
LIBOBJ+= attach.o auth.o btree.o build.o cursor.o date.o delete.o \
LIBOBJ+= attach.o auth.o btree.o build.o date.o delete.o \
expr.o func.o hash.o insert.o \
main.o opcodes.o os_unix.o os_win.o \
pager.o parse.o pragma.o printf.o random.o \
@ -71,7 +71,6 @@ SRC = \
$(TOP)/src/btree.c \
$(TOP)/src/btree.h \
$(TOP)/src/build.c \
$(TOP)/src/cursor.c \
$(TOP)/src/date.c \
$(TOP)/src/delete.c \
$(TOP)/src/expr.c \
@ -224,9 +223,6 @@ config.h:
echo >>config.h
rm -f temp.c temp
cursor.o: $(TOP)/src/cursor.c $(HDR)
$(TCCX) -c $(TOP)/src/cursor.c
date.o: $(TOP)/src/date.c $(HDR)
$(TCCX) -c $(TOP)/src/date.c

View File

@ -1,6 +1,6 @@
C Get\sAUTOINCREMENT\sand\sVACUUM\sworking\stogether.\s\sTicket\s#1095.\s(CVS\s2311)
D 2005-02-03T01:08:20
F Makefile.in ffd81f5e926d40b457071b4de8d7c1fa18f39b5a
C Remove\scode\sfor\sSQL\scursors.\s(CVS\s2312)
D 2005-02-04T04:07:17
F Makefile.in f867ff4c3353a3b10ecf823f338876a47fc7def0
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
F VERSION 6755bb368f6ab4bda43b635142309ce2681506cf
@ -16,7 +16,7 @@ F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
F doc/report1.txt a031aaf37b185e4fa540223cb516d3bccec7eeac
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
F ltmain.sh f6b283068efa69f06eb8aa1fe4bddfdbdeb35826
F main.mk 3156c139b50a996c786c9c13fba3ea06cf12799d
F main.mk a31a2d01af035f18db539e5d9ce0629b2f7616e3
F mkdll.sh 468d4f41d3ea98221371df4825cfbffbaac4d7e4
F mkopcodec.awk bd46ad001c98dfbab07b1713cb8e692fa0e5415d
F mkopcodeh.awk cc36b29ff7c996cc482f91a6fd3fa33297b075d5
@ -29,20 +29,19 @@ F sqlite3.def dbaeb20c153e1d366e8f421b55a573f5dfc00863
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
F src/attach.c f78f76bc6a8e5e487ca53636e21ccba2484a9a61
F src/auth.c 18c5a0befe20f3a58a41e3ddd78f372faeeefe1f
F src/btree.c e68ae12c8b12ef9d45d58d931c36c184055a3880
F src/btree.c c3241d44d44e75b54a249bc7c9ed46c7295dfb2a
F src/btree.h 74d19cf40ab49fd69abe9e4e12a6c321ad86c497
F src/build.c fcb437bcda09a57b3fe898dff5ff558e7536621b
F src/cursor.c de73c00aefc4747ad59b5105cf38bbff0667922e
F src/date.c f3d1f5cd1503dabf426a198f3ebef5afbc122a7f
F src/delete.c 4b94395b52a8f7785acd71135c2ce54f3f5550b3
F src/experimental.c 8cc66b2be6a011055d75ef19ed2584bcfbb585ad
F src/expr.c 06b7ab3d09a5f709744f142263e13b2b1d7c6372
F src/expr.c 2ed29dc4f8feeb55eafa40d41941ad7909666863
F src/func.c f096b6771cc0aaa11790aca95773a50a8f74ba73
F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
F src/insert.c 6ab596846d52bd63d6227f9128a29e4f5b2cf524
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
F src/main.c f08a57ab88b4175cf7594caf03974c5a8bc63904
F src/main.c de1f29d3c3cdfbced0c38b40d65541cda76c6799
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
F src/os.h ae44064dc118b20d39450cb331409a775e8bb1c6
F src/os_common.h 0e7f428ba0a6c40a61bc56c4e96f493231301b73
@ -54,17 +53,17 @@ F src/os_win.c bddeae1c3299be0fbe47077dd4e98b786a067f71
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c d21565d0e844712809140632062a7b72b768fdff
F src/pager.h 9eba8c53dd91eae7f3f90743b2ee242da02a9862
F src/parse.y 959948ee97434a7bab3aa04094cd5be6b7501e8d
F src/pragma.c c893f03104e94e0921861bd2d3dbd80c47515f7b
F src/parse.y 7a4965d65c6c8a1f5012bf365c54c8dea09a3921
F src/pragma.c 572d7dd4f9c9d020ca2967a1c3ec02c3126e9631
F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F src/select.c fee51a0d40f1b56d1157f49f9f0fe7fc5af38769
F src/select.c 16c750c000f0d6aa543c778e2c752154b7272336
F src/shell.c 3cb0ef124ed9cd582ce89aec59ff7c659bc6e61b
F src/sqlite.h.in 2a2cb0131cdbd3fe2082de3261efe0ef002e6816
F src/sqliteInt.h 96790021c6610fb4016ac710a28282f006321bc1
F src/sqliteInt.h f10da39b6407af63002401c7f9cee4a1313f4d2d
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
F src/tclsqlite.c 101994a2c4c0eaa69f1de9bfe4a02167f6049e7d
F src/test1.c 8c320f043b869c08fca86c4f01de027774eb85a8
F src/test1.c feac8a742aca920c8ab18a43b3208ae3a834fe9d
F src/test2.c bbc2ecc58ceeab12d1e40970f831b1017524e40d
F src/test3.c 683e1e3819152ffd35da2f201e507228921148d0
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
@ -75,7 +74,7 @@ F src/update.c b6f4668c11059f86b71581187d09197fa28ec4be
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
F src/util.c 1b7b9a127b66743ab6cba8d44597aeb570723c99
F src/vacuum.c 14d1c346234fc64b326c19ea1ffe8f9e4c73d19a
F src/vdbe.c 84ccc6be09e13ee5825f32a94b289117cc903ab2
F src/vdbe.c b3e920b1df4fe6e57dd3789bea08277821dee286
F src/vdbe.h bb9186484f749a839c6c43953e79a6530253f7cd
F src/vdbeInt.h e80721cd8ff611789e20743eec43363a9fb5a48e
F src/vdbeapi.c 467caa6e6fb9247528b1c7ab9132ae1b4748e8ac
@ -104,7 +103,7 @@ F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4
F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2
F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
F test/btree7.test a6d3b842db22af97dd14b989e90a2fd96066b72f
F test/capi2.test b0e12aa66684424869f899b421ff71df69411998
F test/capi2.test 2bd71f573b32e3ac5b97441a55873eae14eeab0d
F test/capi3.test f50dd4666deba96275f9927fe8ec089a3d8c0efa
F test/capi3b.test 5b6a66f9f295f79f443b5d3f33187fa5ef6cf336
F test/collate1.test f79736d2ebf5492167ee4d1f4ab4c09dda776b03
@ -114,11 +113,10 @@ F test/collate4.test b8668612691c4dcf90f67a8df1eeb1544e7fdaf8
F test/collate5.test 581775b94604b7435dc6a5c6e72fbbf7d69e3830
F test/collate6.test 6c9470d1606ee3e564675b229653e320c49ec638
F test/conflict.test c5b849b01cfbe0a4f63a90cba6f68e2fe3a75f87
F test/corrupt.test 916977f0255c81217a44abe0ac01b8508f65dcbf
F test/corrupt.test 4786177a8ee6d9360fcdeae7b2c66862d34fdd57
F test/corrupt2.test 88342570828f2b8cbbd8369eff3891f5c0bdd5ba
F test/crash.test f38b980a0508655d08c957a6dd27d66bca776504
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/cursor.test d7c65ea0fc4e321e12fbcf5c7f3e2211ef45379b
F test/date.test ef6c679d0b59502457dbd78ee1c3c085c949c4c4
F test/delete.test fc29491f6a7ac899ce29f4549a104809e245d9a6
F test/delete2.test e382b6a97787197eb8b93dd4ccd37797c3725ea3
@ -216,7 +214,7 @@ F tool/lempar.c 9bf2f402ab464d3ffb67e7de6154eb66f99d115c
F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133
F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
F tool/memleak3.tcl b8eb053190e95a55dc188896afb972e8108822d6
F tool/mkkeywordhash.c 548b4b1a7ed6b7679111fe44e6d5fe51360572d5
F tool/mkkeywordhash.c c54532f08211938e03bb3a831781d950e619bb31
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816
@ -272,7 +270,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc
F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl 3e522a06ad41992023c80ca29a048ae2331ca5bd
P 76c4a96c5a2148f253cc5e034567b16317343be7
R de8ee7d41901d3dcf0913474f34055dd
U drh
Z 31d017263f1676c9b05f2efee42d194a
P 332a531d06a610e6597b02105fcda767313f0225
R 0db554372b05850054db90220e676ec2
U danielk1977
Z afbed611780de363a0c619320e406df8

View File

@ -1 +1 @@
332a531d06a610e6597b02105fcda767313f0225
2eb90870556c90b8d85da3d5eb7554f74ec922c2

View File

@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.244 2005/01/21 11:55:26 danielk1977 Exp $
** $Id: btree.c,v 1.245 2005/02/04 04:07:17 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
@ -1951,7 +1951,6 @@ static void invalidateCursors(Btree *pBt){
** Print debugging information about all cursors to standard output.
*/
void sqlite3BtreeCursorList(Btree *pBt){
#ifndef SQLITE_OMIT_CURSOR
BtCursor *pCur;
for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
MemPage *pPage = pCur->pPage;
@ -1962,7 +1961,6 @@ void sqlite3BtreeCursorList(Btree *pBt){
pCur->isValid ? "" : " eof"
);
}
#endif
}
#endif

View File

@ -1,239 +0,0 @@
/*
** 2004 November 21
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the DECLARE...CURSOR syntax
** of SQL and related processing.
**
** Do not confuse SQL cursors and B-tree cursors. An SQL cursor (as
** implemented by this file) is a user-visible cursor that is created
** using the DECLARE...CURSOR command and deleted using CLOSE. A
** B-tree cursor is an abstraction of the b-tree layer. See the btree.c
** module for additional information. There is also a VDBE-cursor that
** is used by the VDBE module. Even though all these objects are called
** cursors, they are really very different things. It is worth your while
** to fully understand the difference.
**
** @(#) $Id: cursor.c,v 1.3 2005/01/20 02:14:31 drh Exp $
*/
#include "sqliteInt.h"
#ifndef SQLITE_OMIT_CURSOR
#include "vdbeInt.h"
/*
** Delete a cursor object.
*/
void sqlite3CursorDelete(SqlCursor *p){
if( p ){
int i;
sqlite3SelectDelete(p->pSelect);
for(i=0; i<p->nPtr; i++){
sqlite3VdbeMemRelease(&p->aPtr[i]);
}
sqliteFree(p->aPtr);
sqliteFree(p);
}
}
/*
** Look up a cursor by name. Return NULL if not found.
*/
static SqlCursor *findCursor(sqlite3 *db, Token *pName){
int i;
SqlCursor *p;
for(i=0; i<db->nSqlCursor; i++){
p = db->apSqlCursor[i];
if( p && sqlite3StrNICmp(p->zName, pName->z, pName->n)==0 ){
return p;
}
}
return 0;
}
/*
** The parser calls this routine in order to create a new cursor.
** The arguments are the name of the new cursor and the SELECT statement
** that the new cursor will access.
*/
void sqlite3CursorCreate(Parse *pParse, Token *pName, Select *pSelect){
SqlCursor *pNew;
sqlite3 *db = pParse->db;
int i;
pNew = findCursor(db, pName);
if( pNew ){
sqlite3ErrorMsg(pParse, "another cursor named %T already exists", pName);
goto end_create_cursor;
}
if( pSelect==0 ){
/* This can only happen due to a prior malloc failure */
goto end_create_cursor;
}
for(i=0; i<db->nSqlCursor; i++){
if( db->apSqlCursor[i]==0 ) break;
}
if( i>=db->nSqlCursor ){
db->apSqlCursor = sqliteRealloc(db->apSqlCursor, (i+1)*sizeof(pNew));
db->nSqlCursor = i+1;
}
db->apSqlCursor[i] = pNew = sqliteMallocRaw( sizeof(*pNew) + pName->n + 1 );
if( pNew==0 ) goto end_create_cursor;
pNew->idx = i;
pNew->zName = (char*)&pNew[1];
memcpy(pNew->zName, pName->z, pName->n);
pNew->zName[pName->n] = 0;
pNew->pSelect = sqlite3SelectDup(pSelect);
pNew->nPtr = 2;
pNew->aPtr = sqliteMalloc( sizeof(Mem)*2 );
for(i=0; i<2; i++){
pNew->aPtr[i].flags = MEM_Null;
}
end_create_cursor:
sqlite3SelectDelete(pSelect);
}
/*
** The parser calls this routine in response to a CLOSE command. Delete
** the cursor named in the argument.
*/
void sqlite3CursorClose(Parse *pParse, Token *pName){
SqlCursor *p;
sqlite3 *db = pParse->db;
p = findCursor(db, pName);
if( p==0 ){
sqlite3ErrorMsg(pParse, "no such cursor: %T", pName);
return;
}
assert( p->idx>=0 && p->idx<db->nSqlCursor );
assert( db->apSqlCursor[p->idx]==p );
db->apSqlCursor[p->idx] = 0;
sqlite3CursorDelete(p);
}
/*
** Reverse the direction the ORDER BY clause on the SELECT statement.
*/
static void reverseSortOrder(Select *p){
if( p->pOrderBy==0 ){
/* If there no ORDER BY clause, add a new one that is "rowid DESC" */
static const Token rowid = { "ROWID", 0, 5 };
Expr *pExpr = sqlite3Expr(TK_ID, 0, 0, &rowid);
ExprList *pList = sqlite3ExprListAppend(0, pExpr, 0);
if( pList ) pList->a[0].sortOrder = SQLITE_SO_DESC;
p->pOrderBy = pList;
}else{
int i;
ExprList *pList = p->pOrderBy;
for(i=0; i<pList->nExpr; i++){
pList->a[i].sortOrder = !pList->a[i].sortOrder;
}
}
}
/*
** The parser calls this routine when it sees a complete FETCH statement.
** This routine generates code to implement the FETCH.
**
** Information about the direction of the FETCH has already been inserted
** into the pParse structure by parser rules. The arguments specify the
** name of the cursor from which we are fetching and the optional INTO
** clause.
*/
void sqlite3Fetch(Parse *pParse, Token *pName, IdList *pInto){
SqlCursor *p;
sqlite3 *db = pParse->db;
Select *pCopy;
Fetch sFetch;
p = findCursor(db, pName);
if( p==0 ){
sqlite3ErrorMsg(pParse, "no such cursor: %T", pName);
return;
}
sFetch.pCursor = p;
pCopy = sqlite3SelectDup(p->pSelect);
pCopy->pFetch = &sFetch;
switch( pParse->fetchDir ){
case TK_FIRST: {
sFetch.isBackwards = 0;
sFetch.doRewind = 1;
pCopy->nLimit = pParse->dirArg1;
pCopy->nOffset = 0;
break;
}
case TK_LAST: {
reverseSortOrder(pCopy);
sFetch.isBackwards = 1;
sFetch.doRewind = 1;
pCopy->nLimit = pParse->dirArg1;
pCopy->nOffset = 0;
break;
}
case TK_NEXT: {
sFetch.isBackwards = 0;
sFetch.doRewind = 0;
pCopy->nLimit = pParse->dirArg1;
pCopy->nOffset = 0;
break;
}
case TK_PRIOR: {
reverseSortOrder(pCopy);
sFetch.isBackwards = 1;
sFetch.doRewind = 0;
pCopy->nLimit = pParse->dirArg1;
pCopy->nOffset = 0;
break;
}
case TK_ABSOLUTE: {
sFetch.isBackwards = 0;
sFetch.doRewind = 1;
pCopy->nLimit = pParse->dirArg1;
pCopy->nOffset = pParse->dirArg2;
break;
}
default: {
assert( pParse->fetchDir==TK_RELATIVE );
if( pParse->dirArg2>=0 ){
/* The index parameter is positive. Move forward from the current
** location */
sFetch.isBackwards = 0;
sFetch.doRewind = 0;
pCopy->nLimit = pParse->dirArg1;
pCopy->nOffset = pParse->dirArg2;
}else{
/* The index is negative. We have to code two separate SELECTs.
** The first one seeks to the no position and the second one does
** the query.
*/
Select *pSeek = sqlite3SelectDup(pCopy);
reverseSortOrder(pSeek);
sFetch.isBackwards = 1;
sFetch.doRewind = 0;
pSeek->nLimit = pParse->dirArg2;
pSeek->pFetch = &sFetch;
sqlite3Select(pParse, pSeek, SRT_Discard, 0, 0, 0, 0, 0);
sFetch.isBackwards = 0;
sFetch.doRewind = 0;
pCopy->nLimit = pParse->dirArg1;
pCopy->nOffset = 0;
}
break;
}
}
sqlite3Select(pParse, pCopy, SRT_Callback, 0, 0, 0, 0, 0);
end_fetch:
sqlite3IdListDelete(pInto);
}
#endif /* SQLITE_OMIT_CURSOR */

View File

@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.190 2005/01/30 09:17:59 danielk1977 Exp $
** $Id: expr.c,v 1.191 2005/02/04 04:07:17 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@ -453,8 +453,8 @@ ExprList *sqlite3ExprListDup(ExprList *p){
** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes
** called with a NULL argument.
*/
#if !defined(SQLITE_OMIT_CURSOR) || !defined(SQLITE_OMIT_VIEW) \
|| !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_SUBQUERY)
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \
|| !defined(SQLITE_OMIT_SUBQUERY)
SrcList *sqlite3SrcListDup(SrcList *p){
SrcList *pNew;
int i;

View File

@ -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.277 2005/01/31 12:42:29 danielk1977 Exp $
** $Id: main.c,v 1.278 2005/02/04 04:07:17 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -500,13 +500,6 @@ int sqlite3_close(sqlite3 *db){
sqlite3ValueFree(db->pErr);
}
#ifndef SQLITE_OMIT_CURSOR
for(j=0; j<db->nSqlCursor; j++){
sqlite3CursorDelete(db->apSqlCursor[j]);
}
sqliteFree(db->apSqlCursor);
#endif
db->magic = SQLITE_MAGIC_ERROR;
sqliteFree(db);
return SQLITE_OK;

View File

@ -14,7 +14,7 @@
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.163 2005/01/29 08:32:45 danielk1977 Exp $
** @(#) $Id: parse.y,v 1.164 2005/02/04 04:07:17 danielk1977 Exp $
*/
%token_prefix TK_
%token_type {Token}
@ -600,9 +600,6 @@ term(A) ::= INTEGER(X). {A = sqlite3Expr(@X, 0, 0, &X);}
term(A) ::= FLOAT(X). {A = sqlite3Expr(@X, 0, 0, &X);}
term(A) ::= STRING(X). {A = sqlite3Expr(@X, 0, 0, &X);}
expr(A) ::= BLOB(X). {A = sqlite3Expr(@X, 0, 0, &X);}
%ifdef SQLITE_ENABLE_CURSOR
expr(A) ::= CURRENT OF id.
%endif
expr(A) ::= REGISTER(X). {A = sqlite3RegisterExpr(pParse, &X);}
expr(A) ::= VARIABLE(X). {
Token *pToken = &X;
@ -968,32 +965,3 @@ cmd ::= ALTER TABLE fullname(X) RENAME TO nm(Z). {
sqlite3AlterRenameTable(pParse,X,&Z);
}
%endif
////////////////////////////// CURSORS //////////////////////////////////////
%ifdef SQLITE_ENABLE_CURSOR
cmd ::= DECLARE nm(X) CURSOR FOR select(Y). {sqlite3CursorCreate(pParse,&X,Y);}
cmd ::= CLOSE nm(X). {sqlite3CursorClose(pParse,&X);}
cmd ::= FETCH direction FROM nm(N) into_opt(D).
{sqlite3Fetch(pParse,&N,D);}
%type into_opt {IdList*}
%destructor into_opt {sqlite3IdListDelete($$);}
into_opt(A) ::= . {A = 0;}
into_opt(A) ::= INTO inscollist(X). {A = X;}
direction ::= NEXT(X) count_opt(Y). {pParse->fetchDir=@X; pParse->dirArg1=Y;}
direction ::= PRIOR(X) count_opt(Y). {pParse->fetchDir=@X; pParse->dirArg1=Y;}
direction ::= FIRST(X) count_opt(Y). {pParse->fetchDir=@X; pParse->dirArg1=Y;}
direction ::= LAST(X) count_opt(Y). {pParse->fetchDir=@X; pParse->dirArg1=Y;}
direction ::= ABSOLUTE(X) signed(Z) comma_count_opt(Y).
{pParse->fetchDir=@X; pParse->dirArg1=Y; pParse->dirArg2=Z;}
direction ::= RELATIVE(X) signed(Z) comma_count_opt(Y).
{pParse->fetchDir=@X; pParse->dirArg1=Y; pParse->dirArg2=Z;}
%type count_opt {int}
count_opt(A) ::= . {A = 1;}
count_opt(A) ::= signed(X). {A = X;}
%type comma_count_opt {int}
comma_count_opt(A) ::= . {A = 1;}
comma_count_opt(A) ::= COMMA signed(X). {A = X;}
%endif // SQLITE_ENABLE_CURSOR

View File

@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.86 2005/01/24 10:25:59 danielk1977 Exp $
** $Id: pragma.c,v 1.87 2005/02/04 04:07:17 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -538,24 +538,6 @@ void sqlite3Pragma(
sqlite3VdbeAddOp(v, OP_Callback, 3, 0);
}
}else
#ifndef SQLITE_OMIT_CURSOR
if( sqlite3StrICmp(zLeft, "cursor_list")==0 ){
int i;
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
sqlite3VdbeSetNumCols(v, 2);
sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC);
sqlite3VdbeSetColName(v, 1, "name", P3_STATIC);
for(i=0; i<db->nSqlCursor; i++){
SqlCursor *p = db->apSqlCursor[i];
if( p==0 ) continue;
assert( p->zName!=0 );
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
sqlite3VdbeOp3(v, OP_String8, 0, 0, p->zName, 0);
sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
}
}else
#endif /* SQLITE_OMIT_CURSOR */
#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
#ifndef SQLITE_OMIT_FOREIGN_KEY

View File

@ -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.237 2005/01/31 12:42:29 danielk1977 Exp $
** $Id: select.c,v 1.238 2005/02/04 04:07:17 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -547,7 +547,7 @@ static int selectInnerLoop(
break;
}
#if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_CURSOR)
#if !defined(SQLITE_OMIT_TRIGGER)
/* Discard the results. This is used for SELECT statements inside
** the body of a TRIGGER. The purpose of such selects is to call
** user-defined functions that have side effects. We do not care
@ -2522,12 +2522,6 @@ int sqlite3Select(
/* If there is are a sequence of queries, do the earlier ones first.
*/
if( p->pPrior ){
#ifndef SQLITE_OMIT_CURSOR
if( p->pFetch ){
sqlite3ErrorMsg(pParse, "cursors cannot be used on compound queries");
goto select_end;
}
#endif
return multiSelect(pParse, p, eDest, iParm, aff);
}
#endif
@ -2583,26 +2577,6 @@ int sqlite3Select(
break;
}
/* We cannot use a SQL cursor on a join or on a DISTINCT query
*/
#ifndef SQLITE_OMIT_CURSOR
if( p->pFetch ){
if( p->isDistinct ){
sqlite3ErrorMsg(pParse, "cursors cannot be used on DISTINCT queries");
goto select_end;
}
if( pTabList->nSrc>0 ){
sqlite3ErrorMsg(pParse, "cursors cannot be used on joins");
goto select_end;
}
if( pTabList->a[0].pSelect ){
sqlite3ErrorMsg(pParse, "cursor cannot be used with nested queries "
"or views");
goto select_end;
}
}
#endif
/* Begin generating code.
*/
v = sqlite3GetVdbe(pParse);

View File

@ -11,19 +11,11 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.365 2005/01/31 12:56:44 danielk1977 Exp $
** @(#) $Id: sqliteInt.h,v 1.366 2005/02/04 04:07:17 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
/*
** Cursor support is turned off unless the SQLITE_ENABLE_CURSOR option
** is defined.
*/
#ifndef SQLITE_ENABLE_CURSOR
# define SQLITE_OMIT_CURSOR 1
#endif
/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it. If the OS lacks
@ -328,10 +320,8 @@ typedef struct AuthContext AuthContext;
typedef struct KeyClass KeyClass;
typedef struct CollSeq CollSeq;
typedef struct KeyInfo KeyInfo;
typedef struct SqlCursor SqlCursor;
typedef struct NameContext NameContext;
typedef struct Fetch Fetch;
typedef struct CursorSubst CursorSubst;
/*
** Each database file to be accessed by the system is an instance
@ -444,10 +434,6 @@ struct sqlite3 {
int (*xProgress)(void *); /* The progress callback */
void *pProgressArg; /* Argument to the progress callback */
int nProgressOps; /* Number of opcodes for progress callback */
#endif
#ifndef SQLITE_OMIT_CURSOR
int nSqlCursor; /* Number of slots in apSqlCursor[] */
SqlCursor **apSqlCursor; /* Pointers to all active SQL cursors */
#endif
int errCode; /* Most recent error code (SQLITE_*) */
u8 enc; /* Text encoding for this database. */
@ -974,16 +960,6 @@ struct WhereInfo {
WhereLevel a[1]; /* Information about each nest loop in the WHERE */
};
/*
** An instance of the following structure is used to store information
** about a single FETCH sql command.
*/
struct Fetch {
SqlCursor *pCursor; /* Cursor used by the fetch */
int isBackwards; /* Cursor moves backwards if true, forward if false */
int doRewind; /* True to rewind cursor before starting */
};
/*
** A NameContext defines a context in which to resolve table and column
** names. The context consists of a list of tables (the pSrcList) field and
@ -1123,11 +1099,6 @@ struct Parse {
int nVarExprAlloc; /* Number of allocated slots in apVarExpr[] */
Expr **apVarExpr; /* Pointers to :aaa and $aaaa wildcard expressions */
u8 explain; /* True if the EXPLAIN flag is found on the query */
#ifndef SQLITE_OMIT_CURSOR
u8 fetchDir; /* The direction argument to the FETCH command */
int dirArg1; /* First argument to the direction */
int dirArg2; /* Second argument to the direction */
#endif
Token sErrToken; /* The token at which the error occurred */
Token sNameToken; /* Token with unqualified schema object name */
Token sLastToken; /* The last token parsed */
@ -1312,19 +1283,6 @@ typedef struct {
char **pzErrMsg; /* Error message stored here */
} InitData;
/*
** Each SQL cursor (a cursor created by the DECLARE ... CURSOR syntax)
** is represented by an instance of the following structure.
*/
struct SqlCursor {
char *zName; /* Name of this cursor */
int idx; /* Index of this cursor in db->apSqlCursor[] */
Select *pSelect; /* The SELECT statement that defines this cursor */
int nPtr; /* Number of slots in aPtr[] */
sqlite3_value *aPtr; /* Values that define the current cursor position */
};
/*
* This global flag is set for performance testing of triggers. When it is set
* SQLite will perform the overhead of building new and old trigger references
@ -1578,11 +1536,4 @@ void sqlite3ExpirePreparedStatements(sqlite3*);
void sqlite3CodeSubselect(Parse *, Expr *);
int sqlite3SelectResolve(Parse *, Select *, NameContext *);
#ifndef SQLITE_OMIT_CURSOR
void sqlite3CursorDelete(SqlCursor*);
void sqlite3CursorCreate(Parse*, Token*, Select*);
void sqlite3CursorClose(Parse*, Token*);
void sqlite3Fetch(Parse*, Token*, IdList*);
#endif /* SQLITE_OMIT_CURSOR */
#endif

View File

@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.128 2005/01/25 04:27:55 danielk1977 Exp $
** $Id: test1.c,v 1.129 2005/02/04 04:07:18 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@ -2729,12 +2729,6 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "conflict", "1", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_OMIT_CURSOR
Tcl_SetVar2(interp, "sqlite_options", "cursor", "0", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "cursor", "1", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_OMIT_DATETIME_FUNCS
Tcl_SetVar2(interp, "sqlite_options", "datetime", "0", TCL_GLOBAL_ONLY);
#else

View File

@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.449 2005/01/29 08:32:45 danielk1977 Exp $
** $Id: vdbe.c,v 1.450 2005/02/04 04:07:18 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -4477,54 +4477,6 @@ case OP_Vacuum: {
break;
}
#ifndef SQLITE_OMIT_CURSOR
/* Opcode: CursorStore P1 P2 *
**
** The implementation of SQL cursors (not to be confused with VDBE cursors
** or B-tree cursors) stores information in the SQLite database connection
** structure (the sqlite3* pointer) that identifies the row
** in a table that an SQL cursor is pointing to. This opcode is
** used to store that information. P1 is an index of an SQL cursor.
** P2 is the index of a memory slot within that SQL cursor. This opcode
** pops the top of the stack and stores it in the SQL cursor.
*/
case OP_CursorStore: {
SqlCursor *pCursor;
assert( pTos>=p->aStack );
assert( pOp->p1>=0 && pOp->p1<db->nSqlCursor );
pCursor = db->apSqlCursor[pOp->p1];
assert( pCursor!=0 );
assert( pOp->p2>=0 && pOp->p2<2 );
rc = sqlite3VdbeMemMove(&pCursor->aPtr[pOp->p1], pTos);
pTos--;
break;
}
/* Opcode: CursorLoad P1 P2 *
**
** The implementation of SQL cursors (not to be confused with VDBE cursors
** or B-tree cursors) stores information in the SQLite database connection
** structure (the sqlite3* pointer) that effectively records the current
** location in a table that an SQL cursor is pointing to. This opcode is
** used to recover that information. P1 is an index of an SQL cursor.
** P2 is the index of a memory slot within that SQL cursor. This opcode
** pushes a new value onto the stack which is a copy of the information
** obtained from entry P2 of cursor P1.
*/
case OP_CursorLoad: {
SqlCursor *pCursor;
int i = pOp->p1;
assert( pTos>=p->aStack );
assert( pOp->p1>=0 && pOp->p1<db->nSqlCursor );
pCursor = db->apSqlCursor[pOp->p1];
assert( pCursor!=0 );
assert( pOp->p2>=0 && pOp->p2<2 );
pTos++;
sqlite3VdbeMemShallowCopy(pTos, &pCursor->aPtr[i], MEM_Ephem);
break;
}
#endif /* SQLITE_OMIT_CURSOR */
/* Opcode: Expire P1 * *
**
** Cause precompiled statements to become expired. An expired statement

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi2.test,v 1.24 2005/01/20 22:48:48 drh Exp $
# $Id: capi2.test,v 1.25 2005/02/04 04:07:18 danielk1977 Exp $
#
set testdir [file dirname $argv0]
@ -252,6 +252,26 @@ do_test capi2-3.19 {
list [sqlite3_finalize $VM] [sqlite3_errmsg $DB]
} {SQLITE_CONSTRAINT {t2.a may not be NULL}}
do_test capi2-3.20 {
execsql {
CREATE TABLE a1(message_id, name , UNIQUE(message_id, name) );
INSERT INTO a1 VALUES(1, 1);
}
} {}
do_test capi2-3.21 {
set VM [sqlite3_prepare $DB {INSERT INTO a1 VALUES(1, 1)} -1 TAIL]
sqlite3_step $VM
} {SQLITE_ERROR}
do_test capi2-3.22 {
sqlite3_errcode $DB
} {SQLITE_ERROR}
do_test capi2-3.23 {
sqlite3_finalize $VM
} {SQLITE_CONSTRAINT}
do_test capi2-3.24 {
sqlite3_errcode $DB
} {SQLITE_CONSTRAINT}
# Two or more virtual machines exists at the same time.
#
do_test capi2-4.1 {

View File

@ -13,7 +13,7 @@
# This file implements tests to make sure SQLite does not crash or
# segfault if it sees a corrupt database file.
#
# $Id: corrupt.test,v 1.4 2005/01/20 02:17:02 danielk1977 Exp $
# $Id: corrupt.test,v 1.5 2005/02/04 04:07:18 danielk1977 Exp $
catch {file delete -force test.db}
catch {file delete -force test.db-journal}
@ -81,7 +81,6 @@ for {set i [expr {1*256}]} {$i<$fsize-256} {incr i 256} {
seek $fd $i
puts -nonewline $fd $junk
close $fd
sqlite3 db test.db
do_test corrupt-2.$tn.1 {
sqlite3 db test.db
catchsql {SELECT count(*) FROM sqlite_master}

View File

@ -1,136 +0,0 @@
# 2004 November 22
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is DECLARE...CURSOR functionality
#
# $Id: cursor.test,v 1.2 2004/11/23 01:47:31 drh Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_OMIT_CURSOR is defined, omit this file.
ifcapable {!cursor} {
finish_test
return
}
########
# Test the logic that creates and destroys cursors
########
do_test cursor-1.1 {
execsql {
CREATE TABLE t1(a,b,c);
CREATE INDEX t1i1 ON t1(a);
CREATE INDEX t1i2 ON t1(b,c);
}
execsql {
DECLARE c1 CURSOR FOR SELECT c FROM t1 ORDER BY a;
}
} {}
ifcapable schema_pragmas {
do_test cursor-1.2 {
execsql {PRAGMA cursor_list}
} {0 c1}
}
do_test cursor-1.3 {
execsql {
DECLARE c2 CURSOR FOR SELECT a FROM t1 ORDER BY b, c;
}
} {}
ifcapable schema_pragmas {
do_test cursor-1.4 {
execsql {PRAGMA cursor_list}
} {0 c1 1 c2}
}
do_test cursor-1.5 {
catchsql {
CLOSE c3;
}
} {1 {no such cursor: c3}}
ifcapable schema_pragmas {
do_test cursor-1.6 {
execsql {PRAGMA cursor_list}
} {0 c1 1 c2}
}
do_test cursor-1.7 {
catchsql {
CLOSE c1;
}
} {0 {}}
ifcapable schema_pragmas {
do_test cursor-1.8 {
execsql {PRAGMA cursor_list}
} {1 c2}
}
do_test cursor-1.9 {
catchsql {
CLOSE c1;
}
} {1 {no such cursor: c1}}
ifcapable schema_pragmas {
do_test cursor-1.10 {
execsql {PRAGMA cursor_list}
} {1 c2}
}
do_test cursor-1.11 {
catchsql {
DECLARE c2 CURSOR FOR SELECT * FROM t1;
}
} {1 {another cursor named c2 already exists}}
do_test cursor-1.12 {
catchsql {
DECLARE c3 CURSOR FOR SELECT * FROM t1;
}
} {0 {}}
ifcapable schema_pragmas {
do_test cursor-1.13 {
execsql {PRAGMA cursor_list}
} {0 c3 1 c2}
}
do_test cursor-1.14 {
execsql {
CLOSE c2;
CLOSE c3;
}
} {}
ifcapable schema_pragmas {
do_test cursor-1.15 {
execsql {PRAGMA cursor_list}
} {}
}
set all {}
for {set i 1} {$i<=50} {incr i} {
lappend all [expr {$i-1}] x$i
do_test cursor-2.1.$i.1 {
execsql "DECLARE x$i CURSOR FOR SELECT * FROM t1"
} {}
ifcapable schema_pragmas {
do_test cursor-2.1.$i.2 {
execsql {PRAGMA cursor_list}
} $all
}
}
for {set i 1} {$i<=50} {incr i} {
set all [lrange $all 2 end]
do_test cursor-2.2.$i.1 {
execsql "CLOSE x$i"
} {}
ifcapable schema_pragmas {
do_test cursor-2.2.$i.2 {
execsql {PRAGMA cursor_list}
} $all
}
}
finish_test

View File

@ -7,13 +7,6 @@
#include <string.h>
#include <stdlib.h>
/*
** Cursor support is off by default.
*/
#if !defined(SQLITE_ENABLE_CURSOR) && !defined(SQLITE_OMIT_CURSOR)
# define SQLITE_OMIT_CURSOR 1
#endif
/*
** All the keywords of the SQL language are stored as in a hash
** table composed of instances of the following structure.
@ -62,11 +55,6 @@ struct Keyword {
#else
# define CONFLICT 32
#endif
#ifdef SQLITE_OMIT_CURSOR
# define CURSOR 0
#else
# define CURSOR 64
#endif
#ifdef SQLITE_OMIT_EXPLAIN
# define EXPLAIN 0
#else
@ -114,7 +102,6 @@ struct Keyword {
*/
static Keyword aKeywordTable[] = {
{ "ABORT", "TK_ABORT", CONFLICT|TRIGGER },
{ "ABSOLUTE", "TK_ABSOLUTE", CURSOR },
{ "AFTER", "TK_AFTER", TRIGGER },
{ "ALL", "TK_ALL", ALWAYS },
{ "ALTER", "TK_ALTER", ALTER },
@ -130,20 +117,16 @@ static Keyword aKeywordTable[] = {
{ "CASCADE", "TK_CASCADE", FKEY },
{ "CASE", "TK_CASE", ALWAYS },
{ "CHECK", "TK_CHECK", ALWAYS },
{ "CLOSE", "TK_CLOSE", CURSOR },
{ "COLLATE", "TK_COLLATE", ALWAYS },
{ "COMMIT", "TK_COMMIT", ALWAYS },
{ "CONFLICT", "TK_CONFLICT", CONFLICT },
{ "CONSTRAINT", "TK_CONSTRAINT", ALWAYS },
{ "CREATE", "TK_CREATE", ALWAYS },
{ "CROSS", "TK_JOIN_KW", ALWAYS },
{ "CURSOR", "TK_CURSOR", CURSOR },
{ "CURRENT", "TK_CURRENT", CURSOR },
{ "CURRENT_DATE", "TK_CDATE", ALWAYS },
{ "CURRENT_TIME", "TK_CTIME", ALWAYS },
{ "CURRENT_TIMESTAMP","TK_CTIMESTAMP", ALWAYS },
{ "DATABASE", "TK_DATABASE", ATTACH },
{ "DECLARE", "TK_DECLARE", CURSOR },
{ "DEFAULT", "TK_DEFAULT", ALWAYS },
{ "DEFERRED", "TK_DEFERRED", ALWAYS },
{ "DEFERRABLE", "TK_DEFERRABLE", FKEY },
@ -161,9 +144,7 @@ static Keyword aKeywordTable[] = {
{ "EXISTS", "TK_EXISTS", SUBQUERY },
{ "EXPLAIN", "TK_EXPLAIN", EXPLAIN },
{ "FAIL", "TK_FAIL", CONFLICT|TRIGGER },
{ "FETCH", "TK_FETCH", CURSOR },
{ "FIRST", "TK_FIRST", CURSOR },
{ "FOR", "TK_FOR", TRIGGER|CURSOR },
{ "FOR", "TK_FOR", TRIGGER },
{ "FOREIGN", "TK_FOREIGN", FKEY },
{ "FROM", "TK_FROM", ALWAYS },
{ "FULL", "TK_JOIN_KW", ALWAYS },
@ -189,7 +170,6 @@ static Keyword aKeywordTable[] = {
{ "LIMIT", "TK_LIMIT", ALWAYS },
{ "MATCH", "TK_MATCH", ALWAYS },
{ "NATURAL", "TK_JOIN_KW", ALWAYS },
{ "NEXT", "TK_NEXT", CURSOR },
{ "NOT", "TK_NOT", ALWAYS },
{ "NOTNULL", "TK_NOTNULL", ALWAYS },
{ "NULL", "TK_NULL", ALWAYS },
@ -200,12 +180,10 @@ static Keyword aKeywordTable[] = {
{ "ORDER", "TK_ORDER", ALWAYS },
{ "OUTER", "TK_JOIN_KW", ALWAYS },
{ "PRAGMA", "TK_PRAGMA", PRAGMA },
{ "PRIOR", "TK_PRIOR", CURSOR },
{ "PRIMARY", "TK_PRIMARY", ALWAYS },
{ "RAISE", "TK_RAISE", TRIGGER },
{ "REFERENCES", "TK_REFERENCES", FKEY },
{ "REINDEX", "TK_REINDEX", REINDEX },
{ "RELATIVE", "TK_RELATIVE", CURSOR },
{ "RENAME", "TK_RENAME", ALTER },
{ "REPLACE", "TK_REPLACE", CONFLICT },
{ "RESTRICT", "TK_RESTRICT", FKEY },