Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch fts3-int-cursor Excluding Merge-Ins
This is equivalent to a diff from 62a86aa6c0 to f4f7196b87
2017-07-17
| ||
20:25 | Enhance error detection and fix other issues in unionvtab code. (check-in: 9c3f1b9a82 user: dan tags: union-vtab) | |
09:30 | Use integer handles for fts3 cursors for a small performance improvement. (Closed-Leaf check-in: f4f7196b87 user: dan tags: union-vtab, fts3-int-cursor) | |
2017-07-15
| ||
20:48 | Add the "unionvtab" virtual table extension in ext/misc/unionvtab.c. (check-in: 62a86aa6c0 user: dan tags: union-vtab) | |
20:33 | Fix a register allocation problem in PRAGMA integrity_check that caused the same register to be used for two different purposes on the first ATTACHed database if the schema for the ATTACHed database was noticable more complex than the schema for the first database. Fix for ticket [a4e06e75a9ab61a1]. (check-in: 253945d480 user: drh tags: trunk) | |
Changes to ext/fts3/fts3.c.
︙ | ︙ | |||
304 305 306 307 308 309 310 311 312 313 314 315 316 317 | #include "fts3.h" #ifndef SQLITE_CORE # include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #endif static int fts3EvalNext(Fts3Cursor *pCsr); static int fts3EvalStart(Fts3Cursor *pCsr); static int fts3TermSegReaderCursor( Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **); #ifndef SQLITE_AMALGAMATION # if defined(SQLITE_DEBUG) | > > > > > > > > | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | #include "fts3.h" #ifndef SQLITE_CORE # include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #endif /* ** GCC does not define the offsetof() macro so we'll have to do it ** ourselves. This definition was copied from sqlite3Int.h. */ #ifndef offsetof #define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) #endif static int fts3EvalNext(Fts3Cursor *pCsr); static int fts3EvalStart(Fts3Cursor *pCsr); static int fts3TermSegReaderCursor( Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **); #ifndef SQLITE_AMALGAMATION # if defined(SQLITE_DEBUG) |
︙ | ︙ | |||
1667 1668 1669 1670 1671 1672 1673 | return SQLITE_OK; } /* ** Implementation of xOpen method. */ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ | > | < < | > > > > > > > | 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 | return SQLITE_OK; } /* ** Implementation of xOpen method. */ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ Fts3Table *p = (Fts3Table *)pVTab; Fts3Cursor *pCsr; /* Allocated cursor */ /* Allocate a buffer large enough for an Fts3Cursor structure. If the ** allocation succeeds, zero it and return SQLITE_OK. Otherwise, ** if the allocation fails, return SQLITE_NOMEM. */ pCsr = (Fts3Cursor*)sqlite3_malloc(sizeof(Fts3Cursor)); *ppCsr = (sqlite3_vtab_cursor*)pCsr; if( !pCsr ){ return SQLITE_NOMEM; } memset(pCsr, 0, sizeof(Fts3Cursor)); /* Link the new cursor into the linked list at Fts3Table.pCsr. */ pCsr->pNext = p->pAllCsr; p->pAllCsr = pCsr; pCsr->iId = ++p->iLastCsrId; return SQLITE_OK; } /* ** Finalize the statement handle at pCsr->pStmt. ** ** Or, if that statement handle is one created by fts3CursorSeekStmt(), |
︙ | ︙ | |||
1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 | } /* ** Free all resources currently held by the cursor passed as the only ** argument. */ static void fts3ClearCursor(Fts3Cursor *pCsr){ fts3CursorFinalizeStmt(pCsr); sqlite3Fts3FreeDeferredTokens(pCsr); sqlite3_free(pCsr->aDoclist); sqlite3Fts3MIBufferFree(pCsr->pMIBuffer); sqlite3Fts3ExprFree(pCsr->pExpr); | > | > | > | | > > | 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 | } /* ** Free all resources currently held by the cursor passed as the only ** argument. */ static void fts3ClearCursor(Fts3Cursor *pCsr){ const int nZero = sizeof(Fts3Cursor)-offsetof(Fts3Cursor,eSearch); fts3CursorFinalizeStmt(pCsr); sqlite3Fts3FreeDeferredTokens(pCsr); sqlite3_free(pCsr->aDoclist); sqlite3Fts3MIBufferFree(pCsr->pMIBuffer); sqlite3Fts3ExprFree(pCsr->pExpr); memset((void*)&pCsr->eSearch, 0, nZero); } /* ** Close the cursor. For additional information see the documentation ** on the xClose method of the virtual table interface. */ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){ Fts3Table *p = (Fts3Table*)pCursor->pVtab; Fts3Cursor *pCsr = (Fts3Cursor*)pCursor; Fts3Cursor **pp; assert( p->pSegments==0 ); fts3ClearCursor(pCsr); assert( p->pSegments==0 ); for(pp=&p->pAllCsr; (*pp)!=pCsr; pp=&(*pp)->pNext); *pp = 0; sqlite3_free(pCsr); return SQLITE_OK; } /* ** If pCsr->pStmt has not been prepared (i.e. if pCsr->pStmt==0), then ** compose and prepare an SQL statement of the form: |
︙ | ︙ | |||
3349 3350 3351 3352 3353 3354 3355 | /* The column value supplied by SQLite must be in range. */ assert( iCol>=0 && iCol<=p->nColumn+2 ); switch( iCol-p->nColumn ){ case 0: /* The special 'table-name' column */ | | | 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 | /* The column value supplied by SQLite must be in range. */ assert( iCol>=0 && iCol<=p->nColumn+2 ); switch( iCol-p->nColumn ){ case 0: /* The special 'table-name' column */ sqlite3_result_int(pCtx, pCsr->iId); break; case 1: /* The docid column */ sqlite3_result_int64(pCtx, pCsr->iPrevId); break; |
︙ | ︙ | |||
3567 3568 3569 3570 3571 3572 3573 | */ static int fts3FunctionArg( sqlite3_context *pContext, /* SQL function call context */ const char *zFunc, /* Function name */ sqlite3_value *pVal, /* argv[0] passed to function */ Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ ){ | | > > | > | > > > | | > | 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 | */ static int fts3FunctionArg( sqlite3_context *pContext, /* SQL function call context */ const char *zFunc, /* Function name */ sqlite3_value *pVal, /* argv[0] passed to function */ Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ ){ int rc = SQLITE_OK; int iId; Fts3Table *p = (Fts3Table*)sqlite3_user_data(pContext); iId = sqlite3_value_int(pVal); Fts3Cursor *pRet; for(pRet=p->pAllCsr; pRet; pRet=pRet->pNext){ if( pRet->iId==iId ) break; } *ppCsr = pRet; if( pRet==0 ){ char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); sqlite3_result_error(pContext, zErr, -1); sqlite3_free(zErr); rc = SQLITE_ERROR; } return rc; } |
︙ | ︙ | |||
3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 | UNUSED_PARAMETER(pVtab); UNUSED_PARAMETER(nArg); UNUSED_PARAMETER(ppArg); for(i=0; i<SizeofArray(aOverload); i++){ if( strcmp(zName, aOverload[i].zName)==0 ){ *pxFunc = aOverload[i].xFunc; return 1; } } /* No function of the specified name was found. Return 0. */ return 0; } | > | 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 | UNUSED_PARAMETER(pVtab); UNUSED_PARAMETER(nArg); UNUSED_PARAMETER(ppArg); for(i=0; i<SizeofArray(aOverload); i++){ if( strcmp(zName, aOverload[i].zName)==0 ){ *pxFunc = aOverload[i].xFunc; *ppArg = (void*)pVtab; return 1; } } /* No function of the specified name was found. Return 0. */ return 0; } |
︙ | ︙ |
Changes to ext/fts3/fts3Int.h.
︙ | ︙ | |||
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | #endif #ifdef SQLITE_TEST /* True to disable the incremental doclist optimization. This is controled ** by special insert command 'test-no-incr-doclist'. */ int bNoIncrDoclist; #endif }; /* ** When the core wants to read from the virtual table, it creates a ** virtual table cursor (an instance of the following structure) using ** the xOpen method. Cursors are destroyed using the xClose method. */ struct Fts3Cursor { sqlite3_vtab_cursor base; /* Base class used by SQLite core */ i16 eSearch; /* Search strategy (see below) */ u8 isEof; /* True if at End Of Results */ u8 isRequireSeek; /* True if must seek pStmt to %_content row */ u8 bSeekStmt; /* True if pStmt is a seek */ sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ Fts3Expr *pExpr; /* Parsed MATCH query string */ int iLangid; /* Language being queried for */ | > > > > > > > > | 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 | #endif #ifdef SQLITE_TEST /* True to disable the incremental doclist optimization. This is controled ** by special insert command 'test-no-incr-doclist'. */ int bNoIncrDoclist; #endif Fts3Cursor *pAllCsr; /* List of all open cursors */ int iLastCsrId; /* Last cursor id assigned (or 0) */ }; /* ** When the core wants to read from the virtual table, it creates a ** virtual table cursor (an instance of the following structure) using ** the xOpen method. Cursors are destroyed using the xClose method. */ struct Fts3Cursor { sqlite3_vtab_cursor base; /* Base class used by SQLite core */ int iId; /* Numeric id of this cursor */ Fts3Cursor *pNext; /* Next in list of all cursors */ /* Variables below this point are zeroed by fts3ClearCursor() */ i16 eSearch; /* Search strategy (see below) */ u8 isEof; /* True if at End Of Results */ u8 isRequireSeek; /* True if must seek pStmt to %_content row */ u8 bSeekStmt; /* True if pStmt is a seek */ sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ Fts3Expr *pExpr; /* Parsed MATCH query string */ int iLangid; /* Language being queried for */ |
︙ | ︙ |