Remove code for SQL cursors. (CVS 2312)
FossilOrigin-Name: 2eb90870556c90b8d85da3d5eb7554f74ec922c2
This commit is contained in:
+1
-3
@@ -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
@@ -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 */
|
||||
+3
-3
@@ -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;
|
||||
|
||||
+1
-8
@@ -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;
|
||||
|
||||
+1
-33
@@ -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
|
||||
|
||||
+1
-19
@@ -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
|
||||
|
||||
+2
-28
@@ -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);
|
||||
|
||||
+1
-50
@@ -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
|
||||
|
||||
+1
-7
@@ -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
|
||||
|
||||
+1
-49
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user