Remove code for SQL cursors. (CVS 2312)
FossilOrigin-Name: 2eb90870556c90b8d85da3d5eb7554f74ec922c2
This commit is contained in:
parent
62d54916c4
commit
6a67fe8edf
@ -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
|
||||
|
||||
|
6
main.mk
6
main.mk
@ -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
|
||||
|
||||
|
42
manifest
42
manifest
@ -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
|
||||
|
@ -1 +1 @@
|
||||
332a531d06a610e6597b02105fcda767313f0225
|
||||
2eb90870556c90b8d85da3d5eb7554f74ec922c2
|
@ -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
|
||||
|
||||
|
239
src/cursor.c
239
src/cursor.c
@ -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 */
|
@ -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;
|
||||
|
@ -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;
|
||||
|
34
src/parse.y
34
src/parse.y
@ -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
|
||||
|
20
src/pragma.c
20
src/pragma.c
@ -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
|
||||
|
30
src/select.c
30
src/select.c
@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle SELECT statements in SQLite.
|
||||
**
|
||||
** $Id: select.c,v 1.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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
50
src/vdbe.c
50
src/vdbe.c
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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}
|
||||
|
136
test/cursor.test
136
test/cursor.test
@ -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
|
@ -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 },
|
||||
|
Loading…
x
Reference in New Issue
Block a user