Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch cache_spill Excluding Merge-Ins
This is equivalent to a diff from f2d175f9 to d07c4331
2013-08-17
| ||
16:37 | Add the cache_spill pragma. Change the fullfsync and checkpoint_fullfsync pragmas to apply to all attached databases. (check-in: 65a85a15 user: drh tags: trunk) | |
15:42 | The fullfsync, checkpoint_fullfsync, and cache_spill pragmas apply to all files of a database connection, including those opened by future ATTACH statements. (Closed-Leaf check-in: d07c4331 user: drh tags: cache_spill) | |
00:25 | Test cases for the cache_spill pragma. (check-in: b85c9ec5 user: drh tags: cache_spill) | |
2013-08-16
| ||
20:42 | Add the cache_spill pragma. (check-in: cdb181c0 user: drh tags: cache_spill) | |
12:26 | Merge recent trunk changes into the STAT4 branch. (check-in: c69b512a user: drh tags: sqlite_stat4) | |
2013-08-15
| ||
22:40 | Make sure that GROUP BY terms select input column names in preference to output column names, in compliance with the SQL standard. Ticket [1c69be2dafc28]. (check-in: f2d175f9 user: drh tags: trunk) | |
20:24 | Bare identifiers in ORDER BY clauses bind more tightly to output column name, but identifiers in expressions bind more tightly to input column names. This is a compromise between SQL92 and SQL99 behavior and is what PostgreSQL and MS-SQL do. Ticket [f617ea3125e9c]. (check-in: c78b357c user: drh tags: trunk) | |
Changes to src/attach.c.
︙ | ︙ | |||
154 155 156 157 158 159 160 161 162 163 164 165 166 167 | "attached databases must use the same text encoding as main database"); rc = SQLITE_ERROR; } pPager = sqlite3BtreePager(aNew->pBt); sqlite3PagerLockingMode(pPager, db->dfltLockMode); sqlite3BtreeSecureDelete(aNew->pBt, sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); } aNew->safety_level = 3; aNew->zName = sqlite3DbStrDup(db, zName); if( rc==SQLITE_OK && aNew->zName==0 ){ rc = SQLITE_NOMEM; } | > | 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | "attached databases must use the same text encoding as main database"); rc = SQLITE_ERROR; } pPager = sqlite3BtreePager(aNew->pBt); sqlite3PagerLockingMode(pPager, db->dfltLockMode); sqlite3BtreeSecureDelete(aNew->pBt, sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK)); } aNew->safety_level = 3; aNew->zName = sqlite3DbStrDup(db, zName); if( rc==SQLITE_OK && aNew->zName==0 ){ rc = SQLITE_NOMEM; } |
︙ | ︙ |
Changes to src/btree.c.
︙ | ︙ | |||
2161 2162 2163 2164 2165 2166 2167 | ** how well the database resists damage due to OS crashes and power ** failures. Level 1 is the same as asynchronous (no syncs() occur and ** there is a high probability of damage) Level 2 is the default. There ** is a very low but non-zero probability of damage. Level 3 reduces the ** probability of damage to near zero but with a write performance reduction. */ #ifndef SQLITE_OMIT_PAGER_PRAGMAS | | < < | < | | 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 | ** how well the database resists damage due to OS crashes and power ** failures. Level 1 is the same as asynchronous (no syncs() occur and ** there is a high probability of damage) Level 2 is the default. There ** is a very low but non-zero probability of damage. Level 3 reduces the ** probability of damage to near zero but with a write performance reduction. */ #ifndef SQLITE_OMIT_PAGER_PRAGMAS int sqlite3BtreeSetPagerFlags( Btree *p, /* The btree to set the safety level on */ unsigned pgFlags /* Various PAGER_* flags */ ){ BtShared *pBt = p->pBt; assert( sqlite3_mutex_held(p->db->mutex) ); sqlite3BtreeEnter(p); sqlite3PagerSetFlags(pBt->pPager, pgFlags); sqlite3BtreeLeave(p); return SQLITE_OK; } #endif /* ** Return TRUE if the given btree is set to safety level 1. In other |
︙ | ︙ |
Changes to src/btree.h.
︙ | ︙ | |||
60 61 62 63 64 65 66 | #define BTREE_MEMORY 2 /* This is an in-memory DB */ #define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */ #define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */ int sqlite3BtreeClose(Btree*); int sqlite3BtreeSetCacheSize(Btree*,int); int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64); | | | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | #define BTREE_MEMORY 2 /* This is an in-memory DB */ #define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */ #define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */ int sqlite3BtreeClose(Btree*); int sqlite3BtreeSetCacheSize(Btree*,int); int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64); int sqlite3BtreeSetPagerFlags(Btree*,unsigned); int sqlite3BtreeSyncDisabled(Btree*); int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); int sqlite3BtreeGetPageSize(Btree*); int sqlite3BtreeMaxPageCount(Btree*,int); u32 sqlite3BtreeLastPage(Btree*); int sqlite3BtreeSecureDelete(Btree*,int); int sqlite3BtreeGetReserve(Btree*); |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
2457 2458 2459 2460 2461 2462 2463 | assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); db->autoCommit = 1; db->nextAutovac = -1; db->szMmap = sqlite3GlobalConfig.szMmap; db->nextPagesize = 0; | | | 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 | assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); db->autoCommit = 1; db->nextAutovac = -1; db->szMmap = sqlite3GlobalConfig.szMmap; db->nextPagesize = 0; db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill #if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX | SQLITE_AutoIndex #endif #if SQLITE_DEFAULT_FILE_FORMAT<4 | SQLITE_LegacyFileFmt #endif #ifdef SQLITE_ENABLE_LOAD_EXTENSION |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
449 450 451 452 453 454 455 456 457 458 459 460 461 462 | Pgno nOrig; /* Original number of pages in file */ Pgno iSubRec; /* Index of first record in sub-journal */ #ifndef SQLITE_OMIT_WAL u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ #endif }; /* ** A open page cache is an instance of struct Pager. A description of ** some of the more important member variables follows: ** ** eState ** ** The current 'state' of the pager object. See the comment and state | > > > > > > > | 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 | Pgno nOrig; /* Original number of pages in file */ Pgno iSubRec; /* Index of first record in sub-journal */ #ifndef SQLITE_OMIT_WAL u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ #endif }; /* ** Bits of the Pager.doNotSpill flag. See further description below. */ #define SPILLFLAG_OFF 0x01 /* Never spill cache. Set via pragma */ #define SPILLFLAG_ROLLBACK 0x02 /* Current rolling back, so do not spill */ #define SPILLFLAG_NOSYNC 0x04 /* Spill is ok, but do not sync */ /* ** A open page cache is an instance of struct Pager. A description of ** some of the more important member variables follows: ** ** eState ** ** The current 'state' of the pager object. See the comment and state |
︙ | ︙ | |||
515 516 517 518 519 520 521 | ** subsequently interrupted transaction that reuses the journal file. ** ** The flag is cleared as soon as the journal file is finalized (either ** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the ** journal file from being successfully finalized, the setMaster flag ** is cleared anyway (and the pager will move to ERROR state). ** | | | | | > | | | > | | 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 | ** subsequently interrupted transaction that reuses the journal file. ** ** The flag is cleared as soon as the journal file is finalized (either ** by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the ** journal file from being successfully finalized, the setMaster flag ** is cleared anyway (and the pager will move to ERROR state). ** ** doNotSpill ** ** This variables control the behavior of cache-spills (calls made by ** the pcache module to the pagerStress() routine to write cached data ** to the file-system in order to free up memory). ** ** When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set, ** writing to the database from pagerStress() is disabled altogether. ** The SPILLFLAG_ROLLBACK case is done in a very obscure case that ** comes up during savepoint rollback that requires the pcache module ** to allocate a new page to prevent the journal file from being written ** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF ** case is a user preference. ** ** If the SPILLFLAG_NOSYNC bit is set, writing to the database from pagerStress() ** is permitted, but syncing the journal file is not. This flag is set ** by sqlite3PagerWrite() when the file-system sector-size is larger than ** the database page-size in order to prevent a journal sync from happening ** in between the journalling of two pages on the same sector. ** ** subjInMemory ** |
︙ | ︙ | |||
631 632 633 634 635 636 637 | ** "configuration" of the pager. */ u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ u8 eLock; /* Current lock held on database file */ u8 changeCountDone; /* Set after incrementing the change-counter */ u8 setMaster; /* True if a m-j name has been written to jrnl */ u8 doNotSpill; /* Do not spill the cache when non-zero */ | < | 640 641 642 643 644 645 646 647 648 649 650 651 652 653 | ** "configuration" of the pager. */ u8 eState; /* Pager state (OPEN, READER, WRITER_LOCKED..) */ u8 eLock; /* Current lock held on database file */ u8 changeCountDone; /* Set after incrementing the change-counter */ u8 setMaster; /* True if a m-j name has been written to jrnl */ u8 doNotSpill; /* Do not spill the cache when non-zero */ u8 subjInMemory; /* True to use in-memory sub-journals */ Pgno dbSize; /* Number of pages in the database */ Pgno dbOrigSize; /* dbSize before the current transaction */ Pgno dbFileSize; /* Number of pages in the database file */ Pgno dbHintSize; /* Value passed to FCNTL_SIZE_HINT call */ int errCode; /* One of several kinds of errors */ int nRec; /* Pages journalled since last j-header written */ |
︙ | ︙ | |||
2291 2292 2293 2294 2295 2296 2297 | ** ** The solution is to add an in-memory page to the cache containing ** the data just read from the sub-journal. Mark the page as dirty ** and if the pager requires a journal-sync, then mark the page as ** requiring a journal-sync before it is written. */ assert( isSavepnt ); | | | | | | 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 | ** ** The solution is to add an in-memory page to the cache containing ** the data just read from the sub-journal. Mark the page as dirty ** and if the pager requires a journal-sync, then mark the page as ** requiring a journal-sync before it is written. */ assert( isSavepnt ); assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 ); pPager->doNotSpill |= SPILLFLAG_ROLLBACK; rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1); assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 ); pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK; if( rc!=SQLITE_OK ) return rc; pPg->flags &= ~PGHDR_NEED_READ; sqlite3PcacheMakeDirty(pPg); } if( pPg ){ /* No page should ever be explicitly rolled back that is in use, except ** for page 1 which is held in use in order to keep the lock on the |
︙ | ︙ | |||
3400 3401 3402 3403 3404 3405 3406 | ** Free as much memory as possible from the pager. */ void sqlite3PagerShrink(Pager *pPager){ sqlite3PcacheShrink(pPager->pPCache); } /* | > > > | | | | 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 | ** Free as much memory as possible from the pager. */ void sqlite3PagerShrink(Pager *pPager){ sqlite3PcacheShrink(pPager->pPCache); } /* ** Adjust settings of the pager to those specified in the pgFlags parameter. ** ** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness ** of the database to damage due to OS crashes or power failures by ** changing the number of syncs()s when writing the journals. ** There are three levels: ** ** OFF sqlite3OsSync() is never called. This is the default ** for temporary and transient files. ** ** NORMAL The journal is synced once before writes begin on the ** database. This is normally adequate protection, but ** it is theoretically possible, though very unlikely, |
︙ | ︙ | |||
3443 3444 3445 3446 3447 3448 3449 | ** synchronous=FULL versus synchronous=NORMAL setting determines when ** the xSync primitive is called and is relevant to all platforms. ** ** Numeric values associated with these states are OFF==1, NORMAL=2, ** and FULL=3. */ #ifndef SQLITE_OMIT_PAGER_PRAGMAS | | < | < > | | > > > > > | 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 | ** synchronous=FULL versus synchronous=NORMAL setting determines when ** the xSync primitive is called and is relevant to all platforms. ** ** Numeric values associated with these states are OFF==1, NORMAL=2, ** and FULL=3. */ #ifndef SQLITE_OMIT_PAGER_PRAGMAS void sqlite3PagerSetFlags( Pager *pPager, /* The pager to set safety level for */ unsigned pgFlags /* Various flags */ ){ unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK; assert( level>=1 && level<=3 ); pPager->noSync = (level==1 || pPager->tempFile) ?1:0; pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0; if( pPager->noSync ){ pPager->syncFlags = 0; pPager->ckptSyncFlags = 0; }else if( pgFlags & PAGER_FULLFSYNC ){ pPager->syncFlags = SQLITE_SYNC_FULL; pPager->ckptSyncFlags = SQLITE_SYNC_FULL; }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){ pPager->syncFlags = SQLITE_SYNC_NORMAL; pPager->ckptSyncFlags = SQLITE_SYNC_FULL; }else{ pPager->syncFlags = SQLITE_SYNC_NORMAL; pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; } pPager->walSyncFlags = pPager->syncFlags; if( pPager->fullSync ){ pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS; } if( pgFlags & PAGER_CACHESPILL ){ pPager->doNotSpill &= ~SPILLFLAG_OFF; }else{ pPager->doNotSpill |= SPILLFLAG_OFF; } } #endif /* ** The following global variable is incremented whenever the library ** attempts to open a temporary file. This information is used for ** testing and analysis only. |
︙ | ︙ | |||
4369 4370 4371 4372 4373 4374 4375 | static int pagerStress(void *p, PgHdr *pPg){ Pager *pPager = (Pager *)p; int rc = SQLITE_OK; assert( pPg->pPager==pPager ); assert( pPg->flags&PGHDR_DIRTY ); | | | | > > > > | > | > | 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 | static int pagerStress(void *p, PgHdr *pPg){ Pager *pPager = (Pager *)p; int rc = SQLITE_OK; assert( pPg->pPager==pPager ); assert( pPg->flags&PGHDR_DIRTY ); /* The doNotSpill NOSYNC bit is set during times when doing a sync of ** journal (and adding a new header) is not allowed. This occurs ** during calls to sqlite3PagerWrite() while trying to journal multiple ** pages belonging to the same sector. ** ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling ** regardless of whether or not a sync is required. This is set during ** a rollback or by user request, respectively. ** ** Spilling is also prohibited when in an error state since that could ** lead to database corruption. In the current implementaton it ** is impossible for sqlite3PcacheFetch() to be called with createFlag==1 ** while in the error state, hence it is impossible for this routine to ** be called in the error state. Nevertheless, we include a NEVER() ** test for the error state as a safeguard against future changes. */ if( NEVER(pPager->errCode) ) return SQLITE_OK; testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK ); testcase( pPager->doNotSpill & SPILLFLAG_OFF ); testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC ); if( pPager->doNotSpill && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0 || (pPg->flags & PGHDR_NEED_SYNC)!=0) ){ return SQLITE_OK; } pPg->pDirty = 0; if( pagerUseWal(pPager) ){ /* Write a single frame for this page to the log. */ if( subjRequiresPage(pPg) ){ |
︙ | ︙ | |||
5740 5741 5742 5743 5744 5745 5746 | if( nPagePerSector>1 ){ Pgno nPageCount; /* Total number of pages in database file */ Pgno pg1; /* First page of the sector pPg is located on. */ int nPage = 0; /* Number of pages starting at pg1 to journal */ int ii; /* Loop counter */ int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ | | | | | 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 | if( nPagePerSector>1 ){ Pgno nPageCount; /* Total number of pages in database file */ Pgno pg1; /* First page of the sector pPg is located on. */ int nPage = 0; /* Number of pages starting at pg1 to journal */ int ii; /* Loop counter */ int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow ** a journal header to be written between the pages journaled by ** this function. */ assert( !MEMDB ); assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 ); pPager->doNotSpill |= SPILLFLAG_NOSYNC; /* This trick assumes that both the page-size and sector-size are ** an integer power of 2. It sets variable pg1 to the identifier ** of the first page of the sector pPg is located on. */ pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1; |
︙ | ︙ | |||
5805 5806 5807 5808 5809 5810 5811 | if( pPage ){ pPage->flags |= PGHDR_NEED_SYNC; sqlite3PagerUnref(pPage); } } } | | | | 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 | if( pPage ){ pPage->flags |= PGHDR_NEED_SYNC; sqlite3PagerUnref(pPage); } } } assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 ); pPager->doNotSpill &= ~SPILLFLAG_NOSYNC; }else{ rc = pager_write(pDbPage); } return rc; } /* |
︙ | ︙ |
Changes to src/pager.h.
︙ | ︙ | |||
80 81 82 83 84 85 86 87 88 89 90 91 92 93 | /* ** Flags that make up the mask passed to sqlite3PagerAcquire(). */ #define PAGER_ACQUIRE_NOCONTENT 0x01 /* Do not load data from disk */ #define PAGER_ACQUIRE_READONLY 0x02 /* Read-only page is acceptable */ /* ** The remainder of this file contains the declarations of the functions ** that make up the Pager sub-system API. See source code comments for ** a detailed description of each routine. */ /* Open and close a Pager connection. */ | > > > > > > > > > > > > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | /* ** Flags that make up the mask passed to sqlite3PagerAcquire(). */ #define PAGER_ACQUIRE_NOCONTENT 0x01 /* Do not load data from disk */ #define PAGER_ACQUIRE_READONLY 0x02 /* Read-only page is acceptable */ /* ** Flags for sqlite3PagerSetFlags() */ #define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */ #define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */ #define PAGER_SYNCHRONOUS_FULL 0x03 /* PRAGMA synchronous=FULL */ #define PAGER_SYNCHRONOUS_MASK 0x03 /* Mask for three values above */ #define PAGER_FULLFSYNC 0x04 /* PRAGMA fullfsync=ON */ #define PAGER_CKPT_FULLFSYNC 0x08 /* PRAGMA checkpoint_fullfsync=ON */ #define PAGER_CACHESPILL 0x10 /* PRAGMA cache_spill=ON */ #define PAGER_FLAGS_MASK 0x1c /* All above except SYNCHRONOUS */ /* ** The remainder of this file contains the declarations of the functions ** that make up the Pager sub-system API. See source code comments for ** a detailed description of each routine. */ /* Open and close a Pager connection. */ |
︙ | ︙ | |||
106 107 108 109 110 111 112 | /* Functions used to configure a Pager object. */ void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); int sqlite3PagerSetPagesize(Pager*, u32*, int); int sqlite3PagerMaxPageCount(Pager*, int); void sqlite3PagerSetCachesize(Pager*, int); void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64); void sqlite3PagerShrink(Pager*); | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | /* Functions used to configure a Pager object. */ void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); int sqlite3PagerSetPagesize(Pager*, u32*, int); int sqlite3PagerMaxPageCount(Pager*, int); void sqlite3PagerSetCachesize(Pager*, int); void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64); void sqlite3PagerShrink(Pager*); void sqlite3PagerSetFlags(Pager*,unsigned); int sqlite3PagerLockingMode(Pager *, int); int sqlite3PagerSetJournalMode(Pager *, int); int sqlite3PagerGetJournalMode(Pager*); int sqlite3PagerOkToChangeJournalMode(Pager*); i64 sqlite3PagerJournalSizeLimit(Pager *, i64); sqlite3_backup **sqlite3PagerBackupPtr(Pager*); |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | memcpy(pI64, &value, sizeof(value)); } sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC); sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); } #ifndef SQLITE_OMIT_FLAG_PRAGMAS /* ** Check to see if zRight and zLeft refer to a pragma that queries ** or changes one of the flags in db->flags. Return 1 if so and 0 if not. ** Also, implement the pragma. */ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ static const struct sPragmaType { const char *zName; /* Name of the pragma */ int mask; /* Mask for the db->flags value */ } aPragma[] = { { "full_column_names", SQLITE_FullColNames }, { "short_column_names", SQLITE_ShortColNames }, { "count_changes", SQLITE_CountRows }, { "empty_result_callbacks", SQLITE_NullCallback }, { "legacy_file_format", SQLITE_LegacyFileFmt }, { "fullfsync", SQLITE_FullFSync }, { "checkpoint_fullfsync", SQLITE_CkptFullFSync }, { "reverse_unordered_selects", SQLITE_ReverseOrder }, { "query_only", SQLITE_QueryOnly }, #ifndef SQLITE_OMIT_AUTOMATIC_INDEX { "automatic_index", SQLITE_AutoIndex }, #endif #ifdef SQLITE_DEBUG { "sql_trace", SQLITE_SqlTrace }, | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 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 214 | memcpy(pI64, &value, sizeof(value)); } sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC); sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); } /* ** Set the safety_level and pager flags for pager iDb. Or if iDb<0 ** set these values for all pagers. */ #ifndef SQLITE_OMIT_PAGER_PRAGMAS static void setAllPagerFlags(sqlite3 *db){ if( db->autoCommit ){ Db *pDb = db->aDb; int n = db->nDb; assert( SQLITE_FullFSync==PAGER_FULLFSYNC ); assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC ); assert( SQLITE_CacheSpill==PAGER_CACHESPILL ); assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL) == PAGER_FLAGS_MASK ); assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level ); while( (n--) > 0 ){ if( pDb->pBt ){ sqlite3BtreeSetPagerFlags(pDb->pBt, pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) ); } pDb++; } } } #endif #ifndef SQLITE_OMIT_FLAG_PRAGMAS /* ** Check to see if zRight and zLeft refer to a pragma that queries ** or changes one of the flags in db->flags. Return 1 if so and 0 if not. ** Also, implement the pragma. */ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ static const struct sPragmaType { const char *zName; /* Name of the pragma */ int mask; /* Mask for the db->flags value */ } aPragma[] = { { "full_column_names", SQLITE_FullColNames }, { "short_column_names", SQLITE_ShortColNames }, { "count_changes", SQLITE_CountRows }, { "empty_result_callbacks", SQLITE_NullCallback }, { "legacy_file_format", SQLITE_LegacyFileFmt }, { "fullfsync", SQLITE_FullFSync }, { "checkpoint_fullfsync", SQLITE_CkptFullFSync }, { "cache_spill", SQLITE_CacheSpill }, { "reverse_unordered_selects", SQLITE_ReverseOrder }, { "query_only", SQLITE_QueryOnly }, #ifndef SQLITE_OMIT_AUTOMATIC_INDEX { "automatic_index", SQLITE_AutoIndex }, #endif #ifdef SQLITE_DEBUG { "sql_trace", SQLITE_SqlTrace }, |
︙ | ︙ | |||
962 963 964 965 966 967 968 969 970 971 972 973 974 975 | returnSingleInt(pParse, "synchronous", pDb->safety_level-1); }else{ if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "Safety level may not be changed inside a transaction"); }else{ pDb->safety_level = getSafetyLevel(zRight,0,1)+1; } } }else #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ #ifndef SQLITE_OMIT_FLAG_PRAGMAS if( flagPragma(pParse, zLeft, zRight) ){ | > | < | 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | returnSingleInt(pParse, "synchronous", pDb->safety_level-1); }else{ if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "Safety level may not be changed inside a transaction"); }else{ pDb->safety_level = getSafetyLevel(zRight,0,1)+1; setAllPagerFlags(db); } } }else #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ #ifndef SQLITE_OMIT_FLAG_PRAGMAS if( flagPragma(pParse, zLeft, zRight) ){ setAllPagerFlags(db); }else #endif /* SQLITE_OMIT_FLAG_PRAGMAS */ #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS /* ** PRAGMA table_info(<table>) ** |
︙ | ︙ | |||
1801 1802 1803 1804 1805 1806 1807 | #endif }else #endif {/* Empty ELSE clause */} | < < < < < < < < < < < | 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 | #endif }else #endif {/* Empty ELSE clause */} pragma_out: sqlite3DbFree(db, zLeft); sqlite3DbFree(db, zRight); } #endif /* SQLITE_OMIT_PRAGMA */ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
968 969 970 971 972 973 974 | #define ENC(db) ((db)->aDb[0].pSchema->enc) /* ** Possible values for the sqlite3.flags. */ #define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ #define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */ | > > > | | | | | | | | | | | < < | | | | | | | | | | | 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 | #define ENC(db) ((db)->aDb[0].pSchema->enc) /* ** Possible values for the sqlite3.flags. */ #define SQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */ #define SQLITE_InternChanges 0x00000002 /* Uncommitted Hash table changes */ #define SQLITE_FullFSync 0x00000004 /* Use full fsync on the backend */ #define SQLITE_CkptFullFSync 0x00000008 /* Use full fsync for checkpoint */ #define SQLITE_CacheSpill 0x00000010 /* OK to spill pager cache */ #define SQLITE_FullColNames 0x00000020 /* Show full column names on SELECT */ #define SQLITE_ShortColNames 0x00000040 /* Show short columns names */ #define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */ /* DELETE, or UPDATE and return */ /* the count using a callback. */ #define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */ /* result set is empty */ #define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */ #define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */ #define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */ #define SQLITE_VdbeAddopTrace 0x00001000 /* Trace sqlite3VdbeAddOp() calls */ #define SQLITE_IgnoreChecks 0x00002000 /* Do not enforce check constraints */ #define SQLITE_ReadUncommitted 0x0004000 /* For shared-cache mode */ #define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */ #define SQLITE_RecoveryMode 0x00010000 /* Ignore schema errors */ #define SQLITE_ReverseOrder 0x00020000 /* Reverse unordered SELECTs */ #define SQLITE_RecTriggers 0x00040000 /* Enable recursive triggers */ #define SQLITE_ForeignKeys 0x00080000 /* Enforce foreign key constraints */ #define SQLITE_AutoIndex 0x00100000 /* Enable automatic indexes */ #define SQLITE_PreferBuiltin 0x00200000 /* Preference to built-in funcs */ #define SQLITE_LoadExtension 0x00400000 /* Enable load_extension */ #define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */ #define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */ #define SQLITE_QueryOnly 0x02000000 /* Disable database changes */ /* ** Bits of the sqlite3.dbOptFlags field that are used by the ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to ** selectively disable various optimizations. */ |
︙ | ︙ |
Changes to test/pragma2.test.
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 | source $testdir/tester.tcl # Test organization: # # pragma2-1.*: Test freelist_count pragma on the main database. # pragma2-2.*: Test freelist_count pragma on an attached database. # pragma2-3.*: Test trying to write to the freelist_count is a no-op. # ifcapable !pragma||!schema_pragmas { finish_test return } | > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | source $testdir/tester.tcl # Test organization: # # pragma2-1.*: Test freelist_count pragma on the main database. # pragma2-2.*: Test freelist_count pragma on an attached database. # pragma2-3.*: Test trying to write to the freelist_count is a no-op. # pragma2-4.*: Tests for PRAGMA cache_spill # ifcapable !pragma||!schema_pragmas { finish_test return } |
︙ | ︙ | |||
111 112 113 114 115 116 117 118 119 | do_test pragma2-3.3 { execsql { PRAGMA aux.freelist_count = 500; PRAGMA aux.freelist_count; } } {9 9} } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 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 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | do_test pragma2-3.3 { execsql { PRAGMA aux.freelist_count = 500; PRAGMA aux.freelist_count; } } {9 9} } # Default setting of PRAGMA cache_spill is always ON # db close delete_file test.db test.db-journal delete_file test2.db test2.db-journal sqlite3 db test.db do_execsql_test pragma2-4.1 { PRAGMA cache_spill; PRAGMA main.cache_spill; PRAGMA temp.cache_spill; } {1 1 1} do_execsql_test pragma2-4.2 { PRAGMA cache_spill=OFF; PRAGMA cache_spill; PRAGMA main.cache_spill; PRAGMA temp.cache_spill; } {0 0 0} do_execsql_test pragma2-4.3 { PRAGMA page_size=1024; PRAGMA cache_size=50; BEGIN; CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d); INSERT INTO t1 VALUES(1, randomblob(400), 1, randomblob(400)); INSERT INTO t1 SELECT a+1, randomblob(400), a+1, randomblob(400) FROM t1; INSERT INTO t1 SELECT a+2, randomblob(400), a+2, randomblob(400) FROM t1; INSERT INTO t1 SELECT a+4, randomblob(400), a+4, randomblob(400) FROM t1; INSERT INTO t1 SELECT a+8, randomblob(400), a+8, randomblob(400) FROM t1; INSERT INTO t1 SELECT a+16, randomblob(400), a+16, randomblob(400) FROM t1; INSERT INTO t1 SELECT a+32, randomblob(400), a+32, randomblob(400) FROM t1; INSERT INTO t1 SELECT a+64, randomblob(400), a+64, randomblob(400) FROM t1; COMMIT; ATTACH 'test2.db' AS aux1; CREATE TABLE aux1.t2(a INTEGER PRIMARY KEY, b, c, d); INSERT INTO t2 SELECT * FROM t1; DETACH aux1; PRAGMA cache_spill=ON; } {} do_test pragma2-4.4 { db eval { BEGIN; UPDATE t1 SET c=c+1; PRAGMA lock_status; } } {main exclusive temp unknown} ;# EXCLUSIVE lock due to cache spill do_test pragma2-4.5 { db eval { COMMIT; PRAGMA cache_spill=OFF; BEGIN; UPDATE t1 SET c=c-1; PRAGMA lock_status; } } {main reserved temp unknown} ;# No cache spill, so no exclusive lock # Verify that newly attached databases inherit the cache_spill=OFF # setting. # do_execsql_test pragma2-4.6 { COMMIT; ATTACH 'test2.db' AS aux1; PRAGMA aux1.cache_size=50; BEGIN; UPDATE t2 SET c=c+1; PRAGMA lock_status; } {main unlocked temp unknown aux1 reserved} do_execsql_test pragma2-4.7 { COMMIT; PRAGMA cache_spill=ON; -- Applies to all databases BEGIN; UPDATE t2 SET c=c-1; PRAGMA lock_status; } {main unlocked temp unknown aux1 exclusive} finish_test |