1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-14 00:22:38 +03:00

Add initial infrastructure for cursors. In where.c, optimize out clauses

of the form "ORDER BY rowid" if a table scan is being performed.  Do a
reverse table scan if "ORDER BY rowid DESC" is present. (CVS 2141)

FossilOrigin-Name: fc8c1393c86017a816beb52725b68af3b973f979
This commit is contained in:
drh
2004-11-22 19:12:19 +00:00
parent 8237d45ed8
commit b6c29897eb
17 changed files with 671 additions and 93 deletions

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.215 2004/11/22 10:02:11 danielk1977 Exp $
** $Id: select.c,v 1.216 2004/11/22 19:12:21 drh Exp $
*/
#include "sqliteInt.h"
@@ -298,7 +298,6 @@ void sqlite3SelectDelete(Select *p){
sqlite3ExprDelete(p->pHaving);
sqlite3ExprListDelete(p->pOrderBy);
sqlite3SelectDelete(p->pPrior);
sqliteFree(p->zSelect);
sqliteFree(p);
}
@@ -2276,6 +2275,12 @@ 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
@@ -2360,6 +2365,26 @@ int sqlite3Select(
goto select_end;
}
/* 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);
@@ -2522,8 +2547,16 @@ int sqlite3Select(
/* Begin the database scan
*/
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0,
pGroupBy ? 0 : &pOrderBy);
#if 0 /* ndef SQLITE_OMIT_CURSOR */
if( p->pFetch ){
pWInfo = sqlite3WhereBeginFetch(pParse, pTabList, pWhere,
pOrderby, p->pFetch);
}else
#endif
{
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0,
pGroupBy ? 0 : &pOrderBy);
}
if( pWInfo==0 ) goto select_end;
/* Use the standard inner loop if we are not dealing with