Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add missing comments and fix other code issues in the new functions in callback.c. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | reuse-schema |
Files: | files | file ages | folders |
SHA3-256: |
441cabb62fe14bbef8b19066941426ee |
User & Date: | dan 2019-02-14 15:47:18.706 |
Context
2019-02-14
| ||
15:56 | Merge latest trunk into this branch. (check-in: 577d163836 user: dan tags: reuse-schema) | |
15:47 | Add missing comments and fix other code issues in the new functions in callback.c. (check-in: 441cabb62f user: dan tags: reuse-schema) | |
2019-02-13
| ||
19:17 | Fix for sqlite3_table_column_metadata() on REUSE_SCHEMA databases. (check-in: 53220ad780 user: dan tags: reuse-schema) | |
Changes
Changes to src/callback.c.
︙ | ︙ | |||
538 539 540 541 542 543 544 545 546 547 548 | /* ** Global linked list of SchemaPool objects. Read and write access must ** be protected by the SQLITE_MUTEX_STATIC_MASTER mutex. */ static SchemaPool *SQLITE_WSD schemaPoolList = 0; #ifdef SQLITE_TEST SchemaPool *sqlite3SchemaPoolList(void){ return schemaPoolList; } #endif /* | > > > > | | > > > > > > > > > > > > > > > > | 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 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 580 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 608 609 610 | /* ** Global linked list of SchemaPool objects. Read and write access must ** be protected by the SQLITE_MUTEX_STATIC_MASTER mutex. */ static SchemaPool *SQLITE_WSD schemaPoolList = 0; #ifdef SQLITE_TEST /* ** Return a pointer to the head of the linked list of SchemaPool objects. ** This is used by the virtual table in file test_schemapool.c. */ SchemaPool *sqlite3SchemaPoolList(void){ return schemaPoolList; } #endif /* ** Check that the schema of db iDb is writable (either because it is the ** temp db schema or because the db handle was opened without ** SQLITE_OPEN_REUSE_SCHEMA). If so, do nothing. Otherwise, leave an ** error in the Parse object. */ void sqlite3SchemaWritable(Parse *pParse, int iDb){ if( iDb!=1 && (pParse->db->openFlags & SQLITE_OPEN_REUSE_SCHEMA) && IN_DECLARE_VTAB==0 ){ sqlite3ErrorMsg(pParse, "attempt to modify read-only schema"); } } /* ** The schema object passed as the only argument was allocated using ** sqlite3_malloc() and then populated using the usual mechanism. This ** function frees both the Schema object and its contents. */ static void schemaDelete(Schema *pSchema){ sqlite3SchemaClear((void*)pSchema); sqlite3_free(pSchema); } /* ** When this function is called, the database connection Db must be ** using a schema-pool (Db.pSPool!=0) and must currently have Db.pSchema ** set to point to a populated schema object checked out from the ** schema-pool. It is also assumed that the STATIC_MASTER mutex is held. ** This function returns the Schema object to the schema-pool and sets ** Db.pSchema to point to the schema-pool's static, empty, Schema object. */ static void schemaRelease(Db *pDb){ assert( pDb->pSPool && pDb->pSchema ); assert( pDb->pSchema->schemaFlags & DB_SchemaLoaded ); assert( sqlite3_mutex_held(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)) ); pDb->pSchema->pNext = pDb->pSPool->pSchema; pDb->pSPool->pSchema = pDb->pSchema; pDb->pSchema = &pDb->pSPool->sSchema; assert( (pDb->pSchema->schemaFlags & DB_SchemaLoaded)==0 ); } /* ** The schema for database iDb of database handle db, which was opened ** with SQLITE_OPEN_REUSE_SCHEMA, has just been parsed. This function either ** finds a matching SchemaPool object on the global list (schemaPoolList) or ** else allocates a new one and sets the Db.pSPool variable accordingly. ** ** SQLITE_OK is returned if no error occurs, or an SQLite error code ** (SQLITE_NOMEM) otherwise. */ int sqlite3SchemaConnect(sqlite3 *db, int iDb, u64 cksum){ Schema *pSchema = db->aDb[iDb].pSchema; SchemaPool *p; assert( pSchema && iDb!=1 && db->aDb[iDb].pSPool==0 ); |
︙ | ︙ | |||
625 626 627 628 629 630 631 632 633 634 635 636 637 638 | sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); db->aDb[iDb].pSPool = p; return (p ? SQLITE_OK : SQLITE_NOMEM); } int sqlite3SchemaDisconnect(sqlite3 *db, int iDb, int bNew){ int rc = SQLITE_OK; if( IsReuseSchema(db) && iDb!=1 ){ Db *pDb = &db->aDb[iDb]; SchemaPool *pSPool = pDb->pSPool; assert_schema_state_ok(db); assert( pDb->pSchema ); | > > > > > > > > > > > > > > > | 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 671 672 673 | sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); db->aDb[iDb].pSPool = p; return (p ? SQLITE_OK : SQLITE_NOMEM); } /* ** If parameter iDb is 1 (the temp db), or if connection handle db was not ** opened with the SQLITE_OPEN_REUSE_SCHEMA flag, this function is a no-op. ** Otherwise, it disconnects from the schema-pool associated with database ** iDb, assuming it is connected. ** ** If parameter bNew is true, then Db.pSchema is set to point to a new, empty, ** Schema object obtained from sqlite3_malloc(). Or, if bNew is false, then ** Db.pSchema is set to NULL before returning. ** ** If the bNew parameter is true, then this function may allocate memory. ** If the allocation attempt fails, then SQLITE_NOMEM is returned and the ** schema-pool is not disconnected from. Or, if no OOM error occurs, ** SQLITE_OK is returned. */ int sqlite3SchemaDisconnect(sqlite3 *db, int iDb, int bNew){ int rc = SQLITE_OK; if( IsReuseSchema(db) && iDb!=1 ){ Db *pDb = &db->aDb[iDb]; SchemaPool *pSPool = pDb->pSPool; assert_schema_state_ok(db); assert( pDb->pSchema ); |
︙ | ︙ | |||
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 | pRet->pNext = 0; } sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); } return pRet; } void sqlite3SchemaReleaseAll(sqlite3 *db){ int i; assert_schema_state_ok(db); sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); for(i=0; i<db->nDb; i++){ if( i!=1 ){ Db *pDb = &db->aDb[i]; if( pDb->pSPool && DbHasProperty(db,i,DB_SchemaLoaded) ){ schemaRelease(pDb); } } } sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); } void sqlite3SchemaRelease(sqlite3 *db, int iDb){ Db *pDb = &db->aDb[iDb]; assert( iDb!=1 ); assert_schema_state_ok(db); sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); if( pDb->pSPool && DbHasProperty(db, iDb, DB_SchemaLoaded) ){ schemaRelease(pDb); } sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); } /* | > > > > > > > > > > | | > > > | 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 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 | pRet->pNext = 0; } sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); } return pRet; } /* ** Return all sharable schemas held by database handle db back to their ** respective schema-pools. Db.pSchema variables are left pointing to ** the static, empty, Schema object owned by each schema-pool. */ void sqlite3SchemaReleaseAll(sqlite3 *db){ int i; assert_schema_state_ok(db); sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); for(i=0; i<db->nDb; i++){ if( i!=1 ){ Db *pDb = &db->aDb[i]; if( pDb->pSPool && DbHasProperty(db,i,DB_SchemaLoaded) ){ schemaRelease(pDb); } } } sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); } /* ** Release any sharable schema held by connection iDb of database handle ** db. Db.pSchema is left pointing to the static, empty, Schema object ** owned by the schema-pool. */ void sqlite3SchemaRelease(sqlite3 *db, int iDb){ Db *pDb = &db->aDb[iDb]; assert( iDb!=1 ); assert_schema_state_ok(db); sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); if( pDb->pSPool && DbHasProperty(db, iDb, DB_SchemaLoaded) ){ schemaRelease(pDb); } sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); } /* ** In most cases, this function finds and returns the schema associated ** with BTree handle pBt, creating a new one if necessary. However, if ** the database handle was opened with the SQLITE_OPEN_REUSE_SCHEMA flag ** specified, a new, empty, Schema object in memory obtained by ** sqlite3_malloc() is always returned. */ Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ Schema *p; if( pBt && (db->openFlags & SQLITE_OPEN_REUSE_SCHEMA)==0 ){ p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); }else{ p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema)); |
︙ | ︙ |
Changes to test/reuse1.test.
︙ | ︙ | |||
84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 4 { ALTER TABLE t1 RENAME TO t3 } 5 { ALTER TABLE t1 ADD COLUMN xyz } 6 { VACUUM } 7 { DROP INDEX i1 } 8 { DROP TABLE t1 } 9 { DROP TRIGGER tr1 } 10 { ANALYZE } } { do_catchsql_test 1.5.$tn $sql {1 {attempt to modify read-only schema}} } #------------------------------------------------------------------------- # reset_db | > | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | 4 { ALTER TABLE t1 RENAME TO t3 } 5 { ALTER TABLE t1 ADD COLUMN xyz } 6 { VACUUM } 7 { DROP INDEX i1 } 8 { DROP TABLE t1 } 9 { DROP TRIGGER tr1 } 10 { ANALYZE } 11 { ALTER TABLE t1 RENAME z TO zzz } } { do_catchsql_test 1.5.$tn $sql {1 {attempt to modify read-only schema}} } #------------------------------------------------------------------------- # reset_db |
︙ | ︙ |