Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Progress toward getting the virtual-table code generator to work. (CVS 3220) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
3532f1340f939b0231c1d82a7b2d186c |
User & Date: | drh 2006-06-13 01:04:52.000 |
Context
2006-06-13
| ||
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 3221) (check-in: f9ea970475 user: danielk1977 tags: trunk) | |
01:04 | Progress toward getting the virtual-table code generator to work. (CVS 3220) (check-in: 3532f1340f user: drh tags: trunk) | |
2006-06-12
| ||
21:59 | Added code to iterate through virtual tables. All regression tests pass but the new code is completely untested. (CVS 3219) (check-in: 0109654331 user: drh tags: trunk) | |
Changes
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.260 2006/06/13 01:04:52 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** Return the 'affinity' of the expression pExpr if any. ** |
︙ | ︙ | |||
1485 1486 1487 1488 1489 1490 1491 | if( pExpr->iTable<0 ){ /* This only happens when coding check constraints */ assert( pParse->ckOffset>0 ); sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1); }else if( pExpr->iColumn>=0 ){ Table *pTab = pExpr->pTab; int iCol = pExpr->iColumn; | > | > | | 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 | if( pExpr->iTable<0 ){ /* This only happens when coding check constraints */ assert( pParse->ckOffset>0 ); sqlite3VdbeAddOp(v, OP_Dup, pParse->ckOffset-pExpr->iColumn-1, 1); }else if( pExpr->iColumn>=0 ){ Table *pTab = pExpr->pTab; int iCol = pExpr->iColumn; sqlite3VdbeAddOp(v, pTab->isVirtual ? OP_VColumn : OP_Column, pExpr->iTable, iCol); sqlite3ColumnDefault(v, pTab, iCol); #ifndef SQLITE_OMIT_FLOATING_POINT if( pTab && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){ sqlite3VdbeAddOp(v, OP_RealAffinity, 0, 0); } #endif }else{ sqlite3VdbeAddOp(v, pExpr->pTab->isVirtual ? OP_VRowid : OP_Rowid, pExpr->iTable, 0); } break; } case TK_INTEGER: { codeInteger(v, (char*)pExpr->token.z, pExpr->token.n); break; } |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
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 header file defines the interface that the SQLite library ** presents to client programs. ** | | | 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 header file defines the interface that the SQLite library ** presents to client programs. ** ** @(#) $Id: sqlite.h.in,v 1.171 2006/06/13 01:04:53 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
1653 1654 1655 1656 1657 1658 1659 | ** Every module implementation uses a subclass of the following structure ** to describe a particular instance of the module. Each subclass will ** be taylored to the specific needs of the module implementation. The ** purpose of this superclass is to define certain fields that are common ** to all module implementations. */ struct sqlite3_vtab { | | | 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 | ** Every module implementation uses a subclass of the following structure ** to describe a particular instance of the module. Each subclass will ** be taylored to the specific needs of the module implementation. The ** purpose of this superclass is to define certain fields that are common ** to all module implementations. */ struct sqlite3_vtab { const sqlite3_module *pModule; /* The module for this virtual table */ /* Virtual table implementations will typically add additional fields */ }; /* Every module implementation uses a subclass of the following structure ** to describe cursors that point into the virtual table and are used ** to loop through the virtual table. Cursors are created using the ** xOpen method of the module. Each module implementation will define |
︙ | ︙ |
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 | ** 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.6 2006/06/13 01:04:53 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> /* ** 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); Tcl_SetVar(interp, "echo_module", zArg, flags); } static void appendToEchoTable(Tcl_Interp *interp, const char *zArg){ int flags = (TCL_APPEND_VALUE | TCL_LIST_ELEMENT | TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "echo_module", zArg, flags); } /* ** This function is called from within the echo-modules xCreate and ** xConnect methods. The argc and argv arguments are copies of those ** passed to the calling method. This function is responsible for ** calling sqlite3_declare_vtab() to declare the schema of the virtual |
︙ | ︙ | |||
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | rc = SQLITE_ERROR; } sqlite3_finalize(pStmt); } return rc; } /* Methods for the echo module */ static int echoCreate( sqlite3 *db, const sqlite3_module *pModule, int argc, char **argv, sqlite3_vtab **ppVtab ){ int i; | > > > > > > > | > > > > | | | > > > > > | > | | > > > > > > > > > | | 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 | rc = SQLITE_ERROR; } sqlite3_finalize(pStmt); } return rc; } /* An echo vtab object */ typedef struct echo_vtab echo_vtab; struct echo_vtab { sqlite3_vtab base; Tcl_Interp *interp; }; /* Methods for the echo module */ static int echoCreate( 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; appendToEchoModule(pVtab->interp, "xCreate"); for(i=0; i<argc; i++){ appendToEchoModule(pVtab->interp, argv[i]); } echoDeclareVtab(db, argc, argv); return 0; } static int echoConnect( sqlite3 *db, const sqlite3_module *pModule, int argc, char **argv, sqlite3_vtab **ppVtab ){ int i; Tcl_Interp *interp = pModule->pAux; echo_vtab *pVtab; pVtab = sqliteMalloc( sizeof(*pVtab) ); *ppVtab = &pVtab->base; pVtab->base.pModule = pModule; pVtab->interp = pModule->pAux; Tcl_SetVar(interp, "echo_module", "xConnect", TCL_GLOBAL_ONLY); for(i=0; i<argc; i++){ Tcl_SetVar(interp, "echo_module", argv[i], TCL_APPEND_VALUE | TCL_LIST_ELEMENT | TCL_GLOBAL_ONLY); } echoDeclareVtab(db, argc, argv); return 0; } static int echoDisconnect(sqlite3_vtab *pVtab){ echo_vtab *p = (echo_vtab*)pVtab; appendToEchoTable(p->interp, "xDisconnect"); sqliteFree(pVtab); return 0; } static int echoDestroy(sqlite3_vtab *pVtab){ echo_vtab *p = (echo_vtab*)pVtab; Tcl_SetVar(p->interp, "echo_module", "xDestroy", TCL_APPEND_VALUE | TCL_LIST_ELEMENT | TCL_GLOBAL_ONLY); return 0; } /* ** 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; return SQLITE_OK; } /* ** A virtual table module that merely echos method calls into TCL ** variables. */ static sqlite3_module echoModule = { 0, /* iVersion */ "echo", /* zName */ 0, /* pAux */ echoCreate, echoConnect, echoBestIndex, echoDisconnect, echoDestroy, }; /* ** Decode a pointer to an sqlite3 object. */ |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** ** $Id: vdbe.h,v 1.104 2006/06/13 01:04:53 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines |
︙ | ︙ | |||
66 67 68 69 70 71 72 73 74 75 76 77 78 79 | #define P3_STATIC (-2) /* Pointer to a static string */ #define P3_COLLSEQ (-4) /* P3 is a pointer to a CollSeq structure */ #define P3_FUNCDEF (-5) /* P3 is a pointer to a FuncDef structure */ #define P3_KEYINFO (-6) /* P3 is a pointer to a KeyInfo structure */ #define P3_VDBEFUNC (-7) /* P3 is a pointer to a VdbeFunc structure */ #define P3_MEM (-8) /* P3 is a pointer to a Mem* structure */ #define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */ /* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure ** is made. That copy is freed when the Vdbe is finalized. But if the ** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used. It still ** gets freed when the Vdbe is finalized so it still should be obtained ** from a single sqliteMalloc(). But no copy is made and the calling ** function should *not* try to free the KeyInfo. | > | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #define P3_STATIC (-2) /* Pointer to a static string */ #define P3_COLLSEQ (-4) /* P3 is a pointer to a CollSeq structure */ #define P3_FUNCDEF (-5) /* P3 is a pointer to a FuncDef structure */ #define P3_KEYINFO (-6) /* P3 is a pointer to a KeyInfo structure */ #define P3_VDBEFUNC (-7) /* P3 is a pointer to a VdbeFunc structure */ #define P3_MEM (-8) /* P3 is a pointer to a Mem* structure */ #define P3_TRANSIENT (-9) /* P3 is a pointer to a transient string */ #define P3_VTAB (-10) /* P3 is a pointer to an sqlite3_vtab structure */ /* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure ** is made. That copy is freed when the Vdbe is finalized. But if the ** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used. It still ** gets freed when the Vdbe is finalized so it still should be obtained ** from a single sqliteMalloc(). But no copy is made and the calling ** function should *not* try to free the KeyInfo. |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
554 555 556 557 558 559 560 | CollSeq *pColl = (CollSeq*)pOp->p3; sprintf(zTemp, "collseq(%.20s)", pColl->zName); zP3 = zTemp; break; } case P3_FUNCDEF: { FuncDef *pDef = (FuncDef*)pOp->p3; | < < | < | > | > > > > > | 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 | CollSeq *pColl = (CollSeq*)pOp->p3; sprintf(zTemp, "collseq(%.20s)", pColl->zName); zP3 = zTemp; break; } case P3_FUNCDEF: { FuncDef *pDef = (FuncDef*)pOp->p3; sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg); zP3 = zTemp; break; } #ifndef SQLITE_OMIT_VIRTUALTABLE case P3_VTAB: { sqlite3_vtab *pVtab = (sqlite3_vtab*)pOp->p3; sqlite3_snprintf(nTemp, zTemp, "%p:%s", pVtab, pVtab->pModule->zName); zP3 = zTemp; break; } #endif default: { zP3 = pOp->p3; if( zP3==0 || pOp->opcode==OP_Noop ){ zP3 = ""; } } } |
︙ | ︙ |
Changes to src/where.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is reponsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.212 2006/06/13 01:04:53 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
1006 1007 1008 1009 1010 1011 1012 | } memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); pIdxInfo->idxNum = 0; pIdxInfo->orderByConsumed = 0; pIdxInfo->estimatedCost = SQLITE_BIG_DBL; nOrderBy = pIdxInfo->nOrderBy; if( pIdxInfo->nOrderBy && !orderByUsable ){ | | | | 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 | } memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); pIdxInfo->idxNum = 0; pIdxInfo->orderByConsumed = 0; pIdxInfo->estimatedCost = SQLITE_BIG_DBL; nOrderBy = pIdxInfo->nOrderBy; if( pIdxInfo->nOrderBy && !orderByUsable ){ *(int*)&pIdxInfo->nOrderBy = 0; } pTab->pVtab->pModule->xBestIndex(pTab->pVtab, pIdxInfo); *(int*)&pIdxInfo->nOrderBy = nOrderBy; return pIdxInfo->estimatedCost; } #endif /* SQLITE_OMIT_VIRTUALTABLE */ /* ** Find the best index for accessing a particular table. Return a pointer ** to the index, flags that describe how the index should be used, the |
︙ | ︙ | |||
1766 1767 1768 1769 1770 1771 1772 | #endif /* SQLITE_OMIT_EXPLAIN */ pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); if( pTab->isEphem || pTab->pSelect ) continue; #ifndef SQLITE_OMIT_VIRTUALTABLE if( pLevel->pIdxInfo ){ | | | 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 | #endif /* SQLITE_OMIT_EXPLAIN */ pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); if( pTab->isEphem || pTab->pSelect ) continue; #ifndef SQLITE_OMIT_VIRTUALTABLE if( pLevel->pIdxInfo ){ sqlite3VdbeOp3(v, OP_VOpen, 0, 0, (const char*)pTab->pVtab, P3_VTAB); }else #endif if( (pLevel->flags & WHERE_IDX_ONLY)==0 ){ sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, OP_OpenRead); if( pTab->nCol<(sizeof(Bitmask)*8) ){ Bitmask b = pTabItem->colUsed; int n = 0; |
︙ | ︙ | |||
1851 1852 1853 1854 1855 1856 1857 | if( pIdxInfo->aConstraintUsage[j].argvIndex==i ){ sqlite3ExprCode(pParse, wc.a[j].pExpr->pRight); break; } } if( j==pIdxInfo->nConstraint ) break; } | | | | < > > | 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 | if( pIdxInfo->aConstraintUsage[j].argvIndex==i ){ sqlite3ExprCode(pParse, wc.a[j].pExpr->pRight); break; } } if( j==pIdxInfo->nConstraint ) break; } sqlite3VdbeAddOp(v, OP_Integer, i-1, 0); sqlite3VdbeAddOp(v, OP_Integer, pIdxInfo->idxNum, 0); sqlite3VdbeAddOp(v, OP_VFilter, iCur, brk); for(i=0; i<pIdxInfo->nConstraint; i++){ if( pIdxInfo->aConstraintUsage[i].omit ){ disableTerm(pLevel, &wc.a[i]); } } pLevel->op = OP_VNext; pLevel->p1 = iCur; pLevel->p2 = sqlite3VdbeCurrentAddr(v); }else #endif /* SQLITE_OMIT_VIRTUALTABLE */ if( pLevel->flags & WHERE_ROWID_EQ ){ /* Case 1: We can directly reference a single row using an ** equality comparison against the ROWID field. Or ** we reference multiple rows using a "rowid IN (...)" |
︙ | ︙ |