Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Disable the feature on this branch in non-SQLITE_ENABLE_SHARED_SCHEMA builds. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | reuse-schema |
Files: | files | file ages | folders |
SHA3-256: |
b8e536089b0e6dec500a28556f826c99 |
User & Date: | dan 2019-03-21 17:13:55.850 |
Context
2019-03-21
| ||
17:22 | Merge latest trunk changes with this branch. (check-in: 3196f5f480 user: dan tags: reuse-schema) | |
17:13 | Disable the feature on this branch in non-SQLITE_ENABLE_SHARED_SCHEMA builds. (check-in: b8e536089b user: dan tags: reuse-schema) | |
2019-03-20
| ||
20:02 | Use the IsReuseSchema() macro more consistently. Also, rename it to IsSharedSchema(). (check-in: c1be211c02 user: dan tags: reuse-schema) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
282 283 284 285 286 287 288 289 290 291 292 293 294 295 | ** list of users and their access credentials. */ int sqlite3UserAuthTable(const char *zTable){ return sqlite3_stricmp(zTable, "sqlite_user")==0; } #endif /* ** If this database connection was opened with the SQLITE_OPEN_SHARED_SCHEMA ** flag specified, then ensure that the database schema for database iDb ** is loaded. Either by obtaining a Schema object from the schema-pool, or ** by reading the contents of the sqlite_master table. Unless it is NULL, ** the location indicated by parameter pbUnload is set to 1 if a shared-schema ** is loaded. | > | 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | ** list of users and their access credentials. */ int sqlite3UserAuthTable(const char *zTable){ return sqlite3_stricmp(zTable, "sqlite_user")==0; } #endif #ifdef SQLITE_ENABLE_SHARED_SCHEMA /* ** If this database connection was opened with the SQLITE_OPEN_SHARED_SCHEMA ** flag specified, then ensure that the database schema for database iDb ** is loaded. Either by obtaining a Schema object from the schema-pool, or ** by reading the contents of the sqlite_master table. Unless it is NULL, ** the location indicated by parameter pbUnload is set to 1 if a shared-schema ** is loaded. |
︙ | ︙ | |||
312 313 314 315 316 317 318 319 320 321 322 323 324 325 | memset(&db->init, 0, sizeof(struct sqlite3InitInfo)); rc = sqlite3InitOne(db, iDb, pzErr, 0); db->init = sv; if( pbUnload && rc==SQLITE_OK && iDb!=1 ) *pbUnload = 1; } return rc; } /* ** Locate the in-memory structure that describes a particular database ** table given the name of that table and (optionally) the name of the ** database containing the table. Return NULL if not found. ** ** If zDatabase is 0, all databases are searched for the table and the | > | 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | memset(&db->init, 0, sizeof(struct sqlite3InitInfo)); rc = sqlite3InitOne(db, iDb, pzErr, 0); db->init = sv; if( pbUnload && rc==SQLITE_OK && iDb!=1 ) *pbUnload = 1; } return rc; } #endif /* ** Locate the in-memory structure that describes a particular database ** table given the name of that table and (optionally) the name of the ** database containing the table. Return NULL if not found. ** ** If zDatabase is 0, all databases are searched for the table and the |
︙ | ︙ |
Changes to src/callback.c.
︙ | ︙ | |||
36 37 38 39 40 41 42 43 44 45 46 47 48 49 | int nDelete; /* Schema objects deleted by ReleaseAll() */ u64 cksum; /* Checksum for this Schema contents */ Schema *pSchema; /* Linked list of Schema objects */ Schema sSchema; /* The single dummy schema object */ SchemaPool *pNext; /* Next element in schemaPoolList */ }; #ifdef SQLITE_DEBUG static void assert_schema_state_ok(sqlite3 *db){ if( IsSharedSchema(db) && db->magic!=SQLITE_MAGIC_ZOMBIE ){ int i; for(i=0; i<db->nDb; i++){ if( i!=1 ){ Db *pDb = &db->aDb[i]; | > | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | int nDelete; /* Schema objects deleted by ReleaseAll() */ u64 cksum; /* Checksum for this Schema contents */ Schema *pSchema; /* Linked list of Schema objects */ Schema sSchema; /* The single dummy schema object */ SchemaPool *pNext; /* Next element in schemaPoolList */ }; #ifdef SQLITE_ENABLE_SHARED_SCHEMA #ifdef SQLITE_DEBUG static void assert_schema_state_ok(sqlite3 *db){ if( IsSharedSchema(db) && db->magic!=SQLITE_MAGIC_ZOMBIE ){ int i; for(i=0; i<db->nDb; i++){ if( i!=1 ){ Db *pDb = &db->aDb[i]; |
︙ | ︙ | |||
65 66 67 68 69 70 71 72 73 74 75 76 77 78 | } } } } #else # define assert_schema_state_ok(x) #endif /* ** Invoke the 'collation needed' callback to request a collation sequence ** in the encoding enc of name zName, length nName. */ static void callCollNeeded(sqlite3 *db, int enc, const char *zName){ assert( !db->xCollNeeded || !db->xCollNeeded16 ); | > | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | } } } } #else # define assert_schema_state_ok(x) #endif #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ /* ** Invoke the 'collation needed' callback to request a collation sequence ** in the encoding enc of name zName, length nName. */ static void callCollNeeded(sqlite3 *db, int enc, const char *zName){ assert( !db->xCollNeeded || !db->xCollNeeded16 ); |
︙ | ︙ | |||
525 526 527 528 529 530 531 532 533 | ** database iDb. ** ** If an OOM error occurs while disconnecting from a schema-pool, ** the db->mallocFailed flag is set. */ void sqlite3SchemaClearOrDisconnect(sqlite3 *db, int iDb){ Db *pDb = &db->aDb[iDb]; if( IsSharedSchema(db) && iDb!=1 && pDb->pSPool ){ sqlite3SchemaDisconnect(db, iDb, 1); | > | > > > | 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 | ** database iDb. ** ** If an OOM error occurs while disconnecting from a schema-pool, ** the db->mallocFailed flag is set. */ void sqlite3SchemaClearOrDisconnect(sqlite3 *db, int iDb){ Db *pDb = &db->aDb[iDb]; #ifdef SQLITE_ENABLE_SHARED_SCHEMA if( IsSharedSchema(db) && iDb!=1 && pDb->pSPool ){ sqlite3SchemaDisconnect(db, iDb, 1); }else #endif { sqlite3SchemaClear(pDb->pSchema); } } #ifdef SQLITE_ENABLE_SHARED_SCHEMA /* ** 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 |
︙ | ︙ | |||
806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 | assert( iDb!=1 ); assert_schema_state_ok(db); sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); schemaRelease(db, 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_SHARED_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 && IsSharedSchema(db)==0 ){ p = (Schema*)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); }else{ | > > < | < | 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 | assert( iDb!=1 ); assert_schema_state_ok(db); sqlite3_mutex_enter( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); schemaRelease(db, pDb); sqlite3_mutex_leave( sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER) ); } #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ /* ** 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_SHARED_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 && IsSharedSchema(db)==0 ){ p = (Schema*)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); }else{ p = (Schema*)sqlite3DbMallocZero(0, sizeof(Schema)); } if( !p ){ sqlite3OomFault(db); }else if ( 0==p->file_format ){ sqlite3HashInit(&p->tblHash); sqlite3HashInit(&p->idxHash); sqlite3HashInit(&p->trigHash); sqlite3HashInit(&p->fkeyHash); p->enc = SQLITE_UTF8; } return p; } |
Changes to src/main.c.
︙ | ︙ | |||
1050 1051 1052 1053 1054 1055 1056 | 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); } } | > | > | 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 | 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); } } #ifdef SQLITE_ENABLE_SHARED_SCHEMA if( IsSharedSchema(db) && i!=1 ){ VTable *pVTable; VTable *pNext; for(pVTable=db->aDb[i].pVTable; pVTable; pVTable=pNext){ pNext = pVTable->pNext; sqlite3VtabUnlock(pVTable); } db->aDb[i].pVTable = 0; } #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ } for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){ Module *pMod = (Module *)sqliteHashData(p); if( pMod->pEpoTab ){ sqlite3VtabDisconnect(db, pMod->pEpoTab); } } |
︙ | ︙ | |||
3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 | sqlite3BtreeEnterAll(db); if( IsSharedSchema(db)==0 ){ rc = sqlite3Init(db, &zErrMsg); } /* Locate the table in question */ if( rc==SQLITE_OK ){ Parse sParse; /* Fake Parse object for FindTable */ Parse *pSaved = db->pParse; memset(&sParse, 0, sizeof(sParse)); db->pParse = &sParse; pTab = sqlite3FindTable(db, zTableName, zDbName); sqlite3_free(sParse.zErrMsg); rc = sParse.rc; db->pParse = pSaved; } if( SQLITE_OK!=rc ) goto error_out; if( !pTab || pTab->pSelect ){ pTab = 0; goto error_out; } | > > > > | 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 | sqlite3BtreeEnterAll(db); if( IsSharedSchema(db)==0 ){ rc = sqlite3Init(db, &zErrMsg); } /* Locate the table in question */ if( rc==SQLITE_OK ){ #ifdef SQLITE_ENABLE_SHARED_SCHEMA Parse sParse; /* Fake Parse object for FindTable */ Parse *pSaved = db->pParse; memset(&sParse, 0, sizeof(sParse)); db->pParse = &sParse; #endif pTab = sqlite3FindTable(db, zTableName, zDbName); #ifdef SQLITE_ENABLE_SHARED_SCHEMA sqlite3_free(sParse.zErrMsg); rc = sParse.rc; db->pParse = pSaved; #endif } if( SQLITE_OK!=rc ) goto error_out; if( !pTab || pTab->pSelect ){ pTab = 0; goto error_out; } |
︙ | ︙ |
Changes to src/prepare.c.
︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 | z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); *pData->pzErrMsg = z; pData->rc = SQLITE_CORRUPT_BKPT; } } /* ** Update the Schema.cksum checksum to account for the database object ** specified by the three arguments following the first. */ | > | > | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); *pData->pzErrMsg = z; pData->rc = SQLITE_CORRUPT_BKPT; } } #ifdef SQLITE_ENABLE_SHARED_SCHEMA /* ** Update the Schema.cksum checksum to account for the database object ** specified by the three arguments following the first. */ static void schemaUpdateChecksum( InitData *pData, /* Schema parse context */ const char *zName, /* Name of new database object */ const char *zRoot, /* Root page of new database object */ const char *zSql /* SQL used to create new database object */ ){ int i; u64 cksum = pData->cksum; if( zName ){ for(i=0; zName[i]; i++) cksum += (cksum<<3) + zName[i]; } if( zRoot ) for(i=0; zRoot[i]; i++) cksum += (cksum<<3) + zRoot[i]; if( zSql ) for(i=0; zSql[i]; i++) cksum += (cksum<<3) + zSql[i]; pData->cksum = cksum; } #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ /* ** Check to see if any sibling index (another index on the same table) ** of pIndex has the same root page number, and if it does, return true. ** This would indicate a corrupt schema. */ int sqlite3IndexHasDuplicateRootPage(Index *pIndex){ |
︙ | ︙ | |||
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | if( db->init.orphanTrigger ){ assert( iDb==1 ); }else{ pData->rc = rc; if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED && (rc&0xFF)!=SQLITE_IOERR ){ corruptSchema(pData, argv[0], sqlite3_errmsg(db)); } } } sqlite3_finalize(pStmt); }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){ | > > | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | if( db->init.orphanTrigger ){ assert( iDb==1 ); }else{ pData->rc = rc; if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); }else if( rc!=SQLITE_INTERRUPT #ifdef SQLITE_ENABLE_SHARED_SCHEMA && (rc&0xFF)!=SQLITE_LOCKED && (rc&0xFF)!=SQLITE_IOERR #endif ){ corruptSchema(pData, argv[0], sqlite3_errmsg(db)); } } } sqlite3_finalize(pStmt); }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){ |
︙ | ︙ | |||
165 166 167 168 169 170 171 | || pIndex->tnum<2 || sqlite3IndexHasDuplicateRootPage(pIndex) ){ corruptSchema(pData, argv[0], pIndex?"invalid rootpage":"orphan index"); } } | > | > | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | || pIndex->tnum<2 || sqlite3IndexHasDuplicateRootPage(pIndex) ){ corruptSchema(pData, argv[0], pIndex?"invalid rootpage":"orphan index"); } } #ifdef SQLITE_ENABLE_SHARED_SCHEMA if( IsSharedSchema(db) && iDb!=1 ){ schemaUpdateChecksum(pData, argv[0], argv[1], argv[2]); } #endif return 0; } /* ** Attempt to read the database schema and initialize internal ** data structures for a single database file. The index of the ** database file is given by iDb. iDb==0 is used for the main |
︙ | ︙ | |||
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ); assert( iDb>=0 && iDb<db->nDb ); assert( db->aDb[iDb].pSchema || (IsSharedSchema(db) && iDb!=1) ); assert( sqlite3_mutex_held(db->mutex) ); assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); pDb = &db->aDb[iDb]; assert( pDb->pSPool==0 || IsSharedSchema(db) ); if( pDb->pSPool ){ /* See if there is a free schema object in the schema-pool. If not, ** disconnect from said schema pool and continue. This function will ** connect to a (possibly different) schema-pool before returning. */ Schema *pNew = sqlite3SchemaExtract(pDb->pSPool); if( pNew ){ pDb->pSchema = pNew; return SQLITE_OK; } rc = sqlite3SchemaDisconnect(db, iDb, 1); if( rc!=SQLITE_OK ) goto error_out; assert( pDb->pSchema && pDb->pSPool==0 ); } db->init.busy = 1; /* Construct the in-memory representation schema tables (sqlite_master or ** sqlite_temp_master) by invoking the parser directly. The appropriate ** table name will be inserted automatically by the parser so we can just ** use the abbreviation "x" here. The parser will also automatically tag | > > | 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ); assert( iDb>=0 && iDb<db->nDb ); assert( db->aDb[iDb].pSchema || (IsSharedSchema(db) && iDb!=1) ); assert( sqlite3_mutex_held(db->mutex) ); assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); pDb = &db->aDb[iDb]; #ifdef SQLITE_ENABLE_SHARED_SCHEMA assert( pDb->pSPool==0 || IsSharedSchema(db) ); if( pDb->pSPool ){ /* See if there is a free schema object in the schema-pool. If not, ** disconnect from said schema pool and continue. This function will ** connect to a (possibly different) schema-pool before returning. */ Schema *pNew = sqlite3SchemaExtract(pDb->pSPool); if( pNew ){ pDb->pSchema = pNew; return SQLITE_OK; } rc = sqlite3SchemaDisconnect(db, iDb, 1); if( rc!=SQLITE_OK ) goto error_out; assert( pDb->pSchema && pDb->pSPool==0 ); } #endif db->init.busy = 1; /* Construct the in-memory representation schema tables (sqlite_master or ** sqlite_temp_master) by invoking the parser directly. The appropriate ** table name will be inserted automatically by the parser so we can just ** use the abbreviation "x" here. The parser will also automatically tag |
︙ | ︙ | |||
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 | } sqlite3ResetOneSchema(db, iDb); } db->init.busy = 0; return rc; } int sqlite3LockReusableSchema(sqlite3 *db){ if( IsSharedSchema(db) && (db->mDbFlags & DBFLAG_SchemaInuse)==0 ){ db->mDbFlags |= DBFLAG_SchemaInuse; return 1; } return 0; } void sqlite3UnlockReusableSchema(sqlite3 *db, int bRelease){ if( bRelease ){ db->mDbFlags &= ~DBFLAG_SchemaInuse; sqlite3SchemaReleaseAll(db); } } /* ** Initialize all database files - the main database file, the file ** used to store temporary tables, and any additional database files ** created using ATTACH statements. Return a success code. If an ** error occurs, write an error message into *pzErrMsg. ** | > > > > > > > > > > > > > > > | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | } sqlite3ResetOneSchema(db, iDb); } db->init.busy = 0; return rc; } #ifdef SQLITE_ENABLE_SHARED_SCHEMA /* ** If this is a SHARED_SCHEMA connection and the DBFLAG_SchemaInUse flag ** is not currently set, set it and return non-zero. Otherwise, return 0. */ int sqlite3LockReusableSchema(sqlite3 *db){ if( IsSharedSchema(db) && (db->mDbFlags & DBFLAG_SchemaInuse)==0 ){ db->mDbFlags |= DBFLAG_SchemaInuse; return 1; } return 0; } #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ #ifdef SQLITE_ENABLE_SHARED_SCHEMA /* ** This function is a no-op for non-SHARED_SCHEMA connections, or if bRelease ** is zero. Otherwise, clear the DBFLAG_SchemaInuse flag and release all ** schema references currently held. */ void sqlite3UnlockReusableSchema(sqlite3 *db, int bRelease){ if( bRelease ){ db->mDbFlags &= ~DBFLAG_SchemaInuse; sqlite3SchemaReleaseAll(db); } } #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ /* ** Initialize all database files - the main database file, the file ** used to store temporary tables, and any additional database files ** created using ATTACH statements. Return a success code. If an ** error occurs, write an error message into *pzErrMsg. ** |
︙ | ︙ |
Changes to src/shell.c.in.
︙ | ︙ | |||
1067 1068 1069 1070 1071 1072 1073 | #define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */ #define AUTOEQP_on 1 /* Automatic EQP is on */ #define AUTOEQP_trigger 2 /* On and also show plans for triggers */ #define AUTOEQP_full 3 /* Show full EXPLAIN */ /* Allowed values for ShellState.openMode */ | | | | | | | | | | 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 | #define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */ #define AUTOEQP_on 1 /* Automatic EQP is on */ #define AUTOEQP_trigger 2 /* On and also show plans for triggers */ #define AUTOEQP_full 3 /* Show full EXPLAIN */ /* Allowed values for ShellState.openMode */ #define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */ #define SHELL_OPEN_NORMAL 1 /* Normal database file */ #define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */ #define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */ #define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */ #define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */ #define SHELL_OPEN_HEXDB 6 /* Use "dbtotxt" output as data source */ #define SHELL_OPEN_SHAREDSCHEMA 7 /* Open for schema reuse */ /* Allowed values for ShellState.eTraceType */ #define SHELL_TRACE_PLAIN 0 /* Show input SQL text */ #define SHELL_TRACE_EXPANDED 1 /* Show expanded SQL text */ #define SHELL_TRACE_NORMALIZED 2 /* Show normalized SQL text */ |
︙ | ︙ | |||
4297 4298 4299 4300 4301 4302 4303 | sqlite3_open(":memory:", &p->db); break; } case SHELL_OPEN_READONLY: { sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READONLY, 0); break; } | | | 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 | sqlite3_open(":memory:", &p->db); break; } case SHELL_OPEN_READONLY: { sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READONLY, 0); break; } case SHELL_OPEN_SHAREDSCHEMA: { sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_SHARED_SCHEMA,0); break; } case SHELL_OPEN_UNSPEC: case SHELL_OPEN_NORMAL: { sqlite3_open(p->zDbFilename, &p->db); |
︙ | ︙ | |||
7241 7242 7243 7244 7245 7246 7247 | }else if( optionMatch(z, "zip") ){ p->openMode = SHELL_OPEN_ZIPFILE; #endif }else if( optionMatch(z, "append") ){ p->openMode = SHELL_OPEN_APPENDVFS; }else if( optionMatch(z, "readonly") ){ p->openMode = SHELL_OPEN_READONLY; | | | | 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 | }else if( optionMatch(z, "zip") ){ p->openMode = SHELL_OPEN_ZIPFILE; #endif }else if( optionMatch(z, "append") ){ p->openMode = SHELL_OPEN_APPENDVFS; }else if( optionMatch(z, "readonly") ){ p->openMode = SHELL_OPEN_READONLY; }else if( optionMatch(z, "sharedschema") ){ p->openMode = SHELL_OPEN_SHAREDSCHEMA; }else if( z[0]=='-' ){ #ifdef SQLITE_ENABLE_DESERIALIZE }else if( optionMatch(z, "deserialize") ){ p->openMode = SHELL_OPEN_DESERIALIZE; }else if( optionMatch(z, "hexdb") ){ p->openMode = SHELL_OPEN_HEXDB; }else if( optionMatch(z, "maxsize") && iName+1<nArg ){ |
︙ | ︙ | |||
9431 9432 9433 9434 9435 9436 9437 | }else if( strcmp(z,"-deserialize")==0 ){ data.openMode = SHELL_OPEN_DESERIALIZE; }else if( strcmp(z,"-maxsize")==0 && i+1<argc ){ data.szMax = integerValue(argv[++i]); #endif }else if( strcmp(z,"-readonly")==0 ){ data.openMode = SHELL_OPEN_READONLY; | | | | 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 | }else if( strcmp(z,"-deserialize")==0 ){ data.openMode = SHELL_OPEN_DESERIALIZE; }else if( strcmp(z,"-maxsize")==0 && i+1<argc ){ data.szMax = integerValue(argv[++i]); #endif }else if( strcmp(z,"-readonly")==0 ){ data.openMode = SHELL_OPEN_READONLY; }else if( strcmp(z,"-sharedschema")==0 ){ data.openMode = SHELL_OPEN_SHAREDSCHEMA; #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) }else if( strncmp(z, "-A",2)==0 ){ /* All remaining command-line arguments are passed to the ".archive" ** command, so ignore them */ break; #endif }else if( strcmp(z, "-memtrace")==0 ){ |
︙ | ︙ | |||
9536 9537 9538 9539 9540 9541 9542 | }else if( strcmp(z,"-deserialize")==0 ){ data.openMode = SHELL_OPEN_DESERIALIZE; }else if( strcmp(z,"-maxsize")==0 && i+1<argc ){ data.szMax = integerValue(argv[++i]); #endif }else if( strcmp(z,"-readonly")==0 ){ data.openMode = SHELL_OPEN_READONLY; | | | | 9536 9537 9538 9539 9540 9541 9542 9543 9544 9545 9546 9547 9548 9549 9550 9551 | }else if( strcmp(z,"-deserialize")==0 ){ data.openMode = SHELL_OPEN_DESERIALIZE; }else if( strcmp(z,"-maxsize")==0 && i+1<argc ){ data.szMax = integerValue(argv[++i]); #endif }else if( strcmp(z,"-readonly")==0 ){ data.openMode = SHELL_OPEN_READONLY; }else if( strcmp(z,"-sharedschema")==0 ){ data.openMode = SHELL_OPEN_SHAREDSCHEMA; }else if( strcmp(z,"-ascii")==0 ){ data.mode = MODE_Ascii; sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Unit); sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Record); }else if( strcmp(z,"-separator")==0 ){ |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
1199 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. | > > | 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 | */ 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) */ #ifdef SQLITE_ENABLE_SHARED_SCHEMA SchemaPool *pSPool; /* For REUSE_SCHEMA mode */ VTable *pVTable; /* List of all VTable objects (REUSE_SCHEMA mode only) */ #endif }; /* ** 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. |
︙ | ︙ | |||
1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 | Hash trigHash; /* All triggers indexed by name */ Hash fkeyHash; /* All foreign keys by referenced table name */ Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ u8 file_format; /* Schema format version for this file */ u8 enc; /* Text encoding used by this database */ u16 schemaFlags; /* Flags associated with this schema */ int cache_size; /* Number of pages to use in the cache */ Schema *pNext; /* Next Schema object SchemaPool (REUSE_SCHEMA) */ }; /* ** These macros can be used to test, set, or clear bits in the ** Db.pSchema->flags field. */ #define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))==(P)) | > > | 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 | Hash trigHash; /* All triggers indexed by name */ Hash fkeyHash; /* All foreign keys by referenced table name */ Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ u8 file_format; /* Schema format version for this file */ u8 enc; /* Text encoding used by this database */ u16 schemaFlags; /* Flags associated with this schema */ int cache_size; /* Number of pages to use in the cache */ #ifdef SQLITE_ENABLE_SHARED_SCHEMA Schema *pNext; /* Next Schema object SchemaPool (REUSE_SCHEMA) */ #endif }; /* ** These macros can be used to test, set, or clear bits in the ** Db.pSchema->flags field. */ #define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))==(P)) |
︙ | ︙ | |||
1501 1502 1503 1504 1505 1506 1507 | sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ #endif #ifdef SQLITE_USER_AUTHENTICATION sqlite3_userauth auth; /* User authentication information */ #endif }; | > | > > > | 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 | sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ #endif #ifdef SQLITE_USER_AUTHENTICATION sqlite3_userauth auth; /* User authentication information */ #endif }; #ifdef SQLITE_ENABLE_SHARED_SCHEMA # define IsSharedSchema(db) (((db)->openFlags & SQLITE_OPEN_SHARED_SCHEMA)!=0) #else # define IsSharedSchema(db) 0 #endif /* ** A macro to discover the encoding of a database. */ #define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc) #define ENC(db) ((db)->enc) |
︙ | ︙ | |||
1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 | 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 { | > > | 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 | 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) */ #ifdef SQLITE_ENABLE_SHARED_SCHEMA char *zName; /* Table name (REUSE_SCHEMA mode) */ #endif }; /* ** The schema for each SQL table and view is represented in memory ** by an instance of the following structure. */ struct Table { |
︙ | ︙ | |||
3263 3264 3265 3266 3267 3268 3269 | u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */ u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */ IdList *pColumns; /* If this is an UPDATE OF <column-list> trigger, the <column-list> is stored here */ Schema *pSchema; /* Schema containing the trigger */ Schema *pTabSchema; /* Schema containing the table */ | < > > > | 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 | u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */ u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */ IdList *pColumns; /* If this is an UPDATE OF <column-list> trigger, the <column-list> is stored here */ Schema *pSchema; /* Schema containing the trigger */ Schema *pTabSchema; /* Schema containing the table */ TriggerStep *step_list; /* Link list of trigger program steps */ Trigger *pNext; /* Next trigger associated with the table */ #ifdef SQLITE_ENABLE_SHARED_SCHEMA char *zTabSchema; /* Temp triggers in IsSharedSchema() dbs only */ #endif }; /* ** A trigger is either a BEFORE or an AFTER trigger. The following constants ** determine which. ** ** If there are multiple triggers, you might of some BEFORE and some AFTER. |
︙ | ︙ | |||
4318 4319 4320 4321 4322 4323 4324 4325 4326 | int sqlite3FindDbName(sqlite3 *, const char *); int sqlite3AnalysisLoad(sqlite3*,int iDB); void sqlite3DeleteIndexSamples(sqlite3*,Index*); void sqlite3DefaultRowEst(Index*); void sqlite3RegisterLikeFunctions(sqlite3*, int); int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); void sqlite3SchemaClear(void *); int sqlite3SchemaConnect(sqlite3*, int, u64); int sqlite3SchemaDisconnect(sqlite3 *, int, int); | > > > < > > > > > > > > > > > > < < | 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 | int sqlite3FindDbName(sqlite3 *, const char *); int sqlite3AnalysisLoad(sqlite3*,int iDB); void sqlite3DeleteIndexSamples(sqlite3*,Index*); void sqlite3DefaultRowEst(Index*); void sqlite3RegisterLikeFunctions(sqlite3*, int); int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); void sqlite3SchemaClear(void *); void sqlite3SchemaClearOrDisconnect(sqlite3*, int); #ifdef SQLITE_ENABLE_SHARED_SCHEMA int sqlite3SchemaConnect(sqlite3*, int, u64); int sqlite3SchemaDisconnect(sqlite3 *, int, int); Schema *sqlite3SchemaExtract(SchemaPool*); int sqlite3SchemaLoad(sqlite3*, int, int*, char**); void sqlite3SchemaReleaseAll(sqlite3*); void sqlite3SchemaRelease(sqlite3*, int); void sqlite3SchemaAdjustUsed(sqlite3*, int, int, int*); void sqlite3SchemaWritable(Parse*, int); void sqlite3UnlockReusableSchema(sqlite3 *db, int bRelease); int sqlite3LockReusableSchema(sqlite3 *db); #else # define sqlite3SchemaWritable(x,y) # define sqlite3UnlockReusableSchema(x,y) # define sqlite3LockReusableSchema(x) 0 # define sqlite3SchemaDisconnect(x,y,z) SQLITE_OK # define sqlite3SchemaLoad(w,x,y,z) SQLITE_OK # define sqlite3SchemaRelease(y,z) # define sqlite3SchemaConnect(x,y,z) SQLITE_OK #endif Schema *sqlite3SchemaGet(sqlite3 *, Btree *); int sqlite3SchemaToIndex(sqlite3 *db, Schema *); KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int); void sqlite3KeyInfoUnref(KeyInfo*); KeyInfo *sqlite3KeyInfoRef(KeyInfo*); KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); #ifdef SQLITE_DEBUG int sqlite3KeyInfoIsWriteable(KeyInfo*); #endif int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*,int,sqlite3_value **), |
︙ | ︙ |
Changes to src/status.c.
︙ | ︙ | |||
277 278 279 280 281 282 283 284 285 | int nByte = 0; /* Used to accumulate return value */ int bReleaseSchema; sqlite3BtreeEnterAll(db); bReleaseSchema = sqlite3LockReusableSchema(db); db->pnBytesFreed = &nByte; for(i=0; i<db->nDb; i++){ int bUnload = 0; int nUsed = nByte; | > > < > | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | int nByte = 0; /* Used to accumulate return value */ int bReleaseSchema; sqlite3BtreeEnterAll(db); bReleaseSchema = sqlite3LockReusableSchema(db); db->pnBytesFreed = &nByte; for(i=0; i<db->nDb; i++){ Schema *pSchema; #ifdef SQLITE_ENABLE_SHARED_SCHEMA int bUnload = 0; int nUsed = nByte; if( db->aDb[i].pSPool ){ char *zDummy = 0; rc = sqlite3SchemaLoad(db, i, &bUnload, &zDummy); sqlite3_free(zDummy); if( rc ) break; } #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ pSchema = db->aDb[i].pSchema; if( ALWAYS(pSchema!=0) ){ HashElem *p; nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * ( pSchema->tblHash.count + pSchema->trigHash.count |
︙ | ︙ | |||
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){ sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p)); } for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ sqlite3DeleteTable(db, (Table *)sqliteHashData(p)); } } if( db->aDb[i].pSPool ){ if( bUnload ) sqlite3SchemaRelease(db, i); sqlite3SchemaAdjustUsed(db, i, nUsed, &nByte); } } sqlite3UnlockReusableSchema(db, bReleaseSchema); db->pnBytesFreed = 0; sqlite3BtreeLeaveAll(db); *pHighwater = 0; *pCurrent = nByte; | > > | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){ sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p)); } for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ sqlite3DeleteTable(db, (Table *)sqliteHashData(p)); } } #ifdef SQLITE_ENABLE_SHARED_SCHEMA if( db->aDb[i].pSPool ){ if( bUnload ) sqlite3SchemaRelease(db, i); sqlite3SchemaAdjustUsed(db, i, nUsed, &nByte); } #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ } sqlite3UnlockReusableSchema(db, bReleaseSchema); db->pnBytesFreed = 0; sqlite3BtreeLeaveAll(db); *pHighwater = 0; *pCurrent = nByte; |
︙ | ︙ |
Changes to src/tclsqlite.c.
︙ | ︙ | |||
3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 | static int sqliteCmdUsage( Tcl_Interp *interp, Tcl_Obj *const*objv ){ Tcl_WrongNumArgs(interp, 1, objv, "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" " ?-shared-schema BOOLEAN?" #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) " ?-key CODECKEY?" #endif ); return TCL_ERROR; } | > > | 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 | static int sqliteCmdUsage( Tcl_Interp *interp, Tcl_Obj *const*objv ){ Tcl_WrongNumArgs(interp, 1, objv, "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" #ifdef SQLITE_ENABLE_SHARED_SCHEMA " ?-shared-schema BOOLEAN?" #endif #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) " ?-key CODECKEY?" #endif ); return TCL_ERROR; } |
︙ | ︙ | |||
3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 | int b; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; if( b ){ flags |= SQLITE_OPEN_URI; }else{ flags &= ~SQLITE_OPEN_URI; } }else if( strcmp(zArg, "-shared-schema")==0 ){ int b; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; if( b ){ flags |= SQLITE_OPEN_SHARED_SCHEMA; }else{ flags &= ~SQLITE_OPEN_SHARED_SCHEMA; } }else{ Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); return TCL_ERROR; } } zErrMsg = 0; p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); | > > | 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 | int b; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; if( b ){ flags |= SQLITE_OPEN_URI; }else{ flags &= ~SQLITE_OPEN_URI; } #ifdef SQLITE_ENABLE_SHARED_SCHEMA }else if( strcmp(zArg, "-shared-schema")==0 ){ int b; if( Tcl_GetBooleanFromObj(interp, objv[i], &b) ) return TCL_ERROR; if( b ){ flags |= SQLITE_OPEN_SHARED_SCHEMA; }else{ flags &= ~SQLITE_OPEN_SHARED_SCHEMA; } #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ }else{ Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); return TCL_ERROR; } } zErrMsg = 0; p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); |
︙ | ︙ |
Changes to src/test_config.c.
︙ | ︙ | |||
769 770 771 772 773 774 775 776 777 778 779 780 781 782 | #endif #ifdef SQLITE_OMIT_WINDOWFUNC Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "1", TCL_GLOBAL_ONLY); #endif #define LINKVAR(x) { \ static const int cv_ ## x = SQLITE_ ## x; \ Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \ TCL_LINK_INT | TCL_LINK_READ_ONLY); } LINKVAR( MAX_LENGTH ); | > > > > > > | 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 | #endif #ifdef SQLITE_OMIT_WINDOWFUNC Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "windowfunc", "1", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_ENABLE_SHARED_SCHEMA Tcl_SetVar2(interp, "sqlite_options", "sharedschema", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "sharedschema", "0", TCL_GLOBAL_ONLY); #endif #define LINKVAR(x) { \ static const int cv_ ## x = SQLITE_ ## x; \ Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \ TCL_LINK_INT | TCL_LINK_READ_ONLY); } LINKVAR( MAX_LENGTH ); |
︙ | ︙ |
Changes to src/test_schemapool.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 | */ /* ** None of this works unless we have virtual tables. */ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_TEST) | | > > > | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | */ /* ** None of this works unless we have virtual tables. */ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_TEST) #include <tcl.h> #ifdef SQLITE_ENABLE_SHARED_SCHEMA #include "sqliteInt.h" /* The code in this file defines a sqlite3 virtual-table module with ** the following schema. */ #define SCHEMAPOOL_SCHEMA \ "CREATE TABLE x(" \ " cksum INTEGER, " \ |
︙ | ︙ | |||
249 250 251 252 253 254 255 | if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3_create_module(db, "schemapool", &schemaPoolModule, 0); #endif return TCL_OK; } | | > > > | 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3_create_module(db, "schemapool", &schemaPoolModule, 0); #endif return TCL_OK; } #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_TEST) */ /* ** Register commands with the TCL interpreter. */ int Sqlitetestschemapool_Init(Tcl_Interp *interp){ #ifdef SQLITE_ENABLE_SHARED_SCHEMA static struct { char *zName; Tcl_ObjCmdProc *xProc; void *clientData; } aObjCmd[] = { { "register_schemapool_module", register_schemapool_module, 0 }, }; int i; for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, aObjCmd[i].clientData, 0); } #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ return TCL_OK; } |
Changes to src/trigger.c.
︙ | ︙ | |||
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | if( pParse->disableTriggers ){ return 0; } if( pTmpSchema!=pTab->pSchema ){ sqlite3 *db = pParse->db; HashElem *p; char *zSchema = 0; if( IsSharedSchema(db) ){ zSchema = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; } assert( sqlite3SchemaMutexHeld(db, 0, pTmpSchema) ); for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){ Trigger *pTrig = (Trigger *)sqliteHashData(p); if( (zSchema==0 && pTrig->pTabSchema==pTab->pSchema) | > > > > | < > > > > | < | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | if( pParse->disableTriggers ){ return 0; } if( pTmpSchema!=pTab->pSchema ){ sqlite3 *db = pParse->db; HashElem *p; #ifdef SQLITE_ENABLE_SHARED_SCHEMA char *zSchema = 0; if( IsSharedSchema(db) ){ zSchema = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; } #endif assert( sqlite3SchemaMutexHeld(db, 0, pTmpSchema) ); for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){ Trigger *pTrig = (Trigger *)sqliteHashData(p); #ifdef SQLITE_ENABLE_SHARED_SCHEMA if( (zSchema==0 && pTrig->pTabSchema==pTab->pSchema) || (zSchema!=0 && 0==sqlite3StrICmp(pTrig->zTabSchema, zSchema)) ) #else if( pTrig->pTabSchema==pTab->pSchema ) #endif { if( 0==sqlite3StrICmp(pTrig->table, pTab->zName) ){ pTrig->pTabSchema = pTab->pSchema; pTrig->pNext = (pList ? pList : pTab->pTrigger); pList = pTrig; } } } } |
︙ | ︙ | |||
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | /* Build the Trigger object */ pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger)); if( pTrigger==0 ) goto trigger_cleanup; pTrigger->zName = zName; zName = 0; pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName); if( IsSharedSchema(db) && iDb==1 ){ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); pTrigger->zTabSchema = sqlite3DbStrDup(db, db->aDb[iTabDb].zDbSName); } pTrigger->pSchema = db->aDb[iDb].pSchema; pTrigger->pTabSchema = pTab->pSchema; pTrigger->op = (u8)op; pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, pTrigger->table, pTableName->a[0].zName); pTrigger->pWhen = pWhen; | > > | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | /* Build the Trigger object */ pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger)); if( pTrigger==0 ) goto trigger_cleanup; pTrigger->zName = zName; zName = 0; pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName); #ifdef SQLITE_ENABLE_SHARED_SCHEMA if( IsSharedSchema(db) && iDb==1 ){ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); pTrigger->zTabSchema = sqlite3DbStrDup(db, db->aDb[iTabDb].zDbSName); } #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ pTrigger->pSchema = db->aDb[iDb].pSchema; pTrigger->pTabSchema = pTab->pSchema; pTrigger->op = (u8)op; pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, pTrigger->table, pTableName->a[0].zName); pTrigger->pWhen = pWhen; |
︙ | ︙ | |||
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 | ** Recursively delete a Trigger structure */ void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ if( pTrigger==0 ) return; sqlite3DeleteTriggerStep(db, pTrigger->step_list); sqlite3DbFree(db, pTrigger->zName); sqlite3DbFree(db, pTrigger->table); sqlite3DbFree(db, pTrigger->zTabSchema); sqlite3ExprDelete(db, pTrigger->pWhen); sqlite3IdListDelete(db, pTrigger->pColumns); sqlite3DbFree(db, pTrigger); } /* ** This function is called to drop a trigger from the database schema. | > > | 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 | ** Recursively delete a Trigger structure */ void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ if( pTrigger==0 ) return; sqlite3DeleteTriggerStep(db, pTrigger->step_list); sqlite3DbFree(db, pTrigger->zName); sqlite3DbFree(db, pTrigger->table); #ifdef SQLITE_ENABLE_SHARED_SCHEMA sqlite3DbFree(db, pTrigger->zTabSchema); #endif sqlite3ExprDelete(db, pTrigger->pWhen); sqlite3IdListDelete(db, pTrigger->pColumns); sqlite3DbFree(db, pTrigger); } /* ** This function is called to drop a trigger from the database schema. |
︙ | ︙ |
Changes to src/vtab.c.
︙ | ︙ | |||
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( IsSharedSchema(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. | > > | 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 | ** 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) ); #ifdef SQLITE_ENABLE_SHARED_SCHEMA if( IsSharedSchema(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; } } #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ 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. |
︙ | ︙ | |||
530 531 532 533 534 535 536 | } zModuleName = sqlite3DbStrDup(db, pTab->zName); if( !zModuleName ){ return SQLITE_NOMEM_BKPT; } | | > > > > > | 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | } zModuleName = sqlite3DbStrDup(db, pTab->zName); if( !zModuleName ){ return SQLITE_NOMEM_BKPT; } nByte = sizeof(VTable); #ifdef SQLITE_ENABLE_SHARED_SCHEMA nByte += sqlite3Strlen30(pTab->zName) + 1; #endif pVTable = (VTable*)sqlite3MallocZero(nByte); if( !pVTable ){ sqlite3OomFault(db); sqlite3DbFree(db, zModuleName); return SQLITE_NOMEM_BKPT; } pVTable->db = db; pVTable->pMod = pMod; #ifdef SQLITE_ENABLE_SHARED_SCHEMA pVTable->zName = (char*)&pVTable[1]; memcpy(pVTable->zName, pTab->zName, nByte-sizeof(VTable)); #endif iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pTab->azModuleArg[1] = db->aDb[iDb].zDbSName; /* Invoke the virtual table constructor */ assert( &db->pVtabCtx ); assert( xConstruct ); |
︙ | ︙ | |||
587 588 589 590 591 592 593 594 595 596 | /* If everything went according to plan, link the new VTable structure ** into the linked list headed by pTab->pVTable. Or, if this is a ** reusable schema, into the linked list headed by Db.pVTable. ** ** Then loop through the columns of the table to see if any of them ** contain the token "hidden". If so, set the Column COLFLAG_HIDDEN flag ** and remove the token from the type string. */ if( IsSharedSchema(db) && iDb!=1 ){ pVTable->pNext = db->aDb[iDb].pVTable; db->aDb[iDb].pVTable = pVTable; | > | > > | 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 | /* If everything went according to plan, link the new VTable structure ** into the linked list headed by pTab->pVTable. Or, if this is a ** reusable schema, into the linked list headed by Db.pVTable. ** ** Then loop through the columns of the table to see if any of them ** contain the token "hidden". If so, set the Column COLFLAG_HIDDEN flag ** and remove the token from the type string. */ #ifdef SQLITE_ENABLE_SHARED_SCHEMA if( IsSharedSchema(db) && iDb!=1 ){ pVTable->pNext = db->aDb[iDb].pVTable; db->aDb[iDb].pVTable = pVTable; }else #endif /* ifdef SQLITE_ENABLE_SHARED_SCHEMA */ { pVTable->pNext = pTab->pVTable; pTab->pVTable = pVTable; } for(iCol=0; iCol<pTab->nCol; iCol++){ char *zType = sqlite3ColumnType(&pTab->aCol[iCol], ""); int nType; |
︙ | ︙ |
Changes to test/reuse1.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 | # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reuse1 | | > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reuse1 ifcapable !sharedschema { finish_test return } forcedelete test.db2 sqlite3 db2 test.db2 do_execsql_test 1.0 { CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE, z); CREATE INDEX i1 ON t1(z); |
︙ | ︙ | |||
118 119 120 121 122 123 124 | do_execsql_test 2.2 { SELECT * FROM aux.ft; } {aux1 aux2 aux3} do_execsql_test 2.2 { SELECT * FROM aux.ft_content; } {1 aux1 2 aux2 3 aux3} | < < | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | do_execsql_test 2.2 { SELECT * FROM aux.ft; } {aux1 aux2 aux3} do_execsql_test 2.2 { SELECT * FROM aux.ft_content; } {1 aux1 2 aux2 3 aux3} } #------------------------------------------------------------------------- # reset_db forcedelete test.db2 do_execsql_test 3.0 { |
︙ | ︙ |
Changes to test/reuse2.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reuse2 do_execsql_test 1.0 { CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE, z); CREATE INDEX i1 ON t1(z); PRAGMA schema_version; } {2} | > > > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reuse2 ifcapable !sharedschema { finish_test return } do_execsql_test 1.0 { CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE, z); CREATE INDEX i1 ON t1(z); PRAGMA schema_version; } {2} |
︙ | ︙ |
Changes to test/reuse3.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reuse3 do_execsql_test 1.0 { CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE, z); CREATE INDEX i1 ON t1(z); CREATE TABLE t2(a); } {} | > > > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reuse3 ifcapable !sharedschema { finish_test return } do_execsql_test 1.0 { CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE, z); CREATE INDEX i1 ON t1(z); CREATE TABLE t2(a); } {} |
︙ | ︙ |
Changes to test/reuse4.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #*********************************************************************** # # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reuse4 foreach {tn sharedschema} { 1 0 2 1 } { reset_db | > > > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #*********************************************************************** # # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reuse4 ifcapable !sharedschema { finish_test return } foreach {tn sharedschema} { 1 0 2 1 } { reset_db |
︙ | ︙ |
Changes to test/reuse5.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reuse5 set CLI [test_find_cli] do_execsql_test 1.0 { CREATE TABLE t1(x, y); CREATE TABLE t2(a, b, c); CREATE INDEX t1x ON t1(x); CREATE INDEX t1y ON t1(y); CREATE VIEW v1 AS SELECT * FROM t2; | > > > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reuse5 set CLI [test_find_cli] ifcapable !sharedschema { finish_test return } do_execsql_test 1.0 { CREATE TABLE t1(x, y); CREATE TABLE t2(a, b, c); CREATE INDEX t1x ON t1(x); CREATE INDEX t1y ON t1(y); CREATE VIEW v1 AS SELECT * FROM t2; |
︙ | ︙ |
Changes to test/reusefault.test.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #*********************************************************************** # # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reusefault do_execsql_test 1.0 { PRAGMA cache_size = 10; CREATE TABLE t1(a UNIQUE, b UNIQUE); INSERT INTO t1 VALUES(1, 2), (3, 4); } faultsim_save_and_close | > > > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #*********************************************************************** # # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix reusefault ifcapable !sharedschema { finish_test return } do_execsql_test 1.0 { PRAGMA cache_size = 10; CREATE TABLE t1(a UNIQUE, b UNIQUE); INSERT INTO t1 VALUES(1, 2), (3, 4); } faultsim_save_and_close |
︙ | ︙ |
Changes to test/tclsqlite.test.
︙ | ︙ | |||
21 22 23 24 25 26 27 | set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix tcl # Check the error messages generated by tclsqlite # | | > > > | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix tcl # Check the error messages generated by tclsqlite # set r "sqlite_orig HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" ifcapable sharedschema { append r " ?-shared-schema BOOLEAN?" } if {[sqlite3 -has-codec]} { append r " ?-key CODECKEY?" } do_test tcl-1.1 { set v [catch {sqlite3 -bogus} msg] regsub {really_sqlite3} $msg {sqlite3} msg lappend v $msg |
︙ | ︙ |