Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix virtual table support for SQLITE_OPEN_REUSABLE_SCHEMA connections. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | reuse-schema |
Files: | files | file ages | folders |
SHA3-256: |
3ca8856a7b1c36885cea007b8fb05b59 |
User & Date: | dan 2019-02-09 17:47:14.573 |
Context
2019-02-11
| ||
19:34 | Add eponymous virtual table "schemapool". For inspecting the current contents of the schema-pool. (check-in: 2ebeb74783 user: dan tags: reuse-schema) | |
2019-02-09
| ||
17:47 | Fix virtual table support for SQLITE_OPEN_REUSABLE_SCHEMA connections. (check-in: 3ca8856a7b user: dan tags: reuse-schema) | |
2019-02-08
| ||
19:30 | Add test cases and fix problems on this branch. (check-in: 2b2e9f81cd user: dan tags: reuse-schema) | |
Changes
Changes to src/callback.c.
︙ | |||
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 | 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 | + + + + + + + + | if( IsReuseSchema(db) && iDb!=1 ){ Db *pDb = &db->aDb[iDb]; SchemaPool *pSPool = pDb->pSPool; assert_schema_state_ok(db); assert( pDb->pSchema ); if( pSPool==0 ){ assert( pDb->pVTable==0 ); if( bNew==0 ){ schemaDelete(pDb->pSchema); pDb->pSchema = 0; } }else{ VTable *p; VTable *pNext; for(p=pDb->pVTable; p; p=pNext){ pNext = p->pNext; sqlite3VtabUnlock(p); } pDb->pVTable = 0; sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); if( DbHasProperty(db, iDb, DB_SchemaLoaded) ){ schemaRelease(pDb); } if( bNew ){ Schema *pNew = sqlite3SchemaGet(db, 0); if( pNew==0 ){ |
︙ | |||
706 707 708 709 710 711 712 | 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 | - + | } /* ** Find and return the schema associated with a BTree. Create ** a new one if necessary. */ Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ |
︙ |
Changes to src/main.c.
︙ | |||
1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 | 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 | + + + + + + + + + | for(i=0; i<db->nDb; i++){ Schema *pSchema = db->aDb[i].pSchema; if( pSchema ){ for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ Table *pTab = (Table *)sqliteHashData(p); if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); } } if( i!=1 && IsReuseSchema(db) ){ VTable *pVTable; VTable *pNext; for(pVTable=db->aDb[i].pVTable; pVTable; pVTable=pNext){ pNext = pVTable->pNext; sqlite3VtabUnlock(pVTable); } db->aDb[i].pVTable = 0; } } for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){ Module *pMod = (Module *)sqliteHashData(p); if( pMod->pEpoTab ){ sqlite3VtabDisconnect(db, pMod->pEpoTab); } |
︙ |
Changes to src/sqliteInt.h.
︙ | |||
1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 | 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 | + | struct Db { char *zDbSName; /* Name of this database. (schema name, not filename) */ Btree *pBt; /* The B*Tree structure for this database file */ u8 safety_level; /* How aggressive at syncing data to disk */ u8 bSyncSet; /* True if "PRAGMA synchronous=N" has been run */ Schema *pSchema; /* Pointer to database schema (possibly shared) */ SchemaPool *pSPool; /* For REUSE_SCHEMA mode */ VTable *pVTable; /* List of all VTable objects (REUSE_SCHEMA mode only) */ }; /* ** An instance of the following structure stores a database schema. ** ** Most Schema objects are associated with a Btree. The exception is ** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing. |
︙ | |||
1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 | 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 | + | sqlite3 *db; /* Database connection associated with this table */ Module *pMod; /* Pointer to module implementation */ sqlite3_vtab *pVtab; /* Pointer to vtab instance */ int nRef; /* Number of pointers to this structure */ u8 bConstraint; /* True if constraints are supported */ int iSavepoint; /* Depth of the SAVEPOINT stack */ VTable *pNext; /* Next in linked list (see above) */ char *zName; /* Table name (REUSE_SCHEMA mode) */ }; /* ** The schema for each SQL table and view is represented in memory ** by an instance of the following structure. */ struct Table { |
︙ |
Changes to src/vtab.c.
︙ | |||
140 141 142 143 144 145 146 147 148 149 150 151 152 153 | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | + + + + + + + + + | ** pTab is a pointer to a Table structure representing a virtual-table. ** Return a pointer to the VTable object used by connection db to access ** this virtual-table, if one has been created, or NULL otherwise. */ VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){ VTable *pVtab; assert( IsVirtual(pTab) ); if( IsReuseSchema(db) ){ int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); if( iDb!=1 ){ for(pVtab=db->aDb[iDb].pVTable; pVtab; pVtab=pVtab->pNext){ if( sqlite3StrICmp(pTab->zName, pVtab->zName)==0 ) break; } return pVtab; } } for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); return pVtab; } /* ** Decrement the ref-count on a virtual table object. When the ref-count ** reaches zero, call the xDisconnect() method to delete the object. |
︙ | |||
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 | 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 | + + - + + + | int rc; const char *const*azArg = (const char *const*)pTab->azModuleArg; int nArg = pTab->nModuleArg; char *zErr = 0; char *zModuleName; int iDb; VtabCtx *pCtx; int nByte; /* Bytes of space to allocate */ /* Check that the virtual-table is not already being initialized */ for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){ if( pCtx->pTab==pTab ){ *pzErr = sqlite3MPrintf(db, "vtable constructor called recursively: %s", pTab->zName ); return SQLITE_LOCKED; } } zModuleName = sqlite3DbStrDup(db, pTab->zName); if( !zModuleName ){ return SQLITE_NOMEM_BKPT; } nByte = sizeof(VTable) + sqlite3Strlen30(pTab->zName) + 1; |
︙ | |||
568 569 570 571 572 573 574 | 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 | - - - - - - + + + + + + + + + + + + + | *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); sqlite3VtabUnlock(pVTable); rc = SQLITE_ERROR; }else{ int iCol; u8 oooHidden = 0; /* If everything went according to plan, link the new VTable structure |
︙ |
Changes to test/reuse2.test.
︙ | |||
12 13 14 15 16 17 18 | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | - | # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reuse2 |
︙ | |||
37 38 39 40 41 42 43 44 45 | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | + + + + + + + + + + + + + + + | do_execsql_test -db db2 1.3.2 { INSERT INTO t1 VALUES(4, 5, 6); } do_execsql_test 1.3.3 { SELECT * FROM t1; } {1 2 3 4 5 6} #-------------------------------------------------------------------------- reset_db ifcapable fts5 { do_execsql_test 2.0 { CREATE VIRTUAL TABLE ft USING fts5(c); INSERT INTO ft VALUES('one two three'); } db close sqlite3 db test.db -reuse-schema 1 do_execsql_test 2.1 { SELECT * FROM ft } {{one two three}} } finish_test |