Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | After an OP_NullRow is executed on a cursor, cause any subsequent OP_Next or OP_Prev to behave as if there were no more rows to traverse. Ticket #3424. (CVS 5782) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
af679f6170b346fe61df7dae963b2a28 |
User & Date: | danielk1977 2008-10-08 17:58:49.000 |
Context
2008-10-09
| ||
14:45 | Minor cleanup of the new "status" command on the TCL bindings. (CVS 5783) (check-in: ec01bd72ee user: drh tags: trunk) | |
2008-10-08
| ||
17:58 | After an OP_NullRow is executed on a cursor, cause any subsequent OP_Next or OP_Prev to behave as if there were no more rows to traverse. Ticket #3424. (CVS 5782) (check-in: af679f6170 user: danielk1977 tags: trunk) | |
2008-10-07
| ||
23:46 | Add the experimental sqlite3_stmt_status() interface. (CVS 5781) (check-in: de473efb35 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* ** $Id: btree.c,v 1.525 2008/10/08 17:58:49 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ #include "btreeInt.h" |
︙ | ︙ | |||
364 365 366 367 368 369 370 | } return SQLITE_OK; } /* ** Clear the current cursor position. */ | | | 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | } return SQLITE_OK; } /* ** Clear the current cursor position. */ void sqlite3BtreeClearCursor(BtCursor *pCur){ assert( cursorHoldsMutex(pCur) ); sqlite3_free(pCur->pKey); pCur->pKey = 0; pCur->eState = CURSOR_INVALID; } /* |
︙ | ︙ | |||
2590 2591 2592 2593 2594 2595 2596 | ** save the state of the cursor. The cursor must be ** invalidated. */ void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){ BtCursor *p; sqlite3BtreeEnter(pBtree); for(p=pBtree->pBt->pCursor; p; p=p->pNext){ | | | 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 | ** save the state of the cursor. The cursor must be ** invalidated. */ void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){ BtCursor *p; sqlite3BtreeEnter(pBtree); for(p=pBtree->pBt->pCursor; p; p=p->pNext){ sqlite3BtreeClearCursor(p); p->eState = CURSOR_FAULT; p->skip = errCode; } sqlite3BtreeLeave(pBtree); } /* |
︙ | ︙ | |||
2863 2864 2865 2866 2867 2868 2869 | int sqlite3BtreeCloseCursor(BtCursor *pCur){ Btree *pBtree = pCur->pBtree; if( pBtree ){ int i; BtShared *pBt = pCur->pBt; sqlite3BtreeEnter(pBtree); pBt->db = pBtree->db; | | | 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 | int sqlite3BtreeCloseCursor(BtCursor *pCur){ Btree *pBtree = pCur->pBtree; if( pBtree ){ int i; BtShared *pBt = pCur->pBt; sqlite3BtreeEnter(pBtree); pBt->db = pBtree->db; sqlite3BtreeClearCursor(pCur); if( pCur->pPrev ){ pCur->pPrev->pNext = pCur->pNext; }else{ pBt->pCursor = pCur->pNext; } if( pCur->pNext ){ pCur->pNext->pPrev = pCur->pPrev; |
︙ | ︙ | |||
3522 3523 3524 3525 3526 3527 3528 | assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); if( pCur->eState>=CURSOR_REQUIRESEEK ){ if( pCur->eState==CURSOR_FAULT ){ return pCur->skip; } | | | 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 | assert( CURSOR_INVALID < CURSOR_REQUIRESEEK ); assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); if( pCur->eState>=CURSOR_REQUIRESEEK ){ if( pCur->eState==CURSOR_FAULT ){ return pCur->skip; } sqlite3BtreeClearCursor(pCur); } if( pCur->iPage>=0 ){ int i; for(i=1; i<=pCur->iPage; i++){ releasePage(pCur->apPage[i]); } |
︙ | ︙ | |||
5767 5768 5769 5770 5771 5772 5773 | return SQLITE_LOCKED; /* The table pCur points to has a read lock */ } if( pCur->eState==CURSOR_FAULT ){ return pCur->skip; } /* Save the positions of any other cursors open on this table */ | | | 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 | return SQLITE_LOCKED; /* The table pCur points to has a read lock */ } if( pCur->eState==CURSOR_FAULT ){ return pCur->skip; } /* Save the positions of any other cursors open on this table */ sqlite3BtreeClearCursor(pCur); if( SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) || SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc)) ){ return rc; } |
︙ | ︙ |
Changes to src/btree.h.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite B-Tree file ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite B-Tree file ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** ** @(#) $Id: btree.h,v 1.104 2008/10/08 17:58:49 danielk1977 Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ /* TODO: This definition is just included so other modules compile. It ** needs to be revisited. */ |
︙ | ︙ | |||
166 167 168 169 170 171 172 173 174 175 176 177 178 179 | int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); struct Pager *sqlite3BtreePager(Btree*); int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); void sqlite3BtreeCacheOverflow(BtCursor *); #ifdef SQLITE_TEST int sqlite3BtreeCursorInfo(BtCursor*, int*, int); void sqlite3BtreeCursorList(Btree*); #endif /* | > | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*); struct Pager *sqlite3BtreePager(Btree*); int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); void sqlite3BtreeCacheOverflow(BtCursor *); void sqlite3BtreeClearCursor(BtCursor *); #ifdef SQLITE_TEST int sqlite3BtreeCursorInfo(BtCursor*, int*, int); void sqlite3BtreeCursorList(Btree*); #endif /* |
︙ | ︙ |
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.782 2008/10/08 17:58:49 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 | Cursor *pC; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); pC->nullRow = 1; pC->rowidIsValid = 0; break; } /* Opcode: Last P1 P2 * * * ** ** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the last entry in the database table or index. | > > > | 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 | Cursor *pC; assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); pC->nullRow = 1; pC->rowidIsValid = 0; if( pC->pCursor ){ sqlite3BtreeClearCursor(pC->pCursor); } break; } /* Opcode: Last P1 P2 * * * ** ** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the last entry in the database table or index. |
︙ | ︙ |
Added test/tkt3424.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | # 2008 October 06 # # 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. # #*********************************************************************** # # # $Id: tkt3424.test,v 1.1 2008/10/08 17:58:50 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl do_test tkt3424-1.1 { execsql { CREATE TABLE names(id INTEGER, data TEXT, code TEXT); INSERT INTO names VALUES(1,'E1','AAA'); INSERT INTO names VALUES(2,NULL,'BBB'); CREATE TABLE orig(code TEXT, data TEXT); INSERT INTO orig VALUES('AAA','E1'); INSERT INTO orig VALUES('AAA','E2'); INSERT INTO orig VALUES('AAA','E3'); INSERT INTO orig VALUES('AAA','E4'); INSERT INTO orig VALUES('AAA','E5'); } } {} do_test tkt3424-1.2 { execsql { SELECT * FROM names LEFT OUTER JOIN orig ON names.data = orig.data AND names.code = orig.code; } } {1 E1 AAA AAA E1 2 {} BBB {} {}} do_test tkt3424-1.3 { execsql { CREATE INDEX udx_orig_code_data ON orig(code, data) } } {} do_test tkt3424-1.4 { execsql { SELECT * FROM names LEFT OUTER JOIN orig ON names.data = orig.data AND names.code = orig.code; } } {1 E1 AAA AAA E1 2 {} BBB {} {}} finish_test |