Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Use the IsReuseSchema() macro more consistently. Also, rename it to IsSharedSchema(). |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | reuse-schema |
Files: | files | file ages | folders |
SHA3-256: |
c1be211c0286a6ff3ef8ab6839136175 |
User & Date: | dan 2019-03-20 20:02:03.478 |
Context
2019-03-21
| ||
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) | |
19:17 | Fix an error message. (check-in: a70fdaa390 user: dan tags: reuse-schema) | |
Changes
Changes to src/attach.c.
︙ | ︙ | |||
229 230 231 232 233 234 235 | ** If this fails, or if opening the file failed, then close the file and ** remove the entry from the db->aDb[] array. i.e. put everything back the ** way we found it. */ if( rc==SQLITE_OK ){ db->init.iDb = 0; db->mDbFlags &= ~(DBFLAG_SchemaKnownOk); | | | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | ** If this fails, or if opening the file failed, then close the file and ** remove the entry from the db->aDb[] array. i.e. put everything back the ** way we found it. */ if( rc==SQLITE_OK ){ db->init.iDb = 0; db->mDbFlags &= ~(DBFLAG_SchemaKnownOk); if( !IsSharedSchema(db) && !REOPEN_AS_MEMDB(db) ){ sqlite3BtreeEnterAll(db); rc = sqlite3Init(db, &zErrDyn); sqlite3BtreeLeaveAll(db); assert( zErrDyn==0 || rc!=SQLITE_OK ); } } #ifdef SQLITE_USER_AUTHENTICATION |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
300 301 302 303 304 305 306 | ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. If ** an error code is returned, (*pzErr) may be set to point to a buffer ** containing an error message. It is the responsibility of the caller to ** eventually free this buffer using sqlite3_free(). */ int sqlite3SchemaLoad(sqlite3 *db, int iDb, int *pbUnload, char **pzErr){ int rc = SQLITE_OK; | | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 | ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. If ** an error code is returned, (*pzErr) may be set to point to a buffer ** containing an error message. It is the responsibility of the caller to ** eventually free this buffer using sqlite3_free(). */ int sqlite3SchemaLoad(sqlite3 *db, int iDb, int *pbUnload, char **pzErr){ int rc = SQLITE_OK; if( IsSharedSchema(db) && DbHasProperty(db, iDb, DB_SchemaLoaded)==0 && (db->init.busy==0 || (iDb!=1 && db->init.iDb==1)) ){ struct sqlite3InitInfo sv = db->init; memset(&db->init, 0, sizeof(struct sqlite3InitInfo)); rc = sqlite3InitOne(db, iDb, pzErr, 0); db->init = sv; |
︙ | ︙ | |||
344 345 346 347 348 349 350 | #endif while(1){ for(i=OMIT_TEMPDB; i<db->nDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ int bUnload = 0; assert( sqlite3SchemaMutexHeld(db, j, 0) ); | | | 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | #endif while(1){ for(i=OMIT_TEMPDB; i<db->nDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ int bUnload = 0; assert( sqlite3SchemaMutexHeld(db, j, 0) ); if( IsSharedSchema(db) ){ Parse *pParse = db->pParse; if( pParse && pParse->nErr==0 ){ pParse->rc = sqlite3SchemaLoad(db, j, &bUnload, &pParse->zErrMsg); if( pParse->rc ) pParse->nErr++; } } p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); |
︙ | ︙ | |||
389 390 391 392 393 394 395 | ){ Table *p; sqlite3 *db = pParse->db; /* Read the database schema. If an error occurs, leave an error message ** and code in pParse and return NULL. */ if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 | | | | | | 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 | ){ Table *p; sqlite3 *db = pParse->db; /* Read the database schema. If an error occurs, leave an error message ** and code in pParse and return NULL. */ if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 && !IsSharedSchema(db) && SQLITE_OK!=sqlite3ReadSchema(pParse) ){ return 0; } p = sqlite3FindTable(db, zName, zDbase); if( p==0 ){ #ifndef SQLITE_OMIT_VIRTUALTABLE /* If zName is the not the name of a table in the schema created using ** CREATE, then check to see if it is the name of an virtual table that ** can be an eponymous virtual table. */ if( pParse->disableVtab==0 ){ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ pMod = sqlite3PragmaVtabRegister(db, zName); } if( pMod ){ if( IsSharedSchema(db) && pParse->nErr==0 ){ int bDummy = 0; pParse->rc = sqlite3SchemaLoad(db, 0, &bDummy, &pParse->zErrMsg); if( pParse->rc ) pParse->nErr++; } if( sqlite3VtabEponymousTableInit(pParse, pMod) ){ Table *pEpoTab = pMod->pEpoTab; assert( IsSharedSchema(db) || pEpoTab->pSchema==db->aDb[0].pSchema ); pEpoTab->pSchema = db->aDb[0].pSchema; /* For SHARED_SCHEMA mode */ return pEpoTab; } } } #endif if( flags & LOCATE_NOERR ) return 0; pParse->checkSchema = 1; }else if( IsVirtual(p) && pParse->disableVtab ){ p = 0; } if( p==0 && (!IsSharedSchema(db) || pParse->nErr==0) ){ const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; if( zDbase ){ sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); }else{ sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); } } |
︙ | ︙ | |||
994 995 996 997 998 999 1000 | ** it does. The exception is if the statement being parsed was passed ** to an sqlite3_declare_vtab() call. In that case only the column names ** and types will be used, so there is no need to test for namespace ** collisions. */ if( !IN_SPECIAL_PARSE ){ char *zDb = db->aDb[iDb].zDbSName; | | | 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 | ** it does. The exception is if the statement being parsed was passed ** to an sqlite3_declare_vtab() call. In that case only the column names ** and types will be used, so there is no need to test for namespace ** collisions. */ if( !IN_SPECIAL_PARSE ){ char *zDb = db->aDb[iDb].zDbSName; if( !IsSharedSchema(db) && SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto begin_table_error; } pTable = sqlite3FindTable(db, zName, zDb); if( pTable ){ if( !noErr ){ sqlite3ErrorMsg(pParse, "table %T already exists", pName); }else{ |
︙ | ︙ | |||
2719 2720 2721 2722 2723 2724 2725 | int iDb; if( db->mallocFailed ){ goto exit_drop_table; } assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); | | | 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 | int iDb; if( db->mallocFailed ){ goto exit_drop_table; } assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); if( !IsSharedSchema(db) && sqlite3ReadSchema(pParse) ) goto exit_drop_table; if( noErr ) db->suppressErr++; assert( isView==0 || isView==LOCATE_VIEW ); pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); if( noErr ) db->suppressErr--; if( pTab==0 ){ if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); |
︙ | ︙ | |||
3143 3144 3145 3146 3147 3148 3149 | if( db->mallocFailed || pParse->nErr>0 ){ goto exit_create_index; } if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){ goto exit_create_index; } | | | 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 | if( db->mallocFailed || pParse->nErr>0 ){ goto exit_create_index; } if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){ goto exit_create_index; } if( !IsSharedSchema(db) && SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_create_index; } /* ** Find the table that is to be indexed. Return early if not found. */ if( pTblName!=0 ){ |
︙ | ︙ |
Changes to src/callback.c.
︙ | ︙ | |||
38 39 40 41 42 43 44 | 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){ | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | 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]; Btree *pBt = pDb->pBt; assert( pBt==0 || sqlite3BtreeSchema(pBt, 0, 0)==0 ); assert( pDb->pSchema ); |
︙ | ︙ | |||
525 526 527 528 529 530 531 | ** 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]; | | | 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 | ** 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); }else{ sqlite3SchemaClear(pDb->pSchema); } } /* |
︙ | ︙ | |||
575 576 577 578 579 580 581 | /* ** 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_SHARED_SCHEMA). If so, do nothing. Otherwise, leave an ** error in the Parse object. */ void sqlite3SchemaWritable(Parse *pParse, int iDb){ | < | < | 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 | /* ** 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_SHARED_SCHEMA). If so, do nothing. Otherwise, leave an ** error in the Parse object. */ void sqlite3SchemaWritable(Parse *pParse, int iDb){ if( iDb!=1 && IsSharedSchema(pParse->db) && 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 |
︙ | ︙ | |||
703 704 705 706 707 708 709 | ** 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; | | | 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 | ** 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( IsSharedSchema(db) ){ Db *pDb = &db->aDb[iDb]; SchemaPool *pSPool = pDb->pSPool; assert_schema_state_ok(db); assert( pDb->pSchema ); if( pSPool==0 ){ assert( pDb->pVTable==0 ); |
︙ | ︙ | |||
817 818 819 820 821 822 823 | ** 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; | | | 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 | ** 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{ db->lookaside.bDisable++; p = (Schema*)sqlite3DbMallocZero(db, sizeof(Schema)); db->lookaside.bDisable--; } if( !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 | 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 && IsSharedSchema(db) ){ VTable *pVTable; VTable *pNext; for(pVTable=db->aDb[i].pVTable; pVTable; pVTable=pNext){ pNext = pVTable->pNext; sqlite3VtabUnlock(pVTable); } db->aDb[i].pVTable = 0; |
︙ | ︙ | |||
3622 3623 3624 3625 3626 3627 3628 | } #endif /* Ensure the database schema has been loaded */ sqlite3_mutex_enter(db->mutex); bUnlock = sqlite3LockReusableSchema(db); sqlite3BtreeEnterAll(db); | | | 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 | } #endif /* Ensure the database schema has been loaded */ sqlite3_mutex_enter(db->mutex); bUnlock = sqlite3LockReusableSchema(db); 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; |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
416 417 418 419 420 421 422 | /* Locate the pragma in the lookup table */ pPragma = pragmaLocate(zLeft); if( pPragma==0 ) goto pragma_out; /* Make sure the database schema is loaded if the pragma requires that */ if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){ | | | 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 | /* Locate the pragma in the lookup table */ pPragma = pragmaLocate(zLeft); if( pPragma==0 ) goto pragma_out; /* Make sure the database schema is loaded if the pragma requires that */ if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){ if( IsSharedSchema(db) && (zDb || (pPragma->mPragFlg & PragFlg_OneSchema)) ){ assert( iDb>=0 && iDb<db->nDb ); pParse->rc = sqlite3SchemaLoad(db, iDb, 0, &pParse->zErrMsg); if( pParse->rc ) goto pragma_out; }else{ if( sqlite3ReadSchema(pParse) ) goto pragma_out; } } |
︙ | ︙ |
Changes to src/prepare.c.
︙ | ︙ | |||
30 31 32 33 34 35 36 | }else if( pData->pzErrMsg[0]!=0 ){ /* A error message has already been generated. Do not overwrite it */ }else if( pData->mInitFlags & INITFLAG_AlterTable ){ *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra); pData->rc = SQLITE_ERROR; }else if( db->flags & SQLITE_WriteSchema ){ pData->rc = SQLITE_CORRUPT_BKPT; | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | }else if( pData->pzErrMsg[0]!=0 ){ /* A error message has already been generated. Do not overwrite it */ }else if( pData->mInitFlags & INITFLAG_AlterTable ){ *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra); pData->rc = SQLITE_ERROR; }else if( db->flags & SQLITE_WriteSchema ){ pData->rc = SQLITE_CORRUPT_BKPT; }else if( IsSharedSchema(db) && 0==sqlite3StrNICmp(zExtra, "malformed database schema", 17) ){ pData->rc = SQLITE_CORRUPT_BKPT; *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra); }else{ char *z; if( zObj==0 ) zObj = "?"; |
︙ | ︙ | |||
165 166 167 168 169 170 171 | || pIndex->tnum<2 || sqlite3IndexHasDuplicateRootPage(pIndex) ){ corruptSchema(pData, argv[0], pIndex?"invalid rootpage":"orphan index"); } } | | | 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | || pIndex->tnum<2 || sqlite3IndexHasDuplicateRootPage(pIndex) ){ corruptSchema(pData, argv[0], pIndex?"invalid rootpage":"orphan index"); } } if( iDb!=1 && IsSharedSchema(db) ){ schemaUpdateChecksum(pData, argv[0], argv[1], argv[2]); } return 0; } /* ** Attempt to read the database schema and initialize internal |
︙ | ︙ | |||
194 195 196 197 198 199 200 | int meta[5]; InitData initData; const char *zMasterName; int openedTransaction = 0; assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ); assert( iDb>=0 && iDb<db->nDb ); | | | | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | int meta[5]; InitData initData; const char *zMasterName; int openedTransaction = 0; 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; |
︙ | ︙ | |||
396 397 398 399 400 401 402 | ** purpose of this is to allow access to the sqlite_master table ** even when its contents have been corrupted. */ DbSetProperty(db, iDb, DB_SchemaLoaded); rc = SQLITE_OK; } | | | 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | ** purpose of this is to allow access to the sqlite_master table ** even when its contents have been corrupted. */ DbSetProperty(db, iDb, DB_SchemaLoaded); rc = SQLITE_OK; } if( rc==SQLITE_OK && iDb!=1 && IsSharedSchema(db) ){ rc = sqlite3SchemaConnect(db, iDb, initData.cksum); } /* Jump here for an error that occurs after successfully allocating ** curMain and calling sqlite3BtreeEnter(). For an error that occurs ** before that point, jump to error_out. */ |
︙ | ︙ | |||
422 423 424 425 426 427 428 | sqlite3ResetOneSchema(db, iDb); } db->init.busy = 0; return rc; } int sqlite3LockReusableSchema(sqlite3 *db){ | | | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | 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 ){ |
︙ | ︙ | |||
490 491 492 493 494 495 496 | assert( sqlite3_mutex_held(db->mutex) ); if( !db->init.busy ){ db->mDbFlags |= DBFLAG_FreeSchema; /* For sharable-schema mode */ rc = sqlite3Init(db, &pParse->zErrMsg); if( rc!=SQLITE_OK ){ pParse->rc = rc; pParse->nErr++; | | | 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 | assert( sqlite3_mutex_held(db->mutex) ); if( !db->init.busy ){ db->mDbFlags |= DBFLAG_FreeSchema; /* For sharable-schema mode */ rc = sqlite3Init(db, &pParse->zErrMsg); if( rc!=SQLITE_OK ){ pParse->rc = rc; pParse->nErr++; }else if( db->noSharedCache && !IsSharedSchema(db) ){ db->mDbFlags |= DBFLAG_SchemaKnownOk; } } return rc; } |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
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 }; | | | 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 | sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ #endif #ifdef SQLITE_USER_AUTHENTICATION sqlite3_userauth auth; /* User authentication information */ #endif }; #define IsSharedSchema(db) (((db)->openFlags & SQLITE_OPEN_SHARED_SCHEMA)!=0) /* ** A macro to discover the encoding of a database. */ #define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc) #define ENC(db) ((db)->enc) |
︙ | ︙ | |||
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 */ | | | 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 | 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 */ char *zTabSchema; /* Temp triggers in IsSharedSchema() dbs only */ TriggerStep *step_list; /* Link list of trigger program steps */ Trigger *pNext; /* Next trigger associated with the table */ }; /* ** A trigger is either a BEFORE or an AFTER trigger. The following constants ** determine which. |
︙ | ︙ |
Changes to src/trigger.c.
︙ | ︙ | |||
54 55 56 57 58 59 60 | return 0; } if( pTmpSchema!=pTab->pSchema ){ sqlite3 *db = pParse->db; HashElem *p; char *zSchema = 0; | | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | 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) || (zSchema!=0 && 0==sqlite3StrICmp(pTrig->zTabSchema, zSchema)) |
︙ | ︙ | |||
249 250 251 252 253 254 255 | /* 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); | | | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | /* 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; |
︙ | ︙ |
Changes to src/vtab.c.
︙ | ︙ | |||
140 141 142 143 144 145 146 | ** 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) ); | | | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | ** 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; } |
︙ | ︙ | |||
587 588 589 590 591 592 593 | /* 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. */ | | | 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 | /* 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; }else{ pVTable->pNext = pTab->pVTable; pTab->pVTable = pVTable; } |
︙ | ︙ |