Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | When a connection disconnects from a shared-cache database, only delete the in-memory schema if there are no other connections. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | shared-schema |
Files: | files | file ages | folders |
SHA1: |
46f4eb5430d7bc9a339cdf7124ff4bd5 |
User & Date: | dan 2012-05-15 17:15:34.812 |
Context
2012-05-15
| ||
18:28 | The former sqlite3ResetInternalSchema() routine was really two different routines, selected by parameter, each with a confused mission. So split this routine up into three separate smaller routines, calling each separately as needed. Hopefully this will make further refactoring and schema reset collateral damage containment easier. (check-in: aa0c3493d3 user: drh tags: shared-schema) | |
17:15 | When a connection disconnects from a shared-cache database, only delete the in-memory schema if there are no other connections. (check-in: 46f4eb5430 user: dan tags: shared-schema) | |
12:49 | Add assert()s to verify that Table objects in the schema never use lookaside memory. (check-in: 736d6ea677 user: drh tags: trunk) | |
Changes
Changes to src/main.c.
︙ | |||
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 | 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 | + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + | pDestructor->nRef--; if( pDestructor->nRef==0 ){ pDestructor->xDestroy(pDestructor->pUserData); sqlite3DbFree(db, pDestructor); } } } /* ** Disconnect all sqlite3_vtab objects that belong to database connection ** db. This is called when db is being closed. */ static void disconnectAllVtab(sqlite3 *db){ #ifndef SQLITE_OMIT_VIRTUALTABLE int i; sqlite3BtreeEnterAll(db); for(i=0; i<db->nDb; i++){ Schema *pSchema = db->aDb[i].pSchema; if( db->aDb[i].pSchema ){ HashElem *p; for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ Table *pTab = (Table *)sqliteHashData(p); if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); } } } sqlite3BtreeLeaveAll(db); #else UNUSED_PARAMETER(db); #endif } /* ** Close an existing SQLite database */ int sqlite3_close(sqlite3 *db){ HashElem *i; /* Hash table iterator */ int j; if( !db ){ return SQLITE_OK; } if( !sqlite3SafetyCheckSickOrOk(db) ){ return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(db->mutex); |
︙ | |||
775 776 777 778 779 780 781 782 783 784 785 786 787 788 | 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 | + + + + + - - | sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; if( j!=1 ){ pDb->pSchema = 0; } } } /* This call frees the schema associated with the temp database only (if ** any). It also frees the db->aDb array, if required. */ sqlite3ResetInternalSchema(db, -1); assert( db->nDb<=2 ); assert( db->aDb==db->aDbStatic ); /* Tell the code in notify.c that the connection no longer holds any ** locks and does not require any further unlock-notify callbacks. */ sqlite3ConnectionClosed(db); |
︙ |
Changes to src/sqliteInt.h.
︙ | |||
3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 | 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 | + | # define sqlite3VtabLock(X) # define sqlite3VtabUnlock(X) # define sqlite3VtabUnlockList(X) # define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK # define sqlite3GetVTable(X,Y) ((VTable*)0) #else void sqlite3VtabClear(sqlite3 *db, Table*); void sqlite3VtabDisconnect(sqlite3 *db, Table *p); int sqlite3VtabSync(sqlite3 *db, char **); int sqlite3VtabRollback(sqlite3 *db); int sqlite3VtabCommit(sqlite3 *db); void sqlite3VtabLock(VTable *); void sqlite3VtabUnlock(VTable *); void sqlite3VtabUnlockList(sqlite3*); int sqlite3VtabSavepoint(sqlite3 *, int, int); |
︙ |
Changes to src/vtab.c.
︙ | |||
175 176 177 178 179 180 181 182 183 184 185 186 187 188 | 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 | + + + + + + + + + + + + + + + + + + + + + + + + + | } pVTable = pNext; } assert( !db || pRet ); return pRet; } /* ** Table *p is a virtual table. This function removes the VTable object ** for table *p associated with database connection db from the linked ** list in p->pVTab. It also decrements the VTable ref count. This is ** used when closing database connection db to free all of its VTable ** objects without disturbing the rest of the Schema object (which may ** be being used by other shared-cache connections). */ void sqlite3VtabDisconnect(sqlite3 *db, Table *p){ VTable **ppVTab; assert( IsVirtual(p) ); assert( sqlite3BtreeHoldsAllMutexes(db) ); assert( sqlite3_mutex_held(db->mutex) ); for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){ if( (*ppVTab)->db==db ){ VTable *pVTab = *ppVTab; *ppVTab = pVTab->pNext; sqlite3VtabUnlock(pVTab); break; } } } /* ** Disconnect all the virtual table objects in the sqlite3.pDisconnect list. ** ** This function may only be called when the mutexes associated with all ** shared b-tree databases opened using connection db are held by the |
︙ |
Changes to test/capi3.test.
︙ | |||
645 646 647 648 649 650 651 652 653 | 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 | + + + + - + - + + | set STMT [sqlite3_prepare $DB $sql -1 TAIL] expr 0 } {0} do_test capi3-6.1 { db cache flush sqlite3_close $DB } {SQLITE_BUSY} # 6.2 and 6.3 used to return SQLITE_ERROR and SQLITE_SCHEMA, respectively. # But since attempting to close a connection no longer resets the internal # schema and expires all statements, this is no longer the case. do_test capi3-6.2 { sqlite3_step $STMT |
︙ |
Added test/shared8.test.