Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add implementations for opcodes required for linear scans of virtual tables. (CVS 3223) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
1f20e1832b38c76d2b0dde5fd720670c |
User & Date: | danielk1977 2006-06-13 10:24:43.000 |
Context
2006-06-13
| ||
11:15 | Minor changes to lempar.c to reduce warnings on some compilers. (CVS 3224) (check-in: dae71de10d user: drh tags: trunk) | |
10:24 | Add implementations for opcodes required for linear scans of virtual tables. (CVS 3223) (check-in: 1f20e1832b user: danielk1977 tags: trunk) | |
04:11 | Bugfixes: Fix a segfault introduced as part of the new vtab code, deallocate memory in the Destroy() method of the echo module. (CVS 3222) (check-in: 00f3c249bc user: danielk1977 tags: trunk) | |
Changes
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.503 2006/06/13 10:24:43 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Extra interface definitions for those who need them */ |
︙ | ︙ | |||
705 706 707 708 709 710 711 | int addColOffset; /* Offset in CREATE TABLE statement to add a new column */ #endif #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3_module *pModule; /* Pointer to the implementation of the module */ sqlite3_vtab *pVtab; /* Pointer to the module instance */ int nModuleArg; /* Number of arguments to the module */ char **azModuleArg; /* Text of all module args. [0] is module name */ | < | 705 706 707 708 709 710 711 712 713 714 715 716 717 718 | int addColOffset; /* Offset in CREATE TABLE statement to add a new column */ #endif #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3_module *pModule; /* Pointer to the implementation of the module */ sqlite3_vtab *pVtab; /* Pointer to the module instance */ int nModuleArg; /* Number of arguments to the module */ char **azModuleArg; /* Text of all module args. [0] is module name */ u8 isVirtual; /* True if this is a virtual table */ #endif Schema *pSchema; }; /* ** Each foreign key constraint is an instance of the following structure. |
︙ | ︙ |
Changes to src/test8.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | > > > > > > > > > > > > > > > > > > | 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 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test8.c,v 1.8 2006/06/13 10:24:43 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> typedef struct echo_vtab echo_vtab; typedef struct echo_cursor echo_cursor; /* An echo vtab object */ struct echo_vtab { sqlite3_vtab base; Tcl_Interp *interp; sqlite3 *db; char *zStmt; }; /* An echo cursor object */ struct echo_cursor { sqlite3_vtab_cursor base; sqlite3_stmt *pStmt; int errcode; /* Error code */ }; /* ** Global Tcl variable $echo_module is a list. This routine appends ** the string element zArg to that list in interpreter interp. */ static void appendToEchoModule(Tcl_Interp *interp, const char *zArg){ int flags = (TCL_APPEND_VALUE | TCL_LIST_ELEMENT | TCL_GLOBAL_ONLY); |
︙ | ︙ | |||
43 44 45 46 47 48 49 | ** ** Then t2 is assumed to be the name of a *real* database table. The ** schema of the virtual table is declared by passing a copy of the ** CREATE TABLE statement for the real table to sqlite3_declare_vtab(). ** Hence, the virtual table should have exactly the same column names and ** types as the real table. */ | | > > > > > > < < < < < < < < | > | | > > > > > > > > > > > < | < | < < < < < < < | < < < | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 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 109 110 111 112 113 114 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 149 150 151 152 153 154 155 156 157 158 159 160 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 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | ** ** Then t2 is assumed to be the name of a *real* database table. The ** schema of the virtual table is declared by passing a copy of the ** CREATE TABLE statement for the real table to sqlite3_declare_vtab(). ** Hence, the virtual table should have exactly the same column names and ** types as the real table. */ static int echoDeclareVtab( echo_vtab *pVtab, sqlite3 *db, int argc, char **argv ){ int rc = SQLITE_OK; if( argc==2 ){ sqlite3_stmt *pStmt = 0; sqlite3_prepare(db, "SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?", -1, &pStmt, 0); sqlite3_bind_text(pStmt, 1, argv[1], -1, 0); if( sqlite3_step(pStmt)==SQLITE_ROW ){ const char *zCreateTable = sqlite3_column_text(pStmt, 0); #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3_declare_vtab(db, zCreateTable); #endif } else { rc = SQLITE_ERROR; } sqlite3_finalize(pStmt); pVtab->zStmt = sqlite3MPrintf("SELECT rowid, * FROM %s ", argv[1]); } return rc; } static int echoConstructor( sqlite3 *db, const sqlite3_module *pModule, int argc, char **argv, sqlite3_vtab **ppVtab ){ int i; echo_vtab *pVtab; pVtab = sqliteMalloc( sizeof(*pVtab) ); *ppVtab = &pVtab->base; pVtab->base.pModule = pModule; pVtab->interp = pModule->pAux; pVtab->db = db; for(i=0; i<argc; i++){ appendToEchoModule(pVtab->interp, argv[i]); } echoDeclareVtab(pVtab, db, argc, argv); return 0; } /* Methods for the echo module */ static int echoCreate( sqlite3 *db, const sqlite3_module *pModule, int argc, char **argv, sqlite3_vtab **ppVtab ){ appendToEchoModule((Tcl_Interp *)(pModule->pAux), "xCreate"); return echoConstructor(db, pModule, argc, argv, ppVtab); } static int echoConnect( sqlite3 *db, const sqlite3_module *pModule, int argc, char **argv, sqlite3_vtab **ppVtab ){ appendToEchoModule((Tcl_Interp *)(pModule->pAux), "xConnect"); return echoConstructor(db, pModule, argc, argv, ppVtab); } static int echoDisconnect(sqlite3_vtab *pVtab){ echo_vtab *p = (echo_vtab*)pVtab; appendToEchoModule(p->interp, "xDisconnect"); sqliteFree(p->zStmt); sqliteFree(p); return 0; } static int echoDestroy(sqlite3_vtab *pVtab){ echo_vtab *p = (echo_vtab*)pVtab; appendToEchoModule(p->interp, "xDestroy"); sqliteFree(p->zStmt); sqliteFree(p); return 0; } static int echoOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) { echo_cursor *pCur; pCur = sqliteMalloc(sizeof(echo_cursor)); *ppCursor = (sqlite3_vtab_cursor *)pCur; return SQLITE_OK; } static int echoClose(sqlite3_vtab_cursor *cur) { echo_cursor *pCur = (echo_cursor *)cur; sqlite3_finalize(pCur->pStmt); sqliteFree(pCur); return SQLITE_OK; } static int echoNext(sqlite3_vtab_cursor *cur) { int rc; echo_cursor *pCur = (echo_cursor *)cur; rc = sqlite3_step(pCur->pStmt); if( rc==SQLITE_ROW ){ rc = 1; } else { pCur->errcode = sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0; rc = 0; } return rc; } static int echoFilter( sqlite3_vtab_cursor *pVtabCursor, int idx, int argc, sqlite3_value **argv ){ int rc; echo_cursor *pCur = (echo_cursor *)pVtabCursor; echo_vtab *pVtab = (echo_vtab *)pVtabCursor->pVtab; sqlite3 *db = pVtab->db; sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0; rc = sqlite3_prepare(db, pVtab->zStmt, -1, &pCur->pStmt, 0); if( rc==SQLITE_OK ){ rc = echoNext(pVtabCursor); } return rc; } static int echoColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i) { int iCol = i + 1; sqlite3_stmt *pStmt = ((echo_cursor *)cur)->pStmt; assert( sqlite3_data_count(pStmt)>iCol ); switch( sqlite3_column_type(pStmt, iCol) ){ case SQLITE_INTEGER: sqlite3_result_int64(ctx, sqlite3_column_int64(pStmt, iCol)); break; case SQLITE_FLOAT: sqlite3_result_double(ctx, sqlite3_column_double(pStmt, iCol)); break; case SQLITE_TEXT: sqlite3_result_text(ctx, sqlite3_column_text(pStmt, iCol), sqlite3_column_bytes(pStmt, iCol), SQLITE_TRANSIENT ); break; case SQLITE_BLOB: sqlite3_result_blob(ctx, sqlite3_column_blob(pStmt, iCol), sqlite3_column_bytes(pStmt, iCol), SQLITE_TRANSIENT ); break; } return SQLITE_OK; } static int echoRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid) { sqlite3_stmt *pStmt = ((echo_cursor *)cur)->pStmt; *pRowid = sqlite3_column_int64(pStmt, 0); return SQLITE_OK; } /* ** The xBestIndex method for the echo module always returns ** an index of 123. */ static int echoBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){ pIdxInfo->idxNum = 123; |
︙ | ︙ | |||
152 153 154 155 156 157 158 159 160 161 162 163 164 165 | "echo", /* zName */ 0, /* pAux */ echoCreate, echoConnect, echoBestIndex, echoDisconnect, echoDestroy, }; /* ** Decode a pointer to an sqlite3 object. */ static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){ *ppDb = (sqlite3*)sqlite3TextToPtr(zA); | > > > > > > | 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | "echo", /* zName */ 0, /* pAux */ echoCreate, echoConnect, echoBestIndex, echoDisconnect, echoDestroy, echoOpen, /* xOpen - open a cursor */ echoClose, /* xClose - close a cursor */ echoFilter, /* xFilter - configure scan constraints */ echoNext, /* xNext - advance a cursor */ echoColumn, /* xColumn - read data */ echoRowid /* xRowid - read data */ }; /* ** Decode a pointer to an sqlite3 object. */ static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){ *ppDb = (sqlite3*)sqlite3TextToPtr(zA); |
︙ | ︙ |
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.555 2006/06/13 10:24:43 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 | /* Opcode: VOpen P1 * P3 ** ** P3 is a pointer to a virtual table object, an sqlite3_vtab structure. ** P1 is a cursor number. This opcode opens a cursor to the virtual ** table and stores that cursor in P1. */ case OP_VOpen: { break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VFilter P1 P2 * ** ** P1 is a cursor opened using VOpen. P2 is an address to jump to if ** the filtered result set is empty. ** ** This opcode invokes the xFilter method on the virtual table specified ** by P1. The index number parameter to xFilter is the top of the stack. ** Next down on the stack is the argc parameter. Beneath the ** next of stack are argc additional parameters which are passed to | > > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 | /* Opcode: VOpen P1 * P3 ** ** P3 is a pointer to a virtual table object, an sqlite3_vtab structure. ** P1 is a cursor number. This opcode opens a cursor to the virtual ** table and stores that cursor in P1. */ case OP_VOpen: { Cursor *pCur = 0; sqlite3_vtab_cursor *pVtabCursor = 0; sqlite3_vtab *pVtab = (sqlite3_vtab *)(pOp->p3); sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule; assert(pVtab && pModule); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = pModule->xOpen(pVtab, &pVtabCursor); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; if( SQLITE_OK==rc ){ /* Initialise sqlite3_vtab_cursor base class */ pVtabCursor->pVtab = pVtab; /* Initialise vdbe cursor object */ pCur = allocateCursor(p, pOp->p1, -1); pCur->pVtabCursor = pVtabCursor; } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VFilter P1 P2 * ** ** P1 is a cursor opened using VOpen. P2 is an address to jump to if ** the filtered result set is empty. ** ** This opcode invokes the xFilter method on the virtual table specified ** by P1. The index number parameter to xFilter is the top of the stack. ** Next down on the stack is the argc parameter. Beneath the ** next of stack are argc additional parameters which are passed to ** xFilter as argv. The topmost parameter (i.e. 3rd element popped from ** the stack) becomes argv[argc-1] when passed to xFilter. ** ** The index number, argc, and all argv stack values are popped from the ** stack before this instruction completes. ** ** A jump is made to P2 if the result set after filtering would be ** empty. */ case OP_VFilter: { int iIndex; int nArg; const sqlite3_module *pModule; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); pModule = pCur->pVtabCursor->pVtab->pModule; /* Grab the index number and argc parameters off the top of the stack. */ assert( (&pTos[-1])>=p->aStack ); assert( pTos[0].flags==MEM_Int && pTos[-1].flags==MEM_Int ); iIndex = pTos[0].i; nArg = pTos[-1].i; /* Invoke the xFilter method if one is defined. */ if( pModule->xFilter ){ int res; Mem *apArg; apArg = &pTos[1-2-nArg]; if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; res = pModule->xFilter(pCur->pVtabCursor, iIndex, nArg, &apArg); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; if( res==0 ){ pc = pOp->p2 - 1; } } /* Pop the index number, argc value and parameters off the stack */ popStack(&pTos, 2+nArg); break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VRowid P1 * * ** ** Push an integer onto the stack which is the rowid of ** the virtual-table that the P1 cursor is pointing to. */ case OP_VRowid: { const sqlite3_module *pModule; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); pModule = pCur->pVtabCursor->pVtab->pModule; if( pModule->xRowid==0 ){ sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xRowid", 0); rc = SQLITE_ERROR; } else { sqlite_int64 iRow; if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = pModule->xRowid(pCur->pVtabCursor, &iRow); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; pTos++; pTos->flags = MEM_Int; pTos->i = iRow; } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VColumn P1 P2 * ** ** Push onto the stack the value of the P2-th column of ** the row of the virtual-table that the P1 cursor is pointing to. */ case OP_VColumn: { const sqlite3_module *pModule; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); pModule = pCur->pVtabCursor->pVtab->pModule; if( pModule->xColumn==0 ){ sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xColumn", 0); rc = SQLITE_ERROR; } else { sqlite3_context sContext; memset(&sContext, 0, sizeof(sContext)); sContext.s.flags = MEM_Null; if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2); /* Copy the result of the function to the top of the stack. 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); pTos++; pTos->flags = 0; sqlite3VdbeMemMove(pTos, &sContext.s); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VNext P1 P2 * ** ** Advance virtual table P1 to the next row in its result set and ** jump to instruction P2. Or, if the virtual table has reached ** the end of its result set, then fall through to the next instruction. */ case OP_VNext: { const sqlite3_module *pModule; int res = 0; Cursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); pModule = pCur->pVtabCursor->pVtab->pModule; if( pModule->xNext==0 ){ sqlite3SetString(&p->zErrMsg, "Unsupported module operation: xNext", 0); rc = SQLITE_ERROR; } else { /* 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 ** some other method is next invoked on the save virtual table cursor. */ if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; res = pModule->xNext(pCur->pVtabCursor); if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; if( res ){ /* If there is data (or an error), jump to P2 */ pc = pOp->p2 - 1; } } break; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* An other opcode is illegal... */ default: { |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
835 836 837 838 839 840 841 | if( pCx->pBt ){ sqlite3BtreeClose(pCx->pBt); } #ifndef SQLITE_OMIT_VIRTUALTABLE if( pCx->pVtabCursor ){ sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor; sqlite3_vtab *pVtab = pVtabCursor->pVtab; | | | 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 | if( pCx->pBt ){ sqlite3BtreeClose(pCx->pBt); } #ifndef SQLITE_OMIT_VIRTUALTABLE if( pCx->pVtabCursor ){ sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor; sqlite3_vtab *pVtab = pVtabCursor->pVtab; const sqlite3_module *pModule = pVtab->pModule; pModule->xClose(pVtabCursor); } #endif sqliteFree(pCx->pData); sqliteFree(pCx->aType); sqliteFree(pCx); } |
︙ | ︙ |
Changes to src/vtab.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 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 contains code used to help implement virtual tables. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 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 contains code used to help implement virtual tables. ** ** $Id: vtab.c,v 1.6 2006/06/13 10:24:43 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" /* ** External API function used to create a new virtual-table module. */ |
︙ | ︙ | |||
363 364 365 366 367 368 369 | *pzErr = sqlite3MPrintf("module create failed: %s", zModule); sqlite3SafetyOn(db); } else { rc = sqlite3SafetyOn(db); } } | < < < | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | *pzErr = sqlite3MPrintf("module create failed: %s", zModule); sqlite3SafetyOn(db); } else { rc = sqlite3SafetyOn(db); } } return rc; } /* ** This function is invoked by the vdbe to call the xDestroy method ** of the virtual table named zTab in database iDb. This occurs ** when a DROP TABLE is mentioned. |
︙ | ︙ |
Changes to test/vtab1.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 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. The # focus of this file is creating and dropping virtual tables. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 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. The # focus of this file is creating and dropping virtual tables. # # $Id: vtab1.test,v 1.8 2006/06/13 10:24:44 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !vtab { finish_test return |
︙ | ︙ | |||
106 107 108 109 110 111 112 | set echo_module [list] execsql { DROP TABLE t2; } set echo_module } [list xDestroy] | < < | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | set echo_module [list] execsql { DROP TABLE t2; } set echo_module } [list xDestroy] do_test vtab1-2.6 { execsql { PRAGMA table_info(t2); } } {} do_test vtab1-2.7 { execsql { |
︙ | ︙ | |||
133 134 135 136 137 138 139 140 141 | set echo_module } [list] do_test vtab1-2.9 { execsql { SELECT sql FROM sqlite_master; } } [list] finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 131 132 133 134 135 136 137 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 170 171 172 173 174 175 176 177 | set echo_module } [list] do_test vtab1-2.9 { execsql { SELECT sql FROM sqlite_master; } } [list] #---------------------------------------------------------------------- # Test case vtab1-3 tests simple linear scans (no filter conditions) of # virtual table modules. do_test vtab1-3.1 { set echo_module "" execsql { CREATE TABLE treal(a INTEGER, b VARCHAR(32), c); CREATE VIRTUAL TABLE t1 USING echo(treal); } set echo_module } [list xCreate echo treal] do_test vtab1-3.2 { # Test that a SELECT on t2 doesn't crash. No rows are returned # because the underlying real table, is currently empty. execsql { SELECT a, b, c FROM t1; } } {} do_test vtab1-3.3 { # Put some data into the table treal. Then try a select on t1. execsql { INSERT INTO treal VALUES(1, 2, 3); INSERT INTO treal VALUES(4, 5, 6); SELECT * FROM t1; } } {1 2 3 4 5 6} do_test vtab1-3.4 { execsql { SELECT a FROM t1; } } {1 4} do_test vtab1-3.5 { execsql { SELECT rowid FROM t1; } } {1 2} finish_test |