Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | More work on the implementation of cursors, but they are still not functioning. (CVS 2142) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
8b61d1ae1ca469b80f2b344d550c3b36 |
User & Date: | drh 2004-11-23 01:47:30.000 |
Context
2004-11-23
| ||
09:06 | Fix a bug involving balance_shallow() and the sqlite_master table. (CVS 2143) (check-in: 557be3ff5b user: danielk1977 tags: trunk) | |
01:47 | More work on the implementation of cursors, but they are still not functioning. (CVS 2142) (check-in: 8b61d1ae1c user: drh tags: trunk) | |
2004-11-22
| ||
19:12 | 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) (check-in: fc8c1393c8 user: drh tags: trunk) | |
Changes
Changes to src/cursor.c.
︙ | ︙ | |||
17 18 19 20 21 22 23 | ** 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. ** | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | ** 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.2 2004/11/23 01:47:30 drh Exp $ */ #ifndef SQLITE_OMIT_CURSOR #include "sqliteInt.h" #include "vdbeInt.h" /* ** Delete a cursor object. |
︙ | ︙ | |||
82 83 84 85 86 87 88 89 90 91 92 | } 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->zName = (char*)&pNew[1]; memcpy(pNew->zName, pName->z, pName->n); pNew->zName[pName->n] = 0; pNew->pSelect = sqlite3SelectDup(pSelect); | > | | > | > | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | } 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 |
︙ | ︙ | |||
112 113 114 115 116 117 118 119 120 121 122 123 124 125 | return; } assert( p->idx>=0 && p->idx<db->nSqlCursor ); assert( db->apSqlCursor[p->idx]==p ); db->apSqlCursor[p->idx] = 0; sqlite3CursorDelete(p); } /* ** 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 | > > > > > > > > > > > > > > > > > > > > | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | 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 |
︙ | ︙ | |||
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | return; } sFetch.pCursor = p; pCopy = sqlite3SelectDup(p->pSelect); pCopy->pFetch = &sFetch; switch( pParse->fetchDir ){ case TK_FIRST: { break; } case TK_LAST: { break; } case TK_NEXT: { break; } case TK_PRIOR: { break; } case TK_ABSOLUTE: { break; } default: { assert( pParse->fetchDir==TK_RELATIVE ); break; } } sqlite3Select(pParse, pCopy, SRT_Callback, 0, 0, 0, 0, 0); end_fetch: sqlite3IdListDelete(pInto); } #endif /* SQLITE_OMIT_CURSOR */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | 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 */ |
Changes to src/delete.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** ** $Id: delete.c,v 1.91 2004/11/23 01:47:30 drh Exp $ */ #include "sqliteInt.h" /* ** Look up every table that is named in pSrc. If any table is not found, ** add an error message to pParse->zErrMsg and return NULL. If all tables ** are found, return a pointer to the last table. |
︙ | ︙ | |||
225 226 227 228 229 230 231 | if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){ goto delete_from_cleanup; } } /* Begin the database scan */ | | | 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | if( sqlite3CheckIndexCollSeq(pParse, pIdx) ){ goto delete_from_cleanup; } } /* Begin the database scan */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 1, 0, 0); if( pWInfo==0 ) goto delete_from_cleanup; /* Remember the key of every item to be deleted. */ sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0); if( db->flags & SQLITE_CountRows ){ sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** ** $Id: expr.c,v 1.174 2004/11/23 01:47:30 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
175 176 177 178 179 180 181 | } /* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqliteMalloc(). The calling function ** is responsible for making sure the node eventually gets freed. */ | | | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | } /* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqliteMalloc(). The calling function ** is responsible for making sure the node eventually gets freed. */ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){ Expr *pNew; pNew = sqliteMalloc( sizeof(Expr) ); if( pNew==0 ){ /* When malloc fails, we leak memory from pLeft and pRight */ return 0; } pNew->op = op; |
︙ | ︙ |
Changes to src/select.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** ** $Id: select.c,v 1.217 2004/11/23 01:47:30 drh Exp $ */ #include "sqliteInt.h" /* ** Allocate a new Select structure and return a pointer to that ** structure. |
︙ | ︙ | |||
2543 2544 2545 2546 2547 2548 2549 | openTempIndex(pParse, p, distinct, 0); }else{ distinct = -1; } /* Begin the database scan */ | < < < < < < < | | < | 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 | openTempIndex(pParse, p, distinct, 0); }else{ distinct = -1; } /* Begin the database scan */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, pGroupBy ? 0 : &pOrderBy, p->pFetch); if( pWInfo==0 ) goto select_end; /* Use the standard inner loop if we are not dealing with ** aggregates */ if( !isAgg ){ if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest, |
︙ | ︙ |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.344 2004/11/23 01:47:30 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** These #defines should enable >2GB file support on Posix if the ** underlying operating system supports it. If the OS lacks |
︙ | ︙ | |||
1277 1278 1279 1280 1281 1282 1283 | void *sqlite3TextToPtr(const char*); void sqlite3SetString(char **, const char *, ...); void sqlite3ErrorMsg(Parse*, const char*, ...); void sqlite3Dequote(char*); int sqlite3KeywordCode(const char*, int); int sqlite3RunParser(Parse*, const char*, char **); void sqlite3FinishCoding(Parse*); | | | 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 | void *sqlite3TextToPtr(const char*); void sqlite3SetString(char **, const char *, ...); void sqlite3ErrorMsg(Parse*, const char*, ...); void sqlite3Dequote(char*); int sqlite3KeywordCode(const char*, int); int sqlite3RunParser(Parse*, const char*, char **); void sqlite3FinishCoding(Parse*); Expr *sqlite3Expr(int, Expr*, Expr*, const Token*); Expr *sqlite3RegisterExpr(Parse*,Token*); Expr *sqlite3ExprAnd(Expr*, Expr*); void sqlite3ExprSpan(Expr*,Token*,Token*); Expr *sqlite3ExprFunction(ExprList*, Token*); void sqlite3ExprAssignVarNumber(Parse*, Expr*); void sqlite3ExprDelete(Expr*); ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*); |
︙ | ︙ | |||
1337 1338 1339 1340 1341 1342 1343 | void sqlite3SelectUnbind(Select*); Table *sqlite3SrcListLookup(Parse*, SrcList*); int sqlite3IsReadOnly(Parse*, Table*, int); void sqlite3OpenTableForReading(Vdbe*, int iCur, Table*); void sqlite3OpenTable(Vdbe*, int iCur, Table*, int); void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); | | | 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 | void sqlite3SelectUnbind(Select*); Table *sqlite3SrcListLookup(Parse*, SrcList*); int sqlite3IsReadOnly(Parse*, Table*, int); void sqlite3OpenTableForReading(Vdbe*, int iCur, Table*); void sqlite3OpenTable(Vdbe*, int iCur, Table*, int); void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, int, ExprList**, Fetch*); void sqlite3WhereEnd(WhereInfo*); void sqlite3ExprCode(Parse*, Expr*); int sqlite3ExprCodeExprList(Parse*, ExprList*); void sqlite3ExprIfTrue(Parse*, Expr*, int, int); void sqlite3ExprIfFalse(Parse*, Expr*, int, int); void sqlite3NextedParse(Parse*, const char*, ...); Table *sqlite3FindTable(sqlite3*,const char*, const char*); |
︙ | ︙ |
Changes to src/update.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** ** $Id: update.c,v 1.97 2004/11/23 01:47:30 drh Exp $ */ #include "sqliteInt.h" /* ** Process an UPDATE statement. ** ** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL; |
︙ | ︙ | |||
231 232 233 234 235 236 237 | pView = sqlite3SelectDup(pTab->pSelect); sqlite3Select(pParse, pView, SRT_TempTable, iCur, 0, 0, 0, 0); sqlite3SelectDelete(pView); } /* Begin the database scan */ | | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | pView = sqlite3SelectDup(pTab->pSelect); sqlite3Select(pParse, pView, SRT_TempTable, iCur, 0, 0, 0, 0); sqlite3SelectDelete(pView); } /* Begin the database scan */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 1, 0, 0); if( pWInfo==0 ) goto update_cleanup; /* Remember the index of every item to be updated. */ sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0); /* End the database scan loop. |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** 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.431 2004/11/23 01:47:30 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 | */ case OP_Vacuum: { if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = sqlite3RunVacuum(&p->zErrMsg, db); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; break; } /* An other opcode is illegal... */ default: { sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode); sqlite3SetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0); rc = SQLITE_INTERNAL; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 | */ case OP_Vacuum: { if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = sqlite3RunVacuum(&p->zErrMsg, db); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; 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 */ /* An other opcode is illegal... */ default: { sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode); sqlite3SetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0); rc = SQLITE_INTERNAL; |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** ** $Id: where.c,v 1.120 2004/11/23 01:47:31 drh Exp $ */ #include "sqliteInt.h" /* ** The query generator uses an array of instances of this structure to ** help it analyze the subexpressions of the WHERE clause. Each WHERE ** clause subexpression is separated from the others by an AND operator. |
︙ | ︙ | |||
494 495 496 497 498 499 500 | ** scan is correct for the ORDER BY clause, then that index is used and ** *ppOrderBy is set to NULL. This is an optimization that prevents an ** unnecessary sort of the result set if an index appropriate for the ** ORDER BY clause already exists. ** ** If the where clause loops cannot be arranged to provide the correct ** output order, then the *ppOrderBy is unchanged. | < < < < | > > > > | 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 | ** scan is correct for the ORDER BY clause, then that index is used and ** *ppOrderBy is set to NULL. This is an optimization that prevents an ** unnecessary sort of the result set if an index appropriate for the ** ORDER BY clause already exists. ** ** If the where clause loops cannot be arranged to provide the correct ** output order, then the *ppOrderBy is unchanged. */ WhereInfo *sqlite3WhereBegin( Parse *pParse, /* The parser context */ SrcList *pTabList, /* A list of all tables to be scanned */ Expr *pWhere, /* The WHERE clause */ int pushKey, /* If TRUE, leave the table key on the stack */ ExprList **ppOrderBy, /* An ORDER BY clause, or NULL */ Fetch *pFetch /* Initial location of cursors. NULL otherwise */ ){ int i; /* Loop counter */ WhereInfo *pWInfo; /* Will become the return value of this function */ Vdbe *v = pParse->pVdbe; /* The virtual database engine */ int brk, cont = 0; /* Addresses used during code generation */ int nExpr; /* Number of subexpressions in the WHERE clause */ int loopMask; /* One bit set for each outer loop */ int haveKey = 0; /* True if KEY is on the stack */ ExprInfo *pTerm; /* A single term in the WHERE clause; ptr to aExpr[] */ ExprMaskSet maskSet; /* The expression mask set */ int iDirectEq[32]; /* Term of the form ROWID==X for the N-th table */ int iDirectLt[32]; /* Term of the form ROWID<X or ROWID<=X */ int iDirectGt[32]; /* Term of the form ROWID>X or ROWID>=X */ ExprInfo aExpr[101]; /* The WHERE clause is divided into these terms */ /* pushKey is only allowed if there is a single table (as in an INSERT or ** UPDATE statement) */ assert( pushKey==0 || pTabList->nSrc==1 ); /* */ /* Split the WHERE clause into separate subexpressions where each ** subexpression is separated by an AND operator. If the aExpr[] ** array fills up, the last entry might point to an expression which ** contains additional unfactored AND operators. */ initMaskSet(&maskSet); |
︙ | ︙ |
Changes to test/cursor.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 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 # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 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} { |
︙ | ︙ |