Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Make sure virtual table interfaces are not invoked after EOF when the virtual table appears in an outer join. Ticket #2894. (CVS 4761) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
face510bc14f440fc08dd5a354882ae0 |
User & Date: | drh 2008-01-31 15:53:45.000 |
Context
2008-01-31
| ||
16:36 | Fixes to API definition comments in sqlite.h.in. Updates to the build script - ticket #2874. (CVS 4762) (check-in: c23f51de61 user: drh tags: trunk) | |
15:53 | Make sure virtual table interfaces are not invoked after EOF when the virtual table appears in an outer join. Ticket #2894. (CVS 4761) (check-in: face510bc1 user: drh tags: trunk) | |
15:31 | Add "return rc;" to the end of sqlite3_test_control(). (CVS 4760) (check-in: b547e7ea75 user: danielk1977 tags: trunk) | |
Changes
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.706 2008/01/31 15:53:45 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 | */ case OP_VRowid: { /* out2-prerelease */ const sqlite3_module *pModule; sqlite_int64 iRow; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); pModule = pCur->pVtabCursor->pVtab->pModule; assert( pModule->xRowid ); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = pModule->xRowid(pCur->pVtabCursor, &iRow); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; pOut->flags = MEM_Int; pOut->u.i = iRow; | > > > | 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 | */ case OP_VRowid: { /* out2-prerelease */ const sqlite3_module *pModule; sqlite_int64 iRow; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); if( pCur->nullRow ){ break; } pModule = pCur->pVtabCursor->pVtab->pModule; assert( pModule->xRowid ); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = pModule->xRowid(pCur->pVtabCursor, &iRow); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; pOut->flags = MEM_Int; pOut->u.i = iRow; |
︙ | ︙ | |||
4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 | case OP_VColumn: { const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); pModule = pCur->pVtabCursor->pVtab->pModule; assert( pModule->xColumn ); memset(&sContext, 0, sizeof(sContext)); sContext.s.flags = MEM_Null; sContext.s.db = db; if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2); /* Copy the result of the function to the P3 register. We ** do this regardless of whether or not an error occured to ensure any ** dynamic allocation in sContext.s (a Mem struct) is released. */ sqlite3VdbeChangeEncoding(&sContext.s, encoding); | > > > > > > < < | 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 | case OP_VColumn: { const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); pDest = &p->aMem[pOp->p3]; if( pCur->nullRow ){ sqlite3VdbeMemSetNull(pDest); break; } pModule = pCur->pVtabCursor->pVtab->pModule; assert( pModule->xColumn ); memset(&sContext, 0, sizeof(sContext)); sContext.s.flags = MEM_Null; sContext.s.db = db; if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2); /* Copy the result of the function to the P3 register. We ** do this regardless of whether or not an error occured to ensure any ** dynamic allocation in sContext.s (a Mem struct) is released. */ sqlite3VdbeChangeEncoding(&sContext.s, encoding); REGISTER_TRACE(pOp->p3, pDest); sqlite3VdbeMemMove(pDest, &sContext.s); UPDATE_MAX_BLOBSIZE(pDest); if( sqlite3SafetyOn(db) ){ goto abort_due_to_misuse; } |
︙ | ︙ | |||
4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 | */ case OP_VNext: { /* jump */ const sqlite3_module *pModule; int res = 0; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); pModule = pCur->pVtabCursor->pVtab->pModule; assert( pModule->xNext ); /* Invoke the xNext() method of the module. There is no way for the ** underlying implementation to return an error if one occurs during ** xNext(). Instead, if an error occurs, true is returned (indicating that ** data is available) and the error code returned when xColumn or | > > > | 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 | */ case OP_VNext: { /* jump */ const sqlite3_module *pModule; int res = 0; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); if( pCur->nullRow ){ break; } pModule = pCur->pVtabCursor->pVtab->pModule; assert( pModule->xNext ); /* Invoke the xNext() method of the module. There is no way for the ** underlying implementation to return an error if one occurs during ** xNext(). Instead, if an error occurs, true is returned (indicating that ** data is available) and the error code returned when xColumn or |
︙ | ︙ |
Changes to test/vtab2.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # 2006 June 10 # # 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. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 2006 June 10 # # 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. # # $Id: vtab2.test,v 1.8 2008/01/31 15:53:46 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !vtab||!schema_pragmas { finish_test return |
︙ | ︙ | |||
83 84 85 86 87 88 89 90 | WHERE name MATCH 'tcl_*' AND arrayname = '' ORDER BY name; } } $result unset result unset var finish_test | > > > > > > > > > > > > > > > > > > | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | WHERE name MATCH 'tcl_*' AND arrayname = '' ORDER BY name; } } $result unset result unset var # Ticket #2894. # # Make sure we do call Column(), and Rowid() methods of # a virtual table when that table is in a LEFT JOIN. # do_test vtab2-3.1 { execsql { SELECT * FROM schema WHERE dflt_value IS NULL LIMIT 1 } } {main schema 0 database {} 0 {} 0} do_test vtab2-3.2 { execsql { SELECT *, b.rowid FROM schema a LEFT JOIN schema b ON a.dflt_value=b.dflt_value WHERE a.rowid=1 } } {main schema 0 database {} 0 {} 0 {} {} {} {} {} {} {} {} {}} finish_test |