PageRenderTime 103ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 1ms

/Community.CsharpSqlite/src/btree_c.cs

https://bitbucket.org/eumario/csharp-sqlite
C# | 9563 lines | 6185 code | 606 blank | 2772 comment | 1866 complexity | d152abc1eaf5724f7b765226a992bc06 MD5 | raw file
  1. using System;
  2. using System.Diagnostics;
  3. using System.Text;
  4. using i64 = System.Int64;
  5. using u8 = System.Byte;
  6. using u16 = System.UInt16;
  7. using u32 = System.UInt32;
  8. using u64 = System.UInt64;
  9. using sqlite3_int64 = System.Int64;
  10. using Pgno = System.UInt32;
  11. namespace Community.CsharpSqlite
  12. {
  13. using DbPage = Sqlite3.PgHdr;
  14. public partial class Sqlite3
  15. {
  16. /*
  17. ** 2004 April 6
  18. **
  19. ** The author disclaims copyright to this source code. In place of
  20. ** a legal notice, here is a blessing:
  21. **
  22. ** May you do good and not evil.
  23. ** May you find forgiveness for yourself and forgive others.
  24. ** May you share freely, never taking more than you give.
  25. **
  26. ** This file implements a external (disk-based) database using BTrees.
  27. ** See the header comment on "btreeInt.h" for additional information.
  28. ** Including a description of file format and an overview of operation.
  29. *************************************************************************
  30. ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
  31. ** C#-SQLite is an independent reimplementation of the SQLite software library
  32. **
  33. ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2
  34. **
  35. *************************************************************************
  36. */
  37. //#include "btreeInt.h"
  38. /*
  39. ** The header string that appears at the beginning of every
  40. ** SQLite database.
  41. */
  42. static byte[] zMagicHeader = Encoding.UTF8.GetBytes( SQLITE_FILE_HEADER );
  43. /*
  44. ** Set this global variable to 1 to enable tracing using the TRACE
  45. ** macro.
  46. */
  47. #if TRACE
  48. static bool sqlite3BtreeTrace=false; /* True to enable tracing */
  49. //# define TRACE(X) if(sqlite3BtreeTrace){printf X;fflush(stdout);}
  50. static void TRACE(string X, params object[] ap) { if (sqlite3BtreeTrace) printf(X, ap); }
  51. #else
  52. //# define TRACE(X)
  53. static void TRACE( string X, params object[] ap )
  54. {
  55. }
  56. #endif
  57. /*
  58. ** Extract a 2-byte big-endian integer from an array of unsigned bytes.
  59. ** But if the value is zero, make it 65536.
  60. **
  61. ** This routine is used to extract the "offset to cell content area" value
  62. ** from the header of a btree page. If the page size is 65536 and the page
  63. ** is empty, the offset should be 65536, but the 2-byte value stores zero.
  64. ** This routine makes the necessary adjustment to 65536.
  65. */
  66. //#define get2byteNotZero(X) (((((int)get2byte(X))-1)&0xffff)+1)
  67. static int get2byteNotZero( byte[] X, int offset )
  68. {
  69. return ( ( ( ( (int)get2byte( X, offset ) ) - 1 ) & 0xffff ) + 1 );
  70. }
  71. #if !SQLITE_OMIT_SHARED_CACHE
  72. /*
  73. ** A list of BtShared objects that are eligible for participation
  74. ** in shared cache. This variable has file scope during normal builds,
  75. ** but the test harness needs to access it so we make it global for
  76. ** test builds.
  77. **
  78. ** Access to this variable is protected by SQLITE_MUTEX_STATIC_MASTER.
  79. */
  80. #if SQLITE_TEST
  81. BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
  82. #else
  83. static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
  84. #endif
  85. #endif //* SQLITE_OMIT_SHARED_CACHE */
  86. #if !SQLITE_OMIT_SHARED_CACHE
  87. /*
  88. ** Enable or disable the shared pager and schema features.
  89. **
  90. ** This routine has no effect on existing database connections.
  91. ** The shared cache setting effects only future calls to
  92. ** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
  93. */
  94. int sqlite3_enable_shared_cache(int enable){
  95. sqlite3GlobalConfig.sharedCacheEnabled = enable;
  96. return SQLITE_OK;
  97. }
  98. #endif
  99. #if SQLITE_OMIT_SHARED_CACHE
  100. /*
  101. ** The functions querySharedCacheTableLock(), setSharedCacheTableLock(),
  102. ** and clearAllSharedCacheTableLocks()
  103. ** manipulate entries in the BtShared.pLock linked list used to store
  104. ** shared-cache table level locks. If the library is compiled with the
  105. ** shared-cache feature disabled, then there is only ever one user
  106. ** of each BtShared structure and so this locking is not necessary.
  107. ** So define the lock related functions as no-ops.
  108. */
  109. //#define querySharedCacheTableLock(a,b,c) SQLITE_OK
  110. static int querySharedCacheTableLock( Btree p, Pgno iTab, u8 eLock )
  111. {
  112. return SQLITE_OK;
  113. }
  114. //#define setSharedCacheTableLock(a,b,c) SQLITE_OK
  115. //#define clearAllSharedCacheTableLocks(a)
  116. static void clearAllSharedCacheTableLocks( Btree a )
  117. {
  118. }
  119. //#define downgradeAllSharedCacheTableLocks(a)
  120. static void downgradeAllSharedCacheTableLocks( Btree a )
  121. {
  122. }
  123. //#define hasSharedCacheTableLock(a,b,c,d) 1
  124. static bool hasSharedCacheTableLock( Btree a, Pgno b, int c, int d )
  125. {
  126. return true;
  127. }
  128. //#define hasReadConflicts(a, b) 0
  129. static bool hasReadConflicts( Btree a, Pgno b )
  130. {
  131. return false;
  132. }
  133. #endif
  134. #if !SQLITE_OMIT_SHARED_CACHE
  135. #if SQLITE_DEBUG
  136. /*
  137. **** This function is only used as part of an assert() statement. ***
  138. **
  139. ** Check to see if pBtree holds the required locks to read or write to the
  140. ** table with root page iRoot. Return 1 if it does and 0 if not.
  141. **
  142. ** For example, when writing to a table with root-page iRoot via
  143. ** Btree connection pBtree:
  144. **
  145. ** assert( hasSharedCacheTableLock(pBtree, iRoot, 0, WRITE_LOCK) );
  146. **
  147. ** When writing to an index that resides in a sharable database, the
  148. ** caller should have first obtained a lock specifying the root page of
  149. ** the corresponding table. This makes things a bit more complicated,
  150. ** as this module treats each table as a separate structure. To determine
  151. ** the table corresponding to the index being written, this
  152. ** function has to search through the database schema.
  153. **
  154. ** Instead of a lock on the table/index rooted at page iRoot, the caller may
  155. ** hold a write-lock on the schema table (root page 1). This is also
  156. ** acceptable.
  157. */
  158. static int hasSharedCacheTableLock(
  159. Btree pBtree, /* Handle that must hold lock */
  160. Pgno iRoot, /* Root page of b-tree */
  161. int isIndex, /* True if iRoot is the root of an index b-tree */
  162. int eLockType /* Required lock type (READ_LOCK or WRITE_LOCK) */
  163. ){
  164. Schema pSchema = (Schema *)pBtree.pBt.pSchema;
  165. Pgno iTab = 0;
  166. BtLock pLock;
  167. /* If this database is not shareable, or if the client is reading
  168. ** and has the read-uncommitted flag set, then no lock is required.
  169. ** Return true immediately.
  170. */
  171. if( (pBtree.sharable==null)
  172. || (eLockType==READ_LOCK && (pBtree.db.flags & SQLITE_ReadUncommitted))
  173. ){
  174. return 1;
  175. }
  176. /* If the client is reading or writing an index and the schema is
  177. ** not loaded, then it is too difficult to actually check to see if
  178. ** the correct locks are held. So do not bother - just return true.
  179. ** This case does not come up very often anyhow.
  180. */
  181. if( isIndex && (!pSchema || (pSchema->flags&DB_SchemaLoaded)==0) ){
  182. return 1;
  183. }
  184. /* Figure out the root-page that the lock should be held on. For table
  185. ** b-trees, this is just the root page of the b-tree being read or
  186. ** written. For index b-trees, it is the root page of the associated
  187. ** table. */
  188. if( isIndex ){
  189. HashElem p;
  190. for(p=sqliteHashFirst(pSchema.idxHash); p!=null; p=sqliteHashNext(p)){
  191. Index pIdx = (Index *)sqliteHashData(p);
  192. if( pIdx.tnum==(int)iRoot ){
  193. iTab = pIdx.pTable.tnum;
  194. }
  195. }
  196. }else{
  197. iTab = iRoot;
  198. }
  199. /* Search for the required lock. Either a write-lock on root-page iTab, a
  200. ** write-lock on the schema table, or (if the client is reading) a
  201. ** read-lock on iTab will suffice. Return 1 if any of these are found. */
  202. for(pLock=pBtree.pBt.pLock; pLock; pLock=pLock.pNext){
  203. if( pLock.pBtree==pBtree
  204. && (pLock.iTable==iTab || (pLock.eLock==WRITE_LOCK && pLock.iTable==1))
  205. && pLock.eLock>=eLockType
  206. ){
  207. return 1;
  208. }
  209. }
  210. /* Failed to find the required lock. */
  211. return 0;
  212. }
  213. #endif //* SQLITE_DEBUG */
  214. #if SQLITE_DEBUG
  215. /*
  216. ** This function may be used as part of assert() statements only. ****
  217. **
  218. ** Return true if it would be illegal for pBtree to write into the
  219. ** table or index rooted at iRoot because other shared connections are
  220. ** simultaneously reading that same table or index.
  221. **
  222. ** It is illegal for pBtree to write if some other Btree object that
  223. ** shares the same BtShared object is currently reading or writing
  224. ** the iRoot table. Except, if the other Btree object has the
  225. ** read-uncommitted flag set, then it is OK for the other object to
  226. ** have a read cursor.
  227. **
  228. ** For example, before writing to any part of the table or index
  229. ** rooted at page iRoot, one should call:
  230. **
  231. ** assert( !hasReadConflicts(pBtree, iRoot) );
  232. */
  233. static int hasReadConflicts(Btree pBtree, Pgno iRoot){
  234. BtCursor p;
  235. for(p=pBtree.pBt.pCursor; p!=null; p=p.pNext){
  236. if( p.pgnoRoot==iRoot
  237. && p.pBtree!=pBtree
  238. && 0==(p.pBtree.db.flags & SQLITE_ReadUncommitted)
  239. ){
  240. return 1;
  241. }
  242. }
  243. return 0;
  244. }
  245. #endif //* #if SQLITE_DEBUG */
  246. /*
  247. ** Query to see if Btree handle p may obtain a lock of type eLock
  248. ** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
  249. ** SQLITE_OK if the lock may be obtained (by calling
  250. ** setSharedCacheTableLock()), or SQLITE_LOCKED if not.
  251. */
  252. static int querySharedCacheTableLock(Btree p, Pgno iTab, u8 eLock){
  253. BtShared pBt = p.pBt;
  254. BtLock pIter;
  255. Debug.Assert( sqlite3BtreeHoldsMutex(p) );
  256. Debug.Assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
  257. Debug.Assert( p.db!=null );
  258. Debug.Assert( !(p.db.flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 );
  259. /* If requesting a write-lock, then the Btree must have an open write
  260. ** transaction on this file. And, obviously, for this to be so there
  261. ** must be an open write transaction on the file itself.
  262. */
  263. Debug.Assert( eLock==READ_LOCK || (p==pBt.pWriter && p.inTrans==TRANS_WRITE) );
  264. Debug.Assert( eLock==READ_LOCK || pBt.inTransaction==TRANS_WRITE );
  265. /* This routine is a no-op if the shared-cache is not enabled */
  266. if( !p.sharable ){
  267. return SQLITE_OK;
  268. }
  269. /* If some other connection is holding an exclusive lock, the
  270. ** requested lock may not be obtained.
  271. */
  272. if( pBt.pWriter!=p && pBt.isExclusive ){
  273. sqlite3ConnectionBlocked(p.db, pBt.pWriter.db);
  274. return SQLITE_LOCKED_SHAREDCACHE;
  275. }
  276. for(pIter=pBt.pLock; pIter; pIter=pIter.pNext){
  277. /* The condition (pIter.eLock!=eLock) in the following if(...)
  278. ** statement is a simplification of:
  279. **
  280. ** (eLock==WRITE_LOCK || pIter.eLock==WRITE_LOCK)
  281. **
  282. ** since we know that if eLock==WRITE_LOCK, then no other connection
  283. ** may hold a WRITE_LOCK on any table in this file (since there can
  284. ** only be a single writer).
  285. */
  286. Debug.Assert( pIter.eLock==READ_LOCK || pIter.eLock==WRITE_LOCK );
  287. Debug.Assert( eLock==READ_LOCK || pIter.pBtree==p || pIter.eLock==READ_LOCK);
  288. if( pIter.pBtree!=p && pIter.iTable==iTab && pIter.eLock!=eLock ){
  289. sqlite3ConnectionBlocked(p.db, pIter.pBtree.db);
  290. if( eLock==WRITE_LOCK ){
  291. Debug.Assert( p==pBt.pWriter );
  292. pBt.isPending = 1;
  293. }
  294. return SQLITE_LOCKED_SHAREDCACHE;
  295. }
  296. }
  297. return SQLITE_OK;
  298. }
  299. #endif //* !SQLITE_OMIT_SHARED_CACHE */
  300. #if !SQLITE_OMIT_SHARED_CACHE
  301. /*
  302. ** Add a lock on the table with root-page iTable to the shared-btree used
  303. ** by Btree handle p. Parameter eLock must be either READ_LOCK or
  304. ** WRITE_LOCK.
  305. **
  306. ** This function assumes the following:
  307. **
  308. ** (a) The specified Btree object p is connected to a sharable
  309. ** database (one with the BtShared.sharable flag set), and
  310. **
  311. ** (b) No other Btree objects hold a lock that conflicts
  312. ** with the requested lock (i.e. querySharedCacheTableLock() has
  313. ** already been called and returned SQLITE_OK).
  314. **
  315. ** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM
  316. ** is returned if a malloc attempt fails.
  317. */
  318. static int setSharedCacheTableLock(Btree p, Pgno iTable, u8 eLock){
  319. BtShared pBt = p.pBt;
  320. BtLock pLock = 0;
  321. BtLock pIter;
  322. Debug.Assert( sqlite3BtreeHoldsMutex(p) );
  323. Debug.Assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
  324. Debug.Assert( p.db!=null );
  325. /* A connection with the read-uncommitted flag set will never try to
  326. ** obtain a read-lock using this function. The only read-lock obtained
  327. ** by a connection in read-uncommitted mode is on the sqlite_master
  328. ** table, and that lock is obtained in BtreeBeginTrans(). */
  329. Debug.Assert( 0==(p.db.flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK );
  330. /* This function should only be called on a sharable b-tree after it
  331. ** has been determined that no other b-tree holds a conflicting lock. */
  332. Debug.Assert( p.sharable );
  333. Debug.Assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) );
  334. /* First search the list for an existing lock on this table. */
  335. for(pIter=pBt.pLock; pIter; pIter=pIter.pNext){
  336. if( pIter.iTable==iTable && pIter.pBtree==p ){
  337. pLock = pIter;
  338. break;
  339. }
  340. }
  341. /* If the above search did not find a BtLock struct associating Btree p
  342. ** with table iTable, allocate one and link it into the list.
  343. */
  344. if( !pLock ){
  345. pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock));
  346. if( !pLock ){
  347. return SQLITE_NOMEM;
  348. }
  349. pLock.iTable = iTable;
  350. pLock.pBtree = p;
  351. pLock.pNext = pBt.pLock;
  352. pBt.pLock = pLock;
  353. }
  354. /* Set the BtLock.eLock variable to the maximum of the current lock
  355. ** and the requested lock. This means if a write-lock was already held
  356. ** and a read-lock requested, we don't incorrectly downgrade the lock.
  357. */
  358. Debug.Assert( WRITE_LOCK>READ_LOCK );
  359. if( eLock>pLock.eLock ){
  360. pLock.eLock = eLock;
  361. }
  362. return SQLITE_OK;
  363. }
  364. #endif //* !SQLITE_OMIT_SHARED_CACHE */
  365. #if !SQLITE_OMIT_SHARED_CACHE
  366. /*
  367. ** Release all the table locks (locks obtained via calls to
  368. ** the setSharedCacheTableLock() procedure) held by Btree object p.
  369. **
  370. ** This function assumes that Btree p has an open read or write
  371. ** transaction. If it does not, then the BtShared.isPending variable
  372. ** may be incorrectly cleared.
  373. */
  374. static void clearAllSharedCacheTableLocks(Btree p){
  375. BtShared pBt = p.pBt;
  376. BtLock **ppIter = &pBt.pLock;
  377. Debug.Assert( sqlite3BtreeHoldsMutex(p) );
  378. Debug.Assert( p.sharable || 0==*ppIter );
  379. Debug.Assert( p.inTrans>0 );
  380. while( ppIter ){
  381. BtLock pLock = ppIter;
  382. Debug.Assert( pBt.isExclusive==null || pBt.pWriter==pLock.pBtree );
  383. Debug.Assert( pLock.pBtree.inTrans>=pLock.eLock );
  384. if( pLock.pBtree==p ){
  385. ppIter = pLock.pNext;
  386. Debug.Assert( pLock.iTable!=1 || pLock==&p.lock );
  387. if( pLock.iTable!=1 ){
  388. pLock=null;//sqlite3_free(ref pLock);
  389. }
  390. }else{
  391. ppIter = &pLock.pNext;
  392. }
  393. }
  394. Debug.Assert( pBt.isPending==null || pBt.pWriter );
  395. if( pBt.pWriter==p ){
  396. pBt.pWriter = 0;
  397. pBt.isExclusive = 0;
  398. pBt.isPending = 0;
  399. }else if( pBt.nTransaction==2 ){
  400. /* This function is called when Btree p is concluding its
  401. ** transaction. If there currently exists a writer, and p is not
  402. ** that writer, then the number of locks held by connections other
  403. ** than the writer must be about to drop to zero. In this case
  404. ** set the isPending flag to 0.
  405. **
  406. ** If there is not currently a writer, then BtShared.isPending must
  407. ** be zero already. So this next line is harmless in that case.
  408. */
  409. pBt.isPending = 0;
  410. }
  411. }
  412. /*
  413. ** This function changes all write-locks held by Btree p into read-locks.
  414. */
  415. static void downgradeAllSharedCacheTableLocks(Btree p){
  416. BtShared pBt = p.pBt;
  417. if( pBt.pWriter==p ){
  418. BtLock pLock;
  419. pBt.pWriter = 0;
  420. pBt.isExclusive = 0;
  421. pBt.isPending = 0;
  422. for(pLock=pBt.pLock; pLock; pLock=pLock.pNext){
  423. Debug.Assert( pLock.eLock==READ_LOCK || pLock.pBtree==p );
  424. pLock.eLock = READ_LOCK;
  425. }
  426. }
  427. }
  428. #endif //* SQLITE_OMIT_SHARED_CACHE */
  429. //static void releasePage(MemPage pPage); /* Forward reference */
  430. /*
  431. ***** This routine is used inside of assert() only ****
  432. **
  433. ** Verify that the cursor holds the mutex on its BtShared
  434. */
  435. #if SQLITE_DEBUG
  436. static bool cursorHoldsMutex( BtCursor p )
  437. {
  438. return sqlite3_mutex_held( p.pBt.mutex );
  439. }
  440. #else
  441. static bool cursorHoldsMutex(BtCursor p) { return true; }
  442. #endif
  443. #if !SQLITE_OMIT_INCRBLOB
  444. /*
  445. ** Invalidate the overflow page-list cache for cursor pCur, if any.
  446. */
  447. static void invalidateOverflowCache(BtCursor pCur){
  448. Debug.Assert( cursorHoldsMutex(pCur) );
  449. //sqlite3_free(ref pCur.aOverflow);
  450. pCur.aOverflow = null;
  451. }
  452. /*
  453. ** Invalidate the overflow page-list cache for all cursors opened
  454. ** on the shared btree structure pBt.
  455. */
  456. static void invalidateAllOverflowCache(BtShared pBt){
  457. BtCursor p;
  458. Debug.Assert( sqlite3_mutex_held(pBt.mutex) );
  459. for(p=pBt.pCursor; p!=null; p=p.pNext){
  460. invalidateOverflowCache(p);
  461. }
  462. }
  463. /*
  464. ** This function is called before modifying the contents of a table
  465. ** to invalidate any incrblob cursors that are open on the
  466. ** row or one of the rows being modified.
  467. **
  468. ** If argument isClearTable is true, then the entire contents of the
  469. ** table is about to be deleted. In this case invalidate all incrblob
  470. ** cursors open on any row within the table with root-page pgnoRoot.
  471. **
  472. ** Otherwise, if argument isClearTable is false, then the row with
  473. ** rowid iRow is being replaced or deleted. In this case invalidate
  474. ** only those incrblob cursors open on that specific row.
  475. */
  476. static void invalidateIncrblobCursors(
  477. Btree pBtree, /* The database file to check */
  478. i64 iRow, /* The rowid that might be changing */
  479. int isClearTable /* True if all rows are being deleted */
  480. ){
  481. BtCursor p;
  482. BtShared pBt = pBtree.pBt;
  483. Debug.Assert( sqlite3BtreeHoldsMutex(pBtree) );
  484. for(p=pBt.pCursor; p!=null; p=p.pNext){
  485. if( p.isIncrblobHandle && (isClearTable || p.info.nKey==iRow) ){
  486. p.eState = CURSOR_INVALID;
  487. }
  488. }
  489. }
  490. #else
  491. /* Stub functions when INCRBLOB is omitted */
  492. //#define invalidateOverflowCache(x)
  493. static void invalidateOverflowCache( BtCursor pCur )
  494. {
  495. }
  496. //#define invalidateAllOverflowCache(x)
  497. static void invalidateAllOverflowCache( BtShared pBt )
  498. {
  499. }
  500. //#define invalidateIncrblobCursors(x,y,z)
  501. static void invalidateIncrblobCursors( Btree x, i64 y, int z )
  502. {
  503. }
  504. #endif //* SQLITE_OMIT_INCRBLOB */
  505. /*
  506. ** Set bit pgno of the BtShared.pHasContent bitvec. This is called
  507. ** when a page that previously contained data becomes a free-list leaf
  508. ** page.
  509. **
  510. ** The BtShared.pHasContent bitvec exists to work around an obscure
  511. ** bug caused by the interaction of two useful IO optimizations surrounding
  512. ** free-list leaf pages:
  513. **
  514. ** 1) When all data is deleted from a page and the page becomes
  515. ** a free-list leaf page, the page is not written to the database
  516. ** (as free-list leaf pages contain no meaningful data). Sometimes
  517. ** such a page is not even journalled (as it will not be modified,
  518. ** why bother journalling it?).
  519. **
  520. ** 2) When a free-list leaf page is reused, its content is not read
  521. ** from the database or written to the journal file (why should it
  522. ** be, if it is not at all meaningful?).
  523. **
  524. ** By themselves, these optimizations work fine and provide a handy
  525. ** performance boost to bulk delete or insert operations. However, if
  526. ** a page is moved to the free-list and then reused within the same
  527. ** transaction, a problem comes up. If the page is not journalled when
  528. ** it is moved to the free-list and it is also not journalled when it
  529. ** is extracted from the free-list and reused, then the original data
  530. ** may be lost. In the event of a rollback, it may not be possible
  531. ** to restore the database to its original configuration.
  532. **
  533. ** The solution is the BtShared.pHasContent bitvec. Whenever a page is
  534. ** moved to become a free-list leaf page, the corresponding bit is
  535. ** set in the bitvec. Whenever a leaf page is extracted from the free-list,
  536. ** optimization 2 above is omitted if the corresponding bit is already
  537. ** set in BtShared.pHasContent. The contents of the bitvec are cleared
  538. ** at the end of every transaction.
  539. */
  540. static int btreeSetHasContent( BtShared pBt, Pgno pgno )
  541. {
  542. int rc = SQLITE_OK;
  543. if ( null == pBt.pHasContent )
  544. {
  545. Debug.Assert( pgno <= pBt.nPage );
  546. pBt.pHasContent = sqlite3BitvecCreate( pBt.nPage );
  547. //if ( null == pBt.pHasContent )
  548. //{
  549. // rc = SQLITE_NOMEM;
  550. //}
  551. }
  552. if ( rc == SQLITE_OK && pgno <= sqlite3BitvecSize( pBt.pHasContent ) )
  553. {
  554. rc = sqlite3BitvecSet( pBt.pHasContent, pgno );
  555. }
  556. return rc;
  557. }
  558. /*
  559. ** Query the BtShared.pHasContent vector.
  560. **
  561. ** This function is called when a free-list leaf page is removed from the
  562. ** free-list for reuse. It returns false if it is safe to retrieve the
  563. ** page from the pager layer with the 'no-content' flag set. True otherwise.
  564. */
  565. static bool btreeGetHasContent( BtShared pBt, Pgno pgno )
  566. {
  567. Bitvec p = pBt.pHasContent;
  568. return ( p != null && ( pgno > sqlite3BitvecSize( p ) || sqlite3BitvecTest( p, pgno ) != 0 ) );
  569. }
  570. /*
  571. ** Clear (destroy) the BtShared.pHasContent bitvec. This should be
  572. ** invoked at the conclusion of each write-transaction.
  573. */
  574. static void btreeClearHasContent( BtShared pBt )
  575. {
  576. sqlite3BitvecDestroy( ref pBt.pHasContent );
  577. pBt.pHasContent = null;
  578. }
  579. /*
  580. ** Save the current cursor position in the variables BtCursor.nKey
  581. ** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
  582. **
  583. ** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID)
  584. ** prior to calling this routine.
  585. */
  586. static int saveCursorPosition( BtCursor pCur )
  587. {
  588. int rc;
  589. Debug.Assert( CURSOR_VALID == pCur.eState );
  590. Debug.Assert( null == pCur.pKey );
  591. Debug.Assert( cursorHoldsMutex( pCur ) );
  592. rc = sqlite3BtreeKeySize( pCur, ref pCur.nKey );
  593. Debug.Assert( rc == SQLITE_OK ); /* KeySize() cannot fail */
  594. /* If this is an intKey table, then the above call to BtreeKeySize()
  595. ** stores the integer key in pCur.nKey. In this case this value is
  596. ** all that is required. Otherwise, if pCur is not open on an intKey
  597. ** table, then malloc space for and store the pCur.nKey bytes of key
  598. ** data.
  599. */
  600. if ( 0 == pCur.apPage[0].intKey )
  601. {
  602. byte[] pKey = sqlite3Malloc( (int)pCur.nKey );
  603. //if( pKey !=null){
  604. rc = sqlite3BtreeKey( pCur, 0, (u32)pCur.nKey, pKey );
  605. if ( rc == SQLITE_OK )
  606. {
  607. pCur.pKey = pKey;
  608. }
  609. //else{
  610. // sqlite3_free(ref pKey);
  611. //}
  612. //}else{
  613. // rc = SQLITE_NOMEM;
  614. //}
  615. }
  616. Debug.Assert( 0 == pCur.apPage[0].intKey || null == pCur.pKey );
  617. if ( rc == SQLITE_OK )
  618. {
  619. int i;
  620. for ( i = 0; i <= pCur.iPage; i++ )
  621. {
  622. releasePage( pCur.apPage[i] );
  623. pCur.apPage[i] = null;
  624. }
  625. pCur.iPage = -1;
  626. pCur.eState = CURSOR_REQUIRESEEK;
  627. }
  628. invalidateOverflowCache( pCur );
  629. return rc;
  630. }
  631. /*
  632. ** Save the positions of all cursors (except pExcept) that are open on
  633. ** the table with root-page iRoot. Usually, this is called just before cursor
  634. ** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
  635. */
  636. static int saveAllCursors( BtShared pBt, Pgno iRoot, BtCursor pExcept )
  637. {
  638. BtCursor p;
  639. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  640. Debug.Assert( pExcept == null || pExcept.pBt == pBt );
  641. for ( p = pBt.pCursor; p != null; p = p.pNext )
  642. {
  643. if ( p != pExcept && ( 0 == iRoot || p.pgnoRoot == iRoot ) &&
  644. p.eState == CURSOR_VALID )
  645. {
  646. int rc = saveCursorPosition( p );
  647. if ( SQLITE_OK != rc )
  648. {
  649. return rc;
  650. }
  651. }
  652. }
  653. return SQLITE_OK;
  654. }
  655. /*
  656. ** Clear the current cursor position.
  657. */
  658. static void sqlite3BtreeClearCursor( BtCursor pCur )
  659. {
  660. Debug.Assert( cursorHoldsMutex( pCur ) );
  661. sqlite3_free( ref pCur.pKey );
  662. pCur.eState = CURSOR_INVALID;
  663. }
  664. /*
  665. ** In this version of BtreeMoveto, pKey is a packed index record
  666. ** such as is generated by the OP_MakeRecord opcode. Unpack the
  667. ** record and then call BtreeMovetoUnpacked() to do the work.
  668. */
  669. static int btreeMoveto(
  670. BtCursor pCur, /* Cursor open on the btree to be searched */
  671. byte[] pKey, /* Packed key if the btree is an index */
  672. i64 nKey, /* Integer key for tables. Size of pKey for indices */
  673. int bias, /* Bias search to the high end */
  674. ref int pRes /* Write search results here */
  675. )
  676. {
  677. int rc; /* Status code */
  678. UnpackedRecord pIdxKey; /* Unpacked index key */
  679. UnpackedRecord aSpace = new UnpackedRecord();//char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */
  680. if ( pKey != null )
  681. {
  682. Debug.Assert( nKey == (i64)(int)nKey );
  683. pIdxKey = sqlite3VdbeRecordUnpack( pCur.pKeyInfo, (int)nKey, pKey,
  684. aSpace, 16 );//sizeof( aSpace ) );
  685. //if ( pIdxKey == null )
  686. // return SQLITE_NOMEM;
  687. }
  688. else
  689. {
  690. pIdxKey = null;
  691. }
  692. rc = sqlite3BtreeMovetoUnpacked( pCur, pIdxKey, nKey, bias != 0 ? 1 : 0, ref pRes );
  693. if ( pKey != null )
  694. {
  695. sqlite3VdbeDeleteUnpackedRecord( pIdxKey );
  696. }
  697. return rc;
  698. }
  699. /*
  700. ** Restore the cursor to the position it was in (or as close to as possible)
  701. ** when saveCursorPosition() was called. Note that this call deletes the
  702. ** saved position info stored by saveCursorPosition(), so there can be
  703. ** at most one effective restoreCursorPosition() call after each
  704. ** saveCursorPosition().
  705. */
  706. static int btreeRestoreCursorPosition( BtCursor pCur )
  707. {
  708. int rc;
  709. Debug.Assert( cursorHoldsMutex( pCur ) );
  710. Debug.Assert( pCur.eState >= CURSOR_REQUIRESEEK );
  711. if ( pCur.eState == CURSOR_FAULT )
  712. {
  713. return pCur.skipNext;
  714. }
  715. pCur.eState = CURSOR_INVALID;
  716. rc = btreeMoveto( pCur, pCur.pKey, pCur.nKey, 0, ref pCur.skipNext );
  717. if ( rc == SQLITE_OK )
  718. {
  719. //sqlite3_free(ref pCur.pKey);
  720. pCur.pKey = null;
  721. Debug.Assert( pCur.eState == CURSOR_VALID || pCur.eState == CURSOR_INVALID );
  722. }
  723. return rc;
  724. }
  725. //#define restoreCursorPosition(p) \
  726. // (p.eState>=CURSOR_REQUIRESEEK ? \
  727. // btreeRestoreCursorPosition(p) : \
  728. // SQLITE_OK)
  729. static int restoreCursorPosition( BtCursor pCur )
  730. {
  731. if ( pCur.eState >= CURSOR_REQUIRESEEK )
  732. return btreeRestoreCursorPosition( pCur );
  733. else
  734. return SQLITE_OK;
  735. }
  736. /*
  737. ** Determine whether or not a cursor has moved from the position it
  738. ** was last placed at. Cursors can move when the row they are pointing
  739. ** at is deleted out from under them.
  740. **
  741. ** This routine returns an error code if something goes wrong. The
  742. ** integer pHasMoved is set to one if the cursor has moved and 0 if not.
  743. */
  744. static int sqlite3BtreeCursorHasMoved( BtCursor pCur, ref int pHasMoved )
  745. {
  746. int rc;
  747. rc = restoreCursorPosition( pCur );
  748. if ( rc != 0 )
  749. {
  750. pHasMoved = 1;
  751. return rc;
  752. }
  753. if ( pCur.eState != CURSOR_VALID || pCur.skipNext != 0 )
  754. {
  755. pHasMoved = 1;
  756. }
  757. else
  758. {
  759. pHasMoved = 0;
  760. }
  761. return SQLITE_OK;
  762. }
  763. #if !SQLITE_OMIT_AUTOVACUUM
  764. /*
  765. ** Given a page number of a regular database page, return the page
  766. ** number for the pointer-map page that contains the entry for the
  767. ** input page number.
  768. **
  769. ** Return 0 (not a valid page) for pgno==1 since there is
  770. ** no pointer map associated with page 1. The integrity_check logic
  771. ** requires that ptrmapPageno(*,1)!=1.
  772. */
  773. static Pgno ptrmapPageno( BtShared pBt, Pgno pgno )
  774. {
  775. int nPagesPerMapPage;
  776. Pgno iPtrMap, ret;
  777. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  778. if ( pgno < 2 )
  779. return 0;
  780. nPagesPerMapPage = (int)( pBt.usableSize / 5 + 1 );
  781. iPtrMap = (Pgno)( ( pgno - 2 ) / nPagesPerMapPage );
  782. ret = (Pgno)( iPtrMap * nPagesPerMapPage ) + 2;
  783. if ( ret == PENDING_BYTE_PAGE( pBt ) )
  784. {
  785. ret++;
  786. }
  787. return ret;
  788. }
  789. /*
  790. ** Write an entry into the pointer map.
  791. **
  792. ** This routine updates the pointer map entry for page number 'key'
  793. ** so that it maps to type 'eType' and parent page number 'pgno'.
  794. **
  795. ** If pRC is initially non-zero (non-SQLITE_OK) then this routine is
  796. ** a no-op. If an error occurs, the appropriate error code is written
  797. ** into pRC.
  798. */
  799. static void ptrmapPut( BtShared pBt, Pgno key, u8 eType, Pgno parent, ref int pRC )
  800. {
  801. PgHdr pDbPage = new PgHdr(); /* The pointer map page */
  802. u8[] pPtrmap; /* The pointer map data */
  803. Pgno iPtrmap; /* The pointer map page number */
  804. int offset; /* Offset in pointer map page */
  805. int rc; /* Return code from subfunctions */
  806. if ( pRC != 0 )
  807. return;
  808. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  809. /* The master-journal page number must never be used as a pointer map page */
  810. Debug.Assert( false == PTRMAP_ISPAGE( pBt, PENDING_BYTE_PAGE( pBt ) ) );
  811. Debug.Assert( pBt.autoVacuum );
  812. if ( key == 0 )
  813. {
  814. pRC = SQLITE_CORRUPT_BKPT();
  815. return;
  816. }
  817. iPtrmap = PTRMAP_PAGENO( pBt, key );
  818. rc = sqlite3PagerGet( pBt.pPager, iPtrmap, ref pDbPage );
  819. if ( rc != SQLITE_OK )
  820. {
  821. pRC = rc;
  822. return;
  823. }
  824. offset = (int)PTRMAP_PTROFFSET( iPtrmap, key );
  825. if ( offset < 0 )
  826. {
  827. pRC = SQLITE_CORRUPT_BKPT();
  828. goto ptrmap_exit;
  829. }
  830. Debug.Assert( offset <= (int)pBt.usableSize - 5 );
  831. pPtrmap = sqlite3PagerGetData( pDbPage );
  832. if ( eType != pPtrmap[offset] || sqlite3Get4byte( pPtrmap, offset + 1 ) != parent )
  833. {
  834. TRACE( "PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent );
  835. pRC = rc = sqlite3PagerWrite( pDbPage );
  836. if ( rc == SQLITE_OK )
  837. {
  838. pPtrmap[offset] = eType;
  839. sqlite3Put4byte( pPtrmap, offset + 1, parent );
  840. }
  841. }
  842. ptrmap_exit:
  843. sqlite3PagerUnref( pDbPage );
  844. }
  845. /*
  846. ** Read an entry from the pointer map.
  847. **
  848. ** This routine retrieves the pointer map entry for page 'key', writing
  849. ** the type and parent page number to pEType and pPgno respectively.
  850. ** An error code is returned if something goes wrong, otherwise SQLITE_OK.
  851. */
  852. static int ptrmapGet( BtShared pBt, Pgno key, ref u8 pEType, ref Pgno pPgno )
  853. {
  854. PgHdr pDbPage = new PgHdr();/* The pointer map page */
  855. int iPtrmap; /* Pointer map page index */
  856. u8[] pPtrmap; /* Pointer map page data */
  857. int offset; /* Offset of entry in pointer map */
  858. int rc;
  859. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  860. iPtrmap = (int)PTRMAP_PAGENO( pBt, key );
  861. rc = sqlite3PagerGet( pBt.pPager, (u32)iPtrmap, ref pDbPage );
  862. if ( rc != 0 )
  863. {
  864. return rc;
  865. }
  866. pPtrmap = sqlite3PagerGetData( pDbPage );
  867. offset = (int)PTRMAP_PTROFFSET( (u32)iPtrmap, key );
  868. if ( offset < 0 )
  869. {
  870. sqlite3PagerUnref( pDbPage );
  871. return SQLITE_CORRUPT_BKPT();
  872. }
  873. Debug.Assert( offset <= (int)pBt.usableSize - 5 );
  874. // Under C# pEType will always exist. No need to test; //
  875. //Debug.Assert( pEType != 0 );
  876. pEType = pPtrmap[offset];
  877. // Under C# pPgno will always exist. No need to test; //
  878. //if ( pPgno != 0 )
  879. pPgno = sqlite3Get4byte( pPtrmap, offset + 1 );
  880. sqlite3PagerUnref( pDbPage );
  881. if ( pEType < 1 || pEType > 5 )
  882. return SQLITE_CORRUPT_BKPT();
  883. return SQLITE_OK;
  884. }
  885. #else //* if defined SQLITE_OMIT_AUTOVACUUM */
  886. //#define ptrmapPut(w,x,y,z,rc)
  887. //#define ptrmapGet(w,x,y,z) SQLITE_OK
  888. //#define ptrmapPutOvflPtr(x, y, rc)
  889. #endif
  890. /*
  891. ** Given a btree page and a cell index (0 means the first cell on
  892. ** the page, 1 means the second cell, and so forth) return a pointer
  893. ** to the cell content.
  894. **
  895. ** This routine works only for pages that do not contain overflow cells.
  896. */
  897. //#define findCell(P,I) \
  898. // ((P).aData + ((P).maskPage & get2byte((P).aData[(P).cellOffset+2*(I)])))
  899. static int findCell( MemPage pPage, int iCell )
  900. {
  901. return get2byte( pPage.aData, pPage.cellOffset + 2 * ( iCell ) );
  902. }
  903. //#define findCellv2(D,M,O,I) (D+(M&get2byte(D+(O+2*(I)))))
  904. static u8[] findCellv2( u8[] pPage, u16 iCell, u16 O, int I )
  905. {
  906. Debugger.Break();
  907. return pPage;
  908. }
  909. /*
  910. ** This a more complex version of findCell() that works for
  911. ** pages that do contain overflow cells.
  912. */
  913. static int findOverflowCell( MemPage pPage, int iCell )
  914. {
  915. int i;
  916. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  917. for ( i = pPage.nOverflow - 1; i >= 0; i-- )
  918. {
  919. int k;
  920. _OvflCell pOvfl;
  921. pOvfl = pPage.aOvfl[i];
  922. k = pOvfl.idx;
  923. if ( k <= iCell )
  924. {
  925. if ( k == iCell )
  926. {
  927. //return pOvfl.pCell;
  928. return -i - 1; // Negative Offset means overflow cells
  929. }
  930. iCell--;
  931. }
  932. }
  933. return findCell( pPage, iCell );
  934. }
  935. /*
  936. ** Parse a cell content block and fill in the CellInfo structure. There
  937. ** are two versions of this function. btreeParseCell() takes a
  938. ** cell index as the second argument and btreeParseCellPtr()
  939. ** takes a pointer to the body of the cell as its second argument.
  940. **
  941. ** Within this file, the parseCell() macro can be called instead of
  942. ** btreeParseCellPtr(). Using some compilers, this will be faster.
  943. */
  944. //OVERLOADS
  945. static void btreeParseCellPtr(
  946. MemPage pPage, /* Page containing the cell */
  947. int iCell, /* Pointer to the cell text. */
  948. ref CellInfo pInfo /* Fill in this structure */
  949. )
  950. {
  951. btreeParseCellPtr( pPage, pPage.aData, iCell, ref pInfo );
  952. }
  953. static void btreeParseCellPtr(
  954. MemPage pPage, /* Page containing the cell */
  955. byte[] pCell, /* The actual data */
  956. ref CellInfo pInfo /* Fill in this structure */
  957. )
  958. {
  959. btreeParseCellPtr( pPage, pCell, 0, ref pInfo );
  960. }
  961. static void btreeParseCellPtr(
  962. MemPage pPage, /* Page containing the cell */
  963. u8[] pCell, /* Pointer to the cell text. */
  964. int iCell, /* Pointer to the cell text. */
  965. ref CellInfo pInfo /* Fill in this structure */
  966. )
  967. {
  968. u16 n; /* Number bytes in cell content header */
  969. u32 nPayload = 0; /* Number of bytes of cell payload */
  970. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  971. if ( pInfo.pCell != pCell )
  972. pInfo.pCell = pCell;
  973. pInfo.iCell = iCell;
  974. Debug.Assert( pPage.leaf == 0 || pPage.leaf == 1 );
  975. n = pPage.childPtrSize;
  976. Debug.Assert( n == 4 - 4 * pPage.leaf );
  977. if ( pPage.intKey != 0 )
  978. {
  979. if ( pPage.hasData != 0 )
  980. {
  981. n += (u16)getVarint32( pCell, iCell + n, out nPayload );
  982. }
  983. else
  984. {
  985. nPayload = 0;
  986. }
  987. n += (u16)getVarint( pCell, iCell + n, out pInfo.nKey );
  988. pInfo.nData = nPayload;
  989. }
  990. else
  991. {
  992. pInfo.nData = 0;
  993. n += (u16)getVarint32( pCell, iCell + n, out nPayload );
  994. pInfo.nKey = nPayload;
  995. }
  996. pInfo.nPayload = nPayload;
  997. pInfo.nHeader = n;
  998. testcase( nPayload == pPage.maxLocal );
  999. testcase( nPayload == pPage.maxLocal + 1 );
  1000. if ( likely( nPayload <= pPage.maxLocal ) )
  1001. {
  1002. /* This is the (easy) common case where the entire payload fits
  1003. ** on the local page. No overflow is required.
  1004. */
  1005. if ( ( pInfo.nSize = (u16)( n + nPayload ) ) < 4 )
  1006. pInfo.nSize = 4;
  1007. pInfo.nLocal = (u16)nPayload;
  1008. pInfo.iOverflow = 0;
  1009. }
  1010. else
  1011. {
  1012. /* If the payload will not fit completely on the local page, we have
  1013. ** to decide how much to store locally and how much to spill onto
  1014. ** overflow pages. The strategy is to minimize the amount of unused
  1015. ** space on overflow pages while keeping the amount of local storage
  1016. ** in between minLocal and maxLocal.
  1017. **
  1018. ** Warning: changing the way overflow payload is distributed in any
  1019. ** way will result in an incompatible file format.
  1020. */
  1021. int minLocal; /* Minimum amount of payload held locally */
  1022. int maxLocal; /* Maximum amount of payload held locally */
  1023. int surplus; /* Overflow payload available for local storage */
  1024. minLocal = pPage.minLocal;
  1025. maxLocal = pPage.maxLocal;
  1026. surplus = (int)( minLocal + ( nPayload - minLocal ) % ( pPage.pBt.usableSize - 4 ) );
  1027. testcase( surplus == maxLocal );
  1028. testcase( surplus == maxLocal + 1 );
  1029. if ( surplus <= maxLocal )
  1030. {
  1031. pInfo.nLocal = (u16)surplus;
  1032. }
  1033. else
  1034. {
  1035. pInfo.nLocal = (u16)minLocal;
  1036. }
  1037. pInfo.iOverflow = (u16)( pInfo.nLocal + n );
  1038. pInfo.nSize = (u16)( pInfo.iOverflow + 4 );
  1039. }
  1040. }
  1041. //#define parseCell(pPage, iCell, pInfo) \
  1042. // btreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo))
  1043. static void parseCell( MemPage pPage, int iCell, ref CellInfo pInfo )
  1044. {
  1045. btreeParseCellPtr( pPage, findCell( pPage, iCell ), ref pInfo );
  1046. }
  1047. static void btreeParseCell(
  1048. MemPage pPage, /* Page containing the cell */
  1049. int iCell, /* The cell index. First cell is 0 */
  1050. ref CellInfo pInfo /* Fill in this structure */
  1051. )
  1052. {
  1053. parseCell( pPage, iCell, ref pInfo );
  1054. }
  1055. /*
  1056. ** Compute the total number of bytes that a Cell needs in the cell
  1057. ** data area of the btree-page. The return number includes the cell
  1058. ** data header and the local payload, but not any overflow page or
  1059. ** the space used by the cell pointer.
  1060. */
  1061. // Alternative form for C#
  1062. static u16 cellSizePtr( MemPage pPage, int iCell )
  1063. {
  1064. CellInfo info = new CellInfo();
  1065. byte[] pCell = new byte[13];
  1066. // Minimum Size = (2 bytes of Header or (4) Child Pointer) + (maximum of) 9 bytes data
  1067. if ( iCell < 0 )// Overflow Cell
  1068. Buffer.BlockCopy( pPage.aOvfl[-( iCell + 1 )].pCell, 0, pCell, 0, pCell.Length < pPage.aOvfl[-( iCell + 1 )].pCell.Length ? pCell.Length : pPage.aOvfl[-( iCell + 1 )].pCell.Length );
  1069. else if ( iCell >= pPage.aData.Length + 1 - pCell.Length )
  1070. Buffer.BlockCopy( pPage.aData, iCell, pCell, 0, pPage.aData.Length - iCell );
  1071. else
  1072. Buffer.BlockCopy( pPage.aData, iCell, pCell, 0, pCell.Length );
  1073. btreeParseCellPtr( pPage, pCell, ref info );
  1074. return info.nSize;
  1075. }
  1076. // Alternative form for C#
  1077. static u16 cellSizePtr( MemPage pPage, byte[] pCell, int offset )
  1078. {
  1079. CellInfo info = new CellInfo();
  1080. info.pCell = sqlite3Malloc( pCell.Length );
  1081. Buffer.BlockCopy( pCell, offset, info.pCell, 0, pCell.Length - offset );
  1082. btreeParseCellPtr( pPage, info.pCell, ref info );
  1083. return info.nSize;
  1084. }
  1085. static u16 cellSizePtr( MemPage pPage, u8[] pCell )
  1086. {
  1087. int _pIter = pPage.childPtrSize; //u8 pIter = &pCell[pPage.childPtrSize];
  1088. u32 nSize = 0;
  1089. #if SQLITE_DEBUG || DEBUG
  1090. /* The value returned by this function should always be the same as
  1091. ** the (CellInfo.nSize) value found by doing a full parse of the
  1092. ** cell. If SQLITE_DEBUG is defined, an Debug.Assert() at the bottom of
  1093. ** this function verifies that this invariant is not violated. */
  1094. CellInfo debuginfo = new CellInfo();
  1095. btreeParseCellPtr( pPage, pCell, ref debuginfo );
  1096. #else
  1097. CellInfo debuginfo = new CellInfo();
  1098. #endif
  1099. if ( pPage.intKey != 0 )
  1100. {
  1101. int pEnd;
  1102. if ( pPage.hasData != 0 )
  1103. {
  1104. _pIter += getVarint32( pCell, out nSize );// pIter += getVarint32( pIter, out nSize );
  1105. }
  1106. else
  1107. {
  1108. nSize = 0;
  1109. }
  1110. /* pIter now points at the 64-bit integer key value, a variable length
  1111. ** integer. The following block moves pIter to point at the first byte
  1112. ** past the end of the key value. */
  1113. pEnd = _pIter + 9;//pEnd = &pIter[9];
  1114. while ( ( ( pCell[_pIter++] ) & 0x80 ) != 0 && _pIter < pEnd )
  1115. ;//while( (pIter++)&0x80 && pIter<pEnd );
  1116. }
  1117. else
  1118. {
  1119. _pIter += getVarint32( pCell, _pIter, out nSize ); //pIter += getVarint32( pIter, out nSize );
  1120. }
  1121. testcase( nSize == pPage.maxLocal );
  1122. testcase( nSize == pPage.maxLocal + 1 );
  1123. if ( nSize > pPage.maxLocal )
  1124. {
  1125. int minLocal = pPage.minLocal;
  1126. nSize = (u32)( minLocal + ( nSize - minLocal ) % ( pPage.pBt.usableSize - 4 ) );
  1127. testcase( nSize == pPage.maxLocal );
  1128. testcase( nSize == pPage.maxLocal + 1 );
  1129. if ( nSize > pPage.maxLocal )
  1130. {
  1131. nSize = (u32)minLocal;
  1132. }
  1133. nSize += 4;
  1134. }
  1135. nSize += (uint)_pIter;//nSize += (u32)(pIter - pCell);
  1136. /* The minimum size of any cell is 4 bytes. */
  1137. if ( nSize < 4 )
  1138. {
  1139. nSize = 4;
  1140. }
  1141. Debug.Assert( nSize == debuginfo.nSize );
  1142. return (u16)nSize;
  1143. }
  1144. #if SQLITE_DEBUG
  1145. /* This variation on cellSizePtr() is used inside of assert() statements
  1146. ** only. */
  1147. static u16 cellSize( MemPage pPage, int iCell )
  1148. {
  1149. return cellSizePtr( pPage, findCell( pPage, iCell ) );
  1150. }
  1151. #else
  1152. static int cellSize(MemPage pPage, int iCell) { return -1; }
  1153. #endif
  1154. #if !SQLITE_OMIT_AUTOVACUUM
  1155. /*
  1156. ** If the cell pCell, part of page pPage contains a pointer
  1157. ** to an overflow page, insert an entry into the pointer-map
  1158. ** for the overflow page.
  1159. */
  1160. static void ptrmapPutOvflPtr( MemPage pPage, int pCell, ref int pRC )
  1161. {
  1162. if ( pRC != 0 )
  1163. return;
  1164. CellInfo info = new CellInfo();
  1165. Debug.Assert( pCell != 0 );
  1166. btreeParseCellPtr( pPage, pCell, ref info );
  1167. Debug.Assert( ( info.nData + ( pPage.intKey != 0 ? 0 : info.nKey ) ) == info.nPayload );
  1168. if ( info.iOverflow != 0 )
  1169. {
  1170. Pgno ovfl = sqlite3Get4byte( pPage.aData, pCell, info.iOverflow );
  1171. ptrmapPut( pPage.pBt, ovfl, PTRMAP_OVERFLOW1, pPage.pgno, ref pRC );
  1172. }
  1173. }
  1174. static void ptrmapPutOvflPtr( MemPage pPage, u8[] pCell, ref int pRC )
  1175. {
  1176. if ( pRC != 0 )
  1177. return;
  1178. CellInfo info = new CellInfo();
  1179. Debug.Assert( pCell != null );
  1180. btreeParseCellPtr( pPage, pCell, ref info );
  1181. Debug.Assert( ( info.nData + ( pPage.intKey != 0 ? 0 : info.nKey ) ) == info.nPayload );
  1182. if ( info.iOverflow != 0 )
  1183. {
  1184. Pgno ovfl = sqlite3Get4byte( pCell, info.iOverflow );
  1185. ptrmapPut( pPage.pBt, ovfl, PTRMAP_OVERFLOW1, pPage.pgno, ref pRC );
  1186. }
  1187. }
  1188. #endif
  1189. /*
  1190. ** Defragment the page given. All Cells are moved to the
  1191. ** end of the page and all free space is collected into one
  1192. ** big FreeBlk that occurs in between the header and cell
  1193. ** pointer array and the cell content area.
  1194. */
  1195. static int defragmentPage( MemPage pPage )
  1196. {
  1197. int i; /* Loop counter */
  1198. int pc; /* Address of a i-th cell */
  1199. int addr; /* Offset of first byte after cell pointer array */
  1200. int hdr; /* Offset to the page header */
  1201. int size; /* Size of a cell */
  1202. int usableSize; /* Number of usable bytes on a page */
  1203. int cellOffset; /* Offset to the cell pointer array */
  1204. int cbrk; /* Offset to the cell content area */
  1205. int nCell; /* Number of cells on the page */
  1206. byte[] data; /* The page data */
  1207. byte[] temp; /* Temp area for cell content */
  1208. int iCellFirst; /* First allowable cell index */
  1209. int iCellLast; /* Last possible cell index */
  1210. Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
  1211. Debug.Assert( pPage.pBt != null );
  1212. Debug.Assert( pPage.pBt.usableSize <= SQLITE_MAX_PAGE_SIZE );
  1213. Debug.Assert( pPage.nOverflow == 0 );
  1214. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  1215. temp = sqlite3PagerTempSpace( pPage.pBt.pPager );
  1216. data = pPage.aData;
  1217. hdr = pPage.hdrOffset;
  1218. cellOffset = pPage.cellOffset;
  1219. nCell = pPage.nCell;
  1220. Debug.Assert( nCell == get2byte( data, hdr + 3 ) );
  1221. usableSize = (int)pPage.pBt.usableSize;
  1222. cbrk = get2byte( data, hdr + 5 );
  1223. Buffer.BlockCopy( data, cbrk, temp, cbrk, usableSize - cbrk );//memcpy( temp[cbrk], ref data[cbrk], usableSize - cbrk );
  1224. cbrk = usableSize;
  1225. iCellFirst = cellOffset + 2 * nCell;
  1226. iCellLast = usableSize - 4;
  1227. for ( i = 0; i < nCell; i++ )
  1228. {
  1229. int pAddr; /* The i-th cell pointer */
  1230. pAddr = cellOffset + i * 2; // &data[cellOffset + i * 2];
  1231. pc = get2byte( data, pAddr );
  1232. testcase( pc == iCellFirst );
  1233. testcase( pc == iCellLast );
  1234. #if !(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
  1235. /* These conditions have already been verified in btreeInitPage()
  1236. ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined
  1237. */
  1238. if ( pc < iCellFirst || pc > iCellLast )
  1239. {
  1240. return SQLITE_CORRUPT_BKPT();
  1241. }
  1242. #endif
  1243. Debug.Assert( pc >= iCellFirst && pc <= iCellLast );
  1244. size = cellSizePtr( pPage, temp, pc );
  1245. cbrk -= size;
  1246. #if (SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
  1247. if ( cbrk < iCellFirst || pc + size > usableSize )
  1248. {
  1249. return SQLITE_CORRUPT_BKPT();
  1250. }
  1251. #else
  1252. if ( cbrk < iCellFirst || pc + size > usableSize )
  1253. {
  1254. return SQLITE_CORRUPT_BKPT();
  1255. }
  1256. #endif
  1257. Debug.Assert( cbrk + size <= usableSize && cbrk >= iCellFirst );
  1258. testcase( cbrk + size == usableSize );
  1259. testcase( pc + size == usableSize );
  1260. Buffer.BlockCopy( temp, pc, data, cbrk, size );//memcpy(data[cbrk], ref temp[pc], size);
  1261. put2byte( data, pAddr, cbrk );
  1262. }
  1263. Debug.Assert( cbrk >= iCellFirst );
  1264. put2byte( data, hdr + 5, cbrk );
  1265. data[hdr + 1] = 0;
  1266. data[hdr + 2] = 0;
  1267. data[hdr + 7] = 0;
  1268. addr = cellOffset + 2 * nCell;
  1269. Array.Clear( data, addr, cbrk - addr ); //memset(data[iCellFirst], 0, cbrk-iCellFirst);
  1270. Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
  1271. if ( cbrk - iCellFirst != pPage.nFree )
  1272. {
  1273. return SQLITE_CORRUPT_BKPT();
  1274. }
  1275. return SQLITE_OK;
  1276. }
  1277. /*
  1278. ** Allocate nByte bytes of space from within the B-Tree page passed
  1279. ** as the first argument. Write into pIdx the index into pPage.aData[]
  1280. ** of the first byte of allocated space. Return either SQLITE_OK or
  1281. ** an error code (usually SQLITE_CORRUPT).
  1282. **
  1283. ** The caller guarantees that there is sufficient space to make the
  1284. ** allocation. This routine might need to defragment in order to bring
  1285. ** all the space together, however. This routine will avoid using
  1286. ** the first two bytes past the cell pointer area since presumably this
  1287. ** allocation is being made in order to insert a new cell, so we will
  1288. ** also end up needing a new cell pointer.
  1289. */
  1290. static int allocateSpace( MemPage pPage, int nByte, ref int pIdx )
  1291. {
  1292. int hdr = pPage.hdrOffset; /* Local cache of pPage.hdrOffset */
  1293. u8[] data = pPage.aData; /* Local cache of pPage.aData */
  1294. int nFrag; /* Number of fragmented bytes on pPage */
  1295. int top; /* First byte of cell content area */
  1296. int gap; /* First byte of gap between cell pointers and cell content */
  1297. int rc; /* Integer return code */
  1298. u32 usableSize; /* Usable size of the page */
  1299. Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
  1300. Debug.Assert( pPage.pBt != null );
  1301. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  1302. Debug.Assert( nByte >= 0 ); /* Minimum cell size is 4 */
  1303. Debug.Assert( pPage.nFree >= nByte );
  1304. Debug.Assert( pPage.nOverflow == 0 );
  1305. usableSize = pPage.pBt.usableSize;
  1306. Debug.Assert( nByte < usableSize - 8 );
  1307. nFrag = data[hdr + 7];
  1308. Debug.Assert( pPage.cellOffset == hdr + 12 - 4 * pPage.leaf );
  1309. gap = pPage.cellOffset + 2 * pPage.nCell;
  1310. top = get2byteNotZero( data, hdr + 5 );
  1311. if ( gap > top )
  1312. return SQLITE_CORRUPT_BKPT();
  1313. testcase( gap + 2 == top );
  1314. testcase( gap + 1 == top );
  1315. testcase( gap == top );
  1316. if ( nFrag >= 60 )
  1317. {
  1318. /* Always defragment highly fragmented pages */
  1319. rc = defragmentPage( pPage );
  1320. if ( rc != 0 )
  1321. return rc;
  1322. top = get2byteNotZero( data, hdr + 5 );
  1323. }
  1324. else if ( gap + 2 <= top )
  1325. {
  1326. /* Search the freelist looking for a free slot big enough to satisfy
  1327. ** the request. The allocation is made from the first free slot in
  1328. ** the list that is large enough to accomadate it.
  1329. */
  1330. int pc, addr;
  1331. for ( addr = hdr + 1; ( pc = get2byte( data, addr ) ) > 0; addr = pc )
  1332. {
  1333. int size; /* Size of free slot */
  1334. if ( pc > usableSize - 4 || pc < addr + 4 )
  1335. {
  1336. return SQLITE_CORRUPT_BKPT();
  1337. }
  1338. size = get2byte( data, pc + 2 );
  1339. if ( size >= nByte )
  1340. {
  1341. int x = size - nByte;
  1342. testcase( x == 4 );
  1343. testcase( x == 3 );
  1344. if ( x < 4 )
  1345. {
  1346. /* Remove the slot from the free-list. Update the number of
  1347. ** fragmented bytes within the page. */
  1348. data[addr + 0] = data[pc + 0];
  1349. data[addr + 1] = data[pc + 1]; //memcpy( data[addr], ref data[pc], 2 );
  1350. data[hdr + 7] = (u8)( nFrag + x );
  1351. }
  1352. else if ( size + pc > usableSize )
  1353. {
  1354. return SQLITE_CORRUPT_BKPT();
  1355. }
  1356. else
  1357. {
  1358. /* The slot remains on the free-list. Reduce its size to account
  1359. ** for the portion used by the new allocation. */
  1360. put2byte( data, pc + 2, x );
  1361. }
  1362. pIdx = pc + x;
  1363. return SQLITE_OK;
  1364. }
  1365. }
  1366. }
  1367. /* Check to make sure there is enough space in the gap to satisfy
  1368. ** the allocation. If not, defragment.
  1369. */
  1370. testcase( gap + 2 + nByte == top );
  1371. if ( gap + 2 + nByte > top )
  1372. {
  1373. rc = defragmentPage( pPage );
  1374. if ( rc != 0 )
  1375. return rc;
  1376. top = get2byteNotZero( data, hdr + 5 );
  1377. Debug.Assert( gap + nByte <= top );
  1378. }
  1379. /* Allocate memory from the gap in between the cell pointer array
  1380. ** and the cell content area. The btreeInitPage() call has already
  1381. ** validated the freelist. Given that the freelist is valid, there
  1382. ** is no way that the allocation can extend off the end of the page.
  1383. ** The Debug.Assert() below verifies the previous sentence.
  1384. */
  1385. top -= nByte;
  1386. put2byte( data, hdr + 5, top );
  1387. Debug.Assert( top + nByte <= (int)pPage.pBt.usableSize );
  1388. pIdx = top;
  1389. return SQLITE_OK;
  1390. }
  1391. /*
  1392. ** Return a section of the pPage.aData to the freelist.
  1393. ** The first byte of the new free block is pPage.aDisk[start]
  1394. ** and the size of the block is "size" bytes.
  1395. **
  1396. ** Most of the effort here is involved in coalesing adjacent
  1397. ** free blocks into a single big free block.
  1398. */
  1399. static int freeSpace( MemPage pPage, u32 start, int size )
  1400. {
  1401. return freeSpace( pPage, (int)start, size );
  1402. }
  1403. static int freeSpace( MemPage pPage, int start, int size )
  1404. {
  1405. int addr, pbegin, hdr;
  1406. int iLast; /* Largest possible freeblock offset */
  1407. byte[] data = pPage.aData;
  1408. Debug.Assert( pPage.pBt != null );
  1409. Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
  1410. Debug.Assert( start >= pPage.hdrOffset + 6 + pPage.childPtrSize );
  1411. Debug.Assert( ( start + size ) <= (int)pPage.pBt.usableSize );
  1412. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  1413. Debug.Assert( size >= 0 ); /* Minimum cell size is 4 */
  1414. if ( pPage.pBt.secureDelete )
  1415. {
  1416. /* Overwrite deleted information with zeros when the secure_delete
  1417. ** option is enabled */
  1418. Array.Clear( data, start, size );// memset(&data[start], 0, size);
  1419. }
  1420. /* Add the space back into the linked list of freeblocks. Note that
  1421. ** even though the freeblock list was checked by btreeInitPage(),
  1422. ** btreeInitPage() did not detect overlapping cells or
  1423. ** freeblocks that overlapped cells. Nor does it detect when the
  1424. ** cell content area exceeds the value in the page header. If these
  1425. ** situations arise, then subsequent insert operations might corrupt
  1426. ** the freelist. So we do need to check for corruption while scanning
  1427. ** the freelist.
  1428. */
  1429. hdr = pPage.hdrOffset;
  1430. addr = hdr + 1;
  1431. iLast = (int)pPage.pBt.usableSize - 4;
  1432. Debug.Assert( start <= iLast );
  1433. while ( ( pbegin = get2byte( data, addr ) ) < start && pbegin > 0 )
  1434. {
  1435. if ( pbegin < addr + 4 )
  1436. {
  1437. return SQLITE_CORRUPT_BKPT();
  1438. }
  1439. addr = pbegin;
  1440. }
  1441. if ( pbegin > iLast )
  1442. {
  1443. return SQLITE_CORRUPT_BKPT();
  1444. }
  1445. Debug.Assert( pbegin > addr || pbegin == 0 );
  1446. put2byte( data, addr, start );
  1447. put2byte( data, start, pbegin );
  1448. put2byte( data, start + 2, size );
  1449. pPage.nFree = (u16)( pPage.nFree + size );
  1450. /* Coalesce adjacent free blocks */
  1451. addr = hdr + 1;
  1452. while ( ( pbegin = get2byte( data, addr ) ) > 0 )
  1453. {
  1454. int pnext, psize, x;
  1455. Debug.Assert( pbegin > addr );
  1456. Debug.Assert( pbegin <= (int)pPage.pBt.usableSize - 4 );
  1457. pnext = get2byte( data, pbegin );
  1458. psize = get2byte( data, pbegin + 2 );
  1459. if ( pbegin + psize + 3 >= pnext && pnext > 0 )
  1460. {
  1461. int frag = pnext - ( pbegin + psize );
  1462. if ( ( frag < 0 ) || ( frag > (int)data[hdr + 7] ) )
  1463. {
  1464. return SQLITE_CORRUPT_BKPT();
  1465. }
  1466. data[hdr + 7] -= (u8)frag;
  1467. x = get2byte( data, pnext );
  1468. put2byte( data, pbegin, x );
  1469. x = pnext + get2byte( data, pnext + 2 ) - pbegin;
  1470. put2byte( data, pbegin + 2, x );
  1471. }
  1472. else
  1473. {
  1474. addr = pbegin;
  1475. }
  1476. }
  1477. /* If the cell content area begins with a freeblock, remove it. */
  1478. if ( data[hdr + 1] == data[hdr + 5] && data[hdr + 2] == data[hdr + 6] )
  1479. {
  1480. int top;
  1481. pbegin = get2byte( data, hdr + 1 );
  1482. put2byte( data, hdr + 1, get2byte( data, pbegin ) ); //memcpy( data[hdr + 1], ref data[pbegin], 2 );
  1483. top = get2byte( data, hdr + 5 ) + get2byte( data, pbegin + 2 );
  1484. put2byte( data, hdr + 5, top );
  1485. }
  1486. Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
  1487. return SQLITE_OK;
  1488. }
  1489. /*
  1490. ** Decode the flags byte (the first byte of the header) for a page
  1491. ** and initialize fields of the MemPage structure accordingly.
  1492. **
  1493. ** Only the following combinations are supported. Anything different
  1494. ** indicates a corrupt database files:
  1495. **
  1496. ** PTF_ZERODATA
  1497. ** PTF_ZERODATA | PTF_LEAF
  1498. ** PTF_LEAFDATA | PTF_INTKEY
  1499. ** PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF
  1500. */
  1501. static int decodeFlags( MemPage pPage, int flagByte )
  1502. {
  1503. BtShared pBt; /* A copy of pPage.pBt */
  1504. Debug.Assert( pPage.hdrOffset == ( pPage.pgno == 1 ? 100 : 0 ) );
  1505. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  1506. pPage.leaf = (u8)( flagByte >> 3 );
  1507. Debug.Assert( PTF_LEAF == 1 << 3 );
  1508. flagByte &= ~PTF_LEAF;
  1509. pPage.childPtrSize = (u8)( 4 - 4 * pPage.leaf );
  1510. pBt = pPage.pBt;
  1511. if ( flagByte == ( PTF_LEAFDATA | PTF_INTKEY ) )
  1512. {
  1513. pPage.intKey = 1;
  1514. pPage.hasData = pPage.leaf;
  1515. pPage.maxLocal = pBt.maxLeaf;
  1516. pPage.minLocal = pBt.minLeaf;
  1517. }
  1518. else if ( flagByte == PTF_ZERODATA )
  1519. {
  1520. pPage.intKey = 0;
  1521. pPage.hasData = 0;
  1522. pPage.maxLocal = pBt.maxLocal;
  1523. pPage.minLocal = pBt.minLocal;
  1524. }
  1525. else
  1526. {
  1527. return SQLITE_CORRUPT_BKPT();
  1528. }
  1529. return SQLITE_OK;
  1530. }
  1531. /*
  1532. ** Initialize the auxiliary information for a disk block.
  1533. **
  1534. ** Return SQLITE_OK on success. If we see that the page does
  1535. ** not contain a well-formed database page, then return
  1536. ** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not
  1537. ** guarantee that the page is well-formed. It only shows that
  1538. ** we failed to detect any corruption.
  1539. */
  1540. static int btreeInitPage( MemPage pPage )
  1541. {
  1542. Debug.Assert( pPage.pBt != null );
  1543. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  1544. Debug.Assert( pPage.pgno == sqlite3PagerPagenumber( pPage.pDbPage ) );
  1545. Debug.Assert( pPage == sqlite3PagerGetExtra( pPage.pDbPage ) );
  1546. Debug.Assert( pPage.aData == sqlite3PagerGetData( pPage.pDbPage ) );
  1547. if ( 0 == pPage.isInit )
  1548. {
  1549. u16 pc; /* Address of a freeblock within pPage.aData[] */
  1550. u8 hdr; /* Offset to beginning of page header */
  1551. u8[] data; /* Equal to pPage.aData */
  1552. BtShared pBt; /* The main btree structure */
  1553. int usableSize; /* Amount of usable space on each page */
  1554. u16 cellOffset; /* Offset from start of page to first cell pointer */
  1555. int nFree; /* Number of unused bytes on the page */
  1556. int top; /* First byte of the cell content area */
  1557. int iCellFirst; /* First allowable cell or freeblock offset */
  1558. int iCellLast; /* Last possible cell or freeblock offset */
  1559. pBt = pPage.pBt;
  1560. hdr = pPage.hdrOffset;
  1561. data = pPage.aData;
  1562. if ( decodeFlags( pPage, data[hdr] ) != 0 )
  1563. return SQLITE_CORRUPT_BKPT();
  1564. Debug.Assert( pBt.pageSize >= 512 && pBt.pageSize <= 65536 );
  1565. pPage.maskPage = (u16)( pBt.pageSize - 1 );
  1566. pPage.nOverflow = 0;
  1567. usableSize = (int)pBt.usableSize;
  1568. pPage.cellOffset = ( cellOffset = (u16)( hdr + 12 - 4 * pPage.leaf ) );
  1569. top = get2byteNotZero( data, hdr + 5 );
  1570. pPage.nCell = (u16)( get2byte( data, hdr + 3 ) );
  1571. if ( pPage.nCell > MX_CELL( pBt ) )
  1572. {
  1573. /* To many cells for a single page. The page must be corrupt */
  1574. return SQLITE_CORRUPT_BKPT();
  1575. }
  1576. testcase( pPage.nCell == MX_CELL( pBt ) );
  1577. /* A malformed database page might cause us to read past the end
  1578. ** of page when parsing a cell.
  1579. **
  1580. ** The following block of code checks early to see if a cell extends
  1581. ** past the end of a page boundary and causes SQLITE_CORRUPT to be
  1582. ** returned if it does.
  1583. */
  1584. iCellFirst = cellOffset + 2 * pPage.nCell;
  1585. iCellLast = usableSize - 4;
  1586. #if (SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
  1587. {
  1588. int i; /* Index into the cell pointer array */
  1589. int sz; /* Size of a cell */
  1590. if ( 0 == pPage.leaf )
  1591. iCellLast--;
  1592. for ( i = 0; i < pPage.nCell; i++ )
  1593. {
  1594. pc = (u16)get2byte( data, cellOffset + i * 2 );
  1595. testcase( pc == iCellFirst );
  1596. testcase( pc == iCellLast );
  1597. if ( pc < iCellFirst || pc > iCellLast )
  1598. {
  1599. return SQLITE_CORRUPT_BKPT();
  1600. }
  1601. sz = cellSizePtr( pPage, data, pc );
  1602. testcase( pc + sz == usableSize );
  1603. if ( pc + sz > usableSize )
  1604. {
  1605. return SQLITE_CORRUPT_BKPT();
  1606. }
  1607. }
  1608. if ( 0 == pPage.leaf )
  1609. iCellLast++;
  1610. }
  1611. #endif
  1612. /* Compute the total free space on the page */
  1613. pc = (u16)get2byte( data, hdr + 1 );
  1614. nFree = (u16)( data[hdr + 7] + top );
  1615. while ( pc > 0 )
  1616. {
  1617. u16 next, size;
  1618. if ( pc < iCellFirst || pc > iCellLast )
  1619. {
  1620. /* Start of free block is off the page */
  1621. return SQLITE_CORRUPT_BKPT();
  1622. }
  1623. next = (u16)get2byte( data, pc );
  1624. size = (u16)get2byte( data, pc + 2 );
  1625. if ( ( next > 0 && next <= pc + size + 3 ) || pc + size > usableSize )
  1626. {
  1627. /* Free blocks must be in ascending order. And the last byte of
  1628. ** the free-block must lie on the database page. */
  1629. return SQLITE_CORRUPT_BKPT();
  1630. }
  1631. nFree = (u16)( nFree + size );
  1632. pc = next;
  1633. }
  1634. /* At this point, nFree contains the sum of the offset to the start
  1635. ** of the cell-content area plus the number of free bytes within
  1636. ** the cell-content area. If this is greater than the usable-size
  1637. ** of the page, then the page must be corrupted. This check also
  1638. ** serves to verify that the offset to the start of the cell-content
  1639. ** area, according to the page header, lies within the page.
  1640. */
  1641. if ( nFree > usableSize )
  1642. {
  1643. return SQLITE_CORRUPT_BKPT();
  1644. }
  1645. pPage.nFree = (u16)( nFree - iCellFirst );
  1646. pPage.isInit = 1;
  1647. }
  1648. return SQLITE_OK;
  1649. }
  1650. /*
  1651. ** Set up a raw page so that it looks like a database page holding
  1652. ** no entries.
  1653. */
  1654. static void zeroPage( MemPage pPage, int flags )
  1655. {
  1656. byte[] data = pPage.aData;
  1657. BtShared pBt = pPage.pBt;
  1658. u8 hdr = pPage.hdrOffset;
  1659. u16 first;
  1660. Debug.Assert( sqlite3PagerPagenumber( pPage.pDbPage ) == pPage.pgno );
  1661. Debug.Assert( sqlite3PagerGetExtra( pPage.pDbPage ) == pPage );
  1662. Debug.Assert( sqlite3PagerGetData( pPage.pDbPage ) == data );
  1663. Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
  1664. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  1665. if ( pBt.secureDelete )
  1666. {
  1667. Array.Clear( data, hdr, (int)( pBt.usableSize - hdr ) );//memset(&data[hdr], 0, pBt->usableSize - hdr);
  1668. }
  1669. data[hdr] = (u8)flags;
  1670. first = (u16)( hdr + 8 + 4 * ( ( flags & PTF_LEAF ) == 0 ? 1 : 0 ) );
  1671. Array.Clear( data, hdr + 1, 4 );//memset(data[hdr+1], 0, 4);
  1672. data[hdr + 7] = 0;
  1673. put2byte( data, hdr + 5, pBt.usableSize );
  1674. pPage.nFree = (u16)( pBt.usableSize - first );
  1675. decodeFlags( pPage, flags );
  1676. pPage.hdrOffset = hdr;
  1677. pPage.cellOffset = first;
  1678. pPage.nOverflow = 0;
  1679. Debug.Assert( pBt.pageSize >= 512 && pBt.pageSize <= 65536 );
  1680. pPage.maskPage = (u16)( pBt.pageSize - 1 );
  1681. pPage.nCell = 0;
  1682. pPage.isInit = 1;
  1683. }
  1684. /*
  1685. ** Convert a DbPage obtained from the pager into a MemPage used by
  1686. ** the btree layer.
  1687. */
  1688. static MemPage btreePageFromDbPage( DbPage pDbPage, Pgno pgno, BtShared pBt )
  1689. {
  1690. MemPage pPage = (MemPage)sqlite3PagerGetExtra( pDbPage );
  1691. pPage.aData = sqlite3PagerGetData( pDbPage );
  1692. pPage.pDbPage = pDbPage;
  1693. pPage.pBt = pBt;
  1694. pPage.pgno = pgno;
  1695. pPage.hdrOffset = (u8)( pPage.pgno == 1 ? 100 : 0 );
  1696. return pPage;
  1697. }
  1698. /*
  1699. ** Get a page from the pager. Initialize the MemPage.pBt and
  1700. ** MemPage.aData elements if needed.
  1701. **
  1702. ** If the noContent flag is set, it means that we do not care about
  1703. ** the content of the page at this time. So do not go to the disk
  1704. ** to fetch the content. Just fill in the content with zeros for now.
  1705. ** If in the future we call sqlite3PagerWrite() on this page, that
  1706. ** means we have started to be concerned about content and the disk
  1707. ** read should occur at that point.
  1708. */
  1709. static int btreeGetPage(
  1710. BtShared pBt, /* The btree */
  1711. Pgno pgno, /* Number of the page to fetch */
  1712. ref MemPage ppPage, /* Return the page in this parameter */
  1713. int noContent /* Do not load page content if true */
  1714. )
  1715. {
  1716. int rc;
  1717. DbPage pDbPage = null;
  1718. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  1719. rc = sqlite3PagerAcquire( pBt.pPager, pgno, ref pDbPage, (u8)noContent );
  1720. if ( rc != 0 )
  1721. return rc;
  1722. ppPage = btreePageFromDbPage( pDbPage, pgno, pBt );
  1723. return SQLITE_OK;
  1724. }
  1725. /*
  1726. ** Retrieve a page from the pager cache. If the requested page is not
  1727. ** already in the pager cache return NULL. Initialize the MemPage.pBt and
  1728. ** MemPage.aData elements if needed.
  1729. */
  1730. static MemPage btreePageLookup( BtShared pBt, Pgno pgno )
  1731. {
  1732. DbPage pDbPage;
  1733. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  1734. pDbPage = sqlite3PagerLookup( pBt.pPager, pgno );
  1735. if ( pDbPage )
  1736. {
  1737. return btreePageFromDbPage( pDbPage, pgno, pBt );
  1738. }
  1739. return null;
  1740. }
  1741. /*
  1742. ** Return the size of the database file in pages. If there is any kind of
  1743. ** error, return ((unsigned int)-1).
  1744. */
  1745. static Pgno btreePagecount( BtShared pBt )
  1746. {
  1747. return pBt.nPage;
  1748. }
  1749. static Pgno sqlite3BtreeLastPage( Btree p )
  1750. {
  1751. Debug.Assert( sqlite3BtreeHoldsMutex( p ) );
  1752. Debug.Assert( ( ( p.pBt.nPage ) & 0x8000000 ) == 0 );
  1753. return (Pgno)btreePagecount( p.pBt );
  1754. }
  1755. /*
  1756. ** Get a page from the pager and initialize it. This routine is just a
  1757. ** convenience wrapper around separate calls to btreeGetPage() and
  1758. ** btreeInitPage().
  1759. **
  1760. ** If an error occurs, then the value ppPage is set to is undefined. It
  1761. ** may remain unchanged, or it may be set to an invalid value.
  1762. */
  1763. static int getAndInitPage(
  1764. BtShared pBt, /* The database file */
  1765. Pgno pgno, /* Number of the page to get */
  1766. ref MemPage ppPage /* Write the page pointer here */
  1767. )
  1768. {
  1769. int rc;
  1770. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  1771. if ( pgno > btreePagecount( pBt ) )
  1772. {
  1773. rc = SQLITE_CORRUPT_BKPT();
  1774. }
  1775. else
  1776. {
  1777. rc = btreeGetPage( pBt, pgno, ref ppPage, 0 );
  1778. if ( rc == SQLITE_OK )
  1779. {
  1780. rc = btreeInitPage( ppPage );
  1781. if ( rc != SQLITE_OK )
  1782. {
  1783. releasePage( ppPage );
  1784. }
  1785. }
  1786. }
  1787. testcase( pgno == 0 );
  1788. Debug.Assert( pgno != 0 || rc == SQLITE_CORRUPT );
  1789. return rc;
  1790. }
  1791. /*
  1792. ** Release a MemPage. This should be called once for each prior
  1793. ** call to btreeGetPage.
  1794. */
  1795. static void releasePage( MemPage pPage )
  1796. {
  1797. if ( pPage != null )
  1798. {
  1799. Debug.Assert( pPage.aData != null );
  1800. Debug.Assert( pPage.pBt != null );
  1801. //TODO -- find out why corrupt9 & diskfull fail on this tests
  1802. //Debug.Assert( sqlite3PagerGetExtra( pPage.pDbPage ) == pPage );
  1803. //Debug.Assert( sqlite3PagerGetData( pPage.pDbPage ) == pPage.aData );
  1804. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  1805. sqlite3PagerUnref( pPage.pDbPage );
  1806. }
  1807. }
  1808. /*
  1809. ** During a rollback, when the pager reloads information into the cache
  1810. ** so that the cache is restored to its original state at the start of
  1811. ** the transaction, for each page restored this routine is called.
  1812. **
  1813. ** This routine needs to reset the extra data section at the end of the
  1814. ** page to agree with the restored data.
  1815. */
  1816. static void pageReinit( DbPage pData )
  1817. {
  1818. MemPage pPage;
  1819. pPage = sqlite3PagerGetExtra( pData );
  1820. Debug.Assert( sqlite3PagerPageRefcount( pData ) > 0 );
  1821. if ( pPage.isInit != 0 )
  1822. {
  1823. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  1824. pPage.isInit = 0;
  1825. if ( sqlite3PagerPageRefcount( pData ) > 1 )
  1826. {
  1827. /* pPage might not be a btree page; it might be an overflow page
  1828. ** or ptrmap page or a free page. In those cases, the following
  1829. ** call to btreeInitPage() will likely return SQLITE_CORRUPT.
  1830. ** But no harm is done by this. And it is very important that
  1831. ** btreeInitPage() be called on every btree page so we make
  1832. ** the call for every page that comes in for re-initing. */
  1833. btreeInitPage( pPage );
  1834. }
  1835. }
  1836. }
  1837. /*
  1838. ** Invoke the busy handler for a btree.
  1839. */
  1840. static int btreeInvokeBusyHandler( object pArg )
  1841. {
  1842. BtShared pBt = (BtShared)pArg;
  1843. Debug.Assert( pBt.db != null );
  1844. Debug.Assert( sqlite3_mutex_held( pBt.db.mutex ) );
  1845. return sqlite3InvokeBusyHandler( pBt.db.busyHandler );
  1846. }
  1847. /*
  1848. ** Open a database file.
  1849. **
  1850. ** zFilename is the name of the database file. If zFilename is NULL
  1851. ** then an ephemeral database is created. The ephemeral database might
  1852. ** be exclusively in memory, or it might use a disk-based memory cache.
  1853. ** Either way, the ephemeral database will be automatically deleted
  1854. ** when sqlite3BtreeClose() is called.
  1855. **
  1856. ** If zFilename is ":memory:" then an in-memory database is created
  1857. ** that is automatically destroyed when it is closed.
  1858. **
  1859. ** The "flags" parameter is a bitmask that might contain bits
  1860. ** BTREE_OMIT_JOURNAL and/or BTREE_NO_READLOCK. The BTREE_NO_READLOCK
  1861. ** bit is also set if the SQLITE_NoReadlock flags is set in db->flags.
  1862. ** These flags are passed through into sqlite3PagerOpen() and must
  1863. ** be the same values as PAGER_OMIT_JOURNAL and PAGER_NO_READLOCK.
  1864. **
  1865. ** If the database is already opened in the same database connection
  1866. ** and we are in shared cache mode, then the open will fail with an
  1867. ** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared
  1868. ** objects in the same database connection since doing so will lead
  1869. ** to problems with locking.
  1870. */
  1871. static int sqlite3BtreeOpen(
  1872. sqlite3_vfs pVfs, /* VFS to use for this b-tree */
  1873. string zFilename, /* Name of the file containing the BTree database */
  1874. sqlite3 db, /* Associated database handle */
  1875. ref Btree ppBtree, /* Pointer to new Btree object written here */
  1876. int flags, /* Options */
  1877. int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */
  1878. )
  1879. {
  1880. BtShared pBt = null; /* Shared part of btree structure */
  1881. Btree p; /* Handle to return */
  1882. sqlite3_mutex mutexOpen = null; /* Prevents a race condition. Ticket #3537 */
  1883. int rc = SQLITE_OK; /* Result code from this function */
  1884. u8 nReserve; /* Byte of unused space on each page */
  1885. byte[] zDbHeader = new byte[100]; /* Database header content */
  1886. /* True if opening an ephemeral, temporary database */
  1887. bool isTempDb = String.IsNullOrEmpty( zFilename );//zFilename==0 || zFilename[0]==0;
  1888. /* Set the variable isMemdb to true for an in-memory database, or
  1889. ** false for a file-based database.
  1890. */
  1891. #if SQLITE_OMIT_MEMORYDB
  1892. bool isMemdb = false;
  1893. #else
  1894. bool isMemdb = ( zFilename == ":memory:" )
  1895. || ( isTempDb && sqlite3TempInMemory( db ) );
  1896. #endif
  1897. Debug.Assert( db != null );
  1898. Debug.Assert( pVfs != null );
  1899. Debug.Assert( sqlite3_mutex_held( db.mutex ) );
  1900. Debug.Assert( ( flags & 0xff ) == flags ); /* flags fit in 8 bits */
  1901. /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */
  1902. Debug.Assert( ( flags & BTREE_UNORDERED ) == 0 || ( flags & BTREE_SINGLE ) != 0 );
  1903. /* A BTREE_SINGLE database is always a temporary and/or ephemeral */
  1904. Debug.Assert( ( flags & BTREE_SINGLE ) == 0 || isTempDb );
  1905. if ( ( db.flags & SQLITE_NoReadlock ) != 0 )
  1906. {
  1907. flags |= BTREE_NO_READLOCK;
  1908. }
  1909. if ( isMemdb )
  1910. {
  1911. flags |= BTREE_MEMORY;
  1912. }
  1913. if ( ( vfsFlags & SQLITE_OPEN_MAIN_DB ) != 0 && ( isMemdb || isTempDb ) )
  1914. {
  1915. vfsFlags = ( vfsFlags & ~SQLITE_OPEN_MAIN_DB ) | SQLITE_OPEN_TEMP_DB;
  1916. }
  1917. p = new Btree();//sqlite3MallocZero(sizeof(Btree));
  1918. //if( !p ){
  1919. // return SQLITE_NOMEM;
  1920. //}
  1921. p.inTrans = TRANS_NONE;
  1922. p.db = db;
  1923. #if !SQLITE_OMIT_SHARED_CACHE
  1924. p.lock.pBtree = p;
  1925. p.lock.iTable = 1;
  1926. #endif
  1927. #if !(SQLITE_OMIT_SHARED_CACHE) && !(SQLITE_OMIT_DISKIO)
  1928. /*
  1929. ** If this Btree is a candidate for shared cache, try to find an
  1930. ** existing BtShared object that we can share with
  1931. */
  1932. if( !isMemdb && !isTempDb ){
  1933. if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
  1934. int nFullPathname = pVfs.mxPathname+1;
  1935. string zFullPathname = sqlite3Malloc(nFullPathname);
  1936. sqlite3_mutex *mutexShared;
  1937. p.sharable = 1;
  1938. if( !zFullPathname ){
  1939. p = null;//sqlite3_free(ref p);
  1940. return SQLITE_NOMEM;
  1941. }
  1942. sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
  1943. mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
  1944. sqlite3_mutex_enter(mutexOpen);
  1945. mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
  1946. sqlite3_mutex_enter(mutexShared);
  1947. for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt.pNext){
  1948. Debug.Assert( pBt.nRef>0 );
  1949. if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt.pPager))
  1950. && sqlite3PagerVfs(pBt.pPager)==pVfs ){
  1951. int iDb;
  1952. for(iDb=db.nDb-1; iDb>=0; iDb--){
  1953. Btree pExisting = db.aDb[iDb].pBt;
  1954. if( pExisting && pExisting.pBt==pBt ){
  1955. sqlite3_mutex_leave(mutexShared);
  1956. sqlite3_mutex_leave(mutexOpen);
  1957. zFullPathname = null;//sqlite3_free(ref zFullPathname);
  1958. p=null;//sqlite3_free(ref p);
  1959. return SQLITE_CONSTRAINT;
  1960. }
  1961. }
  1962. p.pBt = pBt;
  1963. pBt.nRef++;
  1964. break;
  1965. }
  1966. }
  1967. sqlite3_mutex_leave(mutexShared);
  1968. zFullPathname=null;//sqlite3_free(ref zFullPathname);
  1969. }
  1970. #if SQLITE_DEBUG
  1971. else{
  1972. /* In debug mode, we mark all persistent databases as sharable
  1973. ** even when they are not. This exercises the locking code and
  1974. ** gives more opportunity for asserts(sqlite3_mutex_held())
  1975. ** statements to find locking problems.
  1976. */
  1977. p.sharable = 1;
  1978. }
  1979. #endif
  1980. }
  1981. #endif
  1982. if ( pBt == null )
  1983. {
  1984. /*
  1985. ** The following asserts make sure that structures used by the btree are
  1986. ** the right size. This is to guard against size changes that result
  1987. ** when compiling on a different architecture.
  1988. */
  1989. Debug.Assert( sizeof( i64 ) == 8 || sizeof( i64 ) == 4 );
  1990. Debug.Assert( sizeof( u64 ) == 8 || sizeof( u64 ) == 4 );
  1991. Debug.Assert( sizeof( u32 ) == 4 );
  1992. Debug.Assert( sizeof( u16 ) == 2 );
  1993. Debug.Assert( sizeof( Pgno ) == 4 );
  1994. pBt = new BtShared();//sqlite3MallocZero( sizeof(pBt) );
  1995. //if( pBt==null ){
  1996. // rc = SQLITE_NOMEM;
  1997. // goto btree_open_out;
  1998. //}
  1999. rc = sqlite3PagerOpen( pVfs, out pBt.pPager, zFilename,
  2000. EXTRA_SIZE, flags, vfsFlags, pageReinit );
  2001. if ( rc == SQLITE_OK )
  2002. {
  2003. rc = sqlite3PagerReadFileheader( pBt.pPager, zDbHeader.Length, zDbHeader );
  2004. }
  2005. if ( rc != SQLITE_OK )
  2006. {
  2007. goto btree_open_out;
  2008. }
  2009. pBt.openFlags = (u8)flags;
  2010. pBt.db = db;
  2011. sqlite3PagerSetBusyhandler( pBt.pPager, btreeInvokeBusyHandler, pBt );
  2012. p.pBt = pBt;
  2013. pBt.pCursor = null;
  2014. pBt.pPage1 = null;
  2015. pBt.readOnly = sqlite3PagerIsreadonly( pBt.pPager );
  2016. #if SQLITE_SECURE_DELETE
  2017. pBt.secureDelete = true;
  2018. #endif
  2019. pBt.pageSize = (u32)( ( zDbHeader[16] << 8 ) | ( zDbHeader[17] << 16 ) );
  2020. if ( pBt.pageSize < 512 || pBt.pageSize > SQLITE_MAX_PAGE_SIZE
  2021. || ( ( pBt.pageSize - 1 ) & pBt.pageSize ) != 0 )
  2022. {
  2023. pBt.pageSize = 0;
  2024. #if !SQLITE_OMIT_AUTOVACUUM
  2025. /* If the magic name ":memory:" will create an in-memory database, then
  2026. ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if
  2027. ** SQLITE_DEFAULT_AUTOVACUUM is true. On the other hand, if
  2028. ** SQLITE_OMIT_MEMORYDB has been defined, then ":memory:" is just a
  2029. ** regular file-name. In this case the auto-vacuum applies as per normal.
  2030. */
  2031. if ( zFilename != "" && !isMemdb )
  2032. {
  2033. pBt.autoVacuum = ( SQLITE_DEFAULT_AUTOVACUUM != 0 );
  2034. pBt.incrVacuum = ( SQLITE_DEFAULT_AUTOVACUUM == 2 );
  2035. }
  2036. #endif
  2037. nReserve = 0;
  2038. }
  2039. else
  2040. {
  2041. nReserve = zDbHeader[20];
  2042. pBt.pageSizeFixed = true;
  2043. #if !SQLITE_OMIT_AUTOVACUUM
  2044. pBt.autoVacuum = sqlite3Get4byte( zDbHeader, 36 + 4 * 4 ) != 0;
  2045. pBt.incrVacuum = sqlite3Get4byte( zDbHeader, 36 + 7 * 4 ) != 0;
  2046. #endif
  2047. }
  2048. rc = sqlite3PagerSetPagesize( pBt.pPager, ref pBt.pageSize, nReserve );
  2049. if ( rc != 0 )
  2050. goto btree_open_out;
  2051. pBt.usableSize = (u16)( pBt.pageSize - nReserve );
  2052. Debug.Assert( ( pBt.pageSize & 7 ) == 0 ); /* 8-byte alignment of pageSize */
  2053. #if !(SQLITE_OMIT_SHARED_CACHE) && !(SQLITE_OMIT_DISKIO)
  2054. /* Add the new BtShared object to the linked list sharable BtShareds.
  2055. */
  2056. if( p.sharable ){
  2057. sqlite3_mutex *mutexShared;
  2058. pBt.nRef = 1;
  2059. mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
  2060. if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
  2061. pBt.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
  2062. if( pBt.mutex==null ){
  2063. rc = SQLITE_NOMEM;
  2064. db.mallocFailed = 0;
  2065. goto btree_open_out;
  2066. }
  2067. }
  2068. sqlite3_mutex_enter(mutexShared);
  2069. pBt.pNext = GLOBAL(BtShared*,sqlite3SharedCacheList);
  2070. GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt;
  2071. sqlite3_mutex_leave(mutexShared);
  2072. }
  2073. #endif
  2074. }
  2075. #if !(SQLITE_OMIT_SHARED_CACHE) && !(SQLITE_OMIT_DISKIO)
  2076. /* If the new Btree uses a sharable pBtShared, then link the new
  2077. ** Btree into the list of all sharable Btrees for the same connection.
  2078. ** The list is kept in ascending order by pBt address.
  2079. */
  2080. if( p.sharable ){
  2081. int i;
  2082. Btree pSib;
  2083. for(i=0; i<db.nDb; i++){
  2084. if( (pSib = db.aDb[i].pBt)!=null && pSib.sharable ){
  2085. while( pSib.pPrev ){ pSib = pSib.pPrev; }
  2086. if( p.pBt<pSib.pBt ){
  2087. p.pNext = pSib;
  2088. p.pPrev = 0;
  2089. pSib.pPrev = p;
  2090. }else{
  2091. while( pSib.pNext && pSib.pNext.pBt<p.pBt ){
  2092. pSib = pSib.pNext;
  2093. }
  2094. p.pNext = pSib.pNext;
  2095. p.pPrev = pSib;
  2096. if( p.pNext ){
  2097. p.pNext.pPrev = p;
  2098. }
  2099. pSib.pNext = p;
  2100. }
  2101. break;
  2102. }
  2103. }
  2104. }
  2105. #endif
  2106. ppBtree = p;
  2107. btree_open_out:
  2108. if ( rc != SQLITE_OK )
  2109. {
  2110. if ( pBt != null && pBt.pPager != null )
  2111. {
  2112. sqlite3PagerClose( pBt.pPager );
  2113. }
  2114. pBt = null; // sqlite3_free(ref pBt);
  2115. p = null; // sqlite3_free(ref p);
  2116. ppBtree = null;
  2117. }
  2118. else
  2119. {
  2120. /* If the B-Tree was successfully opened, set the pager-cache size to the
  2121. ** default value. Except, when opening on an existing shared pager-cache,
  2122. ** do not change the pager-cache size.
  2123. */
  2124. if ( sqlite3BtreeSchema( p, 0, null ) == null )
  2125. {
  2126. sqlite3PagerSetCachesize( p.pBt.pPager, SQLITE_DEFAULT_CACHE_SIZE );
  2127. }
  2128. }
  2129. if ( mutexOpen != null )
  2130. {
  2131. Debug.Assert( sqlite3_mutex_held( mutexOpen ) );
  2132. sqlite3_mutex_leave( mutexOpen );
  2133. }
  2134. return rc;
  2135. }
  2136. /*
  2137. ** Decrement the BtShared.nRef counter. When it reaches zero,
  2138. ** remove the BtShared structure from the sharing list. Return
  2139. ** true if the BtShared.nRef counter reaches zero and return
  2140. ** false if it is still positive.
  2141. */
  2142. static bool removeFromSharingList( BtShared pBt )
  2143. {
  2144. #if !SQLITE_OMIT_SHARED_CACHE
  2145. sqlite3_mutex pMaster;
  2146. BtShared pList;
  2147. bool removed = false;
  2148. Debug.Assert( sqlite3_mutex_notheld(pBt.mutex) );
  2149. pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
  2150. sqlite3_mutex_enter(pMaster);
  2151. pBt.nRef--;
  2152. if( pBt.nRef<=0 ){
  2153. if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){
  2154. GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt.pNext;
  2155. }else{
  2156. pList = GLOBAL(BtShared*,sqlite3SharedCacheList);
  2157. while( ALWAYS(pList) && pList.pNext!=pBt ){
  2158. pList=pList.pNext;
  2159. }
  2160. if( ALWAYS(pList) ){
  2161. pList.pNext = pBt.pNext;
  2162. }
  2163. }
  2164. if( SQLITE_THREADSAFE ){
  2165. sqlite3_mutex_free(pBt.mutex);
  2166. }
  2167. removed = true;
  2168. }
  2169. sqlite3_mutex_leave(pMaster);
  2170. return removed;
  2171. #else
  2172. return true;
  2173. #endif
  2174. }
  2175. /*
  2176. ** Make sure pBt.pTmpSpace points to an allocation of
  2177. ** MX_CELL_SIZE(pBt) bytes.
  2178. */
  2179. static void allocateTempSpace( BtShared pBt )
  2180. {
  2181. if ( null == pBt.pTmpSpace )
  2182. {
  2183. pBt.pTmpSpace = sqlite3Malloc( pBt.pageSize );
  2184. }
  2185. }
  2186. /*
  2187. ** Free the pBt.pTmpSpace allocation
  2188. */
  2189. static void freeTempSpace( BtShared pBt )
  2190. {
  2191. sqlite3PageFree( ref pBt.pTmpSpace );
  2192. }
  2193. /*
  2194. ** Close an open database and invalidate all cursors.
  2195. */
  2196. static int sqlite3BtreeClose( ref Btree p )
  2197. {
  2198. BtShared pBt = p.pBt;
  2199. BtCursor pCur;
  2200. /* Close all cursors opened via this handle. */
  2201. Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
  2202. sqlite3BtreeEnter( p );
  2203. pCur = pBt.pCursor;
  2204. while ( pCur != null )
  2205. {
  2206. BtCursor pTmp = pCur;
  2207. pCur = pCur.pNext;
  2208. if ( pTmp.pBtree == p )
  2209. {
  2210. sqlite3BtreeCloseCursor( pTmp );
  2211. }
  2212. }
  2213. /* Rollback any active transaction and free the handle structure.
  2214. ** The call to sqlite3BtreeRollback() drops any table-locks held by
  2215. ** this handle.
  2216. */
  2217. sqlite3BtreeRollback( p );
  2218. sqlite3BtreeLeave( p );
  2219. /* If there are still other outstanding references to the shared-btree
  2220. ** structure, return now. The remainder of this procedure cleans
  2221. ** up the shared-btree.
  2222. */
  2223. Debug.Assert( p.wantToLock == 0 && !p.locked );
  2224. if ( !p.sharable || removeFromSharingList( pBt ) )
  2225. {
  2226. /* The pBt is no longer on the sharing list, so we can access
  2227. ** it without having to hold the mutex.
  2228. **
  2229. ** Clean out and delete the BtShared object.
  2230. */
  2231. Debug.Assert( null == pBt.pCursor );
  2232. sqlite3PagerClose( pBt.pPager );
  2233. if ( pBt.xFreeSchema != null && pBt.pSchema != null )
  2234. {
  2235. pBt.xFreeSchema( pBt.pSchema );
  2236. }
  2237. pBt.pSchema = null;// sqlite3DbFree(0, pBt->pSchema);
  2238. //freeTempSpace(pBt);
  2239. pBt = null; //sqlite3_free(ref pBt);
  2240. }
  2241. #if !SQLITE_OMIT_SHARED_CACHE
  2242. Debug.Assert( p.wantToLock==null );
  2243. Debug.Assert( p.locked==null );
  2244. if( p.pPrev ) p.pPrev.pNext = p.pNext;
  2245. if( p.pNext ) p.pNext.pPrev = p.pPrev;
  2246. #endif
  2247. //sqlite3_free(ref p);
  2248. return SQLITE_OK;
  2249. }
  2250. /*
  2251. ** Change the limit on the number of pages allowed in the cache.
  2252. **
  2253. ** The maximum number of cache pages is set to the absolute
  2254. ** value of mxPage. If mxPage is negative, the pager will
  2255. ** operate asynchronously - it will not stop to do fsync()s
  2256. ** to insure data is written to the disk surface before
  2257. ** continuing. Transactions still work if synchronous is off,
  2258. ** and the database cannot be corrupted if this program
  2259. ** crashes. But if the operating system crashes or there is
  2260. ** an abrupt power failure when synchronous is off, the database
  2261. ** could be left in an inconsistent and unrecoverable state.
  2262. ** Synchronous is on by default so database corruption is not
  2263. ** normally a worry.
  2264. */
  2265. static int sqlite3BtreeSetCacheSize( Btree p, int mxPage )
  2266. {
  2267. BtShared pBt = p.pBt;
  2268. Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
  2269. sqlite3BtreeEnter( p );
  2270. sqlite3PagerSetCachesize( pBt.pPager, mxPage );
  2271. sqlite3BtreeLeave( p );
  2272. return SQLITE_OK;
  2273. }
  2274. /*
  2275. ** Change the way data is synced to disk in order to increase or decrease
  2276. ** how well the database resists damage due to OS crashes and power
  2277. ** failures. Level 1 is the same as asynchronous (no syncs() occur and
  2278. ** there is a high probability of damage) Level 2 is the default. There
  2279. ** is a very low but non-zero probability of damage. Level 3 reduces the
  2280. ** probability of damage to near zero but with a write performance reduction.
  2281. */
  2282. #if !SQLITE_OMIT_PAGER_PRAGMAS
  2283. static int sqlite3BtreeSetSafetyLevel(
  2284. Btree p, /* The btree to set the safety level on */
  2285. int level, /* PRAGMA synchronous. 1=OFF, 2=NORMAL, 3=FULL */
  2286. int fullSync, /* PRAGMA fullfsync. */
  2287. int ckptFullSync /* PRAGMA checkpoint_fullfync */
  2288. )
  2289. {
  2290. BtShared pBt = p.pBt;
  2291. Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
  2292. Debug.Assert( level >= 1 && level <= 3 );
  2293. sqlite3BtreeEnter( p );
  2294. sqlite3PagerSetSafetyLevel( pBt.pPager, level, fullSync, ckptFullSync );
  2295. sqlite3BtreeLeave( p );
  2296. return SQLITE_OK;
  2297. }
  2298. #endif
  2299. /*
  2300. ** Return TRUE if the given btree is set to safety level 1. In other
  2301. ** words, return TRUE if no sync() occurs on the disk files.
  2302. */
  2303. static int sqlite3BtreeSyncDisabled( Btree p )
  2304. {
  2305. BtShared pBt = p.pBt;
  2306. int rc;
  2307. Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
  2308. sqlite3BtreeEnter( p );
  2309. Debug.Assert( pBt != null && pBt.pPager != null );
  2310. rc = sqlite3PagerNosync( pBt.pPager ) ? 1 : 0;
  2311. sqlite3BtreeLeave( p );
  2312. return rc;
  2313. }
  2314. /*
  2315. ** Change the default pages size and the number of reserved bytes per page.
  2316. ** Or, if the page size has already been fixed, return SQLITE_READONLY
  2317. ** without changing anything.
  2318. **
  2319. ** The page size must be a power of 2 between 512 and 65536. If the page
  2320. ** size supplied does not meet this constraint then the page size is not
  2321. ** changed.
  2322. **
  2323. ** Page sizes are constrained to be a power of two so that the region
  2324. ** of the database file used for locking (beginning at PENDING_BYTE,
  2325. ** the first byte past the 1GB boundary, 0x40000000) needs to occur
  2326. ** at the beginning of a page.
  2327. **
  2328. ** If parameter nReserve is less than zero, then the number of reserved
  2329. ** bytes per page is left unchanged.
  2330. **
  2331. ** If iFix!=0 then the pageSizeFixed flag is set so that the page size
  2332. ** and autovacuum mode can no longer be changed.
  2333. */
  2334. static int sqlite3BtreeSetPageSize( Btree p, int pageSize, int nReserve, int iFix )
  2335. {
  2336. int rc = SQLITE_OK;
  2337. BtShared pBt = p.pBt;
  2338. Debug.Assert( nReserve >= -1 && nReserve <= 255 );
  2339. sqlite3BtreeEnter( p );
  2340. if ( pBt.pageSizeFixed )
  2341. {
  2342. sqlite3BtreeLeave( p );
  2343. return SQLITE_READONLY;
  2344. }
  2345. if ( nReserve < 0 )
  2346. {
  2347. nReserve = (int)( pBt.pageSize - pBt.usableSize );
  2348. }
  2349. Debug.Assert( nReserve >= 0 && nReserve <= 255 );
  2350. if ( pageSize >= 512 && pageSize <= SQLITE_MAX_PAGE_SIZE &&
  2351. ( ( pageSize - 1 ) & pageSize ) == 0 )
  2352. {
  2353. Debug.Assert( ( pageSize & 7 ) == 0 );
  2354. Debug.Assert( null == pBt.pPage1 && null == pBt.pCursor );
  2355. pBt.pageSize = (u32)pageSize;
  2356. // freeTempSpace(pBt);
  2357. }
  2358. rc = sqlite3PagerSetPagesize( pBt.pPager, ref pBt.pageSize, nReserve );
  2359. pBt.usableSize = (u16)( pBt.pageSize - nReserve );
  2360. if ( iFix != 0 )
  2361. pBt.pageSizeFixed = true;
  2362. sqlite3BtreeLeave( p );
  2363. return rc;
  2364. }
  2365. /*
  2366. ** Return the currently defined page size
  2367. */
  2368. static int sqlite3BtreeGetPageSize( Btree p )
  2369. {
  2370. return (int)p.pBt.pageSize;
  2371. }
  2372. #if !(SQLITE_OMIT_PAGER_PRAGMAS) || !(SQLITE_OMIT_VACUUM)
  2373. /*
  2374. ** Return the number of bytes of space at the end of every page that
  2375. ** are intentually left unused. This is the "reserved" space that is
  2376. ** sometimes used by extensions.
  2377. */
  2378. static int sqlite3BtreeGetReserve( Btree p )
  2379. {
  2380. int n;
  2381. sqlite3BtreeEnter( p );
  2382. n = (int)( p.pBt.pageSize - p.pBt.usableSize );
  2383. sqlite3BtreeLeave( p );
  2384. return n;
  2385. }
  2386. /*
  2387. ** Set the maximum page count for a database if mxPage is positive.
  2388. ** No changes are made if mxPage is 0 or negative.
  2389. ** Regardless of the value of mxPage, return the maximum page count.
  2390. */
  2391. static Pgno sqlite3BtreeMaxPageCount( Btree p, int mxPage )
  2392. {
  2393. Pgno n;
  2394. sqlite3BtreeEnter( p );
  2395. n = sqlite3PagerMaxPageCount( p.pBt.pPager, mxPage );
  2396. sqlite3BtreeLeave( p );
  2397. return n;
  2398. }
  2399. /*
  2400. ** Set the secureDelete flag if newFlag is 0 or 1. If newFlag is -1,
  2401. ** then make no changes. Always return the value of the secureDelete
  2402. ** setting after the change.
  2403. */
  2404. static int sqlite3BtreeSecureDelete( Btree p, int newFlag )
  2405. {
  2406. int b;
  2407. if ( p == null )
  2408. return 0;
  2409. sqlite3BtreeEnter( p );
  2410. if ( newFlag >= 0 )
  2411. {
  2412. p.pBt.secureDelete = ( newFlag != 0 );
  2413. }
  2414. b = p.pBt.secureDelete ? 1 : 0;
  2415. sqlite3BtreeLeave( p );
  2416. return b;
  2417. }
  2418. #endif //* !(SQLITE_OMIT_PAGER_PRAGMAS) || !(SQLITE_OMIT_VACUUM) */
  2419. /*
  2420. ** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
  2421. ** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it
  2422. ** is disabled. The default value for the auto-vacuum property is
  2423. ** determined by the SQLITE_DEFAULT_AUTOVACUUM macro.
  2424. */
  2425. static int sqlite3BtreeSetAutoVacuum( Btree p, int autoVacuum )
  2426. {
  2427. #if SQLITE_OMIT_AUTOVACUUM
  2428. return SQLITE_READONLY;
  2429. #else
  2430. BtShared pBt = p.pBt;
  2431. int rc = SQLITE_OK;
  2432. u8 av = (u8)autoVacuum;
  2433. sqlite3BtreeEnter( p );
  2434. if ( pBt.pageSizeFixed && ( av != 0 ) != pBt.autoVacuum )
  2435. {
  2436. rc = SQLITE_READONLY;
  2437. }
  2438. else
  2439. {
  2440. pBt.autoVacuum = av != 0;
  2441. pBt.incrVacuum = av == 2;
  2442. }
  2443. sqlite3BtreeLeave( p );
  2444. return rc;
  2445. #endif
  2446. }
  2447. /*
  2448. ** Return the value of the 'auto-vacuum' property. If auto-vacuum is
  2449. ** enabled 1 is returned. Otherwise 0.
  2450. */
  2451. static int sqlite3BtreeGetAutoVacuum( Btree p )
  2452. {
  2453. #if SQLITE_OMIT_AUTOVACUUM
  2454. return BTREE_AUTOVACUUM_NONE;
  2455. #else
  2456. int rc;
  2457. sqlite3BtreeEnter( p );
  2458. rc = (
  2459. ( !p.pBt.autoVacuum ) ? BTREE_AUTOVACUUM_NONE :
  2460. ( !p.pBt.incrVacuum ) ? BTREE_AUTOVACUUM_FULL :
  2461. BTREE_AUTOVACUUM_INCR
  2462. );
  2463. sqlite3BtreeLeave( p );
  2464. return rc;
  2465. #endif
  2466. }
  2467. /*
  2468. ** Get a reference to pPage1 of the database file. This will
  2469. ** also acquire a readlock on that file.
  2470. **
  2471. ** SQLITE_OK is returned on success. If the file is not a
  2472. ** well-formed database file, then SQLITE_CORRUPT is returned.
  2473. ** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM
  2474. ** is returned if we run out of memory.
  2475. */
  2476. static int lockBtree( BtShared pBt )
  2477. {
  2478. int rc; /* Result code from subfunctions */
  2479. MemPage pPage1 = null; /* Page 1 of the database file */
  2480. Pgno nPage; /* Number of pages in the database */
  2481. Pgno nPageFile = 0; /* Number of pages in the database file */
  2482. ////Pgno nPageHeader; /* Number of pages in the database according to hdr */
  2483. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  2484. Debug.Assert( pBt.pPage1 == null );
  2485. rc = sqlite3PagerSharedLock( pBt.pPager );
  2486. if ( rc != SQLITE_OK )
  2487. return rc;
  2488. rc = btreeGetPage( pBt, 1, ref pPage1, 0 );
  2489. if ( rc != SQLITE_OK )
  2490. return rc;
  2491. /* Do some checking to help insure the file we opened really is
  2492. ** a valid database file.
  2493. */
  2494. nPage = sqlite3Get4byte( pPage1.aData, 28 );//get4byte(28+(u8*)pPage1->aData);
  2495. sqlite3PagerPagecount( pBt.pPager, out nPageFile );
  2496. if ( nPage == 0 || memcmp( pPage1.aData, 24, pPage1.aData, 92, 4 ) != 0 )//memcmp(24 + (u8*)pPage1.aData, 92 + (u8*)pPage1.aData, 4) != 0)
  2497. {
  2498. nPage = nPageFile;
  2499. }
  2500. if ( nPage > 0 )
  2501. {
  2502. u32 pageSize;
  2503. u32 usableSize;
  2504. u8[] page1 = pPage1.aData;
  2505. rc = SQLITE_NOTADB;
  2506. if ( memcmp( page1, zMagicHeader, 16 ) != 0 )
  2507. {
  2508. goto page1_init_failed;
  2509. }
  2510. #if SQLITE_OMIT_WAL
  2511. if ( page1[18] > 1 )
  2512. {
  2513. pBt.readOnly = true;
  2514. }
  2515. if ( page1[19] > 1 )
  2516. {
  2517. pBt.pSchema.file_format = page1[19];
  2518. goto page1_init_failed;
  2519. }
  2520. #else
  2521. if( page1[18]>2 ){
  2522. pBt.readOnly = true;
  2523. }
  2524. if( page1[19]>2 ){
  2525. goto page1_init_failed;
  2526. }
  2527. /* If the write version is set to 2, this database should be accessed
  2528. ** in WAL mode. If the log is not already open, open it now. Then
  2529. ** return SQLITE_OK and return without populating BtShared.pPage1.
  2530. ** The caller detects this and calls this function again. This is
  2531. ** required as the version of page 1 currently in the page1 buffer
  2532. ** may not be the latest version - there may be a newer one in the log
  2533. ** file.
  2534. */
  2535. if( page1[19]==2 && pBt.doNotUseWAL==false ){
  2536. int isOpen = 0;
  2537. rc = sqlite3PagerOpenWal(pBt.pPager, ref isOpen);
  2538. if( rc!=SQLITE_OK ){
  2539. goto page1_init_failed;
  2540. }else if( isOpen==0 ){
  2541. releasePage(pPage1);
  2542. return SQLITE_OK;
  2543. }
  2544. rc = SQLITE_NOTADB;
  2545. }
  2546. #endif
  2547. /* The maximum embedded fraction must be exactly 25%. And the minimum
  2548. ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data.
  2549. ** The original design allowed these amounts to vary, but as of
  2550. ** version 3.6.0, we require them to be fixed.
  2551. */
  2552. if ( memcmp( page1, 21, "\x0040\x0020\x0020", 3 ) != 0 )// "\100\040\040"
  2553. {
  2554. goto page1_init_failed;
  2555. }
  2556. pageSize = (u32)( ( page1[16] << 8 ) | ( page1[17] << 16 ) );
  2557. if ( ( ( pageSize - 1 ) & pageSize ) != 0
  2558. || pageSize > SQLITE_MAX_PAGE_SIZE
  2559. || pageSize <= 256
  2560. )
  2561. {
  2562. goto page1_init_failed;
  2563. }
  2564. Debug.Assert( ( pageSize & 7 ) == 0 );
  2565. usableSize = pageSize - page1[20];
  2566. if ( pageSize != pBt.pageSize )
  2567. {
  2568. /* After reading the first page of the database assuming a page size
  2569. ** of BtShared.pageSize, we have discovered that the page-size is
  2570. ** actually pageSize. Unlock the database, leave pBt.pPage1 at
  2571. ** zero and return SQLITE_OK. The caller will call this function
  2572. ** again with the correct page-size.
  2573. */
  2574. releasePage( pPage1 );
  2575. pBt.usableSize = usableSize;
  2576. pBt.pageSize = pageSize;
  2577. // freeTempSpace(pBt);
  2578. rc = sqlite3PagerSetPagesize( pBt.pPager, ref pBt.pageSize,
  2579. (int)( pageSize - usableSize ) );
  2580. return rc;
  2581. }
  2582. if ( ( pBt.db.flags & SQLITE_RecoveryMode ) == 0 && nPage > nPageFile )
  2583. {
  2584. rc = SQLITE_CORRUPT_BKPT();
  2585. goto page1_init_failed;
  2586. }
  2587. if ( usableSize < 480 )
  2588. {
  2589. goto page1_init_failed;
  2590. }
  2591. pBt.pageSize = pageSize;
  2592. pBt.usableSize = usableSize;
  2593. #if !SQLITE_OMIT_AUTOVACUUM
  2594. pBt.autoVacuum = ( sqlite3Get4byte( page1, 36 + 4 * 4 ) != 0 );
  2595. pBt.incrVacuum = ( sqlite3Get4byte( page1, 36 + 7 * 4 ) != 0 );
  2596. #endif
  2597. }
  2598. /* maxLocal is the maximum amount of payload to store locally for
  2599. ** a cell. Make sure it is small enough so that at least minFanout
  2600. ** cells can will fit on one page. We assume a 10-byte page header.
  2601. ** Besides the payload, the cell must store:
  2602. ** 2-byte pointer to the cell
  2603. ** 4-byte child pointer
  2604. ** 9-byte nKey value
  2605. ** 4-byte nData value
  2606. ** 4-byte overflow page pointer
  2607. ** So a cell consists of a 2-byte pointer, a header which is as much as
  2608. ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow
  2609. ** page pointer.
  2610. */
  2611. pBt.maxLocal = (u16)( ( pBt.usableSize - 12 ) * 64 / 255 - 23 );
  2612. pBt.minLocal = (u16)( ( pBt.usableSize - 12 ) * 32 / 255 - 23 );
  2613. pBt.maxLeaf = (u16)( pBt.usableSize - 35 );
  2614. pBt.minLeaf = (u16)( ( pBt.usableSize - 12 ) * 32 / 255 - 23 );
  2615. Debug.Assert( pBt.maxLeaf + 23 <= MX_CELL_SIZE( pBt ) );
  2616. pBt.pPage1 = pPage1;
  2617. pBt.nPage = nPage;
  2618. return SQLITE_OK;
  2619. page1_init_failed:
  2620. releasePage( pPage1 );
  2621. pBt.pPage1 = null;
  2622. return rc;
  2623. }
  2624. /*
  2625. ** If there are no outstanding cursors and we are not in the middle
  2626. ** of a transaction but there is a read lock on the database, then
  2627. ** this routine unrefs the first page of the database file which
  2628. ** has the effect of releasing the read lock.
  2629. **
  2630. ** If there is a transaction in progress, this routine is a no-op.
  2631. */
  2632. static void unlockBtreeIfUnused( BtShared pBt )
  2633. {
  2634. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  2635. Debug.Assert( pBt.pCursor == null || pBt.inTransaction > TRANS_NONE );
  2636. if ( pBt.inTransaction == TRANS_NONE && pBt.pPage1 != null )
  2637. {
  2638. Debug.Assert( pBt.pPage1.aData != null );
  2639. //Debug.Assert( sqlite3PagerRefcount( pBt.pPager ) == 1 );
  2640. releasePage( pBt.pPage1 );
  2641. pBt.pPage1 = null;
  2642. }
  2643. }
  2644. /*
  2645. ** If pBt points to an empty file then convert that empty file
  2646. ** into a new empty database by initializing the first page of
  2647. ** the database.
  2648. */
  2649. static int newDatabase( BtShared pBt )
  2650. {
  2651. MemPage pP1;
  2652. byte[] data;
  2653. int rc;
  2654. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  2655. if ( pBt.nPage > 0 )
  2656. {
  2657. return SQLITE_OK;
  2658. }
  2659. pP1 = pBt.pPage1;
  2660. Debug.Assert( pP1 != null );
  2661. data = pP1.aData;
  2662. rc = sqlite3PagerWrite( pP1.pDbPage );
  2663. if ( rc != 0 )
  2664. return rc;
  2665. Buffer.BlockCopy( zMagicHeader, 0, data, 0, 16 );// memcpy(data, zMagicHeader, sizeof(zMagicHeader));
  2666. Debug.Assert( zMagicHeader.Length == 16 );
  2667. data[16] = (u8)( ( pBt.pageSize >> 8 ) & 0xff );
  2668. data[17] = (u8)( ( pBt.pageSize >> 16 ) & 0xff );
  2669. data[18] = 1;
  2670. data[19] = 1;
  2671. Debug.Assert( pBt.usableSize <= pBt.pageSize && pBt.usableSize + 255 >= pBt.pageSize );
  2672. data[20] = (u8)( pBt.pageSize - pBt.usableSize );
  2673. data[21] = 64;
  2674. data[22] = 32;
  2675. data[23] = 32;
  2676. //memset(&data[24], 0, 100-24);
  2677. zeroPage( pP1, PTF_INTKEY | PTF_LEAF | PTF_LEAFDATA );
  2678. pBt.pageSizeFixed = true;
  2679. #if !SQLITE_OMIT_AUTOVACUUM
  2680. Debug.Assert( pBt.autoVacuum == true || pBt.autoVacuum == false );
  2681. Debug.Assert( pBt.incrVacuum == true || pBt.incrVacuum == false );
  2682. sqlite3Put4byte( data, 36 + 4 * 4, pBt.autoVacuum ? 1 : 0 );
  2683. sqlite3Put4byte( data, 36 + 7 * 4, pBt.incrVacuum ? 1 : 0 );
  2684. #endif
  2685. pBt.nPage = 1;
  2686. data[31] = 1;
  2687. return SQLITE_OK;
  2688. }
  2689. /*
  2690. ** Attempt to start a new transaction. A write-transaction
  2691. ** is started if the second argument is nonzero, otherwise a read-
  2692. ** transaction. If the second argument is 2 or more and exclusive
  2693. ** transaction is started, meaning that no other process is allowed
  2694. ** to access the database. A preexisting transaction may not be
  2695. ** upgraded to exclusive by calling this routine a second time - the
  2696. ** exclusivity flag only works for a new transaction.
  2697. **
  2698. ** A write-transaction must be started before attempting any
  2699. ** changes to the database. None of the following routines
  2700. ** will work unless a transaction is started first:
  2701. **
  2702. ** sqlite3BtreeCreateTable()
  2703. ** sqlite3BtreeCreateIndex()
  2704. ** sqlite3BtreeClearTable()
  2705. ** sqlite3BtreeDropTable()
  2706. ** sqlite3BtreeInsert()
  2707. ** sqlite3BtreeDelete()
  2708. ** sqlite3BtreeUpdateMeta()
  2709. **
  2710. ** If an initial attempt to acquire the lock fails because of lock contention
  2711. ** and the database was previously unlocked, then invoke the busy handler
  2712. ** if there is one. But if there was previously a read-lock, do not
  2713. ** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is
  2714. ** returned when there is already a read-lock in order to avoid a deadlock.
  2715. **
  2716. ** Suppose there are two processes A and B. A has a read lock and B has
  2717. ** a reserved lock. B tries to promote to exclusive but is blocked because
  2718. ** of A's read lock. A tries to promote to reserved but is blocked by B.
  2719. ** One or the other of the two processes must give way or there can be
  2720. ** no progress. By returning SQLITE_BUSY and not invoking the busy callback
  2721. ** when A already has a read lock, we encourage A to give up and let B
  2722. ** proceed.
  2723. */
  2724. static int sqlite3BtreeBeginTrans( Btree p, int wrflag )
  2725. {
  2726. BtShared pBt = p.pBt;
  2727. int rc = SQLITE_OK;
  2728. sqlite3BtreeEnter( p );
  2729. btreeIntegrity( p );
  2730. /* If the btree is already in a write-transaction, or it
  2731. ** is already in a read-transaction and a read-transaction
  2732. ** is requested, this is a no-op.
  2733. */
  2734. if ( p.inTrans == TRANS_WRITE || ( p.inTrans == TRANS_READ && 0 == wrflag ) )
  2735. {
  2736. goto trans_begun;
  2737. }
  2738. /* Write transactions are not possible on a read-only database */
  2739. if ( pBt.readOnly && wrflag != 0 )
  2740. {
  2741. rc = SQLITE_READONLY;
  2742. goto trans_begun;
  2743. }
  2744. #if !SQLITE_OMIT_SHARED_CACHE
  2745. /* If another database handle has already opened a write transaction
  2746. ** on this shared-btree structure and a second write transaction is
  2747. ** requested, return SQLITE_LOCKED.
  2748. */
  2749. if( (wrflag && pBt.inTransaction==TRANS_WRITE) || pBt.isPending ){
  2750. sqlite3 pBlock = pBt.pWriter.db;
  2751. }else if( wrflag>1 ){
  2752. BtLock pIter;
  2753. for(pIter=pBt.pLock; pIter; pIter=pIter.pNext){
  2754. if( pIter.pBtree!=p ){
  2755. pBlock = pIter.pBtree.db;
  2756. break;
  2757. }
  2758. }
  2759. }
  2760. if( pBlock ){
  2761. sqlite3ConnectionBlocked(p.db, pBlock);
  2762. rc = SQLITE_LOCKED_SHAREDCACHE;
  2763. goto trans_begun;
  2764. }
  2765. #endif
  2766. /* Any read-only or read-write transaction implies a read-lock on
  2767. ** page 1. So if some other shared-cache client already has a write-lock
  2768. ** on page 1, the transaction cannot be opened. */
  2769. rc = querySharedCacheTableLock( p, MASTER_ROOT, READ_LOCK );
  2770. if ( SQLITE_OK != rc )
  2771. goto trans_begun;
  2772. pBt.initiallyEmpty = pBt.nPage == 0;
  2773. do
  2774. {
  2775. /* Call lockBtree() until either pBt.pPage1 is populated or
  2776. ** lockBtree() returns something other than SQLITE_OK. lockBtree()
  2777. ** may return SQLITE_OK but leave pBt.pPage1 set to 0 if after
  2778. ** reading page 1 it discovers that the page-size of the database
  2779. ** file is not pBt.pageSize. In this case lockBtree() will update
  2780. ** pBt.pageSize to the page-size of the file on disk.
  2781. */
  2782. while ( pBt.pPage1 == null && SQLITE_OK == ( rc = lockBtree( pBt ) ) )
  2783. ;
  2784. if ( rc == SQLITE_OK && wrflag != 0 )
  2785. {
  2786. if ( pBt.readOnly )
  2787. {
  2788. rc = SQLITE_READONLY;
  2789. }
  2790. else
  2791. {
  2792. rc = sqlite3PagerBegin( pBt.pPager, wrflag > 1, sqlite3TempInMemory( p.db ) ? 1 : 0 );
  2793. if ( rc == SQLITE_OK )
  2794. {
  2795. rc = newDatabase( pBt );
  2796. }
  2797. }
  2798. }
  2799. if ( rc != SQLITE_OK )
  2800. {
  2801. unlockBtreeIfUnused( pBt );
  2802. }
  2803. } while ( ( rc & 0xFF ) == SQLITE_BUSY && pBt.inTransaction == TRANS_NONE &&
  2804. btreeInvokeBusyHandler( pBt ) != 0 );
  2805. if ( rc == SQLITE_OK )
  2806. {
  2807. if ( p.inTrans == TRANS_NONE )
  2808. {
  2809. pBt.nTransaction++;
  2810. #if !SQLITE_OMIT_SHARED_CACHE
  2811. if( p.sharable ){
  2812. Debug.Assert( p.lock.pBtree==p && p.lock.iTable==1 );
  2813. p.lock.eLock = READ_LOCK;
  2814. p.lock.pNext = pBt.pLock;
  2815. pBt.pLock = &p.lock;
  2816. }
  2817. #endif
  2818. }
  2819. p.inTrans = ( wrflag != 0 ? TRANS_WRITE : TRANS_READ );
  2820. if ( p.inTrans > pBt.inTransaction )
  2821. {
  2822. pBt.inTransaction = p.inTrans;
  2823. }
  2824. if ( wrflag != 0 )
  2825. {
  2826. MemPage pPage1 = pBt.pPage1;
  2827. #if !SQLITE_OMIT_SHARED_CACHE
  2828. Debug.Assert( !pBt.pWriter );
  2829. pBt.pWriter = p;
  2830. pBt.isExclusive = (u8)(wrflag>1);
  2831. #endif
  2832. /* If the db-size header field is incorrect (as it may be if an old
  2833. ** client has been writing the database file), update it now. Doing
  2834. ** this sooner rather than later means the database size can safely
  2835. ** re-read the database size from page 1 if a savepoint or transaction
  2836. ** rollback occurs within the transaction.
  2837. */
  2838. if ( pBt.nPage != sqlite3Get4byte( pPage1.aData, 28 ) )
  2839. {
  2840. rc = sqlite3PagerWrite( pPage1.pDbPage );
  2841. if ( rc == SQLITE_OK )
  2842. {
  2843. sqlite3Put4byte( pPage1.aData, (u32)28, pBt.nPage );
  2844. }
  2845. }
  2846. }
  2847. }
  2848. trans_begun:
  2849. if ( rc == SQLITE_OK && wrflag != 0 )
  2850. {
  2851. /* This call makes sure that the pager has the correct number of
  2852. ** open savepoints. If the second parameter is greater than 0 and
  2853. ** the sub-journal is not already open, then it will be opened here.
  2854. */
  2855. rc = sqlite3PagerOpenSavepoint( pBt.pPager, p.db.nSavepoint );
  2856. }
  2857. btreeIntegrity( p );
  2858. sqlite3BtreeLeave( p );
  2859. return rc;
  2860. }
  2861. #if !SQLITE_OMIT_AUTOVACUUM
  2862. /*
  2863. ** Set the pointer-map entries for all children of page pPage. Also, if
  2864. ** pPage contains cells that point to overflow pages, set the pointer
  2865. ** map entries for the overflow pages as well.
  2866. */
  2867. static int setChildPtrmaps( MemPage pPage )
  2868. {
  2869. int i; /* Counter variable */
  2870. int nCell; /* Number of cells in page pPage */
  2871. int rc; /* Return code */
  2872. BtShared pBt = pPage.pBt;
  2873. u8 isInitOrig = pPage.isInit;
  2874. Pgno pgno = pPage.pgno;
  2875. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  2876. rc = btreeInitPage( pPage );
  2877. if ( rc != SQLITE_OK )
  2878. {
  2879. goto set_child_ptrmaps_out;
  2880. }
  2881. nCell = pPage.nCell;
  2882. for ( i = 0; i < nCell; i++ )
  2883. {
  2884. int pCell = findCell( pPage, i );
  2885. ptrmapPutOvflPtr( pPage, pCell, ref rc );
  2886. if ( 0 == pPage.leaf )
  2887. {
  2888. Pgno childPgno = sqlite3Get4byte( pPage.aData, pCell );
  2889. ptrmapPut( pBt, childPgno, PTRMAP_BTREE, pgno, ref rc );
  2890. }
  2891. }
  2892. if ( 0 == pPage.leaf )
  2893. {
  2894. Pgno childPgno = sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 );
  2895. ptrmapPut( pBt, childPgno, PTRMAP_BTREE, pgno, ref rc );
  2896. }
  2897. set_child_ptrmaps_out:
  2898. pPage.isInit = isInitOrig;
  2899. return rc;
  2900. }
  2901. /*
  2902. ** Somewhere on pPage is a pointer to page iFrom. Modify this pointer so
  2903. ** that it points to iTo. Parameter eType describes the type of pointer to
  2904. ** be modified, as follows:
  2905. **
  2906. ** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child
  2907. ** page of pPage.
  2908. **
  2909. ** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow
  2910. ** page pointed to by one of the cells on pPage.
  2911. **
  2912. ** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next
  2913. ** overflow page in the list.
  2914. */
  2915. static int modifyPagePointer( MemPage pPage, Pgno iFrom, Pgno iTo, u8 eType )
  2916. {
  2917. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  2918. Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
  2919. if ( eType == PTRMAP_OVERFLOW2 )
  2920. {
  2921. /* The pointer is always the first 4 bytes of the page in this case. */
  2922. if ( sqlite3Get4byte( pPage.aData ) != iFrom )
  2923. {
  2924. return SQLITE_CORRUPT_BKPT();
  2925. }
  2926. sqlite3Put4byte( pPage.aData, iTo );
  2927. }
  2928. else
  2929. {
  2930. u8 isInitOrig = pPage.isInit;
  2931. int i;
  2932. int nCell;
  2933. btreeInitPage( pPage );
  2934. nCell = pPage.nCell;
  2935. for ( i = 0; i < nCell; i++ )
  2936. {
  2937. int pCell = findCell( pPage, i );
  2938. if ( eType == PTRMAP_OVERFLOW1 )
  2939. {
  2940. CellInfo info = new CellInfo();
  2941. btreeParseCellPtr( pPage, pCell, ref info );
  2942. if ( info.iOverflow != 0 )
  2943. {
  2944. if ( iFrom == sqlite3Get4byte( pPage.aData, pCell, info.iOverflow ) )
  2945. {
  2946. sqlite3Put4byte( pPage.aData, pCell + info.iOverflow, (int)iTo );
  2947. break;
  2948. }
  2949. }
  2950. }
  2951. else
  2952. {
  2953. if ( sqlite3Get4byte( pPage.aData, pCell ) == iFrom )
  2954. {
  2955. sqlite3Put4byte( pPage.aData, pCell, (int)iTo );
  2956. break;
  2957. }
  2958. }
  2959. }
  2960. if ( i == nCell )
  2961. {
  2962. if ( eType != PTRMAP_BTREE ||
  2963. sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 ) != iFrom )
  2964. {
  2965. return SQLITE_CORRUPT_BKPT();
  2966. }
  2967. sqlite3Put4byte( pPage.aData, pPage.hdrOffset + 8, iTo );
  2968. }
  2969. pPage.isInit = isInitOrig;
  2970. }
  2971. return SQLITE_OK;
  2972. }
  2973. /*
  2974. ** Move the open database page pDbPage to location iFreePage in the
  2975. ** database. The pDbPage reference remains valid.
  2976. **
  2977. ** The isCommit flag indicates that there is no need to remember that
  2978. ** the journal needs to be sync()ed before database page pDbPage.pgno
  2979. ** can be written to. The caller has already promised not to write to that
  2980. ** page.
  2981. */
  2982. static int relocatePage(
  2983. BtShared pBt, /* Btree */
  2984. MemPage pDbPage, /* Open page to move */
  2985. u8 eType, /* Pointer map 'type' entry for pDbPage */
  2986. Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */
  2987. Pgno iFreePage, /* The location to move pDbPage to */
  2988. int isCommit /* isCommit flag passed to sqlite3PagerMovepage */
  2989. )
  2990. {
  2991. MemPage pPtrPage = new MemPage(); /* The page that contains a pointer to pDbPage */
  2992. Pgno iDbPage = pDbPage.pgno;
  2993. Pager pPager = pBt.pPager;
  2994. int rc;
  2995. Debug.Assert( eType == PTRMAP_OVERFLOW2 || eType == PTRMAP_OVERFLOW1 ||
  2996. eType == PTRMAP_BTREE || eType == PTRMAP_ROOTPAGE );
  2997. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  2998. Debug.Assert( pDbPage.pBt == pBt );
  2999. /* Move page iDbPage from its current location to page number iFreePage */
  3000. TRACE( "AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
  3001. iDbPage, iFreePage, iPtrPage, eType );
  3002. rc = sqlite3PagerMovepage( pPager, pDbPage.pDbPage, iFreePage, isCommit );
  3003. if ( rc != SQLITE_OK )
  3004. {
  3005. return rc;
  3006. }
  3007. pDbPage.pgno = iFreePage;
  3008. /* If pDbPage was a btree-page, then it may have child pages and/or cells
  3009. ** that point to overflow pages. The pointer map entries for all these
  3010. ** pages need to be changed.
  3011. **
  3012. ** If pDbPage is an overflow page, then the first 4 bytes may store a
  3013. ** pointer to a subsequent overflow page. If this is the case, then
  3014. ** the pointer map needs to be updated for the subsequent overflow page.
  3015. */
  3016. if ( eType == PTRMAP_BTREE || eType == PTRMAP_ROOTPAGE )
  3017. {
  3018. rc = setChildPtrmaps( pDbPage );
  3019. if ( rc != SQLITE_OK )
  3020. {
  3021. return rc;
  3022. }
  3023. }
  3024. else
  3025. {
  3026. Pgno nextOvfl = sqlite3Get4byte( pDbPage.aData );
  3027. if ( nextOvfl != 0 )
  3028. {
  3029. ptrmapPut( pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage, ref rc );
  3030. if ( rc != SQLITE_OK )
  3031. {
  3032. return rc;
  3033. }
  3034. }
  3035. }
  3036. /* Fix the database pointer on page iPtrPage that pointed at iDbPage so
  3037. ** that it points at iFreePage. Also fix the pointer map entry for
  3038. ** iPtrPage.
  3039. */
  3040. if ( eType != PTRMAP_ROOTPAGE )
  3041. {
  3042. rc = btreeGetPage( pBt, iPtrPage, ref pPtrPage, 0 );
  3043. if ( rc != SQLITE_OK )
  3044. {
  3045. return rc;
  3046. }
  3047. rc = sqlite3PagerWrite( pPtrPage.pDbPage );
  3048. if ( rc != SQLITE_OK )
  3049. {
  3050. releasePage( pPtrPage );
  3051. return rc;
  3052. }
  3053. rc = modifyPagePointer( pPtrPage, iDbPage, iFreePage, eType );
  3054. releasePage( pPtrPage );
  3055. if ( rc == SQLITE_OK )
  3056. {
  3057. ptrmapPut( pBt, iFreePage, eType, iPtrPage, ref rc );
  3058. }
  3059. }
  3060. return rc;
  3061. }
  3062. /* Forward declaration required by incrVacuumStep(). */
  3063. //static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
  3064. /*
  3065. ** Perform a single step of an incremental-vacuum. If successful,
  3066. ** return SQLITE_OK. If there is no work to do (and therefore no
  3067. ** point in calling this function again), return SQLITE_DONE.
  3068. **
  3069. ** More specificly, this function attempts to re-organize the
  3070. ** database so that the last page of the file currently in use
  3071. ** is no longer in use.
  3072. **
  3073. ** If the nFin parameter is non-zero, this function assumes
  3074. ** that the caller will keep calling incrVacuumStep() until
  3075. ** it returns SQLITE_DONE or an error, and that nFin is the
  3076. ** number of pages the database file will contain after this
  3077. ** process is complete. If nFin is zero, it is assumed that
  3078. ** incrVacuumStep() will be called a finite amount of times
  3079. ** which may or may not empty the freelist. A full autovacuum
  3080. ** has nFin>0. A "PRAGMA incremental_vacuum" has nFin==null.
  3081. */
  3082. static int incrVacuumStep( BtShared pBt, Pgno nFin, Pgno iLastPg )
  3083. {
  3084. Pgno nFreeList; /* Number of pages still on the free-list */
  3085. int rc;
  3086. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  3087. Debug.Assert( iLastPg > nFin );
  3088. if ( !PTRMAP_ISPAGE( pBt, iLastPg ) && iLastPg != PENDING_BYTE_PAGE( pBt ) )
  3089. {
  3090. u8 eType = 0;
  3091. Pgno iPtrPage = 0;
  3092. nFreeList = sqlite3Get4byte( pBt.pPage1.aData, 36 );
  3093. if ( nFreeList == 0 )
  3094. {
  3095. return SQLITE_DONE;
  3096. }
  3097. rc = ptrmapGet( pBt, iLastPg, ref eType, ref iPtrPage );
  3098. if ( rc != SQLITE_OK )
  3099. {
  3100. return rc;
  3101. }
  3102. if ( eType == PTRMAP_ROOTPAGE )
  3103. {
  3104. return SQLITE_CORRUPT_BKPT();
  3105. }
  3106. if ( eType == PTRMAP_FREEPAGE )
  3107. {
  3108. if ( nFin == 0 )
  3109. {
  3110. /* Remove the page from the files free-list. This is not required
  3111. ** if nFin is non-zero. In that case, the free-list will be
  3112. ** truncated to zero after this function returns, so it doesn't
  3113. ** matter if it still contains some garbage entries.
  3114. */
  3115. Pgno iFreePg = 0;
  3116. MemPage pFreePg = new MemPage();
  3117. rc = allocateBtreePage( pBt, ref pFreePg, ref iFreePg, iLastPg, 1 );
  3118. if ( rc != SQLITE_OK )
  3119. {
  3120. return rc;
  3121. }
  3122. Debug.Assert( iFreePg == iLastPg );
  3123. releasePage( pFreePg );
  3124. }
  3125. }
  3126. else
  3127. {
  3128. Pgno iFreePg = 0; /* Index of free page to move pLastPg to */
  3129. MemPage pLastPg = new MemPage();
  3130. rc = btreeGetPage( pBt, iLastPg, ref pLastPg, 0 );
  3131. if ( rc != SQLITE_OK )
  3132. {
  3133. return rc;
  3134. }
  3135. /* If nFin is zero, this loop runs exactly once and page pLastPg
  3136. ** is swapped with the first free page pulled off the free list.
  3137. **
  3138. ** On the other hand, if nFin is greater than zero, then keep
  3139. ** looping until a free-page located within the first nFin pages
  3140. ** of the file is found.
  3141. */
  3142. do
  3143. {
  3144. MemPage pFreePg = new MemPage();
  3145. rc = allocateBtreePage( pBt, ref pFreePg, ref iFreePg, 0, 0 );
  3146. if ( rc != SQLITE_OK )
  3147. {
  3148. releasePage( pLastPg );
  3149. return rc;
  3150. }
  3151. releasePage( pFreePg );
  3152. } while ( nFin != 0 && iFreePg > nFin );
  3153. Debug.Assert( iFreePg < iLastPg );
  3154. rc = sqlite3PagerWrite( pLastPg.pDbPage );
  3155. if ( rc == SQLITE_OK )
  3156. {
  3157. rc = relocatePage( pBt, pLastPg, eType, iPtrPage, iFreePg, ( nFin != 0 ) ? 1 : 0 );
  3158. }
  3159. releasePage( pLastPg );
  3160. if ( rc != SQLITE_OK )
  3161. {
  3162. return rc;
  3163. }
  3164. }
  3165. }
  3166. if ( nFin == 0 )
  3167. {
  3168. iLastPg--;
  3169. while ( iLastPg == PENDING_BYTE_PAGE( pBt ) || PTRMAP_ISPAGE( pBt, iLastPg ) )
  3170. {
  3171. if ( PTRMAP_ISPAGE( pBt, iLastPg ) )
  3172. {
  3173. MemPage pPg = new MemPage();
  3174. rc = btreeGetPage( pBt, iLastPg, ref pPg, 0 );
  3175. if ( rc != SQLITE_OK )
  3176. {
  3177. return rc;
  3178. }
  3179. rc = sqlite3PagerWrite( pPg.pDbPage );
  3180. releasePage( pPg );
  3181. if ( rc != SQLITE_OK )
  3182. {
  3183. return rc;
  3184. }
  3185. }
  3186. iLastPg--;
  3187. }
  3188. sqlite3PagerTruncateImage( pBt.pPager, iLastPg );
  3189. pBt.nPage = iLastPg;
  3190. }
  3191. return SQLITE_OK;
  3192. }
  3193. /*
  3194. ** A write-transaction must be opened before calling this function.
  3195. ** It performs a single unit of work towards an incremental vacuum.
  3196. **
  3197. ** If the incremental vacuum is finished after this function has run,
  3198. ** SQLITE_DONE is returned. If it is not finished, but no error occurred,
  3199. ** SQLITE_OK is returned. Otherwise an SQLite error code.
  3200. */
  3201. static int sqlite3BtreeIncrVacuum( Btree p )
  3202. {
  3203. int rc;
  3204. BtShared pBt = p.pBt;
  3205. sqlite3BtreeEnter( p );
  3206. Debug.Assert( pBt.inTransaction == TRANS_WRITE && p.inTrans == TRANS_WRITE );
  3207. if ( !pBt.autoVacuum )
  3208. {
  3209. rc = SQLITE_DONE;
  3210. }
  3211. else
  3212. {
  3213. invalidateAllOverflowCache( pBt );
  3214. rc = incrVacuumStep( pBt, 0, btreePagecount( pBt ) );
  3215. if ( rc == SQLITE_OK )
  3216. {
  3217. rc = sqlite3PagerWrite( pBt.pPage1.pDbPage );
  3218. sqlite3Put4byte( pBt.pPage1.aData, (u32)28, pBt.nPage );//put4byte(&pBt->pPage1->aData[28], pBt->nPage);
  3219. }
  3220. }
  3221. sqlite3BtreeLeave( p );
  3222. return rc;
  3223. }
  3224. /*
  3225. ** This routine is called prior to sqlite3PagerCommit when a transaction
  3226. ** is commited for an auto-vacuum database.
  3227. **
  3228. ** If SQLITE_OK is returned, then pnTrunc is set to the number of pages
  3229. ** the database file should be truncated to during the commit process.
  3230. ** i.e. the database has been reorganized so that only the first pnTrunc
  3231. ** pages are in use.
  3232. */
  3233. static int autoVacuumCommit( BtShared pBt )
  3234. {
  3235. int rc = SQLITE_OK;
  3236. Pager pPager = pBt.pPager;
  3237. // VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager) );
  3238. #if !NDEBUG || DEBUG
  3239. int nRef = sqlite3PagerRefcount( pPager );
  3240. #else
  3241. int nRef=0;
  3242. #endif
  3243. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  3244. invalidateAllOverflowCache( pBt );
  3245. Debug.Assert( pBt.autoVacuum );
  3246. if ( !pBt.incrVacuum )
  3247. {
  3248. Pgno nFin; /* Number of pages in database after autovacuuming */
  3249. Pgno nFree; /* Number of pages on the freelist initially */
  3250. Pgno nPtrmap; /* Number of PtrMap pages to be freed */
  3251. Pgno iFree; /* The next page to be freed */
  3252. int nEntry; /* Number of entries on one ptrmap page */
  3253. Pgno nOrig; /* Database size before freeing */
  3254. nOrig = btreePagecount( pBt );
  3255. if ( PTRMAP_ISPAGE( pBt, nOrig ) || nOrig == PENDING_BYTE_PAGE( pBt ) )
  3256. {
  3257. /* It is not possible to create a database for which the final page
  3258. ** is either a pointer-map page or the pending-byte page. If one
  3259. ** is encountered, this indicates corruption.
  3260. */
  3261. return SQLITE_CORRUPT_BKPT();
  3262. }
  3263. nFree = sqlite3Get4byte( pBt.pPage1.aData, 36 );
  3264. nEntry = (int)pBt.usableSize / 5;
  3265. nPtrmap = (Pgno)( ( nFree - nOrig + PTRMAP_PAGENO( pBt, nOrig ) + (Pgno)nEntry ) / nEntry );
  3266. nFin = nOrig - nFree - nPtrmap;
  3267. if ( nOrig > PENDING_BYTE_PAGE( pBt ) && nFin < PENDING_BYTE_PAGE( pBt ) )
  3268. {
  3269. nFin--;
  3270. }
  3271. while ( PTRMAP_ISPAGE( pBt, nFin ) || nFin == PENDING_BYTE_PAGE( pBt ) )
  3272. {
  3273. nFin--;
  3274. }
  3275. if ( nFin > nOrig )
  3276. return SQLITE_CORRUPT_BKPT();
  3277. for ( iFree = nOrig; iFree > nFin && rc == SQLITE_OK; iFree-- )
  3278. {
  3279. rc = incrVacuumStep( pBt, nFin, iFree );
  3280. }
  3281. if ( ( rc == SQLITE_DONE || rc == SQLITE_OK ) && nFree > 0 )
  3282. {
  3283. rc = sqlite3PagerWrite( pBt.pPage1.pDbPage );
  3284. sqlite3Put4byte( pBt.pPage1.aData, 32, 0 );
  3285. sqlite3Put4byte( pBt.pPage1.aData, 36, 0 );
  3286. sqlite3Put4byte( pBt.pPage1.aData, (u32)28, nFin );
  3287. sqlite3PagerTruncateImage( pBt.pPager, nFin );
  3288. pBt.nPage = nFin;
  3289. }
  3290. if ( rc != SQLITE_OK )
  3291. {
  3292. sqlite3PagerRollback( pPager );
  3293. }
  3294. }
  3295. Debug.Assert( nRef == sqlite3PagerRefcount( pPager ) );
  3296. return rc;
  3297. }
  3298. #else //* ifndef SQLITE_OMIT_AUTOVACUUM */
  3299. //# define setChildPtrmaps(x) SQLITE_OK
  3300. #endif
  3301. /*
  3302. ** This routine does the first phase of a two-phase commit. This routine
  3303. ** causes a rollback journal to be created (if it does not already exist)
  3304. ** and populated with enough information so that if a power loss occurs
  3305. ** the database can be restored to its original state by playing back
  3306. ** the journal. Then the contents of the journal are flushed out to
  3307. ** the disk. After the journal is safely on oxide, the changes to the
  3308. ** database are written into the database file and flushed to oxide.
  3309. ** At the end of this call, the rollback journal still exists on the
  3310. ** disk and we are still holding all locks, so the transaction has not
  3311. ** committed. See sqlite3BtreeCommitPhaseTwo() for the second phase of the
  3312. ** commit process.
  3313. **
  3314. ** This call is a no-op if no write-transaction is currently active on pBt.
  3315. **
  3316. ** Otherwise, sync the database file for the btree pBt. zMaster points to
  3317. ** the name of a master journal file that should be written into the
  3318. ** individual journal file, or is NULL, indicating no master journal file
  3319. ** (single database transaction).
  3320. **
  3321. ** When this is called, the master journal should already have been
  3322. ** created, populated with this journal pointer and synced to disk.
  3323. **
  3324. ** Once this is routine has returned, the only thing required to commit
  3325. ** the write-transaction for this database file is to delete the journal.
  3326. */
  3327. static int sqlite3BtreeCommitPhaseOne( Btree p, string zMaster )
  3328. {
  3329. int rc = SQLITE_OK;
  3330. if ( p.inTrans == TRANS_WRITE )
  3331. {
  3332. BtShared pBt = p.pBt;
  3333. sqlite3BtreeEnter( p );
  3334. #if !SQLITE_OMIT_AUTOVACUUM
  3335. if ( pBt.autoVacuum )
  3336. {
  3337. rc = autoVacuumCommit( pBt );
  3338. if ( rc != SQLITE_OK )
  3339. {
  3340. sqlite3BtreeLeave( p );
  3341. return rc;
  3342. }
  3343. }
  3344. #endif
  3345. rc = sqlite3PagerCommitPhaseOne( pBt.pPager, zMaster, false );
  3346. sqlite3BtreeLeave( p );
  3347. }
  3348. return rc;
  3349. }
  3350. /*
  3351. ** This function is called from both BtreeCommitPhaseTwo() and BtreeRollback()
  3352. ** at the conclusion of a transaction.
  3353. */
  3354. static void btreeEndTransaction( Btree p )
  3355. {
  3356. BtShared pBt = p.pBt;
  3357. Debug.Assert( sqlite3BtreeHoldsMutex( p ) );
  3358. btreeClearHasContent( pBt );
  3359. if ( p.inTrans > TRANS_NONE && p.db.activeVdbeCnt > 1 )
  3360. {
  3361. /* If there are other active statements that belong to this database
  3362. ** handle, downgrade to a read-only transaction. The other statements
  3363. ** may still be reading from the database. */
  3364. downgradeAllSharedCacheTableLocks( p );
  3365. p.inTrans = TRANS_READ;
  3366. }
  3367. else
  3368. {
  3369. /* If the handle had any kind of transaction open, decrement the
  3370. ** transaction count of the shared btree. If the transaction count
  3371. ** reaches 0, set the shared state to TRANS_NONE. The unlockBtreeIfUnused()
  3372. ** call below will unlock the pager. */
  3373. if ( p.inTrans != TRANS_NONE )
  3374. {
  3375. clearAllSharedCacheTableLocks( p );
  3376. pBt.nTransaction--;
  3377. if ( 0 == pBt.nTransaction )
  3378. {
  3379. pBt.inTransaction = TRANS_NONE;
  3380. }
  3381. }
  3382. /* Set the current transaction state to TRANS_NONE and unlock the
  3383. ** pager if this call closed the only read or write transaction. */
  3384. p.inTrans = TRANS_NONE;
  3385. unlockBtreeIfUnused( pBt );
  3386. }
  3387. btreeIntegrity( p );
  3388. }
  3389. /*
  3390. ** Commit the transaction currently in progress.
  3391. **
  3392. ** This routine implements the second phase of a 2-phase commit. The
  3393. ** sqlite3BtreeCommitPhaseOne() routine does the first phase and should
  3394. ** be invoked prior to calling this routine. The sqlite3BtreeCommitPhaseOne()
  3395. ** routine did all the work of writing information out to disk and flushing the
  3396. ** contents so that they are written onto the disk platter. All this
  3397. ** routine has to do is delete or truncate or zero the header in the
  3398. ** the rollback journal (which causes the transaction to commit) and
  3399. ** drop locks.
  3400. **
  3401. ** Normally, if an error occurs while the pager layer is attempting to
  3402. ** finalize the underlying journal file, this function returns an error and
  3403. ** the upper layer will attempt a rollback. However, if the second argument
  3404. ** is non-zero then this b-tree transaction is part of a multi-file
  3405. ** transaction. In this case, the transaction has already been committed
  3406. ** (by deleting a master journal file) and the caller will ignore this
  3407. ** functions return code. So, even if an error occurs in the pager layer,
  3408. ** reset the b-tree objects internal state to indicate that the write
  3409. ** transaction has been closed. This is quite safe, as the pager will have
  3410. ** transitioned to the error state.
  3411. **
  3412. ** This will release the write lock on the database file. If there
  3413. ** are no active cursors, it also releases the read lock.
  3414. */
  3415. static int sqlite3BtreeCommitPhaseTwo( Btree p, int bCleanup)
  3416. {
  3417. if ( p.inTrans == TRANS_NONE )
  3418. return SQLITE_OK;
  3419. sqlite3BtreeEnter( p );
  3420. btreeIntegrity( p );
  3421. /* If the handle has a write-transaction open, commit the shared-btrees
  3422. ** transaction and set the shared state to TRANS_READ.
  3423. */
  3424. if ( p.inTrans == TRANS_WRITE )
  3425. {
  3426. int rc;
  3427. BtShared pBt = p.pBt;
  3428. Debug.Assert( pBt.inTransaction == TRANS_WRITE );
  3429. Debug.Assert( pBt.nTransaction > 0 );
  3430. rc = sqlite3PagerCommitPhaseTwo( pBt.pPager );
  3431. if ( rc != SQLITE_OK && bCleanup == 0 )
  3432. {
  3433. sqlite3BtreeLeave( p );
  3434. return rc;
  3435. }
  3436. pBt.inTransaction = TRANS_READ;
  3437. }
  3438. btreeEndTransaction( p );
  3439. sqlite3BtreeLeave( p );
  3440. return SQLITE_OK;
  3441. }
  3442. /*
  3443. ** Do both phases of a commit.
  3444. */
  3445. static int sqlite3BtreeCommit( Btree p )
  3446. {
  3447. int rc;
  3448. sqlite3BtreeEnter( p );
  3449. rc = sqlite3BtreeCommitPhaseOne( p, null );
  3450. if ( rc == SQLITE_OK )
  3451. {
  3452. rc = sqlite3BtreeCommitPhaseTwo( p, 0 );
  3453. }
  3454. sqlite3BtreeLeave( p );
  3455. return rc;
  3456. }
  3457. #if !NDEBUG || DEBUG
  3458. /*
  3459. ** Return the number of write-cursors open on this handle. This is for use
  3460. ** in Debug.Assert() expressions, so it is only compiled if NDEBUG is not
  3461. ** defined.
  3462. **
  3463. ** For the purposes of this routine, a write-cursor is any cursor that
  3464. ** is capable of writing to the databse. That means the cursor was
  3465. ** originally opened for writing and the cursor has not be disabled
  3466. ** by having its state changed to CURSOR_FAULT.
  3467. */
  3468. static int countWriteCursors( BtShared pBt )
  3469. {
  3470. BtCursor pCur;
  3471. int r = 0;
  3472. for ( pCur = pBt.pCursor; pCur != null; pCur = pCur.pNext )
  3473. {
  3474. if ( pCur.wrFlag != 0 && pCur.eState != CURSOR_FAULT )
  3475. r++;
  3476. }
  3477. return r;
  3478. }
  3479. #else
  3480. static int countWriteCursors(BtShared pBt) { return -1; }
  3481. #endif
  3482. /*
  3483. ** This routine sets the state to CURSOR_FAULT and the error
  3484. ** code to errCode for every cursor on BtShared that pBtree
  3485. ** references.
  3486. **
  3487. ** Every cursor is tripped, including cursors that belong
  3488. ** to other database connections that happen to be sharing
  3489. ** the cache with pBtree.
  3490. **
  3491. ** This routine gets called when a rollback occurs.
  3492. ** All cursors using the same cache must be tripped
  3493. ** to prevent them from trying to use the btree after
  3494. ** the rollback. The rollback may have deleted tables
  3495. ** or moved root pages, so it is not sufficient to
  3496. ** save the state of the cursor. The cursor must be
  3497. ** invalidated.
  3498. */
  3499. static void sqlite3BtreeTripAllCursors( Btree pBtree, int errCode )
  3500. {
  3501. BtCursor p;
  3502. sqlite3BtreeEnter( pBtree );
  3503. for ( p = pBtree.pBt.pCursor; p != null; p = p.pNext )
  3504. {
  3505. int i;
  3506. sqlite3BtreeClearCursor( p );
  3507. p.eState = CURSOR_FAULT;
  3508. p.skipNext = errCode;
  3509. for ( i = 0; i <= p.iPage; i++ )
  3510. {
  3511. releasePage( p.apPage[i] );
  3512. p.apPage[i] = null;
  3513. }
  3514. }
  3515. sqlite3BtreeLeave( pBtree );
  3516. }
  3517. /*
  3518. ** Rollback the transaction in progress. All cursors will be
  3519. ** invalided by this operation. Any attempt to use a cursor
  3520. ** that was open at the beginning of this operation will result
  3521. ** in an error.
  3522. **
  3523. ** This will release the write lock on the database file. If there
  3524. ** are no active cursors, it also releases the read lock.
  3525. */
  3526. static int sqlite3BtreeRollback( Btree p )
  3527. {
  3528. int rc;
  3529. BtShared pBt = p.pBt;
  3530. MemPage pPage1 = new MemPage();
  3531. sqlite3BtreeEnter( p );
  3532. rc = saveAllCursors( pBt, 0, null );
  3533. #if !SQLITE_OMIT_SHARED_CACHE
  3534. if( rc!=SQLITE_OK ){
  3535. /* This is a horrible situation. An IO or malloc() error occurred whilst
  3536. ** trying to save cursor positions. If this is an automatic rollback (as
  3537. ** the result of a constraint, malloc() failure or IO error) then
  3538. ** the cache may be internally inconsistent (not contain valid trees) so
  3539. ** we cannot simply return the error to the caller. Instead, abort
  3540. ** all queries that may be using any of the cursors that failed to save.
  3541. */
  3542. sqlite3BtreeTripAllCursors(p, rc);
  3543. }
  3544. #endif
  3545. btreeIntegrity( p );
  3546. if ( p.inTrans == TRANS_WRITE )
  3547. {
  3548. int rc2;
  3549. Debug.Assert( TRANS_WRITE == pBt.inTransaction );
  3550. rc2 = sqlite3PagerRollback( pBt.pPager );
  3551. if ( rc2 != SQLITE_OK )
  3552. {
  3553. rc = rc2;
  3554. }
  3555. /* The rollback may have destroyed the pPage1.aData value. So
  3556. ** call btreeGetPage() on page 1 again to make
  3557. ** sure pPage1.aData is set correctly. */
  3558. if ( btreeGetPage( pBt, 1, ref pPage1, 0 ) == SQLITE_OK )
  3559. {
  3560. Pgno nPage = sqlite3Get4byte( pPage1.aData, 28 );
  3561. testcase( nPage == 0 );
  3562. if ( nPage == 0 )
  3563. sqlite3PagerPagecount( pBt.pPager, out nPage );
  3564. testcase( pBt.nPage != nPage );
  3565. pBt.nPage = nPage;
  3566. releasePage( pPage1 );
  3567. }
  3568. Debug.Assert( countWriteCursors( pBt ) == 0 );
  3569. pBt.inTransaction = TRANS_READ;
  3570. }
  3571. btreeEndTransaction( p );
  3572. sqlite3BtreeLeave( p );
  3573. return rc;
  3574. }
  3575. /*
  3576. ** Start a statement subtransaction. The subtransaction can can be rolled
  3577. ** back independently of the main transaction. You must start a transaction
  3578. ** before starting a subtransaction. The subtransaction is ended automatically
  3579. ** if the main transaction commits or rolls back.
  3580. **
  3581. ** Statement subtransactions are used around individual SQL statements
  3582. ** that are contained within a BEGIN...COMMIT block. If a constraint
  3583. ** error occurs within the statement, the effect of that one statement
  3584. ** can be rolled back without having to rollback the entire transaction.
  3585. **
  3586. ** A statement sub-transaction is implemented as an anonymous savepoint. The
  3587. ** value passed as the second parameter is the total number of savepoints,
  3588. ** including the new anonymous savepoint, open on the B-Tree. i.e. if there
  3589. ** are no active savepoints and no other statement-transactions open,
  3590. ** iStatement is 1. This anonymous savepoint can be released or rolled back
  3591. ** using the sqlite3BtreeSavepoint() function.
  3592. */
  3593. static int sqlite3BtreeBeginStmt( Btree p, int iStatement )
  3594. {
  3595. int rc;
  3596. BtShared pBt = p.pBt;
  3597. sqlite3BtreeEnter( p );
  3598. Debug.Assert( p.inTrans == TRANS_WRITE );
  3599. Debug.Assert( !pBt.readOnly );
  3600. Debug.Assert( iStatement > 0 );
  3601. Debug.Assert( iStatement > p.db.nSavepoint );
  3602. Debug.Assert( pBt.inTransaction == TRANS_WRITE );
  3603. /* At the pager level, a statement transaction is a savepoint with
  3604. ** an index greater than all savepoints created explicitly using
  3605. ** SQL statements. It is illegal to open, release or rollback any
  3606. ** such savepoints while the statement transaction savepoint is active.
  3607. */
  3608. rc = sqlite3PagerOpenSavepoint( pBt.pPager, iStatement );
  3609. sqlite3BtreeLeave( p );
  3610. return rc;
  3611. }
  3612. /*
  3613. ** The second argument to this function, op, is always SAVEPOINT_ROLLBACK
  3614. ** or SAVEPOINT_RELEASE. This function either releases or rolls back the
  3615. ** savepoint identified by parameter iSavepoint, depending on the value
  3616. ** of op.
  3617. **
  3618. ** Normally, iSavepoint is greater than or equal to zero. However, if op is
  3619. ** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the
  3620. ** contents of the entire transaction are rolled back. This is different
  3621. ** from a normal transaction rollback, as no locks are released and the
  3622. ** transaction remains open.
  3623. */
  3624. static int sqlite3BtreeSavepoint( Btree p, int op, int iSavepoint )
  3625. {
  3626. int rc = SQLITE_OK;
  3627. if ( p != null && p.inTrans == TRANS_WRITE )
  3628. {
  3629. BtShared pBt = p.pBt;
  3630. Debug.Assert( op == SAVEPOINT_RELEASE || op == SAVEPOINT_ROLLBACK );
  3631. Debug.Assert( iSavepoint >= 0 || ( iSavepoint == -1 && op == SAVEPOINT_ROLLBACK ) );
  3632. sqlite3BtreeEnter( p );
  3633. rc = sqlite3PagerSavepoint( pBt.pPager, op, iSavepoint );
  3634. if ( rc == SQLITE_OK )
  3635. {
  3636. if ( iSavepoint < 0 && pBt.initiallyEmpty )
  3637. pBt.nPage = 0;
  3638. rc = newDatabase( pBt );
  3639. pBt.nPage = sqlite3Get4byte( pBt.pPage1.aData, 28 );
  3640. /* The database size was written into the offset 28 of the header
  3641. ** when the transaction started, so we know that the value at offset
  3642. ** 28 is nonzero. */
  3643. Debug.Assert( pBt.nPage > 0 );
  3644. }
  3645. sqlite3BtreeLeave( p );
  3646. }
  3647. return rc;
  3648. }
  3649. /*
  3650. ** Create a new cursor for the BTree whose root is on the page
  3651. ** iTable. If a read-only cursor is requested, it is assumed that
  3652. ** the caller already has at least a read-only transaction open
  3653. ** on the database already. If a write-cursor is requested, then
  3654. ** the caller is assumed to have an open write transaction.
  3655. **
  3656. ** If wrFlag==null, then the cursor can only be used for reading.
  3657. ** If wrFlag==1, then the cursor can be used for reading or for
  3658. ** writing if other conditions for writing are also met. These
  3659. ** are the conditions that must be met in order for writing to
  3660. ** be allowed:
  3661. **
  3662. ** 1: The cursor must have been opened with wrFlag==1
  3663. **
  3664. ** 2: Other database connections that share the same pager cache
  3665. ** but which are not in the READ_UNCOMMITTED state may not have
  3666. ** cursors open with wrFlag==null on the same table. Otherwise
  3667. ** the changes made by this write cursor would be visible to
  3668. ** the read cursors in the other database connection.
  3669. **
  3670. ** 3: The database must be writable (not on read-only media)
  3671. **
  3672. ** 4: There must be an active transaction.
  3673. **
  3674. ** No checking is done to make sure that page iTable really is the
  3675. ** root page of a b-tree. If it is not, then the cursor acquired
  3676. ** will not work correctly.
  3677. **
  3678. ** It is assumed that the sqlite3BtreeCursorZero() has been called
  3679. ** on pCur to initialize the memory space prior to invoking this routine.
  3680. */
  3681. static int btreeCursor(
  3682. Btree p, /* The btree */
  3683. int iTable, /* Root page of table to open */
  3684. int wrFlag, /* 1 to write. 0 read-only */
  3685. KeyInfo pKeyInfo, /* First arg to comparison function */
  3686. BtCursor pCur /* Space for new cursor */
  3687. )
  3688. {
  3689. BtShared pBt = p.pBt; /* Shared b-tree handle */
  3690. Debug.Assert( sqlite3BtreeHoldsMutex( p ) );
  3691. Debug.Assert( wrFlag == 0 || wrFlag == 1 );
  3692. /* The following Debug.Assert statements verify that if this is a sharable
  3693. ** b-tree database, the connection is holding the required table locks,
  3694. ** and that no other connection has any open cursor that conflicts with
  3695. ** this lock. */
  3696. Debug.Assert( hasSharedCacheTableLock( p, (u32)iTable, pKeyInfo != null ? 1 : 0, wrFlag + 1 ) );
  3697. Debug.Assert( wrFlag == 0 || !hasReadConflicts( p, (u32)iTable ) );
  3698. /* Assert that the caller has opened the required transaction. */
  3699. Debug.Assert( p.inTrans > TRANS_NONE );
  3700. Debug.Assert( wrFlag == 0 || p.inTrans == TRANS_WRITE );
  3701. Debug.Assert( pBt.pPage1 != null && pBt.pPage1.aData != null );
  3702. if ( NEVER( wrFlag != 0 && pBt.readOnly ) )
  3703. {
  3704. return SQLITE_READONLY;
  3705. }
  3706. if ( iTable == 1 && btreePagecount( pBt ) == 0 )
  3707. {
  3708. return SQLITE_EMPTY;
  3709. }
  3710. /* Now that no other errors can occur, finish filling in the BtCursor
  3711. ** variables and link the cursor into the BtShared list. */
  3712. pCur.pgnoRoot = (Pgno)iTable;
  3713. pCur.iPage = -1;
  3714. pCur.pKeyInfo = pKeyInfo;
  3715. pCur.pBtree = p;
  3716. pCur.pBt = pBt;
  3717. pCur.wrFlag = (u8)wrFlag;
  3718. pCur.pNext = pBt.pCursor;
  3719. if ( pCur.pNext != null )
  3720. {
  3721. pCur.pNext.pPrev = pCur;
  3722. }
  3723. pBt.pCursor = pCur;
  3724. pCur.eState = CURSOR_INVALID;
  3725. pCur.cachedRowid = 0;
  3726. return SQLITE_OK;
  3727. }
  3728. static int sqlite3BtreeCursor(
  3729. Btree p, /* The btree */
  3730. int iTable, /* Root page of table to open */
  3731. int wrFlag, /* 1 to write. 0 read-only */
  3732. KeyInfo pKeyInfo, /* First arg to xCompare() */
  3733. BtCursor pCur /* Write new cursor here */
  3734. )
  3735. {
  3736. int rc;
  3737. sqlite3BtreeEnter( p );
  3738. rc = btreeCursor( p, iTable, wrFlag, pKeyInfo, pCur );
  3739. sqlite3BtreeLeave( p );
  3740. return rc;
  3741. }
  3742. /*
  3743. ** Return the size of a BtCursor object in bytes.
  3744. **
  3745. ** This interfaces is needed so that users of cursors can preallocate
  3746. ** sufficient storage to hold a cursor. The BtCursor object is opaque
  3747. ** to users so they cannot do the sizeof() themselves - they must call
  3748. ** this routine.
  3749. */
  3750. static int sqlite3BtreeCursorSize()
  3751. {
  3752. return -1; // Not Used -- return ROUND8(sizeof(BtCursor));
  3753. }
  3754. /*
  3755. ** Initialize memory that will be converted into a BtCursor object.
  3756. **
  3757. ** The simple approach here would be to memset() the entire object
  3758. ** to zero. But it turns out that the apPage[] and aiIdx[] arrays
  3759. ** do not need to be zeroed and they are large, so we can save a lot
  3760. ** of run-time by skipping the initialization of those elements.
  3761. */
  3762. static void sqlite3BtreeCursorZero( BtCursor p )
  3763. {
  3764. p.Clear(); // memset( p, 0, offsetof( BtCursor, iPage ) );
  3765. }
  3766. /*
  3767. ** Set the cached rowid value of every cursor in the same database file
  3768. ** as pCur and having the same root page number as pCur. The value is
  3769. ** set to iRowid.
  3770. **
  3771. ** Only positive rowid values are considered valid for this cache.
  3772. ** The cache is initialized to zero, indicating an invalid cache.
  3773. ** A btree will work fine with zero or negative rowids. We just cannot
  3774. ** cache zero or negative rowids, which means tables that use zero or
  3775. ** negative rowids might run a little slower. But in practice, zero
  3776. ** or negative rowids are very uncommon so this should not be a problem.
  3777. */
  3778. static void sqlite3BtreeSetCachedRowid( BtCursor pCur, sqlite3_int64 iRowid )
  3779. {
  3780. BtCursor p;
  3781. for ( p = pCur.pBt.pCursor; p != null; p = p.pNext )
  3782. {
  3783. if ( p.pgnoRoot == pCur.pgnoRoot )
  3784. p.cachedRowid = iRowid;
  3785. }
  3786. Debug.Assert( pCur.cachedRowid == iRowid );
  3787. }
  3788. /*
  3789. ** Return the cached rowid for the given cursor. A negative or zero
  3790. ** return value indicates that the rowid cache is invalid and should be
  3791. ** ignored. If the rowid cache has never before been set, then a
  3792. ** zero is returned.
  3793. */
  3794. static sqlite3_int64 sqlite3BtreeGetCachedRowid( BtCursor pCur )
  3795. {
  3796. return pCur.cachedRowid;
  3797. }
  3798. /*
  3799. ** Close a cursor. The read lock on the database file is released
  3800. ** when the last cursor is closed.
  3801. */
  3802. static int sqlite3BtreeCloseCursor( BtCursor pCur )
  3803. {
  3804. Btree pBtree = pCur.pBtree;
  3805. if ( pBtree != null )
  3806. {
  3807. int i;
  3808. BtShared pBt = pCur.pBt;
  3809. sqlite3BtreeEnter( pBtree );
  3810. sqlite3BtreeClearCursor( pCur );
  3811. if ( pCur.pPrev != null )
  3812. {
  3813. pCur.pPrev.pNext = pCur.pNext;
  3814. }
  3815. else
  3816. {
  3817. pBt.pCursor = pCur.pNext;
  3818. }
  3819. if ( pCur.pNext != null )
  3820. {
  3821. pCur.pNext.pPrev = pCur.pPrev;
  3822. }
  3823. for ( i = 0; i <= pCur.iPage; i++ )
  3824. {
  3825. releasePage( pCur.apPage[i] );
  3826. }
  3827. unlockBtreeIfUnused( pBt );
  3828. invalidateOverflowCache( pCur );
  3829. /* sqlite3_free(ref pCur); */
  3830. sqlite3BtreeLeave( pBtree );
  3831. }
  3832. return SQLITE_OK;
  3833. }
  3834. /*
  3835. ** Make sure the BtCursor* given in the argument has a valid
  3836. ** BtCursor.info structure. If it is not already valid, call
  3837. ** btreeParseCell() to fill it in.
  3838. **
  3839. ** BtCursor.info is a cache of the information in the current cell.
  3840. ** Using this cache reduces the number of calls to btreeParseCell().
  3841. **
  3842. ** 2007-06-25: There is a bug in some versions of MSVC that cause the
  3843. ** compiler to crash when getCellInfo() is implemented as a macro.
  3844. ** But there is a measureable speed advantage to using the macro on gcc
  3845. ** (when less compiler optimizations like -Os or -O0 are used and the
  3846. ** compiler is not doing agressive inlining.) So we use a real function
  3847. ** for MSVC and a macro for everything else. Ticket #2457.
  3848. */
  3849. #if !NDEBUG
  3850. static void assertCellInfo( BtCursor pCur )
  3851. {
  3852. CellInfo info;
  3853. int iPage = pCur.iPage;
  3854. info = new CellInfo();//memset(info, 0, sizeof(info));
  3855. btreeParseCell( pCur.apPage[iPage], pCur.aiIdx[iPage], ref info );
  3856. Debug.Assert( info.GetHashCode() == pCur.info.GetHashCode() || info.Equals( pCur.info ) );//memcmp(info, pCur.info, sizeof(info))==0 );
  3857. }
  3858. #else
  3859. // #define assertCellInfo(x)
  3860. static void assertCellInfo(BtCursor pCur) { }
  3861. #endif
  3862. #if _MSC_VER
  3863. /* Use a real function in MSVC to work around bugs in that compiler. */
  3864. static void getCellInfo( BtCursor pCur )
  3865. {
  3866. if ( pCur.info.nSize == 0 )
  3867. {
  3868. int iPage = pCur.iPage;
  3869. btreeParseCell( pCur.apPage[iPage], pCur.aiIdx[iPage], ref pCur.info );
  3870. pCur.validNKey = true;
  3871. }
  3872. else
  3873. {
  3874. assertCellInfo( pCur );
  3875. }
  3876. }
  3877. #else //* if not _MSC_VER */
  3878. /* Use a macro in all other compilers so that the function is inlined */
  3879. //#define getCellInfo(pCur) \
  3880. // if( pCur.info.nSize==null ){ \
  3881. // int iPage = pCur.iPage; \
  3882. // btreeParseCell(pCur.apPage[iPage],pCur.aiIdx[iPage],&pCur.info); \
  3883. // pCur.validNKey = true; \
  3884. // }else{ \
  3885. // assertCellInfo(pCur); \
  3886. // }
  3887. #endif //* _MSC_VER */
  3888. #if !NDEBUG //* The next routine used only within Debug.Assert() statements */
  3889. /*
  3890. ** Return true if the given BtCursor is valid. A valid cursor is one
  3891. ** that is currently pointing to a row in a (non-empty) table.
  3892. ** This is a verification routine is used only within Debug.Assert() statements.
  3893. */
  3894. static bool sqlite3BtreeCursorIsValid( BtCursor pCur )
  3895. {
  3896. return pCur != null && pCur.eState == CURSOR_VALID;
  3897. }
  3898. #else
  3899. static bool sqlite3BtreeCursorIsValid(BtCursor pCur) { return true; }
  3900. #endif //* NDEBUG */
  3901. /*
  3902. ** Set pSize to the size of the buffer needed to hold the value of
  3903. ** the key for the current entry. If the cursor is not pointing
  3904. ** to a valid entry, pSize is set to 0.
  3905. **
  3906. ** For a table with the INTKEY flag set, this routine returns the key
  3907. ** itself, not the number of bytes in the key.
  3908. **
  3909. ** The caller must position the cursor prior to invoking this routine.
  3910. **
  3911. ** This routine cannot fail. It always returns SQLITE_OK.
  3912. */
  3913. static int sqlite3BtreeKeySize( BtCursor pCur, ref i64 pSize )
  3914. {
  3915. Debug.Assert( cursorHoldsMutex( pCur ) );
  3916. Debug.Assert( pCur.eState == CURSOR_INVALID || pCur.eState == CURSOR_VALID );
  3917. if ( pCur.eState != CURSOR_VALID )
  3918. {
  3919. pSize = 0;
  3920. }
  3921. else
  3922. {
  3923. getCellInfo( pCur );
  3924. pSize = pCur.info.nKey;
  3925. }
  3926. return SQLITE_OK;
  3927. }
  3928. /*
  3929. ** Set pSize to the number of bytes of data in the entry the
  3930. ** cursor currently points to.
  3931. **
  3932. ** The caller must guarantee that the cursor is pointing to a non-NULL
  3933. ** valid entry. In other words, the calling procedure must guarantee
  3934. ** that the cursor has Cursor.eState==CURSOR_VALID.
  3935. **
  3936. ** Failure is not possible. This function always returns SQLITE_OK.
  3937. ** It might just as well be a procedure (returning void) but we continue
  3938. ** to return an integer result code for historical reasons.
  3939. */
  3940. static int sqlite3BtreeDataSize( BtCursor pCur, ref u32 pSize )
  3941. {
  3942. Debug.Assert( cursorHoldsMutex( pCur ) );
  3943. Debug.Assert( pCur.eState == CURSOR_VALID );
  3944. getCellInfo( pCur );
  3945. pSize = pCur.info.nData;
  3946. return SQLITE_OK;
  3947. }
  3948. /*
  3949. ** Given the page number of an overflow page in the database (parameter
  3950. ** ovfl), this function finds the page number of the next page in the
  3951. ** linked list of overflow pages. If possible, it uses the auto-vacuum
  3952. ** pointer-map data instead of reading the content of page ovfl to do so.
  3953. **
  3954. ** If an error occurs an SQLite error code is returned. Otherwise:
  3955. **
  3956. ** The page number of the next overflow page in the linked list is
  3957. ** written to pPgnoNext. If page ovfl is the last page in its linked
  3958. ** list, pPgnoNext is set to zero.
  3959. **
  3960. ** If ppPage is not NULL, and a reference to the MemPage object corresponding
  3961. ** to page number pOvfl was obtained, then ppPage is set to point to that
  3962. ** reference. It is the responsibility of the caller to call releasePage()
  3963. ** on ppPage to free the reference. In no reference was obtained (because
  3964. ** the pointer-map was used to obtain the value for pPgnoNext), then
  3965. ** ppPage is set to zero.
  3966. */
  3967. static int getOverflowPage(
  3968. BtShared pBt, /* The database file */
  3969. Pgno ovfl, /* Current overflow page number */
  3970. out MemPage ppPage, /* OUT: MemPage handle (may be NULL) */
  3971. out Pgno pPgnoNext /* OUT: Next overflow page number */
  3972. )
  3973. {
  3974. Pgno next = 0;
  3975. MemPage pPage = null;
  3976. ppPage = null;
  3977. int rc = SQLITE_OK;
  3978. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  3979. // Debug.Assert( pPgnoNext);
  3980. #if !SQLITE_OMIT_AUTOVACUUM
  3981. /* Try to find the next page in the overflow list using the
  3982. ** autovacuum pointer-map pages. Guess that the next page in
  3983. ** the overflow list is page number (ovfl+1). If that guess turns
  3984. ** out to be wrong, fall back to loading the data of page
  3985. ** number ovfl to determine the next page number.
  3986. */
  3987. if ( pBt.autoVacuum )
  3988. {
  3989. Pgno pgno = 0;
  3990. Pgno iGuess = ovfl + 1;
  3991. u8 eType = 0;
  3992. while ( PTRMAP_ISPAGE( pBt, iGuess ) || iGuess == PENDING_BYTE_PAGE( pBt ) )
  3993. {
  3994. iGuess++;
  3995. }
  3996. if ( iGuess <= btreePagecount( pBt ) )
  3997. {
  3998. rc = ptrmapGet( pBt, iGuess, ref eType, ref pgno );
  3999. if ( rc == SQLITE_OK && eType == PTRMAP_OVERFLOW2 && pgno == ovfl )
  4000. {
  4001. next = iGuess;
  4002. rc = SQLITE_DONE;
  4003. }
  4004. }
  4005. }
  4006. #endif
  4007. Debug.Assert( next == 0 || rc == SQLITE_DONE );
  4008. if ( rc == SQLITE_OK )
  4009. {
  4010. rc = btreeGetPage( pBt, ovfl, ref pPage, 0 );
  4011. Debug.Assert( rc == SQLITE_OK || pPage == null );
  4012. if ( rc == SQLITE_OK )
  4013. {
  4014. next = sqlite3Get4byte( pPage.aData );
  4015. }
  4016. }
  4017. pPgnoNext = next;
  4018. if ( ppPage != null )
  4019. {
  4020. ppPage = pPage;
  4021. }
  4022. else
  4023. {
  4024. releasePage( pPage );
  4025. }
  4026. return ( rc == SQLITE_DONE ? SQLITE_OK : rc );
  4027. }
  4028. /*
  4029. ** Copy data from a buffer to a page, or from a page to a buffer.
  4030. **
  4031. ** pPayload is a pointer to data stored on database page pDbPage.
  4032. ** If argument eOp is false, then nByte bytes of data are copied
  4033. ** from pPayload to the buffer pointed at by pBuf. If eOp is true,
  4034. ** then sqlite3PagerWrite() is called on pDbPage and nByte bytes
  4035. ** of data are copied from the buffer pBuf to pPayload.
  4036. **
  4037. ** SQLITE_OK is returned on success, otherwise an error code.
  4038. */
  4039. static int copyPayload(
  4040. byte[] pPayload, /* Pointer to page data */
  4041. u32 payloadOffset, /* Offset into page data */
  4042. byte[] pBuf, /* Pointer to buffer */
  4043. u32 pBufOffset, /* Offset into buffer */
  4044. u32 nByte, /* Number of bytes to copy */
  4045. int eOp, /* 0 . copy from page, 1 . copy to page */
  4046. DbPage pDbPage /* Page containing pPayload */
  4047. )
  4048. {
  4049. if ( eOp != 0 )
  4050. {
  4051. /* Copy data from buffer to page (a write operation) */
  4052. int rc = sqlite3PagerWrite( pDbPage );
  4053. if ( rc != SQLITE_OK )
  4054. {
  4055. return rc;
  4056. }
  4057. Buffer.BlockCopy( pBuf, (int)pBufOffset, pPayload, (int)payloadOffset, (int)nByte );// memcpy( pPayload, pBuf, nByte );
  4058. }
  4059. else
  4060. {
  4061. /* Copy data from page to buffer (a read operation) */
  4062. Buffer.BlockCopy( pPayload, (int)payloadOffset, pBuf, (int)pBufOffset, (int)nByte );//memcpy(pBuf, pPayload, nByte);
  4063. }
  4064. return SQLITE_OK;
  4065. }
  4066. //static int copyPayload(
  4067. // byte[] pPayload, /* Pointer to page data */
  4068. // byte[] pBuf, /* Pointer to buffer */
  4069. // int nByte, /* Number of bytes to copy */
  4070. // int eOp, /* 0 -> copy from page, 1 -> copy to page */
  4071. // DbPage pDbPage /* Page containing pPayload */
  4072. //){
  4073. // if( eOp!=0 ){
  4074. // /* Copy data from buffer to page (a write operation) */
  4075. // int rc = sqlite3PagerWrite(pDbPage);
  4076. // if( rc!=SQLITE_OK ){
  4077. // return rc;
  4078. // }
  4079. // memcpy(pPayload, pBuf, nByte);
  4080. // }else{
  4081. // /* Copy data from page to buffer (a read operation) */
  4082. // memcpy(pBuf, pPayload, nByte);
  4083. // }
  4084. // return SQLITE_OK;
  4085. //}
  4086. /*
  4087. ** This function is used to read or overwrite payload information
  4088. ** for the entry that the pCur cursor is pointing to. If the eOp
  4089. ** parameter is 0, this is a read operation (data copied into
  4090. ** buffer pBuf). If it is non-zero, a write (data copied from
  4091. ** buffer pBuf).
  4092. **
  4093. ** A total of "amt" bytes are read or written beginning at "offset".
  4094. ** Data is read to or from the buffer pBuf.
  4095. **
  4096. ** The content being read or written might appear on the main page
  4097. ** or be scattered out on multiple overflow pages.
  4098. **
  4099. ** If the BtCursor.isIncrblobHandle flag is set, and the current
  4100. ** cursor entry uses one or more overflow pages, this function
  4101. ** allocates space for and lazily popluates the overflow page-list
  4102. ** cache array (BtCursor.aOverflow). Subsequent calls use this
  4103. ** cache to make seeking to the supplied offset more efficient.
  4104. **
  4105. ** Once an overflow page-list cache has been allocated, it may be
  4106. ** invalidated if some other cursor writes to the same table, or if
  4107. ** the cursor is moved to a different row. Additionally, in auto-vacuum
  4108. ** mode, the following events may invalidate an overflow page-list cache.
  4109. **
  4110. ** * An incremental vacuum,
  4111. ** * A commit in auto_vacuum="full" mode,
  4112. ** * Creating a table (may require moving an overflow page).
  4113. */
  4114. static int accessPayload(
  4115. BtCursor pCur, /* Cursor pointing to entry to read from */
  4116. u32 offset, /* Begin reading this far into payload */
  4117. u32 amt, /* Read this many bytes */
  4118. byte[] pBuf, /* Write the bytes into this buffer */
  4119. int eOp /* zero to read. non-zero to write. */
  4120. )
  4121. {
  4122. u32 pBufOffset = 0;
  4123. byte[] aPayload;
  4124. int rc = SQLITE_OK;
  4125. u32 nKey;
  4126. int iIdx = 0;
  4127. MemPage pPage = pCur.apPage[pCur.iPage]; /* Btree page of current entry */
  4128. BtShared pBt = pCur.pBt; /* Btree this cursor belongs to */
  4129. Debug.Assert( pPage != null );
  4130. Debug.Assert( pCur.eState == CURSOR_VALID );
  4131. Debug.Assert( pCur.aiIdx[pCur.iPage] < pPage.nCell );
  4132. Debug.Assert( cursorHoldsMutex( pCur ) );
  4133. getCellInfo( pCur );
  4134. aPayload = pCur.info.pCell; //pCur.info.pCell + pCur.info.nHeader;
  4135. nKey = (u32)( pPage.intKey != 0 ? 0 : (int)pCur.info.nKey );
  4136. if ( NEVER( offset + amt > nKey + pCur.info.nData )
  4137. || pCur.info.nLocal > pBt.usableSize//&aPayload[pCur.info.nLocal] > &pPage.aData[pBt.usableSize]
  4138. )
  4139. {
  4140. /* Trying to read or write past the end of the data is an error */
  4141. return SQLITE_CORRUPT_BKPT();
  4142. }
  4143. /* Check if data must be read/written to/from the btree page itself. */
  4144. if ( offset < pCur.info.nLocal )
  4145. {
  4146. int a = (int)amt;
  4147. if ( a + offset > pCur.info.nLocal )
  4148. {
  4149. a = (int)( pCur.info.nLocal - offset );
  4150. }
  4151. rc = copyPayload( aPayload, (u32)( offset + pCur.info.iCell + pCur.info.nHeader ), pBuf, pBufOffset, (u32)a, eOp, pPage.pDbPage );
  4152. offset = 0;
  4153. pBufOffset += (u32)a; //pBuf += a;
  4154. amt -= (u32)a;
  4155. }
  4156. else
  4157. {
  4158. offset -= pCur.info.nLocal;
  4159. }
  4160. if ( rc == SQLITE_OK && amt > 0 )
  4161. {
  4162. u32 ovflSize = (u32)( pBt.usableSize - 4 ); /* Bytes content per ovfl page */
  4163. Pgno nextPage;
  4164. nextPage = sqlite3Get4byte( aPayload, pCur.info.nLocal + pCur.info.iCell + pCur.info.nHeader );
  4165. #if !SQLITE_OMIT_INCRBLOB
  4166. /* If the isIncrblobHandle flag is set and the BtCursor.aOverflow[]
  4167. ** has not been allocated, allocate it now. The array is sized at
  4168. ** one entry for each overflow page in the overflow chain. The
  4169. ** page number of the first overflow page is stored in aOverflow[0],
  4170. ** etc. A value of 0 in the aOverflow[] array means "not yet known"
  4171. ** (the cache is lazily populated).
  4172. */
  4173. if( pCur.isIncrblobHandle && !pCur.aOverflow ){
  4174. int nOvfl = (pCur.info.nPayload-pCur.info.nLocal+ovflSize-1)/ovflSize;
  4175. pCur.aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl);
  4176. /* nOvfl is always positive. If it were zero, fetchPayload would have
  4177. ** been used instead of this routine. */
  4178. if( ALWAYS(nOvfl) && !pCur.aOverflow ){
  4179. rc = SQLITE_NOMEM;
  4180. }
  4181. }
  4182. /* If the overflow page-list cache has been allocated and the
  4183. ** entry for the first required overflow page is valid, skip
  4184. ** directly to it.
  4185. */
  4186. if( pCur.aOverflow && pCur.aOverflow[offset/ovflSize] ){
  4187. iIdx = (offset/ovflSize);
  4188. nextPage = pCur.aOverflow[iIdx];
  4189. offset = (offset%ovflSize);
  4190. }
  4191. #endif
  4192. for ( ; rc == SQLITE_OK && amt > 0 && nextPage != 0; iIdx++ )
  4193. {
  4194. #if !SQLITE_OMIT_INCRBLOB
  4195. /* If required, populate the overflow page-list cache. */
  4196. if( pCur.aOverflow ){
  4197. Debug.Assert(!pCur.aOverflow[iIdx] || pCur.aOverflow[iIdx]==nextPage);
  4198. pCur.aOverflow[iIdx] = nextPage;
  4199. }
  4200. #endif
  4201. MemPage MemPageDummy = null;
  4202. if ( offset >= ovflSize )
  4203. {
  4204. /* The only reason to read this page is to obtain the page
  4205. ** number for the next page in the overflow chain. The page
  4206. ** data is not required. So first try to lookup the overflow
  4207. ** page-list cache, if any, then fall back to the getOverflowPage()
  4208. ** function.
  4209. */
  4210. #if !SQLITE_OMIT_INCRBLOB
  4211. if( pCur.aOverflow && pCur.aOverflow[iIdx+1] ){
  4212. nextPage = pCur.aOverflow[iIdx+1];
  4213. } else
  4214. #endif
  4215. rc = getOverflowPage( pBt, nextPage, out MemPageDummy, out nextPage );
  4216. offset -= ovflSize;
  4217. }
  4218. else
  4219. {
  4220. /* Need to read this page properly. It contains some of the
  4221. ** range of data that is being read (eOp==null) or written (eOp!=null).
  4222. */
  4223. PgHdr pDbPage = new PgHdr();
  4224. int a = (int)amt;
  4225. rc = sqlite3PagerGet( pBt.pPager, nextPage, ref pDbPage );
  4226. if ( rc == SQLITE_OK )
  4227. {
  4228. aPayload = sqlite3PagerGetData( pDbPage );
  4229. nextPage = sqlite3Get4byte( aPayload );
  4230. if ( a + offset > ovflSize )
  4231. {
  4232. a = (int)( ovflSize - offset );
  4233. }
  4234. rc = copyPayload( aPayload, offset + 4, pBuf, pBufOffset, (u32)a, eOp, pDbPage );
  4235. sqlite3PagerUnref( pDbPage );
  4236. offset = 0;
  4237. amt -= (u32)a;
  4238. pBufOffset += (u32)a;//pBuf += a;
  4239. }
  4240. }
  4241. }
  4242. }
  4243. if ( rc == SQLITE_OK && amt > 0 )
  4244. {
  4245. return SQLITE_CORRUPT_BKPT();
  4246. }
  4247. return rc;
  4248. }
  4249. /*
  4250. ** Read part of the key associated with cursor pCur. Exactly
  4251. ** "amt" bytes will be transfered into pBuf[]. The transfer
  4252. ** begins at "offset".
  4253. **
  4254. ** The caller must ensure that pCur is pointing to a valid row
  4255. ** in the table.
  4256. **
  4257. ** Return SQLITE_OK on success or an error code if anything goes
  4258. ** wrong. An error is returned if "offset+amt" is larger than
  4259. ** the available payload.
  4260. */
  4261. static int sqlite3BtreeKey( BtCursor pCur, u32 offset, u32 amt, byte[] pBuf )
  4262. {
  4263. Debug.Assert( cursorHoldsMutex( pCur ) );
  4264. Debug.Assert( pCur.eState == CURSOR_VALID );
  4265. Debug.Assert( pCur.iPage >= 0 && pCur.apPage[pCur.iPage] != null );
  4266. Debug.Assert( pCur.aiIdx[pCur.iPage] < pCur.apPage[pCur.iPage].nCell );
  4267. return accessPayload( pCur, offset, amt, pBuf, 0 );
  4268. }
  4269. /*
  4270. ** Read part of the data associated with cursor pCur. Exactly
  4271. ** "amt" bytes will be transfered into pBuf[]. The transfer
  4272. ** begins at "offset".
  4273. **
  4274. ** Return SQLITE_OK on success or an error code if anything goes
  4275. ** wrong. An error is returned if "offset+amt" is larger than
  4276. ** the available payload.
  4277. */
  4278. static int sqlite3BtreeData( BtCursor pCur, u32 offset, u32 amt, byte[] pBuf )
  4279. {
  4280. int rc;
  4281. #if !SQLITE_OMIT_INCRBLOB
  4282. if ( pCur.eState==CURSOR_INVALID ){
  4283. return SQLITE_ABORT;
  4284. }
  4285. #endif
  4286. Debug.Assert( cursorHoldsMutex( pCur ) );
  4287. rc = restoreCursorPosition( pCur );
  4288. if ( rc == SQLITE_OK )
  4289. {
  4290. Debug.Assert( pCur.eState == CURSOR_VALID );
  4291. Debug.Assert( pCur.iPage >= 0 && pCur.apPage[pCur.iPage] != null );
  4292. Debug.Assert( pCur.aiIdx[pCur.iPage] < pCur.apPage[pCur.iPage].nCell );
  4293. rc = accessPayload( pCur, offset, amt, pBuf, 0 );
  4294. }
  4295. return rc;
  4296. }
  4297. /*
  4298. ** Return a pointer to payload information from the entry that the
  4299. ** pCur cursor is pointing to. The pointer is to the beginning of
  4300. ** the key if skipKey==null and it points to the beginning of data if
  4301. ** skipKey==1. The number of bytes of available key/data is written
  4302. ** into pAmt. If pAmt==null, then the value returned will not be
  4303. ** a valid pointer.
  4304. **
  4305. ** This routine is an optimization. It is common for the entire key
  4306. ** and data to fit on the local page and for there to be no overflow
  4307. ** pages. When that is so, this routine can be used to access the
  4308. ** key and data without making a copy. If the key and/or data spills
  4309. ** onto overflow pages, then accessPayload() must be used to reassemble
  4310. ** the key/data and copy it into a preallocated buffer.
  4311. **
  4312. ** The pointer returned by this routine looks directly into the cached
  4313. ** page of the database. The data might change or move the next time
  4314. ** any btree routine is called.
  4315. */
  4316. static byte[] fetchPayload(
  4317. BtCursor pCur, /* Cursor pointing to entry to read from */
  4318. ref int pAmt, /* Write the number of available bytes here */
  4319. ref int outOffset, /* Offset into Buffer */
  4320. bool skipKey /* read beginning at data if this is true */
  4321. )
  4322. {
  4323. byte[] aPayload;
  4324. MemPage pPage;
  4325. u32 nKey;
  4326. u32 nLocal;
  4327. Debug.Assert( pCur != null && pCur.iPage >= 0 && pCur.apPage[pCur.iPage] != null );
  4328. Debug.Assert( pCur.eState == CURSOR_VALID );
  4329. Debug.Assert( cursorHoldsMutex( pCur ) );
  4330. outOffset = -1;
  4331. pPage = pCur.apPage[pCur.iPage];
  4332. Debug.Assert( pCur.aiIdx[pCur.iPage] < pPage.nCell );
  4333. if ( NEVER( pCur.info.nSize == 0 ) )
  4334. {
  4335. btreeParseCell( pCur.apPage[pCur.iPage], pCur.aiIdx[pCur.iPage],
  4336. ref pCur.info );
  4337. }
  4338. //aPayload = pCur.info.pCell;
  4339. //aPayload += pCur.info.nHeader;
  4340. aPayload = sqlite3Malloc( pCur.info.nSize - pCur.info.nHeader );
  4341. if ( pPage.intKey != 0 )
  4342. {
  4343. nKey = 0;
  4344. }
  4345. else
  4346. {
  4347. nKey = (u32)pCur.info.nKey;
  4348. }
  4349. if ( skipKey )
  4350. {
  4351. //aPayload += nKey;
  4352. outOffset = (int)( pCur.info.iCell + pCur.info.nHeader + nKey );
  4353. Buffer.BlockCopy( pCur.info.pCell, outOffset, aPayload, 0, (int)( pCur.info.nSize - pCur.info.nHeader - nKey ) );
  4354. nLocal = pCur.info.nLocal - nKey;
  4355. }
  4356. else
  4357. {
  4358. outOffset = (int)( pCur.info.iCell + pCur.info.nHeader );
  4359. Buffer.BlockCopy( pCur.info.pCell, outOffset, aPayload, 0, pCur.info.nSize - pCur.info.nHeader );
  4360. nLocal = pCur.info.nLocal;
  4361. Debug.Assert( nLocal <= nKey );
  4362. }
  4363. pAmt = (int)nLocal;
  4364. return aPayload;
  4365. }
  4366. /*
  4367. ** For the entry that cursor pCur is point to, return as
  4368. ** many bytes of the key or data as are available on the local
  4369. ** b-tree page. Write the number of available bytes into pAmt.
  4370. **
  4371. ** The pointer returned is ephemeral. The key/data may move
  4372. ** or be destroyed on the next call to any Btree routine,
  4373. ** including calls from other threads against the same cache.
  4374. ** Hence, a mutex on the BtShared should be held prior to calling
  4375. ** this routine.
  4376. **
  4377. ** These routines is used to get quick access to key and data
  4378. ** in the common case where no overflow pages are used.
  4379. */
  4380. static byte[] sqlite3BtreeKeyFetch( BtCursor pCur, ref int pAmt, ref int outOffset )
  4381. {
  4382. byte[] p = null;
  4383. Debug.Assert( sqlite3_mutex_held( pCur.pBtree.db.mutex ) );
  4384. Debug.Assert( cursorHoldsMutex( pCur ) );
  4385. if ( ALWAYS( pCur.eState == CURSOR_VALID ) )
  4386. {
  4387. p = fetchPayload( pCur, ref pAmt, ref outOffset, false );
  4388. }
  4389. return p;
  4390. }
  4391. static byte[] sqlite3BtreeDataFetch( BtCursor pCur, ref int pAmt, ref int outOffset )
  4392. {
  4393. byte[] p = null;
  4394. Debug.Assert( sqlite3_mutex_held( pCur.pBtree.db.mutex ) );
  4395. Debug.Assert( cursorHoldsMutex( pCur ) );
  4396. if ( ALWAYS( pCur.eState == CURSOR_VALID ) )
  4397. {
  4398. p = fetchPayload( pCur, ref pAmt, ref outOffset, true );
  4399. }
  4400. return p;
  4401. }
  4402. /*
  4403. ** Move the cursor down to a new child page. The newPgno argument is the
  4404. ** page number of the child page to move to.
  4405. **
  4406. ** This function returns SQLITE_CORRUPT if the page-header flags field of
  4407. ** the new child page does not match the flags field of the parent (i.e.
  4408. ** if an intkey page appears to be the parent of a non-intkey page, or
  4409. ** vice-versa).
  4410. */
  4411. static int moveToChild( BtCursor pCur, u32 newPgno )
  4412. {
  4413. int rc;
  4414. int i = pCur.iPage;
  4415. MemPage pNewPage = new MemPage();
  4416. BtShared pBt = pCur.pBt;
  4417. Debug.Assert( cursorHoldsMutex( pCur ) );
  4418. Debug.Assert( pCur.eState == CURSOR_VALID );
  4419. Debug.Assert( pCur.iPage < BTCURSOR_MAX_DEPTH );
  4420. if ( pCur.iPage >= ( BTCURSOR_MAX_DEPTH - 1 ) )
  4421. {
  4422. return SQLITE_CORRUPT_BKPT();
  4423. }
  4424. rc = getAndInitPage( pBt, newPgno, ref pNewPage );
  4425. if ( rc != 0 )
  4426. return rc;
  4427. pCur.apPage[i + 1] = pNewPage;
  4428. pCur.aiIdx[i + 1] = 0;
  4429. pCur.iPage++;
  4430. pCur.info.nSize = 0;
  4431. pCur.validNKey = false;
  4432. if ( pNewPage.nCell < 1 || pNewPage.intKey != pCur.apPage[i].intKey )
  4433. {
  4434. return SQLITE_CORRUPT_BKPT();
  4435. }
  4436. return SQLITE_OK;
  4437. }
  4438. #if !NDEBUG
  4439. /*
  4440. ** Page pParent is an internal (non-leaf) tree page. This function
  4441. ** asserts that page number iChild is the left-child if the iIdx'th
  4442. ** cell in page pParent. Or, if iIdx is equal to the total number of
  4443. ** cells in pParent, that page number iChild is the right-child of
  4444. ** the page.
  4445. */
  4446. static void assertParentIndex( MemPage pParent, int iIdx, Pgno iChild )
  4447. {
  4448. Debug.Assert( iIdx <= pParent.nCell );
  4449. if ( iIdx == pParent.nCell )
  4450. {
  4451. Debug.Assert( sqlite3Get4byte( pParent.aData, pParent.hdrOffset + 8 ) == iChild );
  4452. }
  4453. else
  4454. {
  4455. Debug.Assert( sqlite3Get4byte( pParent.aData, findCell( pParent, iIdx ) ) == iChild );
  4456. }
  4457. }
  4458. #else
  4459. //# define assertParentIndex(x,y,z)
  4460. static void assertParentIndex(MemPage pParent, int iIdx, Pgno iChild) { }
  4461. #endif
  4462. /*
  4463. ** Move the cursor up to the parent page.
  4464. **
  4465. ** pCur.idx is set to the cell index that contains the pointer
  4466. ** to the page we are coming from. If we are coming from the
  4467. ** right-most child page then pCur.idx is set to one more than
  4468. ** the largest cell index.
  4469. */
  4470. static void moveToParent( BtCursor pCur )
  4471. {
  4472. Debug.Assert( cursorHoldsMutex( pCur ) );
  4473. Debug.Assert( pCur.eState == CURSOR_VALID );
  4474. Debug.Assert( pCur.iPage > 0 );
  4475. Debug.Assert( pCur.apPage[pCur.iPage] != null );
  4476. assertParentIndex(
  4477. pCur.apPage[pCur.iPage - 1],
  4478. pCur.aiIdx[pCur.iPage - 1],
  4479. pCur.apPage[pCur.iPage].pgno
  4480. );
  4481. releasePage( pCur.apPage[pCur.iPage] );
  4482. pCur.iPage--;
  4483. pCur.info.nSize = 0;
  4484. pCur.validNKey = false;
  4485. }
  4486. /*
  4487. ** Move the cursor to point to the root page of its b-tree structure.
  4488. **
  4489. ** If the table has a virtual root page, then the cursor is moved to point
  4490. ** to the virtual root page instead of the actual root page. A table has a
  4491. ** virtual root page when the actual root page contains no cells and a
  4492. ** single child page. This can only happen with the table rooted at page 1.
  4493. **
  4494. ** If the b-tree structure is empty, the cursor state is set to
  4495. ** CURSOR_INVALID. Otherwise, the cursor is set to point to the first
  4496. ** cell located on the root (or virtual root) page and the cursor state
  4497. ** is set to CURSOR_VALID.
  4498. **
  4499. ** If this function returns successfully, it may be assumed that the
  4500. ** page-header flags indicate that the [virtual] root-page is the expected
  4501. ** kind of b-tree page (i.e. if when opening the cursor the caller did not
  4502. ** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D,
  4503. ** indicating a table b-tree, or if the caller did specify a KeyInfo
  4504. ** structure the flags byte is set to 0x02 or 0x0A, indicating an index
  4505. ** b-tree).
  4506. */
  4507. static int moveToRoot( BtCursor pCur )
  4508. {
  4509. MemPage pRoot;
  4510. int rc = SQLITE_OK;
  4511. Btree p = pCur.pBtree;
  4512. BtShared pBt = p.pBt;
  4513. Debug.Assert( cursorHoldsMutex( pCur ) );
  4514. Debug.Assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
  4515. Debug.Assert( CURSOR_VALID < CURSOR_REQUIRESEEK );
  4516. Debug.Assert( CURSOR_FAULT > CURSOR_REQUIRESEEK );
  4517. if ( pCur.eState >= CURSOR_REQUIRESEEK )
  4518. {
  4519. if ( pCur.eState == CURSOR_FAULT )
  4520. {
  4521. Debug.Assert( pCur.skipNext != SQLITE_OK );
  4522. return pCur.skipNext;
  4523. }
  4524. sqlite3BtreeClearCursor( pCur );
  4525. }
  4526. if ( pCur.iPage >= 0 )
  4527. {
  4528. int i;
  4529. for ( i = 1; i <= pCur.iPage; i++ )
  4530. {
  4531. releasePage( pCur.apPage[i] );
  4532. }
  4533. pCur.iPage = 0;
  4534. }
  4535. else
  4536. {
  4537. rc = getAndInitPage( pBt, pCur.pgnoRoot, ref pCur.apPage[0] );
  4538. if ( rc != SQLITE_OK )
  4539. {
  4540. pCur.eState = CURSOR_INVALID;
  4541. return rc;
  4542. }
  4543. pCur.iPage = 0;
  4544. /* If pCur.pKeyInfo is not NULL, then the caller that opened this cursor
  4545. ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
  4546. ** NULL, the caller expects a table b-tree. If this is not the case,
  4547. ** return an SQLITE_CORRUPT error. */
  4548. Debug.Assert( pCur.apPage[0].intKey == 1 || pCur.apPage[0].intKey == 0 );
  4549. if ( ( pCur.pKeyInfo == null ) != ( pCur.apPage[0].intKey != 0 ) )
  4550. {
  4551. return SQLITE_CORRUPT_BKPT();
  4552. }
  4553. }
  4554. /* Assert that the root page is of the correct type. This must be the
  4555. ** case as the call to this function that loaded the root-page (either
  4556. ** this call or a previous invocation) would have detected corruption
  4557. ** if the assumption were not true, and it is not possible for the flags
  4558. ** byte to have been modified while this cursor is holding a reference
  4559. ** to the page. */
  4560. pRoot = pCur.apPage[0];
  4561. Debug.Assert( pRoot.pgno == pCur.pgnoRoot );
  4562. Debug.Assert( pRoot.isInit != 0 && ( pCur.pKeyInfo == null ) == ( pRoot.intKey != 0 ) );
  4563. pCur.aiIdx[0] = 0;
  4564. pCur.info.nSize = 0;
  4565. pCur.atLast = 0;
  4566. pCur.validNKey = false;
  4567. if ( pRoot.nCell == 0 && 0 == pRoot.leaf )
  4568. {
  4569. Pgno subpage;
  4570. if ( pRoot.pgno != 1 )
  4571. return SQLITE_CORRUPT_BKPT();
  4572. subpage = sqlite3Get4byte( pRoot.aData, pRoot.hdrOffset + 8 );
  4573. pCur.eState = CURSOR_VALID;
  4574. rc = moveToChild( pCur, subpage );
  4575. }
  4576. else
  4577. {
  4578. pCur.eState = ( ( pRoot.nCell > 0 ) ? CURSOR_VALID : CURSOR_INVALID );
  4579. }
  4580. return rc;
  4581. }
  4582. /*
  4583. ** Move the cursor down to the left-most leaf entry beneath the
  4584. ** entry to which it is currently pointing.
  4585. **
  4586. ** The left-most leaf is the one with the smallest key - the first
  4587. ** in ascending order.
  4588. */
  4589. static int moveToLeftmost( BtCursor pCur )
  4590. {
  4591. Pgno pgno;
  4592. int rc = SQLITE_OK;
  4593. MemPage pPage;
  4594. Debug.Assert( cursorHoldsMutex( pCur ) );
  4595. Debug.Assert( pCur.eState == CURSOR_VALID );
  4596. while ( rc == SQLITE_OK && 0 == ( pPage = pCur.apPage[pCur.iPage] ).leaf )
  4597. {
  4598. Debug.Assert( pCur.aiIdx[pCur.iPage] < pPage.nCell );
  4599. pgno = sqlite3Get4byte( pPage.aData, findCell( pPage, pCur.aiIdx[pCur.iPage] ) );
  4600. rc = moveToChild( pCur, pgno );
  4601. }
  4602. return rc;
  4603. }
  4604. /*
  4605. ** Move the cursor down to the right-most leaf entry beneath the
  4606. ** page to which it is currently pointing. Notice the difference
  4607. ** between moveToLeftmost() and moveToRightmost(). moveToLeftmost()
  4608. ** finds the left-most entry beneath the *entry* whereas moveToRightmost()
  4609. ** finds the right-most entry beneath the page*.
  4610. **
  4611. ** The right-most entry is the one with the largest key - the last
  4612. ** key in ascending order.
  4613. */
  4614. static int moveToRightmost( BtCursor pCur )
  4615. {
  4616. Pgno pgno;
  4617. int rc = SQLITE_OK;
  4618. MemPage pPage = null;
  4619. Debug.Assert( cursorHoldsMutex( pCur ) );
  4620. Debug.Assert( pCur.eState == CURSOR_VALID );
  4621. while ( rc == SQLITE_OK && 0 == ( pPage = pCur.apPage[pCur.iPage] ).leaf )
  4622. {
  4623. pgno = sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 );
  4624. pCur.aiIdx[pCur.iPage] = pPage.nCell;
  4625. rc = moveToChild( pCur, pgno );
  4626. }
  4627. if ( rc == SQLITE_OK )
  4628. {
  4629. pCur.aiIdx[pCur.iPage] = (u16)( pPage.nCell - 1 );
  4630. pCur.info.nSize = 0;
  4631. pCur.validNKey = false;
  4632. }
  4633. return rc;
  4634. }
  4635. /* Move the cursor to the first entry in the table. Return SQLITE_OK
  4636. ** on success. Set pRes to 0 if the cursor actually points to something
  4637. ** or set pRes to 1 if the table is empty.
  4638. */
  4639. static int sqlite3BtreeFirst( BtCursor pCur, ref int pRes )
  4640. {
  4641. int rc;
  4642. Debug.Assert( cursorHoldsMutex( pCur ) );
  4643. Debug.Assert( sqlite3_mutex_held( pCur.pBtree.db.mutex ) );
  4644. rc = moveToRoot( pCur );
  4645. if ( rc == SQLITE_OK )
  4646. {
  4647. if ( pCur.eState == CURSOR_INVALID )
  4648. {
  4649. Debug.Assert( pCur.apPage[pCur.iPage].nCell == 0 );
  4650. pRes = 1;
  4651. }
  4652. else
  4653. {
  4654. Debug.Assert( pCur.apPage[pCur.iPage].nCell > 0 );
  4655. pRes = 0;
  4656. rc = moveToLeftmost( pCur );
  4657. }
  4658. }
  4659. return rc;
  4660. }
  4661. /* Move the cursor to the last entry in the table. Return SQLITE_OK
  4662. ** on success. Set pRes to 0 if the cursor actually points to something
  4663. ** or set pRes to 1 if the table is empty.
  4664. */
  4665. static int sqlite3BtreeLast( BtCursor pCur, ref int pRes )
  4666. {
  4667. int rc;
  4668. Debug.Assert( cursorHoldsMutex( pCur ) );
  4669. Debug.Assert( sqlite3_mutex_held( pCur.pBtree.db.mutex ) );
  4670. /* If the cursor already points to the last entry, this is a no-op. */
  4671. if ( CURSOR_VALID == pCur.eState && pCur.atLast != 0 )
  4672. {
  4673. #if SQLITE_DEBUG
  4674. /* This block serves to Debug.Assert() that the cursor really does point
  4675. ** to the last entry in the b-tree. */
  4676. int ii;
  4677. for ( ii = 0; ii < pCur.iPage; ii++ )
  4678. {
  4679. Debug.Assert( pCur.aiIdx[ii] == pCur.apPage[ii].nCell );
  4680. }
  4681. Debug.Assert( pCur.aiIdx[pCur.iPage] == pCur.apPage[pCur.iPage].nCell - 1 );
  4682. Debug.Assert( pCur.apPage[pCur.iPage].leaf != 0 );
  4683. #endif
  4684. return SQLITE_OK;
  4685. }
  4686. rc = moveToRoot( pCur );
  4687. if ( rc == SQLITE_OK )
  4688. {
  4689. if ( CURSOR_INVALID == pCur.eState )
  4690. {
  4691. Debug.Assert( pCur.apPage[pCur.iPage].nCell == 0 );
  4692. pRes = 1;
  4693. }
  4694. else
  4695. {
  4696. Debug.Assert( pCur.eState == CURSOR_VALID );
  4697. pRes = 0;
  4698. rc = moveToRightmost( pCur );
  4699. pCur.atLast = (u8)( rc == SQLITE_OK ? 1 : 0 );
  4700. }
  4701. }
  4702. return rc;
  4703. }
  4704. /* Move the cursor so that it points to an entry near the key
  4705. ** specified by pIdxKey or intKey. Return a success code.
  4706. **
  4707. ** For INTKEY tables, the intKey parameter is used. pIdxKey
  4708. ** must be NULL. For index tables, pIdxKey is used and intKey
  4709. ** is ignored.
  4710. **
  4711. ** If an exact match is not found, then the cursor is always
  4712. ** left pointing at a leaf page which would hold the entry if it
  4713. ** were present. The cursor might point to an entry that comes
  4714. ** before or after the key.
  4715. **
  4716. ** An integer is written into pRes which is the result of
  4717. ** comparing the key with the entry to which the cursor is
  4718. ** pointing. The meaning of the integer written into
  4719. ** pRes is as follows:
  4720. **
  4721. ** pRes<0 The cursor is left pointing at an entry that
  4722. ** is smaller than intKey/pIdxKey or if the table is empty
  4723. ** and the cursor is therefore left point to nothing.
  4724. **
  4725. ** pRes==null The cursor is left pointing at an entry that
  4726. ** exactly matches intKey/pIdxKey.
  4727. **
  4728. ** pRes>0 The cursor is left pointing at an entry that
  4729. ** is larger than intKey/pIdxKey.
  4730. **
  4731. */
  4732. static int sqlite3BtreeMovetoUnpacked(
  4733. BtCursor pCur, /* The cursor to be moved */
  4734. UnpackedRecord pIdxKey, /* Unpacked index key */
  4735. i64 intKey, /* The table key */
  4736. int biasRight, /* If true, bias the search to the high end */
  4737. ref int pRes /* Write search results here */
  4738. )
  4739. {
  4740. int rc;
  4741. Debug.Assert( cursorHoldsMutex( pCur ) );
  4742. Debug.Assert( sqlite3_mutex_held( pCur.pBtree.db.mutex ) );
  4743. // Not needed in C# // Debug.Assert( pRes != 0 );
  4744. Debug.Assert( ( pIdxKey == null ) == ( pCur.pKeyInfo == null ) );
  4745. /* If the cursor is already positioned at the point we are trying
  4746. ** to move to, then just return without doing any work */
  4747. if ( pCur.eState == CURSOR_VALID && pCur.validNKey
  4748. && pCur.apPage[0].intKey != 0
  4749. )
  4750. {
  4751. if ( pCur.info.nKey == intKey )
  4752. {
  4753. pRes = 0;
  4754. return SQLITE_OK;
  4755. }
  4756. if ( pCur.atLast != 0 && pCur.info.nKey < intKey )
  4757. {
  4758. pRes = -1;
  4759. return SQLITE_OK;
  4760. }
  4761. }
  4762. rc = moveToRoot( pCur );
  4763. if ( rc != 0 )
  4764. {
  4765. return rc;
  4766. }
  4767. Debug.Assert( pCur.apPage[pCur.iPage] != null );
  4768. Debug.Assert( pCur.apPage[pCur.iPage].isInit != 0 );
  4769. Debug.Assert( pCur.apPage[pCur.iPage].nCell > 0 || pCur.eState == CURSOR_INVALID );
  4770. if ( pCur.eState == CURSOR_INVALID )
  4771. {
  4772. pRes = -1;
  4773. Debug.Assert( pCur.apPage[pCur.iPage].nCell == 0 );
  4774. return SQLITE_OK;
  4775. }
  4776. Debug.Assert( pCur.apPage[0].intKey != 0 || pIdxKey != null );
  4777. for ( ; ; )
  4778. {
  4779. int lwr, upr, idx;
  4780. Pgno chldPg;
  4781. MemPage pPage = pCur.apPage[pCur.iPage];
  4782. int c;
  4783. /* pPage.nCell must be greater than zero. If this is the root-page
  4784. ** the cursor would have been INVALID above and this for(;;) loop
  4785. ** not run. If this is not the root-page, then the moveToChild() routine
  4786. ** would have already detected db corruption. Similarly, pPage must
  4787. ** be the right kind (index or table) of b-tree page. Otherwise
  4788. ** a moveToChild() or moveToRoot() call would have detected corruption. */
  4789. Debug.Assert( pPage.nCell > 0 );
  4790. Debug.Assert( pPage.intKey == ( ( pIdxKey == null ) ? 1 : 0 ) );
  4791. lwr = 0;
  4792. upr = pPage.nCell - 1;
  4793. if ( biasRight != 0 )
  4794. {
  4795. pCur.aiIdx[pCur.iPage] = (u16)( idx = upr );
  4796. }
  4797. else
  4798. {
  4799. pCur.aiIdx[pCur.iPage] = (u16)( idx = ( upr + lwr ) / 2 );
  4800. }
  4801. for ( ; ; )
  4802. {
  4803. int pCell; /* Pointer to current cell in pPage */
  4804. Debug.Assert( idx == pCur.aiIdx[pCur.iPage] );
  4805. pCur.info.nSize = 0;
  4806. pCell = findCell( pPage, idx ) + pPage.childPtrSize;
  4807. if ( pPage.intKey != 0 )
  4808. {
  4809. i64 nCellKey = 0;
  4810. if ( pPage.hasData != 0 )
  4811. {
  4812. u32 Dummy0 = 0;
  4813. pCell += getVarint32( pPage.aData, pCell, out Dummy0 );
  4814. }
  4815. getVarint( pPage.aData, pCell, out nCellKey );
  4816. if ( nCellKey == intKey )
  4817. {
  4818. c = 0;
  4819. }
  4820. else if ( nCellKey < intKey )
  4821. {
  4822. c = -1;
  4823. }
  4824. else
  4825. {
  4826. Debug.Assert( nCellKey > intKey );
  4827. c = +1;
  4828. }
  4829. pCur.validNKey = true;
  4830. pCur.info.nKey = nCellKey;
  4831. }
  4832. else
  4833. {
  4834. /* The maximum supported page-size is 65536 bytes. This means that
  4835. ** the maximum number of record bytes stored on an index B-Tree
  4836. ** page is less than 16384 bytes and may be stored as a 2-byte
  4837. ** varint. This information is used to attempt to avoid parsing
  4838. ** the entire cell by checking for the cases where the record is
  4839. ** stored entirely within the b-tree page by inspecting the first
  4840. ** 2 bytes of the cell.
  4841. */
  4842. int nCell = pPage.aData[pCell + 0]; //pCell[0];
  4843. if ( 0 == ( nCell & 0x80 ) && nCell <= pPage.maxLocal )
  4844. {
  4845. /* This branch runs if the record-size field of the cell is a
  4846. ** single byte varint and the record fits entirely on the main
  4847. ** b-tree page. */
  4848. c = sqlite3VdbeRecordCompare( nCell, pPage.aData, pCell + 1, pIdxKey ); //c = sqlite3VdbeRecordCompare( nCell, (void*)&pCell[1], pIdxKey );
  4849. }
  4850. else if ( 0 == ( pPage.aData[pCell + 1] & 0x80 )//!(pCell[1] & 0x80)
  4851. && ( nCell = ( ( nCell & 0x7f ) << 7 ) + pPage.aData[pCell + 1] ) <= pPage.maxLocal//pCell[1])<=pPage.maxLocal
  4852. )
  4853. {
  4854. /* The record-size field is a 2 byte varint and the record
  4855. ** fits entirely on the main b-tree page. */
  4856. c = sqlite3VdbeRecordCompare( nCell, pPage.aData, pCell + 2, pIdxKey ); //c = sqlite3VdbeRecordCompare( nCell, (void*)&pCell[2], pIdxKey );
  4857. }
  4858. else
  4859. {
  4860. /* The record flows over onto one or more overflow pages. In
  4861. ** this case the whole cell needs to be parsed, a buffer allocated
  4862. ** and accessPayload() used to retrieve the record into the
  4863. ** buffer before VdbeRecordCompare() can be called. */
  4864. u8[] pCellKey;
  4865. u8[] pCellBody = new u8[pPage.aData.Length - pCell + pPage.childPtrSize];
  4866. Buffer.BlockCopy( pPage.aData, pCell - pPage.childPtrSize, pCellBody, 0, pCellBody.Length );// u8 * const pCellBody = pCell - pPage->childPtrSize;
  4867. btreeParseCellPtr( pPage, pCellBody, ref pCur.info );
  4868. nCell = (int)pCur.info.nKey;
  4869. pCellKey = sqlite3Malloc( nCell );
  4870. //if ( pCellKey == null )
  4871. //{
  4872. // rc = SQLITE_NOMEM;
  4873. // goto moveto_finish;
  4874. //}
  4875. rc = accessPayload( pCur, 0, (u32)nCell, pCellKey, 0 );
  4876. if ( rc != 0 )
  4877. {
  4878. pCellKey = null;// sqlite3_free(ref pCellKey );
  4879. goto moveto_finish;
  4880. }
  4881. c = sqlite3VdbeRecordCompare( nCell, pCellKey, pIdxKey );
  4882. pCellKey = null;// sqlite3_free(ref pCellKey );
  4883. }
  4884. }
  4885. if ( c == 0 )
  4886. {
  4887. if ( pPage.intKey != 0 && 0 == pPage.leaf )
  4888. {
  4889. lwr = idx;
  4890. upr = lwr - 1;
  4891. break;
  4892. }
  4893. else
  4894. {
  4895. pRes = 0;
  4896. rc = SQLITE_OK;
  4897. goto moveto_finish;
  4898. }
  4899. }
  4900. if ( c < 0 )
  4901. {
  4902. lwr = idx + 1;
  4903. }
  4904. else
  4905. {
  4906. upr = idx - 1;
  4907. }
  4908. if ( lwr > upr )
  4909. {
  4910. break;
  4911. }
  4912. pCur.aiIdx[pCur.iPage] = (u16)( idx = ( lwr + upr ) / 2 );
  4913. }
  4914. Debug.Assert( lwr == upr + 1 );
  4915. Debug.Assert( pPage.isInit != 0 );
  4916. if ( pPage.leaf != 0 )
  4917. {
  4918. chldPg = 0;
  4919. }
  4920. else if ( lwr >= pPage.nCell )
  4921. {
  4922. chldPg = sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 );
  4923. }
  4924. else
  4925. {
  4926. chldPg = sqlite3Get4byte( pPage.aData, findCell( pPage, lwr ) );
  4927. }
  4928. if ( chldPg == 0 )
  4929. {
  4930. Debug.Assert( pCur.aiIdx[pCur.iPage] < pCur.apPage[pCur.iPage].nCell );
  4931. pRes = c;
  4932. rc = SQLITE_OK;
  4933. goto moveto_finish;
  4934. }
  4935. pCur.aiIdx[pCur.iPage] = (u16)lwr;
  4936. pCur.info.nSize = 0;
  4937. pCur.validNKey = false;
  4938. rc = moveToChild( pCur, chldPg );
  4939. if ( rc != 0 )
  4940. goto moveto_finish;
  4941. }
  4942. moveto_finish:
  4943. return rc;
  4944. }
  4945. /*
  4946. ** Return TRUE if the cursor is not pointing at an entry of the table.
  4947. **
  4948. ** TRUE will be returned after a call to sqlite3BtreeNext() moves
  4949. ** past the last entry in the table or sqlite3BtreePrev() moves past
  4950. ** the first entry. TRUE is also returned if the table is empty.
  4951. */
  4952. static bool sqlite3BtreeEof( BtCursor pCur )
  4953. {
  4954. /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries
  4955. ** have been deleted? This API will need to change to return an error code
  4956. ** as well as the boolean result value.
  4957. */
  4958. return ( CURSOR_VALID != pCur.eState );
  4959. }
  4960. /*
  4961. ** Advance the cursor to the next entry in the database. If
  4962. ** successful then set pRes=0. If the cursor
  4963. ** was already pointing to the last entry in the database before
  4964. ** this routine was called, then set pRes=1.
  4965. */
  4966. static int sqlite3BtreeNext( BtCursor pCur, ref int pRes )
  4967. {
  4968. int rc;
  4969. int idx;
  4970. MemPage pPage;
  4971. Debug.Assert( cursorHoldsMutex( pCur ) );
  4972. rc = restoreCursorPosition( pCur );
  4973. if ( rc != SQLITE_OK )
  4974. {
  4975. return rc;
  4976. }
  4977. // Not needed in C# // Debug.Assert( pRes != 0 );
  4978. if ( CURSOR_INVALID == pCur.eState )
  4979. {
  4980. pRes = 1;
  4981. return SQLITE_OK;
  4982. }
  4983. if ( pCur.skipNext > 0 )
  4984. {
  4985. pCur.skipNext = 0;
  4986. pRes = 0;
  4987. return SQLITE_OK;
  4988. }
  4989. pCur.skipNext = 0;
  4990. pPage = pCur.apPage[pCur.iPage];
  4991. idx = ++pCur.aiIdx[pCur.iPage];
  4992. Debug.Assert( pPage.isInit != 0 );
  4993. Debug.Assert( idx <= pPage.nCell );
  4994. pCur.info.nSize = 0;
  4995. pCur.validNKey = false;
  4996. if ( idx >= pPage.nCell )
  4997. {
  4998. if ( 0 == pPage.leaf )
  4999. {
  5000. rc = moveToChild( pCur, sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 ) );
  5001. if ( rc != 0 )
  5002. return rc;
  5003. rc = moveToLeftmost( pCur );
  5004. pRes = 0;
  5005. return rc;
  5006. }
  5007. do
  5008. {
  5009. if ( pCur.iPage == 0 )
  5010. {
  5011. pRes = 1;
  5012. pCur.eState = CURSOR_INVALID;
  5013. return SQLITE_OK;
  5014. }
  5015. moveToParent( pCur );
  5016. pPage = pCur.apPage[pCur.iPage];
  5017. } while ( pCur.aiIdx[pCur.iPage] >= pPage.nCell );
  5018. pRes = 0;
  5019. if ( pPage.intKey != 0 )
  5020. {
  5021. rc = sqlite3BtreeNext( pCur, ref pRes );
  5022. }
  5023. else
  5024. {
  5025. rc = SQLITE_OK;
  5026. }
  5027. return rc;
  5028. }
  5029. pRes = 0;
  5030. if ( pPage.leaf != 0 )
  5031. {
  5032. return SQLITE_OK;
  5033. }
  5034. rc = moveToLeftmost( pCur );
  5035. return rc;
  5036. }
  5037. /*
  5038. ** Step the cursor to the back to the previous entry in the database. If
  5039. ** successful then set pRes=0. If the cursor
  5040. ** was already pointing to the first entry in the database before
  5041. ** this routine was called, then set pRes=1.
  5042. */
  5043. static int sqlite3BtreePrevious( BtCursor pCur, ref int pRes )
  5044. {
  5045. int rc;
  5046. MemPage pPage;
  5047. Debug.Assert( cursorHoldsMutex( pCur ) );
  5048. rc = restoreCursorPosition( pCur );
  5049. if ( rc != SQLITE_OK )
  5050. {
  5051. return rc;
  5052. }
  5053. pCur.atLast = 0;
  5054. if ( CURSOR_INVALID == pCur.eState )
  5055. {
  5056. pRes = 1;
  5057. return SQLITE_OK;
  5058. }
  5059. if ( pCur.skipNext < 0 )
  5060. {
  5061. pCur.skipNext = 0;
  5062. pRes = 0;
  5063. return SQLITE_OK;
  5064. }
  5065. pCur.skipNext = 0;
  5066. pPage = pCur.apPage[pCur.iPage];
  5067. Debug.Assert( pPage.isInit != 0 );
  5068. if ( 0 == pPage.leaf )
  5069. {
  5070. int idx = pCur.aiIdx[pCur.iPage];
  5071. rc = moveToChild( pCur, sqlite3Get4byte( pPage.aData, findCell( pPage, idx ) ) );
  5072. if ( rc != 0 )
  5073. {
  5074. return rc;
  5075. }
  5076. rc = moveToRightmost( pCur );
  5077. }
  5078. else
  5079. {
  5080. while ( pCur.aiIdx[pCur.iPage] == 0 )
  5081. {
  5082. if ( pCur.iPage == 0 )
  5083. {
  5084. pCur.eState = CURSOR_INVALID;
  5085. pRes = 1;
  5086. return SQLITE_OK;
  5087. }
  5088. moveToParent( pCur );
  5089. }
  5090. pCur.info.nSize = 0;
  5091. pCur.validNKey = false;
  5092. pCur.aiIdx[pCur.iPage]--;
  5093. pPage = pCur.apPage[pCur.iPage];
  5094. if ( pPage.intKey != 0 && 0 == pPage.leaf )
  5095. {
  5096. rc = sqlite3BtreePrevious( pCur, ref pRes );
  5097. }
  5098. else
  5099. {
  5100. rc = SQLITE_OK;
  5101. }
  5102. }
  5103. pRes = 0;
  5104. return rc;
  5105. }
  5106. /*
  5107. ** Allocate a new page from the database file.
  5108. **
  5109. ** The new page is marked as dirty. (In other words, sqlite3PagerWrite()
  5110. ** has already been called on the new page.) The new page has also
  5111. ** been referenced and the calling routine is responsible for calling
  5112. ** sqlite3PagerUnref() on the new page when it is done.
  5113. **
  5114. ** SQLITE_OK is returned on success. Any other return value indicates
  5115. ** an error. ppPage and pPgno are undefined in the event of an error.
  5116. ** Do not invoke sqlite3PagerUnref() on ppPage if an error is returned.
  5117. **
  5118. ** If the "nearby" parameter is not 0, then a (feeble) effort is made to
  5119. ** locate a page close to the page number "nearby". This can be used in an
  5120. ** attempt to keep related pages close to each other in the database file,
  5121. ** which in turn can make database access faster.
  5122. **
  5123. ** If the "exact" parameter is not 0, and the page-number nearby exists
  5124. ** anywhere on the free-list, then it is guarenteed to be returned. This
  5125. ** is only used by auto-vacuum databases when allocating a new table.
  5126. */
  5127. static int allocateBtreePage(
  5128. BtShared pBt,
  5129. ref MemPage ppPage,
  5130. ref Pgno pPgno,
  5131. Pgno nearby,
  5132. u8 exact
  5133. )
  5134. {
  5135. MemPage pPage1;
  5136. int rc;
  5137. u32 n; /* Number of pages on the freelist */
  5138. u32 k; /* Number of leaves on the trunk of the freelist */
  5139. MemPage pTrunk = null;
  5140. MemPage pPrevTrunk = null;
  5141. Pgno mxPage; /* Total size of the database file */
  5142. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  5143. pPage1 = pBt.pPage1;
  5144. mxPage = btreePagecount( pBt );
  5145. n = sqlite3Get4byte( pPage1.aData, 36 );
  5146. testcase( n == mxPage - 1 );
  5147. if ( n >= mxPage )
  5148. {
  5149. return SQLITE_CORRUPT_BKPT();
  5150. }
  5151. if ( n > 0 )
  5152. {
  5153. /* There are pages on the freelist. Reuse one of those pages. */
  5154. Pgno iTrunk;
  5155. u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
  5156. /* If the 'exact' parameter was true and a query of the pointer-map
  5157. ** shows that the page 'nearby' is somewhere on the free-list, then
  5158. ** the entire-list will be searched for that page.
  5159. */
  5160. #if !SQLITE_OMIT_AUTOVACUUM
  5161. if ( exact != 0 && nearby <= mxPage )
  5162. {
  5163. u8 eType = 0;
  5164. Debug.Assert( nearby > 0 );
  5165. Debug.Assert( pBt.autoVacuum );
  5166. u32 Dummy0 = 0;
  5167. rc = ptrmapGet( pBt, nearby, ref eType, ref Dummy0 );
  5168. if ( rc != 0 )
  5169. return rc;
  5170. if ( eType == PTRMAP_FREEPAGE )
  5171. {
  5172. searchList = 1;
  5173. }
  5174. pPgno = nearby;
  5175. }
  5176. #endif
  5177. /* Decrement the free-list count by 1. Set iTrunk to the index of the
  5178. ** first free-list trunk page. iPrevTrunk is initially 1.
  5179. */
  5180. rc = sqlite3PagerWrite( pPage1.pDbPage );
  5181. if ( rc != 0 )
  5182. return rc;
  5183. sqlite3Put4byte( pPage1.aData, (u32)36, n - 1 );
  5184. /* The code within this loop is run only once if the 'searchList' variable
  5185. ** is not true. Otherwise, it runs once for each trunk-page on the
  5186. ** free-list until the page 'nearby' is located.
  5187. */
  5188. do
  5189. {
  5190. pPrevTrunk = pTrunk;
  5191. if ( pPrevTrunk != null )
  5192. {
  5193. iTrunk = sqlite3Get4byte( pPrevTrunk.aData, 0 );
  5194. }
  5195. else
  5196. {
  5197. iTrunk = sqlite3Get4byte( pPage1.aData, 32 );
  5198. }
  5199. testcase( iTrunk == mxPage );
  5200. if ( iTrunk > mxPage )
  5201. {
  5202. rc = SQLITE_CORRUPT_BKPT();
  5203. }
  5204. else
  5205. {
  5206. rc = btreeGetPage( pBt, iTrunk, ref pTrunk, 0 );
  5207. }
  5208. if ( rc != 0 )
  5209. {
  5210. pTrunk = null;
  5211. goto end_allocate_page;
  5212. }
  5213. k = sqlite3Get4byte( pTrunk.aData, 4 ); /* # of leaves on this trunk page */
  5214. if ( k == 0 && 0 == searchList )
  5215. {
  5216. /* The trunk has no leaves and the list is not being searched.
  5217. ** So extract the trunk page itself and use it as the newly
  5218. ** allocated page */
  5219. Debug.Assert( pPrevTrunk == null );
  5220. rc = sqlite3PagerWrite( pTrunk.pDbPage );
  5221. if ( rc != 0 )
  5222. {
  5223. goto end_allocate_page;
  5224. }
  5225. pPgno = iTrunk;
  5226. Buffer.BlockCopy( pTrunk.aData, 0, pPage1.aData, 32, 4 );//memcpy( pPage1.aData[32], ref pTrunk.aData[0], 4 );
  5227. ppPage = pTrunk;
  5228. pTrunk = null;
  5229. TRACE( "ALLOCATE: %d trunk - %d free pages left\n", pPgno, n - 1 );
  5230. }
  5231. else if ( k > (u32)( pBt.usableSize / 4 - 2 ) )
  5232. {
  5233. /* Value of k is out of range. Database corruption */
  5234. rc = SQLITE_CORRUPT_BKPT();
  5235. goto end_allocate_page;
  5236. #if !SQLITE_OMIT_AUTOVACUUM
  5237. }
  5238. else if ( searchList != 0 && nearby == iTrunk )
  5239. {
  5240. /* The list is being searched and this trunk page is the page
  5241. ** to allocate, regardless of whether it has leaves.
  5242. */
  5243. Debug.Assert( pPgno == iTrunk );
  5244. ppPage = pTrunk;
  5245. searchList = 0;
  5246. rc = sqlite3PagerWrite( pTrunk.pDbPage );
  5247. if ( rc != 0 )
  5248. {
  5249. goto end_allocate_page;
  5250. }
  5251. if ( k == 0 )
  5252. {
  5253. if ( null == pPrevTrunk )
  5254. {
  5255. //memcpy(pPage1.aData[32], pTrunk.aData[0], 4);
  5256. pPage1.aData[32 + 0] = pTrunk.aData[0 + 0];
  5257. pPage1.aData[32 + 1] = pTrunk.aData[0 + 1];
  5258. pPage1.aData[32 + 2] = pTrunk.aData[0 + 2];
  5259. pPage1.aData[32 + 3] = pTrunk.aData[0 + 3];
  5260. }
  5261. else
  5262. {
  5263. rc = sqlite3PagerWrite( pPrevTrunk.pDbPage );
  5264. if ( rc != SQLITE_OK )
  5265. {
  5266. goto end_allocate_page;
  5267. }
  5268. //memcpy(pPrevTrunk.aData[0], pTrunk.aData[0], 4);
  5269. pPrevTrunk.aData[0 + 0] = pTrunk.aData[0 + 0];
  5270. pPrevTrunk.aData[0 + 1] = pTrunk.aData[0 + 1];
  5271. pPrevTrunk.aData[0 + 2] = pTrunk.aData[0 + 2];
  5272. pPrevTrunk.aData[0 + 3] = pTrunk.aData[0 + 3];
  5273. }
  5274. }
  5275. else
  5276. {
  5277. /* The trunk page is required by the caller but it contains
  5278. ** pointers to free-list leaves. The first leaf becomes a trunk
  5279. ** page in this case.
  5280. */
  5281. MemPage pNewTrunk = new MemPage();
  5282. Pgno iNewTrunk = sqlite3Get4byte( pTrunk.aData, 8 );
  5283. if ( iNewTrunk > mxPage )
  5284. {
  5285. rc = SQLITE_CORRUPT_BKPT();
  5286. goto end_allocate_page;
  5287. }
  5288. testcase( iNewTrunk == mxPage );
  5289. rc = btreeGetPage( pBt, iNewTrunk, ref pNewTrunk, 0 );
  5290. if ( rc != SQLITE_OK )
  5291. {
  5292. goto end_allocate_page;
  5293. }
  5294. rc = sqlite3PagerWrite( pNewTrunk.pDbPage );
  5295. if ( rc != SQLITE_OK )
  5296. {
  5297. releasePage( pNewTrunk );
  5298. goto end_allocate_page;
  5299. }
  5300. //memcpy(pNewTrunk.aData[0], pTrunk.aData[0], 4);
  5301. pNewTrunk.aData[0 + 0] = pTrunk.aData[0 + 0];
  5302. pNewTrunk.aData[0 + 1] = pTrunk.aData[0 + 1];
  5303. pNewTrunk.aData[0 + 2] = pTrunk.aData[0 + 2];
  5304. pNewTrunk.aData[0 + 3] = pTrunk.aData[0 + 3];
  5305. sqlite3Put4byte( pNewTrunk.aData, (u32)4, (u32)( k - 1 ) );
  5306. Buffer.BlockCopy( pTrunk.aData, 12, pNewTrunk.aData, 8, (int)( k - 1 ) * 4 );//memcpy( pNewTrunk.aData[8], ref pTrunk.aData[12], ( k - 1 ) * 4 );
  5307. releasePage( pNewTrunk );
  5308. if ( null == pPrevTrunk )
  5309. {
  5310. Debug.Assert( sqlite3PagerIswriteable( pPage1.pDbPage ) );
  5311. sqlite3Put4byte( pPage1.aData, (u32)32, iNewTrunk );
  5312. }
  5313. else
  5314. {
  5315. rc = sqlite3PagerWrite( pPrevTrunk.pDbPage );
  5316. if ( rc != 0 )
  5317. {
  5318. goto end_allocate_page;
  5319. }
  5320. sqlite3Put4byte( pPrevTrunk.aData, (u32)0, iNewTrunk );
  5321. }
  5322. }
  5323. pTrunk = null;
  5324. TRACE( "ALLOCATE: %d trunk - %d free pages left\n", pPgno, n - 1 );
  5325. #endif
  5326. }
  5327. else if ( k > 0 )
  5328. {
  5329. /* Extract a leaf from the trunk */
  5330. u32 closest;
  5331. Pgno iPage;
  5332. byte[] aData = pTrunk.aData;
  5333. if ( nearby > 0 )
  5334. {
  5335. u32 i;
  5336. int dist;
  5337. closest = 0;
  5338. dist = sqlite3AbsInt32( (int)(sqlite3Get4byte( aData, 8 ) - nearby ));
  5339. for ( i = 1; i < k; i++ )
  5340. {
  5341. int d2 = sqlite3AbsInt32( (int)(sqlite3Get4byte( aData, 8 + i * 4 ) - nearby ));
  5342. if ( d2 < dist )
  5343. {
  5344. closest = i;
  5345. dist = d2;
  5346. }
  5347. }
  5348. }
  5349. else
  5350. {
  5351. closest = 0;
  5352. }
  5353. iPage = sqlite3Get4byte( aData, 8 + closest * 4 );
  5354. testcase( iPage == mxPage );
  5355. if ( iPage > mxPage )
  5356. {
  5357. rc = SQLITE_CORRUPT_BKPT();
  5358. goto end_allocate_page;
  5359. }
  5360. testcase( iPage == mxPage );
  5361. if ( 0 == searchList || iPage == nearby )
  5362. {
  5363. int noContent;
  5364. pPgno = iPage;
  5365. TRACE( "ALLOCATE: %d was leaf %d of %d on trunk %d" +
  5366. ": %d more free pages\n",
  5367. pPgno, closest + 1, k, pTrunk.pgno, n - 1 );
  5368. rc = sqlite3PagerWrite( pTrunk.pDbPage );
  5369. if ( rc != 0)
  5370. goto end_allocate_page;
  5371. if ( closest < k - 1 )
  5372. {
  5373. Buffer.BlockCopy( aData, (int)( 4 + k * 4 ), aData, 8 + (int)closest * 4, 4 );//memcpy( aData[8 + closest * 4], ref aData[4 + k * 4], 4 );
  5374. }
  5375. sqlite3Put4byte( aData, (u32)4, ( k - 1 ) );// sqlite3Put4byte( aData, 4, k - 1 );
  5376. noContent = !btreeGetHasContent( pBt, pPgno ) ? 1 : 0;
  5377. rc = btreeGetPage( pBt, pPgno, ref ppPage, noContent );
  5378. if ( rc == SQLITE_OK )
  5379. {
  5380. rc = sqlite3PagerWrite( ( ppPage ).pDbPage );
  5381. if ( rc != SQLITE_OK )
  5382. {
  5383. releasePage( ppPage );
  5384. }
  5385. }
  5386. searchList = 0;
  5387. }
  5388. }
  5389. releasePage( pPrevTrunk );
  5390. pPrevTrunk = null;
  5391. } while ( searchList != 0 );
  5392. }
  5393. else
  5394. {
  5395. /* There are no pages on the freelist, so create a new page at the
  5396. ** end of the file */
  5397. rc = sqlite3PagerWrite( pBt.pPage1.pDbPage );
  5398. if ( rc != 0 )
  5399. return rc;
  5400. pBt.nPage++;
  5401. if ( pBt.nPage == PENDING_BYTE_PAGE( pBt ) )
  5402. pBt.nPage++;
  5403. #if !SQLITE_OMIT_AUTOVACUUM
  5404. if ( pBt.autoVacuum && PTRMAP_ISPAGE( pBt, pBt.nPage ) )
  5405. {
  5406. /* If pPgno refers to a pointer-map page, allocate two new pages
  5407. ** at the end of the file instead of one. The first allocated page
  5408. ** becomes a new pointer-map page, the second is used by the caller.
  5409. */
  5410. MemPage pPg = null;
  5411. TRACE( "ALLOCATE: %d from end of file (pointer-map page)\n", pPgno );
  5412. Debug.Assert( pBt.nPage != PENDING_BYTE_PAGE( pBt ) );
  5413. rc = btreeGetPage( pBt, pBt.nPage, ref pPg, 1 );
  5414. if ( rc == SQLITE_OK )
  5415. {
  5416. rc = sqlite3PagerWrite( pPg.pDbPage );
  5417. releasePage( pPg );
  5418. }
  5419. if ( rc != 0 )
  5420. return rc;
  5421. pBt.nPage++;
  5422. if ( pBt.nPage == PENDING_BYTE_PAGE( pBt ) )
  5423. {
  5424. pBt.nPage++;
  5425. }
  5426. }
  5427. #endif
  5428. sqlite3Put4byte( pBt.pPage1.aData, (u32)28, pBt.nPage );
  5429. pPgno = pBt.nPage;
  5430. Debug.Assert( pPgno != PENDING_BYTE_PAGE( pBt ) );
  5431. rc = btreeGetPage( pBt, pPgno, ref ppPage, 1 );
  5432. if ( rc != 0 )
  5433. return rc;
  5434. rc = sqlite3PagerWrite( ( ppPage ).pDbPage );
  5435. if ( rc != SQLITE_OK )
  5436. {
  5437. releasePage( ppPage );
  5438. }
  5439. TRACE( "ALLOCATE: %d from end of file\n", pPgno );
  5440. }
  5441. Debug.Assert( pPgno != PENDING_BYTE_PAGE( pBt ) );
  5442. end_allocate_page:
  5443. releasePage( pTrunk );
  5444. releasePage( pPrevTrunk );
  5445. if ( rc == SQLITE_OK )
  5446. {
  5447. if ( sqlite3PagerPageRefcount( ( ppPage ).pDbPage ) > 1 )
  5448. {
  5449. releasePage( ppPage );
  5450. return SQLITE_CORRUPT_BKPT();
  5451. }
  5452. ( ppPage ).isInit = 0;
  5453. }
  5454. else
  5455. {
  5456. ppPage = null;
  5457. }
  5458. Debug.Assert( rc != SQLITE_OK || sqlite3PagerIswriteable( ( ppPage ).pDbPage ) );
  5459. return rc;
  5460. }
  5461. /*
  5462. ** This function is used to add page iPage to the database file free-list.
  5463. ** It is assumed that the page is not already a part of the free-list.
  5464. **
  5465. ** The value passed as the second argument to this function is optional.
  5466. ** If the caller happens to have a pointer to the MemPage object
  5467. ** corresponding to page iPage handy, it may pass it as the second value.
  5468. ** Otherwise, it may pass NULL.
  5469. **
  5470. ** If a pointer to a MemPage object is passed as the second argument,
  5471. ** its reference count is not altered by this function.
  5472. */
  5473. static int freePage2( BtShared pBt, MemPage pMemPage, Pgno iPage )
  5474. {
  5475. MemPage pTrunk = null; /* Free-list trunk page */
  5476. Pgno iTrunk = 0; /* Page number of free-list trunk page */
  5477. MemPage pPage1 = pBt.pPage1; /* Local reference to page 1 */
  5478. MemPage pPage; /* Page being freed. May be NULL. */
  5479. int rc; /* Return Code */
  5480. int nFree; /* Initial number of pages on free-list */
  5481. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  5482. Debug.Assert( iPage > 1 );
  5483. Debug.Assert( null == pMemPage || pMemPage.pgno == iPage );
  5484. if ( pMemPage != null )
  5485. {
  5486. pPage = pMemPage;
  5487. sqlite3PagerRef( pPage.pDbPage );
  5488. }
  5489. else
  5490. {
  5491. pPage = btreePageLookup( pBt, iPage );
  5492. }
  5493. /* Increment the free page count on pPage1 */
  5494. rc = sqlite3PagerWrite( pPage1.pDbPage );
  5495. if ( rc != 0 )
  5496. goto freepage_out;
  5497. nFree = (int)sqlite3Get4byte( pPage1.aData, 36 );
  5498. sqlite3Put4byte( pPage1.aData, 36, nFree + 1 );
  5499. if ( pBt.secureDelete )
  5500. {
  5501. /* If the secure_delete option is enabled, then
  5502. ** always fully overwrite deleted information with zeros.
  5503. */
  5504. if ( ( null == pPage && ( ( rc = btreeGetPage( pBt, iPage, ref pPage, 0 ) ) != 0 ) )
  5505. || ( ( rc = sqlite3PagerWrite( pPage.pDbPage ) ) != 0 )
  5506. )
  5507. {
  5508. goto freepage_out;
  5509. }
  5510. Array.Clear( pPage.aData, 0, (int)pPage.pBt.pageSize );//memset(pPage->aData, 0, pPage->pBt->pageSize);
  5511. }
  5512. /* If the database supports auto-vacuum, write an entry in the pointer-map
  5513. ** to indicate that the page is free.
  5514. */
  5515. #if !SQLITE_OMIT_AUTOVACUUM // if ( ISAUTOVACUUM )
  5516. if ( pBt.autoVacuum )
  5517. #else
  5518. if (false)
  5519. #endif
  5520. {
  5521. ptrmapPut( pBt, iPage, PTRMAP_FREEPAGE, 0, ref rc );
  5522. if ( rc != 0 )
  5523. goto freepage_out;
  5524. }
  5525. /* Now manipulate the actual database free-list structure. There are two
  5526. ** possibilities. If the free-list is currently empty, or if the first
  5527. ** trunk page in the free-list is full, then this page will become a
  5528. ** new free-list trunk page. Otherwise, it will become a leaf of the
  5529. ** first trunk page in the current free-list. This block tests if it
  5530. ** is possible to add the page as a new free-list leaf.
  5531. */
  5532. if ( nFree != 0 )
  5533. {
  5534. u32 nLeaf; /* Initial number of leaf cells on trunk page */
  5535. iTrunk = sqlite3Get4byte( pPage1.aData, 32 );
  5536. rc = btreeGetPage( pBt, iTrunk, ref pTrunk, 0 );
  5537. if ( rc != SQLITE_OK )
  5538. {
  5539. goto freepage_out;
  5540. }
  5541. nLeaf = sqlite3Get4byte( pTrunk.aData, 4 );
  5542. Debug.Assert( pBt.usableSize > 32 );
  5543. if ( nLeaf > (u32)pBt.usableSize / 4 - 2 )
  5544. {
  5545. rc = SQLITE_CORRUPT_BKPT();
  5546. goto freepage_out;
  5547. }
  5548. if ( nLeaf < (u32)pBt.usableSize / 4 - 8 )
  5549. {
  5550. /* In this case there is room on the trunk page to insert the page
  5551. ** being freed as a new leaf.
  5552. **
  5553. ** Note that the trunk page is not really full until it contains
  5554. ** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have
  5555. ** coded. But due to a coding error in versions of SQLite prior to
  5556. ** 3.6.0, databases with freelist trunk pages holding more than
  5557. ** usableSize/4 - 8 entries will be reported as corrupt. In order
  5558. ** to maintain backwards compatibility with older versions of SQLite,
  5559. ** we will continue to restrict the number of entries to usableSize/4 - 8
  5560. ** for now. At some point in the future (once everyone has upgraded
  5561. ** to 3.6.0 or later) we should consider fixing the conditional above
  5562. ** to read "usableSize/4-2" instead of "usableSize/4-8".
  5563. */
  5564. rc = sqlite3PagerWrite( pTrunk.pDbPage );
  5565. if ( rc == SQLITE_OK )
  5566. {
  5567. sqlite3Put4byte( pTrunk.aData, (u32)4, nLeaf + 1 );
  5568. sqlite3Put4byte( pTrunk.aData, (u32)8 + nLeaf * 4, iPage );
  5569. if ( pPage != null && !pBt.secureDelete )
  5570. {
  5571. sqlite3PagerDontWrite( pPage.pDbPage );
  5572. }
  5573. rc = btreeSetHasContent( pBt, iPage );
  5574. }
  5575. TRACE( "FREE-PAGE: %d leaf on trunk page %d\n", iPage, pTrunk.pgno );
  5576. goto freepage_out;
  5577. }
  5578. }
  5579. /* If control flows to this point, then it was not possible to add the
  5580. ** the page being freed as a leaf page of the first trunk in the free-list.
  5581. ** Possibly because the free-list is empty, or possibly because the
  5582. ** first trunk in the free-list is full. Either way, the page being freed
  5583. ** will become the new first trunk page in the free-list.
  5584. */
  5585. if ( pPage == null && SQLITE_OK != ( rc = btreeGetPage( pBt, iPage, ref pPage, 0 ) ) )
  5586. {
  5587. goto freepage_out;
  5588. }
  5589. rc = sqlite3PagerWrite( pPage.pDbPage );
  5590. if ( rc != SQLITE_OK )
  5591. {
  5592. goto freepage_out;
  5593. }
  5594. sqlite3Put4byte( pPage.aData, iTrunk );
  5595. sqlite3Put4byte( pPage.aData, 4, 0 );
  5596. sqlite3Put4byte( pPage1.aData, (u32)32, iPage );
  5597. TRACE( "FREE-PAGE: %d new trunk page replacing %d\n", pPage.pgno, iTrunk );
  5598. freepage_out:
  5599. if ( pPage != null )
  5600. {
  5601. pPage.isInit = 0;
  5602. }
  5603. releasePage( pPage );
  5604. releasePage( pTrunk );
  5605. return rc;
  5606. }
  5607. static void freePage( MemPage pPage, ref int pRC )
  5608. {
  5609. if ( ( pRC ) == SQLITE_OK )
  5610. {
  5611. pRC = freePage2( pPage.pBt, pPage, pPage.pgno );
  5612. }
  5613. }
  5614. /*
  5615. ** Free any overflow pages associated with the given Cell.
  5616. */
  5617. static int clearCell( MemPage pPage, int pCell )
  5618. {
  5619. BtShared pBt = pPage.pBt;
  5620. CellInfo info = new CellInfo();
  5621. Pgno ovflPgno;
  5622. int rc;
  5623. int nOvfl;
  5624. u32 ovflPageSize;
  5625. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  5626. btreeParseCellPtr( pPage, pCell, ref info );
  5627. if ( info.iOverflow == 0 )
  5628. {
  5629. return SQLITE_OK; /* No overflow pages. Return without doing anything */
  5630. }
  5631. ovflPgno = sqlite3Get4byte( pPage.aData, pCell, info.iOverflow );
  5632. Debug.Assert( pBt.usableSize > 4 );
  5633. ovflPageSize = (u16)( pBt.usableSize - 4 );
  5634. nOvfl = (int)( ( info.nPayload - info.nLocal + ovflPageSize - 1 ) / ovflPageSize );
  5635. Debug.Assert( ovflPgno == 0 || nOvfl > 0 );
  5636. while ( nOvfl-- != 0 )
  5637. {
  5638. Pgno iNext = 0;
  5639. MemPage pOvfl = null;
  5640. if ( ovflPgno < 2 || ovflPgno > btreePagecount( pBt ) )
  5641. {
  5642. /* 0 is not a legal page number and page 1 cannot be an
  5643. ** overflow page. Therefore if ovflPgno<2 or past the end of the
  5644. ** file the database must be corrupt. */
  5645. return SQLITE_CORRUPT_BKPT();
  5646. }
  5647. if ( nOvfl != 0 )
  5648. {
  5649. rc = getOverflowPage( pBt, ovflPgno, out pOvfl, out iNext );
  5650. if ( rc != 0 )
  5651. return rc;
  5652. }
  5653. if ( ( pOvfl != null || ( ( pOvfl = btreePageLookup( pBt, ovflPgno ) ) != null ) )
  5654. && sqlite3PagerPageRefcount( pOvfl.pDbPage ) != 1
  5655. )
  5656. {
  5657. /* There is no reason any cursor should have an outstanding reference
  5658. ** to an overflow page belonging to a cell that is being deleted/updated.
  5659. ** So if there exists more than one reference to this page, then it
  5660. ** must not really be an overflow page and the database must be corrupt.
  5661. ** It is helpful to detect this before calling freePage2(), as
  5662. ** freePage2() may zero the page contents if secure-delete mode is
  5663. ** enabled. If this 'overflow' page happens to be a page that the
  5664. ** caller is iterating through or using in some other way, this
  5665. ** can be problematic.
  5666. */
  5667. rc = SQLITE_CORRUPT_BKPT();
  5668. }
  5669. else
  5670. {
  5671. rc = freePage2( pBt, pOvfl, ovflPgno );
  5672. }
  5673. if ( pOvfl != null )
  5674. {
  5675. sqlite3PagerUnref( pOvfl.pDbPage );
  5676. }
  5677. if ( rc != 0 )
  5678. return rc;
  5679. ovflPgno = iNext;
  5680. }
  5681. return SQLITE_OK;
  5682. }
  5683. /*
  5684. ** Create the byte sequence used to represent a cell on page pPage
  5685. ** and write that byte sequence into pCell[]. Overflow pages are
  5686. ** allocated and filled in as necessary. The calling procedure
  5687. ** is responsible for making sure sufficient space has been allocated
  5688. ** for pCell[].
  5689. **
  5690. ** Note that pCell does not necessary need to point to the pPage.aData
  5691. ** area. pCell might point to some temporary storage. The cell will
  5692. ** be constructed in this temporary area then copied into pPage.aData
  5693. ** later.
  5694. */
  5695. static int fillInCell(
  5696. MemPage pPage, /* The page that contains the cell */
  5697. byte[] pCell, /* Complete text of the cell */
  5698. byte[] pKey, i64 nKey, /* The key */
  5699. byte[] pData, int nData, /* The data */
  5700. int nZero, /* Extra zero bytes to append to pData */
  5701. ref int pnSize /* Write cell size here */
  5702. )
  5703. {
  5704. int nPayload;
  5705. u8[] pSrc;
  5706. int pSrcIndex = 0;
  5707. int nSrc, n, rc;
  5708. int spaceLeft;
  5709. MemPage pOvfl = null;
  5710. MemPage pToRelease = null;
  5711. byte[] pPrior;
  5712. int pPriorIndex = 0;
  5713. byte[] pPayload;
  5714. int pPayloadIndex = 0;
  5715. BtShared pBt = pPage.pBt;
  5716. Pgno pgnoOvfl = 0;
  5717. int nHeader;
  5718. CellInfo info = new CellInfo();
  5719. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  5720. /* pPage is not necessarily writeable since pCell might be auxiliary
  5721. ** buffer space that is separate from the pPage buffer area */
  5722. // TODO -- Determine if the following Assert is needed under c#
  5723. //Debug.Assert( pCell < pPage.aData || pCell >= &pPage.aData[pBt.pageSize]
  5724. // || sqlite3PagerIswriteable(pPage.pDbPage) );
  5725. /* Fill in the header. */
  5726. nHeader = 0;
  5727. if ( 0 == pPage.leaf )
  5728. {
  5729. nHeader += 4;
  5730. }
  5731. if ( pPage.hasData != 0 )
  5732. {
  5733. nHeader += (int)putVarint( pCell, nHeader, (int)( nData + nZero ) ); //putVarint( pCell[nHeader], nData + nZero );
  5734. }
  5735. else
  5736. {
  5737. nData = nZero = 0;
  5738. }
  5739. nHeader += putVarint( pCell, nHeader, (u64)nKey ); //putVarint( pCell[nHeader], *(u64*)&nKey );
  5740. btreeParseCellPtr( pPage, pCell, ref info );
  5741. Debug.Assert( info.nHeader == nHeader );
  5742. Debug.Assert( info.nKey == nKey );
  5743. Debug.Assert( info.nData == (u32)( nData + nZero ) );
  5744. /* Fill in the payload */
  5745. nPayload = nData + nZero;
  5746. if ( pPage.intKey != 0 )
  5747. {
  5748. pSrc = pData;
  5749. nSrc = nData;
  5750. nData = 0;
  5751. }
  5752. else
  5753. {
  5754. if ( NEVER( nKey > 0x7fffffff || pKey == null ) )
  5755. {
  5756. return SQLITE_CORRUPT_BKPT();
  5757. }
  5758. nPayload += (int)nKey;
  5759. pSrc = pKey;
  5760. nSrc = (int)nKey;
  5761. }
  5762. pnSize = info.nSize;
  5763. spaceLeft = info.nLocal;
  5764. // pPayload = &pCell[nHeader];
  5765. pPayload = pCell;
  5766. pPayloadIndex = nHeader;
  5767. // pPrior = &pCell[info.iOverflow];
  5768. pPrior = pCell;
  5769. pPriorIndex = info.iOverflow;
  5770. while ( nPayload > 0 )
  5771. {
  5772. if ( spaceLeft == 0 )
  5773. {
  5774. #if !SQLITE_OMIT_AUTOVACUUM
  5775. Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
  5776. if ( pBt.autoVacuum )
  5777. {
  5778. do
  5779. {
  5780. pgnoOvfl++;
  5781. } while (
  5782. PTRMAP_ISPAGE( pBt, pgnoOvfl ) || pgnoOvfl == PENDING_BYTE_PAGE( pBt )
  5783. );
  5784. }
  5785. #endif
  5786. rc = allocateBtreePage( pBt, ref pOvfl, ref pgnoOvfl, pgnoOvfl, 0 );
  5787. #if !SQLITE_OMIT_AUTOVACUUM
  5788. /* If the database supports auto-vacuum, and the second or subsequent
  5789. ** overflow page is being allocated, add an entry to the pointer-map
  5790. ** for that page now.
  5791. **
  5792. ** If this is the first overflow page, then write a partial entry
  5793. ** to the pointer-map. If we write nothing to this pointer-map slot,
  5794. ** then the optimistic overflow chain processing in clearCell()
  5795. ** may misinterpret the uninitialised values and delete the
  5796. ** wrong pages from the database.
  5797. */
  5798. if ( pBt.autoVacuum && rc == SQLITE_OK )
  5799. {
  5800. u8 eType = (u8)( pgnoPtrmap != 0 ? PTRMAP_OVERFLOW2 : PTRMAP_OVERFLOW1 );
  5801. ptrmapPut( pBt, pgnoOvfl, eType, pgnoPtrmap, ref rc );
  5802. if ( rc != 0 )
  5803. {
  5804. releasePage( pOvfl );
  5805. }
  5806. }
  5807. #endif
  5808. if ( rc != 0 )
  5809. {
  5810. releasePage( pToRelease );
  5811. return rc;
  5812. }
  5813. /* If pToRelease is not zero than pPrior points into the data area
  5814. ** of pToRelease. Make sure pToRelease is still writeable. */
  5815. Debug.Assert( pToRelease == null || sqlite3PagerIswriteable( pToRelease.pDbPage ) );
  5816. /* If pPrior is part of the data area of pPage, then make sure pPage
  5817. ** is still writeable */
  5818. // TODO -- Determine if the following Assert is needed under c#
  5819. //Debug.Assert( pPrior < pPage.aData || pPrior >= &pPage.aData[pBt.pageSize]
  5820. // || sqlite3PagerIswriteable(pPage.pDbPage) );
  5821. sqlite3Put4byte( pPrior, pPriorIndex, pgnoOvfl );
  5822. releasePage( pToRelease );
  5823. pToRelease = pOvfl;
  5824. pPrior = pOvfl.aData;
  5825. pPriorIndex = 0;
  5826. sqlite3Put4byte( pPrior, 0 );
  5827. pPayload = pOvfl.aData;
  5828. pPayloadIndex = 4; //&pOvfl.aData[4];
  5829. spaceLeft = (int)pBt.usableSize - 4;
  5830. }
  5831. n = nPayload;
  5832. if ( n > spaceLeft )
  5833. n = spaceLeft;
  5834. /* If pToRelease is not zero than pPayload points into the data area
  5835. ** of pToRelease. Make sure pToRelease is still writeable. */
  5836. Debug.Assert( pToRelease == null || sqlite3PagerIswriteable( pToRelease.pDbPage ) );
  5837. /* If pPayload is part of the data area of pPage, then make sure pPage
  5838. ** is still writeable */
  5839. // TODO -- Determine if the following Assert is needed under c#
  5840. //Debug.Assert( pPayload < pPage.aData || pPayload >= &pPage.aData[pBt.pageSize]
  5841. // || sqlite3PagerIswriteable(pPage.pDbPage) );
  5842. if ( nSrc > 0 )
  5843. {
  5844. if ( n > nSrc )
  5845. n = nSrc;
  5846. Debug.Assert( pSrc != null );
  5847. Buffer.BlockCopy( pSrc, pSrcIndex, pPayload, pPayloadIndex, n );//memcpy(pPayload, pSrc, n);
  5848. }
  5849. else
  5850. {
  5851. byte[] pZeroBlob = sqlite3Malloc( n ); // memset(pPayload, 0, n);
  5852. Buffer.BlockCopy( pZeroBlob, 0, pPayload, pPayloadIndex, n );
  5853. }
  5854. nPayload -= n;
  5855. pPayloadIndex += n;// pPayload += n;
  5856. pSrcIndex += n;// pSrc += n;
  5857. nSrc -= n;
  5858. spaceLeft -= n;
  5859. if ( nSrc == 0 )
  5860. {
  5861. nSrc = nData;
  5862. pSrc = pData;
  5863. }
  5864. }
  5865. releasePage( pToRelease );
  5866. return SQLITE_OK;
  5867. }
  5868. /*
  5869. ** Remove the i-th cell from pPage. This routine effects pPage only.
  5870. ** The cell content is not freed or deallocated. It is assumed that
  5871. ** the cell content has been copied someplace else. This routine just
  5872. ** removes the reference to the cell from pPage.
  5873. **
  5874. ** "sz" must be the number of bytes in the cell.
  5875. */
  5876. static void dropCell( MemPage pPage, int idx, int sz, ref int pRC )
  5877. {
  5878. u32 pc; /* Offset to cell content of cell being deleted */
  5879. u8[] data; /* pPage.aData */
  5880. int ptr; /* Used to move bytes around within data[] */
  5881. int endPtr; /* End of loop */
  5882. int rc; /* The return code */
  5883. int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */
  5884. if ( pRC != 0 )
  5885. return;
  5886. Debug.Assert( idx >= 0 && idx < pPage.nCell );
  5887. #if SQLITE_DEBUG
  5888. Debug.Assert( sz == cellSize( pPage, idx ) );
  5889. #endif
  5890. Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
  5891. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  5892. data = pPage.aData;
  5893. ptr = pPage.cellOffset + 2 * idx; //ptr = &data[pPage.cellOffset + 2 * idx];
  5894. pc = (u32)get2byte( data, ptr );
  5895. hdr = pPage.hdrOffset;
  5896. testcase( pc == get2byte( data, hdr + 5 ) );
  5897. testcase( pc + sz == pPage.pBt.usableSize );
  5898. if ( pc < (u32)get2byte( data, hdr + 5 ) || pc + sz > pPage.pBt.usableSize )
  5899. {
  5900. pRC = SQLITE_CORRUPT_BKPT();
  5901. return;
  5902. }
  5903. rc = freeSpace( pPage, pc, sz );
  5904. if ( rc != 0 )
  5905. {
  5906. pRC = rc;
  5907. return;
  5908. }
  5909. //endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2];
  5910. //assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */
  5911. //while( ptr<endPtr ){
  5912. // *(u16*)ptr = *(u16*)&ptr[2];
  5913. // ptr += 2;
  5914. Buffer.BlockCopy( data, ptr + 2, data, ptr, ( pPage.nCell - 1 - idx ) * 2 );
  5915. pPage.nCell--;
  5916. data[pPage.hdrOffset + 3] = (byte)( pPage.nCell >> 8 );
  5917. data[pPage.hdrOffset + 4] = (byte)( pPage.nCell ); //put2byte( data, hdr + 3, pPage.nCell );
  5918. pPage.nFree += 2;
  5919. }
  5920. /*
  5921. ** Insert a new cell on pPage at cell index "i". pCell points to the
  5922. ** content of the cell.
  5923. **
  5924. ** If the cell content will fit on the page, then put it there. If it
  5925. ** will not fit, then make a copy of the cell content into pTemp if
  5926. ** pTemp is not null. Regardless of pTemp, allocate a new entry
  5927. ** in pPage.aOvfl[] and make it point to the cell content (either
  5928. ** in pTemp or the original pCell) and also record its index.
  5929. ** Allocating a new entry in pPage.aCell[] implies that
  5930. ** pPage.nOverflow is incremented.
  5931. **
  5932. ** If nSkip is non-zero, then do not copy the first nSkip bytes of the
  5933. ** cell. The caller will overwrite them after this function returns. If
  5934. ** nSkip is non-zero, then pCell may not point to an invalid memory location
  5935. ** (but pCell+nSkip is always valid).
  5936. */
  5937. static void insertCell(
  5938. MemPage pPage, /* Page into which we are copying */
  5939. int i, /* New cell becomes the i-th cell of the page */
  5940. u8[] pCell, /* Content of the new cell */
  5941. int sz, /* Bytes of content in pCell */
  5942. u8[] pTemp, /* Temp storage space for pCell, if needed */
  5943. Pgno iChild, /* If non-zero, replace first 4 bytes with this value */
  5944. ref int pRC /* Read and write return code from here */
  5945. )
  5946. {
  5947. int idx = 0; /* Where to write new cell content in data[] */
  5948. int j; /* Loop counter */
  5949. int end; /* First byte past the last cell pointer in data[] */
  5950. int ins; /* Index in data[] where new cell pointer is inserted */
  5951. int cellOffset; /* Address of first cell pointer in data[] */
  5952. u8[] data; /* The content of the whole page */
  5953. u8 ptr; /* Used for moving information around in data[] */
  5954. u8 endPtr; /* End of the loop */
  5955. int nSkip = ( iChild != 0 ? 4 : 0 );
  5956. if ( pRC != 0 )
  5957. return;
  5958. Debug.Assert( i >= 0 && i <= pPage.nCell + pPage.nOverflow );
  5959. Debug.Assert( pPage.nCell <= MX_CELL( pPage.pBt ) && MX_CELL( pPage.pBt ) <= 10921 );
  5960. Debug.Assert( pPage.nOverflow <= ArraySize( pPage.aOvfl ) );
  5961. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  5962. /* The cell should normally be sized correctly. However, when moving a
  5963. ** malformed cell from a leaf page to an interior page, if the cell size
  5964. ** wanted to be less than 4 but got rounded up to 4 on the leaf, then size
  5965. ** might be less than 8 (leaf-size + pointer) on the interior node. Hence
  5966. ** the term after the || in the following assert(). */
  5967. Debug.Assert( sz == cellSizePtr( pPage, pCell ) || ( sz == 8 && iChild > 0 ) );
  5968. if ( pPage.nOverflow != 0 || sz + 2 > pPage.nFree )
  5969. {
  5970. if ( pTemp != null )
  5971. {
  5972. Buffer.BlockCopy( pCell, nSkip, pTemp, nSkip, sz - nSkip );//memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
  5973. pCell = pTemp;
  5974. }
  5975. if ( iChild != 0 )
  5976. {
  5977. sqlite3Put4byte( pCell, iChild );
  5978. }
  5979. j = pPage.nOverflow++;
  5980. Debug.Assert( j < pPage.aOvfl.Length );//(int)(sizeof(pPage.aOvfl)/sizeof(pPage.aOvfl[0])) );
  5981. pPage.aOvfl[j].pCell = pCell;
  5982. pPage.aOvfl[j].idx = (u16)i;
  5983. }
  5984. else
  5985. {
  5986. int rc = sqlite3PagerWrite( pPage.pDbPage );
  5987. if ( rc != SQLITE_OK )
  5988. {
  5989. pRC = rc;
  5990. return;
  5991. }
  5992. Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
  5993. data = pPage.aData;
  5994. cellOffset = pPage.cellOffset;
  5995. end = cellOffset + 2 * pPage.nCell;
  5996. ins = cellOffset + 2 * i;
  5997. rc = allocateSpace( pPage, sz, ref idx );
  5998. if ( rc != 0 )
  5999. {
  6000. pRC = rc;
  6001. return;
  6002. }
  6003. /* The allocateSpace() routine guarantees the following two properties
  6004. ** if it returns success */
  6005. Debug.Assert( idx >= end + 2 );
  6006. Debug.Assert( idx + sz <= (int)pPage.pBt.usableSize );
  6007. pPage.nCell++;
  6008. pPage.nFree -= (u16)( 2 + sz );
  6009. Buffer.BlockCopy( pCell, nSkip, data, idx + nSkip, sz - nSkip ); //memcpy( data[idx + nSkip], pCell + nSkip, sz - nSkip );
  6010. if ( iChild != 0 )
  6011. {
  6012. sqlite3Put4byte( data, idx, iChild );
  6013. }
  6014. //ptr = &data[end];
  6015. //endPtr = &data[ins];
  6016. //assert( ( SQLITE_PTR_TO_INT( ptr ) & 1 ) == 0 ); /* ptr is always 2-byte aligned */
  6017. //while ( ptr > endPtr )
  6018. //{
  6019. // *(u16*)ptr = *(u16*)&ptr[-2];
  6020. // ptr -= 2;
  6021. //}
  6022. for ( j = end; j > ins; j -= 2 )
  6023. {
  6024. data[j + 0] = data[j - 2];
  6025. data[j + 1] = data[j - 1];
  6026. }
  6027. put2byte( data, ins, idx );
  6028. put2byte( data, pPage.hdrOffset + 3, pPage.nCell );
  6029. #if !SQLITE_OMIT_AUTOVACUUM
  6030. if ( pPage.pBt.autoVacuum )
  6031. {
  6032. /* The cell may contain a pointer to an overflow page. If so, write
  6033. ** the entry for the overflow page into the pointer map.
  6034. */
  6035. ptrmapPutOvflPtr( pPage, pCell, ref pRC );
  6036. }
  6037. #endif
  6038. }
  6039. }
  6040. /*
  6041. ** Add a list of cells to a page. The page should be initially empty.
  6042. ** The cells are guaranteed to fit on the page.
  6043. */
  6044. static void assemblePage(
  6045. MemPage pPage, /* The page to be assemblied */
  6046. int nCell, /* The number of cells to add to this page */
  6047. u8[] apCell, /* Pointer to a single the cell bodies */
  6048. int[] aSize /* Sizes of the cells bodie*/
  6049. )
  6050. {
  6051. int i; /* Loop counter */
  6052. int pCellptr; /* Address of next cell pointer */
  6053. int cellbody; /* Address of next cell body */
  6054. byte[] data = pPage.aData; /* Pointer to data for pPage */
  6055. int hdr = pPage.hdrOffset; /* Offset of header on pPage */
  6056. int nUsable = (int)pPage.pBt.usableSize; /* Usable size of page */
  6057. Debug.Assert( pPage.nOverflow == 0 );
  6058. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  6059. Debug.Assert( nCell >= 0 && nCell <= (int)MX_CELL( pPage.pBt )
  6060. && (int)MX_CELL( pPage.pBt ) <= 10921 );
  6061. Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
  6062. /* Check that the page has just been zeroed by zeroPage() */
  6063. Debug.Assert( pPage.nCell == 0 );
  6064. Debug.Assert( get2byteNotZero( data, hdr + 5 ) == nUsable );
  6065. pCellptr = pPage.cellOffset + nCell * 2; //data[pPage.cellOffset + nCell * 2];
  6066. cellbody = nUsable;
  6067. for ( i = nCell - 1; i >= 0; i-- )
  6068. {
  6069. u16 sz = (u16)aSize[i];
  6070. pCellptr -= 2;
  6071. cellbody -= sz;
  6072. put2byte( data, pCellptr, cellbody );
  6073. Buffer.BlockCopy( apCell, 0, data, cellbody, sz );// memcpy(&data[cellbody], apCell[i], sz);
  6074. }
  6075. put2byte( data, hdr + 3, nCell );
  6076. put2byte( data, hdr + 5, cellbody );
  6077. pPage.nFree -= (u16)( nCell * 2 + nUsable - cellbody );
  6078. pPage.nCell = (u16)nCell;
  6079. }
  6080. static void assemblePage(
  6081. MemPage pPage, /* The page to be assemblied */
  6082. int nCell, /* The number of cells to add to this page */
  6083. u8[][] apCell, /* Pointers to cell bodies */
  6084. u16[] aSize, /* Sizes of the cells */
  6085. int offset /* Offset into the cell bodies, for c# */
  6086. )
  6087. {
  6088. int i; /* Loop counter */
  6089. int pCellptr; /* Address of next cell pointer */
  6090. int cellbody; /* Address of next cell body */
  6091. byte[] data = pPage.aData; /* Pointer to data for pPage */
  6092. int hdr = pPage.hdrOffset; /* Offset of header on pPage */
  6093. int nUsable = (int)pPage.pBt.usableSize; /* Usable size of page */
  6094. Debug.Assert( pPage.nOverflow == 0 );
  6095. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  6096. Debug.Assert( nCell >= 0 && nCell <= MX_CELL( pPage.pBt ) && MX_CELL( pPage.pBt ) <= 5460 );
  6097. Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
  6098. /* Check that the page has just been zeroed by zeroPage() */
  6099. Debug.Assert( pPage.nCell == 0 );
  6100. Debug.Assert( get2byte( data, hdr + 5 ) == nUsable );
  6101. pCellptr = pPage.cellOffset + nCell * 2; //data[pPage.cellOffset + nCell * 2];
  6102. cellbody = nUsable;
  6103. for ( i = nCell - 1; i >= 0; i-- )
  6104. {
  6105. pCellptr -= 2;
  6106. cellbody -= aSize[i + offset];
  6107. put2byte( data, pCellptr, cellbody );
  6108. Buffer.BlockCopy( apCell[offset + i], 0, data, cellbody, aSize[i + offset] );// memcpy(&data[cellbody], apCell[i], aSize[i]);
  6109. }
  6110. put2byte( data, hdr + 3, nCell );
  6111. put2byte( data, hdr + 5, cellbody );
  6112. pPage.nFree -= (u16)( nCell * 2 + nUsable - cellbody );
  6113. pPage.nCell = (u16)nCell;
  6114. }
  6115. static void assemblePage(
  6116. MemPage pPage, /* The page to be assemblied */
  6117. int nCell, /* The number of cells to add to this page */
  6118. u8[] apCell, /* Pointers to cell bodies */
  6119. u16[] aSize /* Sizes of the cells */
  6120. )
  6121. {
  6122. int i; /* Loop counter */
  6123. int pCellptr; /* Address of next cell pointer */
  6124. int cellbody; /* Address of next cell body */
  6125. u8[] data = pPage.aData; /* Pointer to data for pPage */
  6126. int hdr = pPage.hdrOffset; /* Offset of header on pPage */
  6127. int nUsable = (int)pPage.pBt.usableSize; /* Usable size of page */
  6128. Debug.Assert( pPage.nOverflow == 0 );
  6129. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  6130. Debug.Assert( nCell >= 0 && nCell <= MX_CELL( pPage.pBt ) && MX_CELL( pPage.pBt ) <= 5460 );
  6131. Debug.Assert( sqlite3PagerIswriteable( pPage.pDbPage ) );
  6132. /* Check that the page has just been zeroed by zeroPage() */
  6133. Debug.Assert( pPage.nCell == 0 );
  6134. Debug.Assert( get2byte( data, hdr + 5 ) == nUsable );
  6135. pCellptr = pPage.cellOffset + nCell * 2; //&data[pPage.cellOffset + nCell * 2];
  6136. cellbody = nUsable;
  6137. for ( i = nCell - 1; i >= 0; i-- )
  6138. {
  6139. pCellptr -= 2;
  6140. cellbody -= aSize[i];
  6141. put2byte( data, pCellptr, cellbody );
  6142. Buffer.BlockCopy( apCell, 0, data, cellbody, aSize[i] );//memcpy( data[cellbody], apCell[i], aSize[i] );
  6143. }
  6144. put2byte( data, hdr + 3, nCell );
  6145. put2byte( data, hdr + 5, cellbody );
  6146. pPage.nFree -= (u16)( nCell * 2 + nUsable - cellbody );
  6147. pPage.nCell = (u16)nCell;
  6148. }
  6149. /*
  6150. ** The following parameters determine how many adjacent pages get involved
  6151. ** in a balancing operation. NN is the number of neighbors on either side
  6152. ** of the page that participate in the balancing operation. NB is the
  6153. ** total number of pages that participate, including the target page and
  6154. ** NN neighbors on either side.
  6155. **
  6156. ** The minimum value of NN is 1 (of course). Increasing NN above 1
  6157. ** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
  6158. ** in exchange for a larger degradation in INSERT and UPDATE performance.
  6159. ** The value of NN appears to give the best results overall.
  6160. */
  6161. static int NN = 1; /* Number of neighbors on either side of pPage */
  6162. static int NB = ( NN * 2 + 1 ); /* Total pages involved in the balance */
  6163. #if !SQLITE_OMIT_QUICKBALANCE
  6164. /*
  6165. ** This version of balance() handles the common special case where
  6166. ** a new entry is being inserted on the extreme right-end of the
  6167. ** tree, in other words, when the new entry will become the largest
  6168. ** entry in the tree.
  6169. **
  6170. ** Instead of trying to balance the 3 right-most leaf pages, just add
  6171. ** a new page to the right-hand side and put the one new entry in
  6172. ** that page. This leaves the right side of the tree somewhat
  6173. ** unbalanced. But odds are that we will be inserting new entries
  6174. ** at the end soon afterwards so the nearly empty page will quickly
  6175. ** fill up. On average.
  6176. **
  6177. ** pPage is the leaf page which is the right-most page in the tree.
  6178. ** pParent is its parent. pPage must have a single overflow entry
  6179. ** which is also the right-most entry on the page.
  6180. **
  6181. ** The pSpace buffer is used to store a temporary copy of the divider
  6182. ** cell that will be inserted into pParent. Such a cell consists of a 4
  6183. ** byte page number followed by a variable length integer. In other
  6184. ** words, at most 13 bytes. Hence the pSpace buffer must be at
  6185. ** least 13 bytes in size.
  6186. */
  6187. static int balance_quick( MemPage pParent, MemPage pPage, u8[] pSpace )
  6188. {
  6189. BtShared pBt = pPage.pBt; /* B-Tree Database */
  6190. MemPage pNew = new MemPage();/* Newly allocated page */
  6191. int rc; /* Return Code */
  6192. Pgno pgnoNew = 0; /* Page number of pNew */
  6193. Debug.Assert( sqlite3_mutex_held( pPage.pBt.mutex ) );
  6194. Debug.Assert( sqlite3PagerIswriteable( pParent.pDbPage ) );
  6195. Debug.Assert( pPage.nOverflow == 1 );
  6196. /* This error condition is now caught prior to reaching this function */
  6197. if ( pPage.nCell <= 0 )
  6198. return SQLITE_CORRUPT_BKPT();
  6199. /* Allocate a new page. This page will become the right-sibling of
  6200. ** pPage. Make the parent page writable, so that the new divider cell
  6201. ** may be inserted. If both these operations are successful, proceed.
  6202. */
  6203. rc = allocateBtreePage( pBt, ref pNew, ref pgnoNew, 0, 0 );
  6204. if ( rc == SQLITE_OK )
  6205. {
  6206. int pOut = 4;//u8 pOut = &pSpace[4];
  6207. u8[] pCell = pPage.aOvfl[0].pCell;
  6208. int[] szCell = new int[1];
  6209. szCell[0] = cellSizePtr( pPage, pCell );
  6210. int pStop;
  6211. Debug.Assert( sqlite3PagerIswriteable( pNew.pDbPage ) );
  6212. Debug.Assert( pPage.aData[0] == ( PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF ) );
  6213. zeroPage( pNew, PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF );
  6214. assemblePage( pNew, 1, pCell, szCell );
  6215. /* If this is an auto-vacuum database, update the pointer map
  6216. ** with entries for the new page, and any pointer from the
  6217. ** cell on the page to an overflow page. If either of these
  6218. ** operations fails, the return code is set, but the contents
  6219. ** of the parent page are still manipulated by thh code below.
  6220. ** That is Ok, at this point the parent page is guaranteed to
  6221. ** be marked as dirty. Returning an error code will cause a
  6222. ** rollback, undoing any changes made to the parent page.
  6223. */
  6224. #if !SQLITE_OMIT_AUTOVACUUM // if ( ISAUTOVACUUM )
  6225. if ( pBt.autoVacuum )
  6226. #else
  6227. if (false)
  6228. #endif
  6229. {
  6230. ptrmapPut( pBt, pgnoNew, PTRMAP_BTREE, pParent.pgno, ref rc );
  6231. if ( szCell[0] > pNew.minLocal )
  6232. {
  6233. ptrmapPutOvflPtr( pNew, pCell, ref rc );
  6234. }
  6235. }
  6236. /* Create a divider cell to insert into pParent. The divider cell
  6237. ** consists of a 4-byte page number (the page number of pPage) and
  6238. ** a variable length key value (which must be the same value as the
  6239. ** largest key on pPage).
  6240. **
  6241. ** To find the largest key value on pPage, first find the right-most
  6242. ** cell on pPage. The first two fields of this cell are the
  6243. ** record-length (a variable length integer at most 32-bits in size)
  6244. ** and the key value (a variable length integer, may have any value).
  6245. ** The first of the while(...) loops below skips over the record-length
  6246. ** field. The second while(...) loop copies the key value from the
  6247. ** cell on pPage into the pSpace buffer.
  6248. */
  6249. int iCell = findCell( pPage, pPage.nCell - 1 ); //pCell = findCell( pPage, pPage.nCell - 1 );
  6250. pCell = pPage.aData;
  6251. int _pCell = iCell;
  6252. pStop = _pCell + 9; //pStop = &pCell[9];
  6253. while ( ( ( pCell[_pCell++] ) & 0x80 ) != 0 && _pCell < pStop )
  6254. ; //while ( ( *( pCell++ ) & 0x80 ) && pCell < pStop ) ;
  6255. pStop = _pCell + 9;//pStop = &pCell[9];
  6256. while ( ( ( pSpace[pOut++] = pCell[_pCell++] ) & 0x80 ) != 0 && _pCell < pStop )
  6257. ; //while ( ( ( *( pOut++ ) = *( pCell++ ) ) & 0x80 ) && pCell < pStop ) ;
  6258. /* Insert the new divider cell into pParent. */
  6259. insertCell( pParent, pParent.nCell, pSpace, pOut, //(int)(pOut-pSpace),
  6260. null, pPage.pgno, ref rc );
  6261. /* Set the right-child pointer of pParent to point to the new page. */
  6262. sqlite3Put4byte( pParent.aData, pParent.hdrOffset + 8, pgnoNew );
  6263. /* Release the reference to the new page. */
  6264. releasePage( pNew );
  6265. }
  6266. return rc;
  6267. }
  6268. #endif //* SQLITE_OMIT_QUICKBALANCE */
  6269. #if FALSE
  6270. /*
  6271. ** This function does not contribute anything to the operation of SQLite.
  6272. ** it is sometimes activated temporarily while debugging code responsible
  6273. ** for setting pointer-map entries.
  6274. */
  6275. static int ptrmapCheckPages(MemPage **apPage, int nPage){
  6276. int i, j;
  6277. for(i=0; i<nPage; i++){
  6278. Pgno n;
  6279. u8 e;
  6280. MemPage pPage = apPage[i];
  6281. BtShared pBt = pPage.pBt;
  6282. Debug.Assert( pPage.isInit!=0 );
  6283. for(j=0; j<pPage.nCell; j++){
  6284. CellInfo info;
  6285. u8 *z;
  6286. z = findCell(pPage, j);
  6287. btreeParseCellPtr(pPage, z, info);
  6288. if( info.iOverflow ){
  6289. Pgno ovfl = sqlite3Get4byte(z[info.iOverflow]);
  6290. ptrmapGet(pBt, ovfl, ref e, ref n);
  6291. Debug.Assert( n==pPage.pgno && e==PTRMAP_OVERFLOW1 );
  6292. }
  6293. if( 0==pPage.leaf ){
  6294. Pgno child = sqlite3Get4byte(z);
  6295. ptrmapGet(pBt, child, ref e, ref n);
  6296. Debug.Assert( n==pPage.pgno && e==PTRMAP_BTREE );
  6297. }
  6298. }
  6299. if( 0==pPage.leaf ){
  6300. Pgno child = sqlite3Get4byte(pPage.aData,pPage.hdrOffset+8]);
  6301. ptrmapGet(pBt, child, ref e, ref n);
  6302. Debug.Assert( n==pPage.pgno && e==PTRMAP_BTREE );
  6303. }
  6304. }
  6305. return 1;
  6306. }
  6307. #endif
  6308. /*
  6309. ** This function is used to copy the contents of the b-tree node stored
  6310. ** on page pFrom to page pTo. If page pFrom was not a leaf page, then
  6311. ** the pointer-map entries for each child page are updated so that the
  6312. ** parent page stored in the pointer map is page pTo. If pFrom contained
  6313. ** any cells with overflow page pointers, then the corresponding pointer
  6314. ** map entries are also updated so that the parent page is page pTo.
  6315. **
  6316. ** If pFrom is currently carrying any overflow cells (entries in the
  6317. ** MemPage.aOvfl[] array), they are not copied to pTo.
  6318. **
  6319. ** Before returning, page pTo is reinitialized using btreeInitPage().
  6320. **
  6321. ** The performance of this function is not critical. It is only used by
  6322. ** the balance_shallower() and balance_deeper() procedures, neither of
  6323. ** which are called often under normal circumstances.
  6324. */
  6325. static void copyNodeContent( MemPage pFrom, MemPage pTo, ref int pRC )
  6326. {
  6327. if ( ( pRC ) == SQLITE_OK )
  6328. {
  6329. BtShared pBt = pFrom.pBt;
  6330. u8[] aFrom = pFrom.aData;
  6331. u8[] aTo = pTo.aData;
  6332. int iFromHdr = pFrom.hdrOffset;
  6333. int iToHdr = ( ( pTo.pgno == 1 ) ? 100 : 0 );
  6334. int rc;
  6335. int iData;
  6336. Debug.Assert( pFrom.isInit != 0 );
  6337. Debug.Assert( pFrom.nFree >= iToHdr );
  6338. Debug.Assert( get2byte( aFrom, iFromHdr + 5 ) <= (int)pBt.usableSize );
  6339. /* Copy the b-tree node content from page pFrom to page pTo. */
  6340. iData = get2byte( aFrom, iFromHdr + 5 );
  6341. Buffer.BlockCopy( aFrom, iData, aTo, iData, (int)pBt.usableSize - iData );//memcpy(aTo[iData], ref aFrom[iData], pBt.usableSize-iData);
  6342. Buffer.BlockCopy( aFrom, iFromHdr, aTo, iToHdr, pFrom.cellOffset + 2 * pFrom.nCell );//memcpy(aTo[iToHdr], ref aFrom[iFromHdr], pFrom.cellOffset + 2*pFrom.nCell);
  6343. /* Reinitialize page pTo so that the contents of the MemPage structure
  6344. ** match the new data. The initialization of pTo can actually fail under
  6345. ** fairly obscure circumstances, even though it is a copy of initialized
  6346. ** page pFrom.
  6347. */
  6348. pTo.isInit = 0;
  6349. rc = btreeInitPage( pTo );
  6350. if ( rc != SQLITE_OK )
  6351. {
  6352. pRC = rc;
  6353. return;
  6354. }
  6355. /* If this is an auto-vacuum database, update the pointer-map entries
  6356. ** for any b-tree or overflow pages that pTo now contains the pointers to.
  6357. */
  6358. #if !SQLITE_OMIT_AUTOVACUUM // if ( ISAUTOVACUUM )
  6359. if ( pBt.autoVacuum )
  6360. #else
  6361. if (false)
  6362. #endif
  6363. {
  6364. pRC = setChildPtrmaps( pTo );
  6365. }
  6366. }
  6367. }
  6368. /*
  6369. ** This routine redistributes cells on the iParentIdx'th child of pParent
  6370. ** (hereafter "the page") and up to 2 siblings so that all pages have about the
  6371. ** same amount of free space. Usually a single sibling on either side of the
  6372. ** page are used in the balancing, though both siblings might come from one
  6373. ** side if the page is the first or last child of its parent. If the page
  6374. ** has fewer than 2 siblings (something which can only happen if the page
  6375. ** is a root page or a child of a root page) then all available siblings
  6376. ** participate in the balancing.
  6377. **
  6378. ** The number of siblings of the page might be increased or decreased by
  6379. ** one or two in an effort to keep pages nearly full but not over full.
  6380. **
  6381. ** Note that when this routine is called, some of the cells on the page
  6382. ** might not actually be stored in MemPage.aData[]. This can happen
  6383. ** if the page is overfull. This routine ensures that all cells allocated
  6384. ** to the page and its siblings fit into MemPage.aData[] before returning.
  6385. **
  6386. ** In the course of balancing the page and its siblings, cells may be
  6387. ** inserted into or removed from the parent page (pParent). Doing so
  6388. ** may cause the parent page to become overfull or underfull. If this
  6389. ** happens, it is the responsibility of the caller to invoke the correct
  6390. ** balancing routine to fix this problem (see the balance() routine).
  6391. **
  6392. ** If this routine fails for any reason, it might leave the database
  6393. ** in a corrupted state. So if this routine fails, the database should
  6394. ** be rolled back.
  6395. **
  6396. ** The third argument to this function, aOvflSpace, is a pointer to a
  6397. ** buffer big enough to hold one page. If while inserting cells into the parent
  6398. ** page (pParent) the parent page becomes overfull, this buffer is
  6399. ** used to store the parent's overflow cells. Because this function inserts
  6400. ** a maximum of four divider cells into the parent page, and the maximum
  6401. ** size of a cell stored within an internal node is always less than 1/4
  6402. ** of the page-size, the aOvflSpace[] buffer is guaranteed to be large
  6403. ** enough for all overflow cells.
  6404. **
  6405. ** If aOvflSpace is set to a null pointer, this function returns
  6406. ** SQLITE_NOMEM.
  6407. */
  6408. // under C#; Try to reuse Memory
  6409. static int balance_nonroot(
  6410. MemPage pParent, /* Parent page of siblings being balanced */
  6411. int iParentIdx, /* Index of "the page" in pParent */
  6412. u8[] aOvflSpace, /* page-size bytes of space for parent ovfl */
  6413. int isRoot /* True if pParent is a root-page */
  6414. )
  6415. {
  6416. MemPage[] apOld = new MemPage[NB]; /* pPage and up to two siblings */
  6417. MemPage[] apCopy = new MemPage[NB]; /* Private copies of apOld[] pages */
  6418. MemPage[] apNew = new MemPage[NB + 2];/* pPage and up to NB siblings after balancing */
  6419. int[] apDiv = new int[NB - 1]; /* Divider cells in pParent */
  6420. int[] cntNew = new int[NB + 2]; /* Index in aCell[] of cell after i-th page */
  6421. int[] szNew = new int[NB + 2]; /* Combined size of cells place on i-th page */
  6422. u16[] szCell = new u16[1]; /* Local size of all cells in apCell[] */
  6423. BtShared pBt; /* The whole database */
  6424. int nCell = 0; /* Number of cells in apCell[] */
  6425. int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */
  6426. int nNew = 0; /* Number of pages in apNew[] */
  6427. int nOld; /* Number of pages in apOld[] */
  6428. int i, j, k; /* Loop counters */
  6429. int nxDiv; /* Next divider slot in pParent.aCell[] */
  6430. int rc = SQLITE_OK; /* The return code */
  6431. u16 leafCorrection; /* 4 if pPage is a leaf. 0 if not */
  6432. int leafData; /* True if pPage is a leaf of a LEAFDATA tree */
  6433. int usableSpace; /* Bytes in pPage beyond the header */
  6434. int pageFlags; /* Value of pPage.aData[0] */
  6435. int subtotal; /* Subtotal of bytes in cells on one page */
  6436. //int iSpace1 = 0; /* First unused byte of aSpace1[] */
  6437. int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */
  6438. int szScratch; /* Size of scratch memory requested */
  6439. int pRight; /* Location in parent of right-sibling pointer */
  6440. u8[][] apCell = null; /* All cells begin balanced */
  6441. //u16[] szCell; /* Local size of all cells in apCell[] */
  6442. //u8[] aSpace1; /* Space for copies of dividers cells */
  6443. Pgno pgno; /* Temp var to store a page number in */
  6444. pBt = pParent.pBt;
  6445. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  6446. Debug.Assert( sqlite3PagerIswriteable( pParent.pDbPage ) );
  6447. #if FALSE
  6448. TRACE("BALANCE: begin page %d child of %d\n", pPage.pgno, pParent.pgno);
  6449. #endif
  6450. /* At this point pParent may have at most one overflow cell. And if
  6451. ** this overflow cell is present, it must be the cell with
  6452. ** index iParentIdx. This scenario comes about when this function
  6453. ** is called (indirectly) from sqlite3BtreeDelete().
  6454. */
  6455. Debug.Assert( pParent.nOverflow == 0 || pParent.nOverflow == 1 );
  6456. Debug.Assert( pParent.nOverflow == 0 || pParent.aOvfl[0].idx == iParentIdx );
  6457. //if( !aOvflSpace ){
  6458. // return SQLITE_NOMEM;
  6459. //}
  6460. /* Find the sibling pages to balance. Also locate the cells in pParent
  6461. ** that divide the siblings. An attempt is made to find NN siblings on
  6462. ** either side of pPage. More siblings are taken from one side, however,
  6463. ** if there are fewer than NN siblings on the other side. If pParent
  6464. ** has NB or fewer children then all children of pParent are taken.
  6465. **
  6466. ** This loop also drops the divider cells from the parent page. This
  6467. ** way, the remainder of the function does not have to deal with any
  6468. ** overflow cells in the parent page, since if any existed they will
  6469. ** have already been removed.
  6470. */
  6471. i = pParent.nOverflow + pParent.nCell;
  6472. if ( i < 2 )
  6473. {
  6474. nxDiv = 0;
  6475. nOld = i + 1;
  6476. }
  6477. else
  6478. {
  6479. nOld = 3;
  6480. if ( iParentIdx == 0 )
  6481. {
  6482. nxDiv = 0;
  6483. }
  6484. else if ( iParentIdx == i )
  6485. {
  6486. nxDiv = i - 2;
  6487. }
  6488. else
  6489. {
  6490. nxDiv = iParentIdx - 1;
  6491. }
  6492. i = 2;
  6493. }
  6494. if ( ( i + nxDiv - pParent.nOverflow ) == pParent.nCell )
  6495. {
  6496. pRight = pParent.hdrOffset + 8; //&pParent.aData[pParent.hdrOffset + 8];
  6497. }
  6498. else
  6499. {
  6500. pRight = findCell( pParent, i + nxDiv - pParent.nOverflow );
  6501. }
  6502. pgno = sqlite3Get4byte( pParent.aData, pRight );
  6503. while ( true )
  6504. {
  6505. rc = getAndInitPage( pBt, pgno, ref apOld[i] );
  6506. if ( rc != 0 )
  6507. {
  6508. //memset(apOld, 0, (i+1)*sizeof(MemPage*));
  6509. goto balance_cleanup;
  6510. }
  6511. nMaxCells += 1 + apOld[i].nCell + apOld[i].nOverflow;
  6512. if ( ( i-- ) == 0 )
  6513. break;
  6514. if ( i + nxDiv == pParent.aOvfl[0].idx && pParent.nOverflow != 0 )
  6515. {
  6516. apDiv[i] = 0;// = pParent.aOvfl[0].pCell;
  6517. pgno = sqlite3Get4byte( pParent.aOvfl[0].pCell, apDiv[i] );
  6518. szNew[i] = cellSizePtr( pParent, apDiv[i] );
  6519. pParent.nOverflow = 0;
  6520. }
  6521. else
  6522. {
  6523. apDiv[i] = findCell( pParent, i + nxDiv - pParent.nOverflow );
  6524. pgno = sqlite3Get4byte( pParent.aData, apDiv[i] );
  6525. szNew[i] = cellSizePtr( pParent, apDiv[i] );
  6526. /* Drop the cell from the parent page. apDiv[i] still points to
  6527. ** the cell within the parent, even though it has been dropped.
  6528. ** This is safe because dropping a cell only overwrites the first
  6529. ** four bytes of it, and this function does not need the first
  6530. ** four bytes of the divider cell. So the pointer is safe to use
  6531. ** later on.
  6532. **
  6533. ** Unless SQLite is compiled in secure-delete mode. In this case,
  6534. ** the dropCell() routine will overwrite the entire cell with zeroes.
  6535. ** In this case, temporarily copy the cell into the aOvflSpace[]
  6536. ** buffer. It will be copied out again as soon as the aSpace[] buffer
  6537. ** is allocated. */
  6538. //if (pBt.secureDelete)
  6539. //{
  6540. // int iOff = (int)(apDiv[i]) - (int)(pParent.aData); //SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent.aData);
  6541. // if( (iOff+szNew[i])>(int)pBt->usableSize )
  6542. // {
  6543. // rc = SQLITE_CORRUPT_BKPT();
  6544. // Array.Clear(apOld[0].aData,0,apOld[0].aData.Length); //memset(apOld, 0, (i + 1) * sizeof(MemPage*));
  6545. // goto balance_cleanup;
  6546. // }
  6547. // else
  6548. // {
  6549. // memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]);
  6550. // apDiv[i] = &aOvflSpace[apDiv[i] - pParent.aData];
  6551. // }
  6552. //}
  6553. dropCell( pParent, i + nxDiv - pParent.nOverflow, szNew[i], ref rc );
  6554. }
  6555. }
  6556. /* Make nMaxCells a multiple of 4 in order to preserve 8-byte
  6557. ** alignment */
  6558. nMaxCells = ( nMaxCells + 3 ) & ~3;
  6559. /*
  6560. ** Allocate space for memory structures
  6561. */
  6562. //k = pBt.pageSize + ROUND8(sizeof(MemPage));
  6563. //szScratch =
  6564. // nMaxCells*sizeof(u8*) /* apCell */
  6565. // + nMaxCells*sizeof(u16) /* szCell */
  6566. // + pBt.pageSize /* aSpace1 */
  6567. // + k*nOld; /* Page copies (apCopy) */
  6568. apCell = sqlite3ScratchMalloc( apCell, nMaxCells );
  6569. //if( apCell==null ){
  6570. // rc = SQLITE_NOMEM;
  6571. // goto balance_cleanup;
  6572. //}
  6573. if ( szCell.Length < nMaxCells )
  6574. Array.Resize( ref szCell, nMaxCells ); //(u16*)&apCell[nMaxCells];
  6575. //aSpace1 = new byte[pBt.pageSize * (nMaxCells)];// aSpace1 = (u8*)&szCell[nMaxCells];
  6576. //Debug.Assert( EIGHT_BYTE_ALIGNMENT(aSpace1) );
  6577. /*
  6578. ** Load pointers to all cells on sibling pages and the divider cells
  6579. ** into the local apCell[] array. Make copies of the divider cells
  6580. ** into space obtained from aSpace1[] and remove the the divider Cells
  6581. ** from pParent.
  6582. **
  6583. ** If the siblings are on leaf pages, then the child pointers of the
  6584. ** divider cells are stripped from the cells before they are copied
  6585. ** into aSpace1[]. In this way, all cells in apCell[] are without
  6586. ** child pointers. If siblings are not leaves, then all cell in
  6587. ** apCell[] include child pointers. Either way, all cells in apCell[]
  6588. ** are alike.
  6589. **
  6590. ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf.
  6591. ** leafData: 1 if pPage holds key+data and pParent holds only keys.
  6592. */
  6593. leafCorrection = (u16)( apOld[0].leaf * 4 );
  6594. leafData = apOld[0].hasData;
  6595. for ( i = 0; i < nOld; i++ )
  6596. {
  6597. int limit;
  6598. /* Before doing anything else, take a copy of the i'th original sibling
  6599. ** The rest of this function will use data from the copies rather
  6600. ** that the original pages since the original pages will be in the
  6601. ** process of being overwritten. */
  6602. //MemPage pOld = apCopy[i] = (MemPage*)&aSpace1[pBt.pageSize + k*i];
  6603. //memcpy(pOld, apOld[i], sizeof(MemPage));
  6604. //pOld.aData = (void*)&pOld[1];
  6605. //memcpy(pOld.aData, apOld[i].aData, pBt.pageSize);
  6606. MemPage pOld = apCopy[i] = apOld[i].Copy();
  6607. limit = pOld.nCell + pOld.nOverflow;
  6608. if( pOld.nOverflow>0 || true){
  6609. for ( j = 0; j < limit; j++ )
  6610. {
  6611. Debug.Assert( nCell < nMaxCells );
  6612. //apCell[nCell] = findOverflowCell( pOld, j );
  6613. //szCell[nCell] = cellSizePtr( pOld, apCell, nCell );
  6614. int iFOFC = findOverflowCell( pOld, j );
  6615. szCell[nCell] = cellSizePtr( pOld, iFOFC );
  6616. // Copy the Data Locally
  6617. if ( apCell[nCell] == null )
  6618. apCell[nCell] = new u8[szCell[nCell]];
  6619. else if ( apCell[nCell].Length < szCell[nCell] )
  6620. Array.Resize( ref apCell[nCell], szCell[nCell] );
  6621. if ( iFOFC < 0 ) // Overflow Cell
  6622. Buffer.BlockCopy( pOld.aOvfl[-( iFOFC + 1 )].pCell, 0, apCell[nCell], 0, szCell[nCell] );
  6623. else
  6624. Buffer.BlockCopy( pOld.aData, iFOFC, apCell[nCell], 0, szCell[nCell] );
  6625. nCell++;
  6626. }
  6627. }
  6628. else
  6629. {
  6630. u8[] aData = pOld.aData;
  6631. u16 maskPage = pOld.maskPage;
  6632. u16 cellOffset = pOld.cellOffset;
  6633. for ( j = 0; j < limit; j++ )
  6634. {
  6635. Debugger.Break();
  6636. Debug.Assert( nCell < nMaxCells );
  6637. apCell[nCell] = findCellv2( aData, maskPage, cellOffset, j );
  6638. szCell[nCell] = cellSizePtr( pOld, apCell[nCell] );
  6639. nCell++;
  6640. }
  6641. }
  6642. if ( i < nOld - 1 && 0 == leafData )
  6643. {
  6644. u16 sz = (u16)szNew[i];
  6645. byte[] pTemp = sqlite3Malloc( sz + leafCorrection );
  6646. Debug.Assert( nCell < nMaxCells );
  6647. szCell[nCell] = sz;
  6648. //pTemp = &aSpace1[iSpace1];
  6649. //iSpace1 += sz;
  6650. Debug.Assert( sz <= pBt.maxLocal + 23 );
  6651. //Debug.Assert(iSpace1 <= (int)pBt.pageSize);
  6652. Buffer.BlockCopy( pParent.aData, apDiv[i], pTemp, 0, sz );//memcpy( pTemp, apDiv[i], sz );
  6653. if ( apCell[nCell] == null || apCell[nCell].Length < sz )
  6654. Array.Resize( ref apCell[nCell], sz );
  6655. Buffer.BlockCopy( pTemp, leafCorrection, apCell[nCell], 0, sz );//apCell[nCell] = pTemp + leafCorrection;
  6656. Debug.Assert( leafCorrection == 0 || leafCorrection == 4 );
  6657. szCell[nCell] = (u16)( szCell[nCell] - leafCorrection );
  6658. if ( 0 == pOld.leaf )
  6659. {
  6660. Debug.Assert( leafCorrection == 0 );
  6661. Debug.Assert( pOld.hdrOffset == 0 );
  6662. /* The right pointer of the child page pOld becomes the left
  6663. ** pointer of the divider cell */
  6664. Buffer.BlockCopy( pOld.aData, 8, apCell[nCell], 0, 4 );//memcpy( apCell[nCell], ref pOld.aData[8], 4 );
  6665. }
  6666. else
  6667. {
  6668. Debug.Assert( leafCorrection == 4 );
  6669. if ( szCell[nCell] < 4 )
  6670. {
  6671. /* Do not allow any cells smaller than 4 bytes. */
  6672. szCell[nCell] = 4;
  6673. }
  6674. }
  6675. nCell++;
  6676. }
  6677. }
  6678. /*
  6679. ** Figure out the number of pages needed to hold all nCell cells.
  6680. ** Store this number in "k". Also compute szNew[] which is the total
  6681. ** size of all cells on the i-th page and cntNew[] which is the index
  6682. ** in apCell[] of the cell that divides page i from page i+1.
  6683. ** cntNew[k] should equal nCell.
  6684. **
  6685. ** Values computed by this block:
  6686. **
  6687. ** k: The total number of sibling pages
  6688. ** szNew[i]: Spaced used on the i-th sibling page.
  6689. ** cntNew[i]: Index in apCell[] and szCell[] for the first cell to
  6690. ** the right of the i-th sibling page.
  6691. ** usableSpace: Number of bytes of space available on each sibling.
  6692. **
  6693. */
  6694. usableSpace = (int)pBt.usableSize - 12 + leafCorrection;
  6695. for ( subtotal = k = i = 0; i < nCell; i++ )
  6696. {
  6697. Debug.Assert( i < nMaxCells );
  6698. subtotal += szCell[i] + 2;
  6699. if ( subtotal > usableSpace )
  6700. {
  6701. szNew[k] = subtotal - szCell[i];
  6702. cntNew[k] = i;
  6703. if ( leafData != 0 )
  6704. {
  6705. i--;
  6706. }
  6707. subtotal = 0;
  6708. k++;
  6709. if ( k > NB + 1 )
  6710. {
  6711. rc = SQLITE_CORRUPT_BKPT();
  6712. goto balance_cleanup;
  6713. }
  6714. }
  6715. }
  6716. szNew[k] = subtotal;
  6717. cntNew[k] = nCell;
  6718. k++;
  6719. /*
  6720. ** The packing computed by the previous block is biased toward the siblings
  6721. ** on the left side. The left siblings are always nearly full, while the
  6722. ** right-most sibling might be nearly empty. This block of code attempts
  6723. ** to adjust the packing of siblings to get a better balance.
  6724. **
  6725. ** This adjustment is more than an optimization. The packing above might
  6726. ** be so out of balance as to be illegal. For example, the right-most
  6727. ** sibling might be completely empty. This adjustment is not optional.
  6728. */
  6729. for ( i = k - 1; i > 0; i-- )
  6730. {
  6731. int szRight = szNew[i]; /* Size of sibling on the right */
  6732. int szLeft = szNew[i - 1]; /* Size of sibling on the left */
  6733. int r; /* Index of right-most cell in left sibling */
  6734. int d; /* Index of first cell to the left of right sibling */
  6735. r = cntNew[i - 1] - 1;
  6736. d = r + 1 - leafData;
  6737. Debug.Assert( d < nMaxCells );
  6738. Debug.Assert( r < nMaxCells );
  6739. while ( szRight == 0 || szRight + szCell[d] + 2 <= szLeft - ( szCell[r] + 2 ) )
  6740. {
  6741. szRight += szCell[d] + 2;
  6742. szLeft -= szCell[r] + 2;
  6743. cntNew[i - 1]--;
  6744. r = cntNew[i - 1] - 1;
  6745. d = r + 1 - leafData;
  6746. }
  6747. szNew[i] = szRight;
  6748. szNew[i - 1] = szLeft;
  6749. }
  6750. /* Either we found one or more cells (cntnew[0])>0) or pPage is
  6751. ** a virtual root page. A virtual root page is when the real root
  6752. ** page is page 1 and we are the only child of that page.
  6753. */
  6754. Debug.Assert( cntNew[0] > 0 || ( pParent.pgno == 1 && pParent.nCell == 0 ) );
  6755. TRACE( "BALANCE: old: %d %d %d ",
  6756. apOld[0].pgno,
  6757. nOld >= 2 ? apOld[1].pgno : 0,
  6758. nOld >= 3 ? apOld[2].pgno : 0
  6759. );
  6760. /*
  6761. ** Allocate k new pages. Reuse old pages where possible.
  6762. */
  6763. if ( apOld[0].pgno <= 1 )
  6764. {
  6765. rc = SQLITE_CORRUPT_BKPT();
  6766. goto balance_cleanup;
  6767. }
  6768. pageFlags = apOld[0].aData[0];
  6769. for ( i = 0; i < k; i++ )
  6770. {
  6771. MemPage pNew = new MemPage();
  6772. if ( i < nOld )
  6773. {
  6774. pNew = apNew[i] = apOld[i];
  6775. apOld[i] = null;
  6776. rc = sqlite3PagerWrite( pNew.pDbPage );
  6777. nNew++;
  6778. if ( rc != 0 )
  6779. goto balance_cleanup;
  6780. }
  6781. else
  6782. {
  6783. Debug.Assert( i > 0 );
  6784. rc = allocateBtreePage( pBt, ref pNew, ref pgno, pgno, 0 );
  6785. if ( rc != 0 )
  6786. goto balance_cleanup;
  6787. apNew[i] = pNew;
  6788. nNew++;
  6789. /* Set the pointer-map entry for the new sibling page. */
  6790. #if !SQLITE_OMIT_AUTOVACUUM // if ( ISAUTOVACUUM )
  6791. if ( pBt.autoVacuum )
  6792. #else
  6793. if (false)
  6794. #endif
  6795. {
  6796. ptrmapPut( pBt, pNew.pgno, PTRMAP_BTREE, pParent.pgno, ref rc );
  6797. if ( rc != SQLITE_OK )
  6798. {
  6799. goto balance_cleanup;
  6800. }
  6801. }
  6802. }
  6803. }
  6804. /* Free any old pages that were not reused as new pages.
  6805. */
  6806. while ( i < nOld )
  6807. {
  6808. freePage( apOld[i], ref rc );
  6809. if ( rc != 0 )
  6810. goto balance_cleanup;
  6811. releasePage( apOld[i] );
  6812. apOld[i] = null;
  6813. i++;
  6814. }
  6815. /*
  6816. ** Put the new pages in accending order. This helps to
  6817. ** keep entries in the disk file in order so that a scan
  6818. ** of the table is a linear scan through the file. That
  6819. ** in turn helps the operating system to deliver pages
  6820. ** from the disk more rapidly.
  6821. **
  6822. ** An O(n^2) insertion sort algorithm is used, but since
  6823. ** n is never more than NB (a small constant), that should
  6824. ** not be a problem.
  6825. **
  6826. ** When NB==3, this one optimization makes the database
  6827. ** about 25% faster for large insertions and deletions.
  6828. */
  6829. for ( i = 0; i < k - 1; i++ )
  6830. {
  6831. int minV = (int)apNew[i].pgno;
  6832. int minI = i;
  6833. for ( j = i + 1; j < k; j++ )
  6834. {
  6835. if ( apNew[j].pgno < (u32)minV )
  6836. {
  6837. minI = j;
  6838. minV = (int)apNew[j].pgno;
  6839. }
  6840. }
  6841. if ( minI > i )
  6842. {
  6843. MemPage pT;
  6844. pT = apNew[i];
  6845. apNew[i] = apNew[minI];
  6846. apNew[minI] = pT;
  6847. }
  6848. }
  6849. TRACE( "new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n",
  6850. apNew[0].pgno, szNew[0],
  6851. nNew >= 2 ? apNew[1].pgno : 0, nNew >= 2 ? szNew[1] : 0,
  6852. nNew >= 3 ? apNew[2].pgno : 0, nNew >= 3 ? szNew[2] : 0,
  6853. nNew >= 4 ? apNew[3].pgno : 0, nNew >= 4 ? szNew[3] : 0,
  6854. nNew >= 5 ? apNew[4].pgno : 0, nNew >= 5 ? szNew[4] : 0 );
  6855. Debug.Assert( sqlite3PagerIswriteable( pParent.pDbPage ) );
  6856. sqlite3Put4byte( pParent.aData, pRight, apNew[nNew - 1].pgno );
  6857. /*
  6858. ** Evenly distribute the data in apCell[] across the new pages.
  6859. ** Insert divider cells into pParent as necessary.
  6860. */
  6861. j = 0;
  6862. for ( i = 0; i < nNew; i++ )
  6863. {
  6864. /* Assemble the new sibling page. */
  6865. MemPage pNew = apNew[i];
  6866. Debug.Assert( j < nMaxCells );
  6867. zeroPage( pNew, pageFlags );
  6868. assemblePage( pNew, cntNew[i] - j, apCell, szCell, j );
  6869. Debug.Assert( pNew.nCell > 0 || ( nNew == 1 && cntNew[0] == 0 ) );
  6870. Debug.Assert( pNew.nOverflow == 0 );
  6871. j = cntNew[i];
  6872. /* If the sibling page assembled above was not the right-most sibling,
  6873. ** insert a divider cell into the parent page.
  6874. */
  6875. Debug.Assert( i < nNew - 1 || j == nCell );
  6876. if ( j < nCell )
  6877. {
  6878. u8[] pCell;
  6879. u8[] pTemp;
  6880. int sz;
  6881. Debug.Assert( j < nMaxCells );
  6882. pCell = apCell[j];
  6883. sz = szCell[j] + leafCorrection;
  6884. pTemp = sqlite3Malloc( sz );//&aOvflSpace[iOvflSpace];
  6885. if ( 0 == pNew.leaf )
  6886. {
  6887. Buffer.BlockCopy( pCell, 0, pNew.aData, 8, 4 );//memcpy( pNew.aData[8], pCell, 4 );
  6888. }
  6889. else if ( leafData != 0 )
  6890. {
  6891. /* If the tree is a leaf-data tree, and the siblings are leaves,
  6892. ** then there is no divider cell in apCell[]. Instead, the divider
  6893. ** cell consists of the integer key for the right-most cell of
  6894. ** the sibling-page assembled above only.
  6895. */
  6896. CellInfo info = new CellInfo();
  6897. j--;
  6898. btreeParseCellPtr( pNew, apCell[j], ref info );
  6899. pCell = pTemp;
  6900. sz = 4 + putVarint( pCell, 4, (u64)info.nKey );
  6901. pTemp = null;
  6902. }
  6903. else
  6904. {
  6905. //------------ pCell -= 4;
  6906. byte[] _pCell_4 = sqlite3Malloc( pCell.Length + 4 );
  6907. Buffer.BlockCopy( pCell, 0, _pCell_4, 4, pCell.Length );
  6908. pCell = _pCell_4;
  6909. //
  6910. /* Obscure case for non-leaf-data trees: If the cell at pCell was
  6911. ** previously stored on a leaf node, and its reported size was 4
  6912. ** bytes, then it may actually be smaller than this
  6913. ** (see btreeParseCellPtr(), 4 bytes is the minimum size of
  6914. ** any cell). But it is important to pass the correct size to
  6915. ** insertCell(), so reparse the cell now.
  6916. **
  6917. ** Note that this can never happen in an SQLite data file, as all
  6918. ** cells are at least 4 bytes. It only happens in b-trees used
  6919. ** to evaluate "IN (SELECT ...)" and similar clauses.
  6920. */
  6921. if ( szCell[j] == 4 )
  6922. {
  6923. Debug.Assert( leafCorrection == 4 );
  6924. sz = cellSizePtr( pParent, pCell );
  6925. }
  6926. }
  6927. iOvflSpace += sz;
  6928. Debug.Assert( sz <= pBt.maxLocal + 23 );
  6929. Debug.Assert( iOvflSpace <= (int)pBt.pageSize );
  6930. insertCell( pParent, nxDiv, pCell, sz, pTemp, pNew.pgno, ref rc );
  6931. if ( rc != SQLITE_OK )
  6932. goto balance_cleanup;
  6933. Debug.Assert( sqlite3PagerIswriteable( pParent.pDbPage ) );
  6934. j++;
  6935. nxDiv++;
  6936. }
  6937. }
  6938. Debug.Assert( j == nCell );
  6939. Debug.Assert( nOld > 0 );
  6940. Debug.Assert( nNew > 0 );
  6941. if ( ( pageFlags & PTF_LEAF ) == 0 )
  6942. {
  6943. Buffer.BlockCopy( apCopy[nOld - 1].aData, 8, apNew[nNew - 1].aData, 8, 4 ); //u8* zChild = &apCopy[nOld - 1].aData[8];
  6944. //memcpy( apNew[nNew - 1].aData[8], zChild, 4 );
  6945. }
  6946. if ( isRoot != 0 && pParent.nCell == 0 && pParent.hdrOffset <= apNew[0].nFree )
  6947. {
  6948. /* The root page of the b-tree now contains no cells. The only sibling
  6949. ** page is the right-child of the parent. Copy the contents of the
  6950. ** child page into the parent, decreasing the overall height of the
  6951. ** b-tree structure by one. This is described as the "balance-shallower"
  6952. ** sub-algorithm in some documentation.
  6953. **
  6954. ** If this is an auto-vacuum database, the call to copyNodeContent()
  6955. ** sets all pointer-map entries corresponding to database image pages
  6956. ** for which the pointer is stored within the content being copied.
  6957. **
  6958. ** The second Debug.Assert below verifies that the child page is defragmented
  6959. ** (it must be, as it was just reconstructed using assemblePage()). This
  6960. ** is important if the parent page happens to be page 1 of the database
  6961. ** image. */
  6962. Debug.Assert( nNew == 1 );
  6963. Debug.Assert( apNew[0].nFree ==
  6964. ( get2byte( apNew[0].aData, 5 ) - apNew[0].cellOffset - apNew[0].nCell * 2 )
  6965. );
  6966. copyNodeContent( apNew[0], pParent, ref rc );
  6967. freePage( apNew[0], ref rc );
  6968. }
  6969. else
  6970. #if !SQLITE_OMIT_AUTOVACUUM // if ( ISAUTOVACUUM )
  6971. if ( pBt.autoVacuum )
  6972. #else
  6973. if (false)
  6974. #endif
  6975. {
  6976. /* Fix the pointer-map entries for all the cells that were shifted around.
  6977. ** There are several different types of pointer-map entries that need to
  6978. ** be dealt with by this routine. Some of these have been set already, but
  6979. ** many have not. The following is a summary:
  6980. **
  6981. ** 1) The entries associated with new sibling pages that were not
  6982. ** siblings when this function was called. These have already
  6983. ** been set. We don't need to worry about old siblings that were
  6984. ** moved to the free-list - the freePage() code has taken care
  6985. ** of those.
  6986. **
  6987. ** 2) The pointer-map entries associated with the first overflow
  6988. ** page in any overflow chains used by new divider cells. These
  6989. ** have also already been taken care of by the insertCell() code.
  6990. **
  6991. ** 3) If the sibling pages are not leaves, then the child pages of
  6992. ** cells stored on the sibling pages may need to be updated.
  6993. **
  6994. ** 4) If the sibling pages are not internal intkey nodes, then any
  6995. ** overflow pages used by these cells may need to be updated
  6996. ** (internal intkey nodes never contain pointers to overflow pages).
  6997. **
  6998. ** 5) If the sibling pages are not leaves, then the pointer-map
  6999. ** entries for the right-child pages of each sibling may need
  7000. ** to be updated.
  7001. **
  7002. ** Cases 1 and 2 are dealt with above by other code. The next
  7003. ** block deals with cases 3 and 4 and the one after that, case 5. Since
  7004. ** setting a pointer map entry is a relatively expensive operation, this
  7005. ** code only sets pointer map entries for child or overflow pages that have
  7006. ** actually moved between pages. */
  7007. MemPage pNew = apNew[0];
  7008. MemPage pOld = apCopy[0];
  7009. int nOverflow = pOld.nOverflow;
  7010. int iNextOld = pOld.nCell + nOverflow;
  7011. int iOverflow = ( nOverflow != 0 ? pOld.aOvfl[0].idx : -1 );
  7012. j = 0; /* Current 'old' sibling page */
  7013. k = 0; /* Current 'new' sibling page */
  7014. for ( i = 0; i < nCell; i++ )
  7015. {
  7016. int isDivider = 0;
  7017. while ( i == iNextOld )
  7018. {
  7019. /* Cell i is the cell immediately following the last cell on old
  7020. ** sibling page j. If the siblings are not leaf pages of an
  7021. ** intkey b-tree, then cell i was a divider cell. */
  7022. pOld = apCopy[++j];
  7023. iNextOld = i + ( 0 == leafData ? 1 : 0 ) + pOld.nCell + pOld.nOverflow;
  7024. if ( pOld.nOverflow != 0 )
  7025. {
  7026. nOverflow = pOld.nOverflow;
  7027. iOverflow = i + ( 0 == leafData ? 1 : 0 ) + pOld.aOvfl[0].idx;
  7028. }
  7029. isDivider = 0 == leafData ? 1 : 0;
  7030. }
  7031. Debug.Assert( nOverflow > 0 || iOverflow < i );
  7032. Debug.Assert( nOverflow < 2 || pOld.aOvfl[0].idx == pOld.aOvfl[1].idx - 1 );
  7033. Debug.Assert( nOverflow < 3 || pOld.aOvfl[1].idx == pOld.aOvfl[2].idx - 1 );
  7034. if ( i == iOverflow )
  7035. {
  7036. isDivider = 1;
  7037. if ( ( --nOverflow ) > 0 )
  7038. {
  7039. iOverflow++;
  7040. }
  7041. }
  7042. if ( i == cntNew[k] )
  7043. {
  7044. /* Cell i is the cell immediately following the last cell on new
  7045. ** sibling page k. If the siblings are not leaf pages of an
  7046. ** intkey b-tree, then cell i is a divider cell. */
  7047. pNew = apNew[++k];
  7048. if ( 0 == leafData )
  7049. continue;
  7050. }
  7051. Debug.Assert( j < nOld );
  7052. Debug.Assert( k < nNew );
  7053. /* If the cell was originally divider cell (and is not now) or
  7054. ** an overflow cell, or if the cell was located on a different sibling
  7055. ** page before the balancing, then the pointer map entries associated
  7056. ** with any child or overflow pages need to be updated. */
  7057. if ( isDivider != 0 || pOld.pgno != pNew.pgno )
  7058. {
  7059. if ( 0 == leafCorrection )
  7060. {
  7061. ptrmapPut( pBt, sqlite3Get4byte( apCell[i] ), PTRMAP_BTREE, pNew.pgno, ref rc );
  7062. }
  7063. if ( szCell[i] > pNew.minLocal )
  7064. {
  7065. ptrmapPutOvflPtr( pNew, apCell[i], ref rc );
  7066. }
  7067. }
  7068. }
  7069. if ( 0 == leafCorrection )
  7070. {
  7071. for ( i = 0; i < nNew; i++ )
  7072. {
  7073. u32 key = sqlite3Get4byte( apNew[i].aData, 8 );
  7074. ptrmapPut( pBt, key, PTRMAP_BTREE, apNew[i].pgno, ref rc );
  7075. }
  7076. }
  7077. #if FALSE
  7078. /* The ptrmapCheckPages() contains Debug.Assert() statements that verify that
  7079. ** all pointer map pages are set correctly. This is helpful while
  7080. ** debugging. This is usually disabled because a corrupt database may
  7081. ** cause an Debug.Assert() statement to fail. */
  7082. ptrmapCheckPages(apNew, nNew);
  7083. ptrmapCheckPages(pParent, 1);
  7084. #endif
  7085. }
  7086. Debug.Assert( pParent.isInit != 0 );
  7087. TRACE( "BALANCE: finished: old=%d new=%d cells=%d\n",
  7088. nOld, nNew, nCell );
  7089. /*
  7090. ** Cleanup before returning.
  7091. */
  7092. balance_cleanup:
  7093. sqlite3ScratchFree( apCell );
  7094. for ( i = 0; i < nOld; i++ )
  7095. {
  7096. releasePage( apOld[i] );
  7097. }
  7098. for ( i = 0; i < nNew; i++ )
  7099. {
  7100. releasePage( apNew[i] );
  7101. }
  7102. return rc;
  7103. }
  7104. /*
  7105. ** This function is called when the root page of a b-tree structure is
  7106. ** overfull (has one or more overflow pages).
  7107. **
  7108. ** A new child page is allocated and the contents of the current root
  7109. ** page, including overflow cells, are copied into the child. The root
  7110. ** page is then overwritten to make it an empty page with the right-child
  7111. ** pointer pointing to the new page.
  7112. **
  7113. ** Before returning, all pointer-map entries corresponding to pages
  7114. ** that the new child-page now contains pointers to are updated. The
  7115. ** entry corresponding to the new right-child pointer of the root
  7116. ** page is also updated.
  7117. **
  7118. ** If successful, ppChild is set to contain a reference to the child
  7119. ** page and SQLITE_OK is returned. In this case the caller is required
  7120. ** to call releasePage() on ppChild exactly once. If an error occurs,
  7121. ** an error code is returned and ppChild is set to 0.
  7122. */
  7123. static int balance_deeper( MemPage pRoot, ref MemPage ppChild )
  7124. {
  7125. int rc; /* Return value from subprocedures */
  7126. MemPage pChild = null; /* Pointer to a new child page */
  7127. Pgno pgnoChild = 0; /* Page number of the new child page */
  7128. BtShared pBt = pRoot.pBt; /* The BTree */
  7129. Debug.Assert( pRoot.nOverflow > 0 );
  7130. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  7131. /* Make pRoot, the root page of the b-tree, writable. Allocate a new
  7132. ** page that will become the new right-child of pPage. Copy the contents
  7133. ** of the node stored on pRoot into the new child page.
  7134. */
  7135. rc = sqlite3PagerWrite( pRoot.pDbPage );
  7136. if ( rc == SQLITE_OK )
  7137. {
  7138. rc = allocateBtreePage( pBt, ref pChild, ref pgnoChild, pRoot.pgno, 0 );
  7139. copyNodeContent( pRoot, pChild, ref rc );
  7140. #if !SQLITE_OMIT_AUTOVACUUM // if ( ISAUTOVACUUM )
  7141. if ( pBt.autoVacuum )
  7142. #else
  7143. if (false)
  7144. #endif
  7145. {
  7146. ptrmapPut( pBt, pgnoChild, PTRMAP_BTREE, pRoot.pgno, ref rc );
  7147. }
  7148. }
  7149. if ( rc != 0 )
  7150. {
  7151. ppChild = null;
  7152. releasePage( pChild );
  7153. return rc;
  7154. }
  7155. Debug.Assert( sqlite3PagerIswriteable( pChild.pDbPage ) );
  7156. Debug.Assert( sqlite3PagerIswriteable( pRoot.pDbPage ) );
  7157. Debug.Assert( pChild.nCell == pRoot.nCell );
  7158. TRACE( "BALANCE: copy root %d into %d\n", pRoot.pgno, pChild.pgno );
  7159. /* Copy the overflow cells from pRoot to pChild */
  7160. Array.Copy( pRoot.aOvfl, pChild.aOvfl, pRoot.nOverflow );//memcpy(pChild.aOvfl, pRoot.aOvfl, pRoot.nOverflow*sizeof(pRoot.aOvfl[0]));
  7161. pChild.nOverflow = pRoot.nOverflow;
  7162. /* Zero the contents of pRoot. Then install pChild as the right-child. */
  7163. zeroPage( pRoot, pChild.aData[0] & ~PTF_LEAF );
  7164. sqlite3Put4byte( pRoot.aData, pRoot.hdrOffset + 8, pgnoChild );
  7165. ppChild = pChild;
  7166. return SQLITE_OK;
  7167. }
  7168. /*
  7169. ** The page that pCur currently points to has just been modified in
  7170. ** some way. This function figures out if this modification means the
  7171. ** tree needs to be balanced, and if so calls the appropriate balancing
  7172. ** routine. Balancing routines are:
  7173. **
  7174. ** balance_quick()
  7175. ** balance_deeper()
  7176. ** balance_nonroot()
  7177. */
  7178. static u8[] aBalanceQuickSpace = new u8[13];
  7179. static int balance( BtCursor pCur )
  7180. {
  7181. int rc = SQLITE_OK;
  7182. int nMin = (int)pCur.pBt.usableSize * 2 / 3;
  7183. //u8[] pFree = null;
  7184. #if !NDEBUG || SQLITE_COVERAGE_TEST || DEBUG
  7185. int balance_quick_called = 0;//TESTONLY( int balance_quick_called = 0 );
  7186. int balance_deeper_called = 0;//TESTONLY( int balance_deeper_called = 0 );
  7187. #else
  7188. int balance_quick_called = 0;
  7189. int balance_deeper_called = 0;
  7190. #endif
  7191. do
  7192. {
  7193. int iPage = pCur.iPage;
  7194. MemPage pPage = pCur.apPage[iPage];
  7195. if ( iPage == 0 )
  7196. {
  7197. if ( pPage.nOverflow != 0 )
  7198. {
  7199. /* The root page of the b-tree is overfull. In this case call the
  7200. ** balance_deeper() function to create a new child for the root-page
  7201. ** and copy the current contents of the root-page to it. The
  7202. ** next iteration of the do-loop will balance the child page.
  7203. */
  7204. Debug.Assert( ( balance_deeper_called++ ) == 0 );
  7205. rc = balance_deeper( pPage, ref pCur.apPage[1] );
  7206. if ( rc == SQLITE_OK )
  7207. {
  7208. pCur.iPage = 1;
  7209. pCur.aiIdx[0] = 0;
  7210. pCur.aiIdx[1] = 0;
  7211. Debug.Assert( pCur.apPage[1].nOverflow != 0 );
  7212. }
  7213. }
  7214. else
  7215. {
  7216. break;
  7217. }
  7218. }
  7219. else if ( pPage.nOverflow == 0 && pPage.nFree <= nMin )
  7220. {
  7221. break;
  7222. }
  7223. else
  7224. {
  7225. MemPage pParent = pCur.apPage[iPage - 1];
  7226. int iIdx = pCur.aiIdx[iPage - 1];
  7227. rc = sqlite3PagerWrite( pParent.pDbPage );
  7228. if ( rc == SQLITE_OK )
  7229. {
  7230. #if !SQLITE_OMIT_QUICKBALANCE
  7231. if ( pPage.hasData != 0
  7232. && pPage.nOverflow == 1
  7233. && pPage.aOvfl[0].idx == pPage.nCell
  7234. && pParent.pgno != 1
  7235. && pParent.nCell == iIdx
  7236. )
  7237. {
  7238. /* Call balance_quick() to create a new sibling of pPage on which
  7239. ** to store the overflow cell. balance_quick() inserts a new cell
  7240. ** into pParent, which may cause pParent overflow. If this
  7241. ** happens, the next interation of the do-loop will balance pParent
  7242. ** use either balance_nonroot() or balance_deeper(). Until this
  7243. ** happens, the overflow cell is stored in the aBalanceQuickSpace[]
  7244. ** buffer.
  7245. **
  7246. ** The purpose of the following Debug.Assert() is to check that only a
  7247. ** single call to balance_quick() is made for each call to this
  7248. ** function. If this were not verified, a subtle bug involving reuse
  7249. ** of the aBalanceQuickSpace[] might sneak in.
  7250. */
  7251. Debug.Assert( ( balance_quick_called++ ) == 0 );
  7252. rc = balance_quick( pParent, pPage, aBalanceQuickSpace );
  7253. }
  7254. else
  7255. #endif
  7256. {
  7257. /* In this case, call balance_nonroot() to redistribute cells
  7258. ** between pPage and up to 2 of its sibling pages. This involves
  7259. ** modifying the contents of pParent, which may cause pParent to
  7260. ** become overfull or underfull. The next iteration of the do-loop
  7261. ** will balance the parent page to correct this.
  7262. **
  7263. ** If the parent page becomes overfull, the overflow cell or cells
  7264. ** are stored in the pSpace buffer allocated immediately below.
  7265. ** A subsequent iteration of the do-loop will deal with this by
  7266. ** calling balance_nonroot() (balance_deeper() may be called first,
  7267. ** but it doesn't deal with overflow cells - just moves them to a
  7268. ** different page). Once this subsequent call to balance_nonroot()
  7269. ** has completed, it is safe to release the pSpace buffer used by
  7270. ** the previous call, as the overflow cell data will have been
  7271. ** copied either into the body of a database page or into the new
  7272. ** pSpace buffer passed to the latter call to balance_nonroot().
  7273. */
  7274. ////u8[] pSpace = new u8[pCur.pBt.pageSize];// u8 pSpace = sqlite3PageMalloc( pCur.pBt.pageSize );
  7275. rc = balance_nonroot( pParent, iIdx, null, iPage == 1 ? 1 : 0 );
  7276. //if (pFree != null)
  7277. //{
  7278. // /* If pFree is not NULL, it points to the pSpace buffer used
  7279. // ** by a previous call to balance_nonroot(). Its contents are
  7280. // ** now stored either on real database pages or within the
  7281. // ** new pSpace buffer, so it may be safely freed here. */
  7282. // sqlite3PageFree(ref pFree);
  7283. //}
  7284. /* The pSpace buffer will be freed after the next call to
  7285. ** balance_nonroot(), or just before this function returns, whichever
  7286. ** comes first. */
  7287. //pFree = pSpace;
  7288. }
  7289. }
  7290. pPage.nOverflow = 0;
  7291. /* The next iteration of the do-loop balances the parent page. */
  7292. releasePage( pPage );
  7293. pCur.iPage--;
  7294. }
  7295. } while ( rc == SQLITE_OK );
  7296. //if (pFree != null)
  7297. //{
  7298. // sqlite3PageFree(ref pFree);
  7299. //}
  7300. return rc;
  7301. }
  7302. /*
  7303. ** Insert a new record into the BTree. The key is given by (pKey,nKey)
  7304. ** and the data is given by (pData,nData). The cursor is used only to
  7305. ** define what table the record should be inserted into. The cursor
  7306. ** is left pointing at a random location.
  7307. **
  7308. ** For an INTKEY table, only the nKey value of the key is used. pKey is
  7309. ** ignored. For a ZERODATA table, the pData and nData are both ignored.
  7310. **
  7311. ** If the seekResult parameter is non-zero, then a successful call to
  7312. ** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already
  7313. ** been performed. seekResult is the search result returned (a negative
  7314. ** number if pCur points at an entry that is smaller than (pKey, nKey), or
  7315. ** a positive value if pCur points at an etry that is larger than
  7316. ** (pKey, nKey)).
  7317. **
  7318. ** If the seekResult parameter is non-zero, then the caller guarantees that
  7319. ** cursor pCur is pointing at the existing copy of a row that is to be
  7320. ** overwritten. If the seekResult parameter is 0, then cursor pCur may
  7321. ** point to any entry or to no entry at all and so this function has to seek
  7322. ** the cursor before the new key can be inserted.
  7323. */
  7324. static int sqlite3BtreeInsert(
  7325. BtCursor pCur, /* Insert data into the table of this cursor */
  7326. byte[] pKey, i64 nKey, /* The key of the new record */
  7327. byte[] pData, int nData, /* The data of the new record */
  7328. int nZero, /* Number of extra 0 bytes to append to data */
  7329. int appendBias, /* True if this is likely an append */
  7330. int seekResult /* Result of prior MovetoUnpacked() call */
  7331. )
  7332. {
  7333. int rc;
  7334. int loc = seekResult; /* -1: before desired location +1: after */
  7335. int szNew = 0;
  7336. int idx;
  7337. MemPage pPage;
  7338. Btree p = pCur.pBtree;
  7339. BtShared pBt = p.pBt;
  7340. int oldCell;
  7341. byte[] newCell = null;
  7342. if ( pCur.eState == CURSOR_FAULT )
  7343. {
  7344. Debug.Assert( pCur.skipNext != SQLITE_OK );
  7345. return pCur.skipNext;
  7346. }
  7347. Debug.Assert( cursorHoldsMutex( pCur ) );
  7348. Debug.Assert( pCur.wrFlag != 0 && pBt.inTransaction == TRANS_WRITE && !pBt.readOnly );
  7349. Debug.Assert( hasSharedCacheTableLock( p, pCur.pgnoRoot, pCur.pKeyInfo != null ? 1 : 0, 2 ) );
  7350. /* Assert that the caller has been consistent. If this cursor was opened
  7351. ** expecting an index b-tree, then the caller should be inserting blob
  7352. ** keys with no associated data. If the cursor was opened expecting an
  7353. ** intkey table, the caller should be inserting integer keys with a
  7354. ** blob of associated data. */
  7355. Debug.Assert( ( pKey == null ) == ( pCur.pKeyInfo == null ) );
  7356. /* If this is an insert into a table b-tree, invalidate any incrblob
  7357. ** cursors open on the row being replaced (assuming this is a replace
  7358. ** operation - if it is not, the following is a no-op). */
  7359. if ( pCur.pKeyInfo == null )
  7360. {
  7361. invalidateIncrblobCursors( p, nKey, 0 );
  7362. }
  7363. /* Save the positions of any other cursors open on this table.
  7364. **
  7365. ** In some cases, the call to btreeMoveto() below is a no-op. For
  7366. ** example, when inserting data into a table with auto-generated integer
  7367. ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the
  7368. ** integer key to use. It then calls this function to actually insert the
  7369. ** data into the intkey B-Tree. In this case btreeMoveto() recognizes
  7370. ** that the cursor is already where it needs to be and returns without
  7371. ** doing any work. To avoid thwarting these optimizations, it is important
  7372. ** not to clear the cursor here.
  7373. */
  7374. rc = saveAllCursors( pBt, pCur.pgnoRoot, pCur );
  7375. if ( rc != 0 )
  7376. return rc;
  7377. if ( 0 == loc )
  7378. {
  7379. rc = btreeMoveto( pCur, pKey, nKey, appendBias, ref loc );
  7380. if ( rc != 0 )
  7381. return rc;
  7382. }
  7383. Debug.Assert( pCur.eState == CURSOR_VALID || ( pCur.eState == CURSOR_INVALID && loc != 0 ) );
  7384. pPage = pCur.apPage[pCur.iPage];
  7385. Debug.Assert( pPage.intKey != 0 || nKey >= 0 );
  7386. Debug.Assert( pPage.leaf != 0 || 0 == pPage.intKey );
  7387. TRACE( "INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
  7388. pCur.pgnoRoot, nKey, nData, pPage.pgno,
  7389. loc == 0 ? "overwrite" : "new entry" );
  7390. Debug.Assert( pPage.isInit != 0 );
  7391. allocateTempSpace( pBt );
  7392. newCell = pBt.pTmpSpace;
  7393. //if (newCell == null) return SQLITE_NOMEM;
  7394. rc = fillInCell( pPage, newCell, pKey, nKey, pData, nData, nZero, ref szNew );
  7395. if ( rc != 0 )
  7396. goto end_insert;
  7397. Debug.Assert( szNew == cellSizePtr( pPage, newCell ) );
  7398. Debug.Assert( szNew <= MX_CELL_SIZE( pBt ) );
  7399. idx = pCur.aiIdx[pCur.iPage];
  7400. if ( loc == 0 )
  7401. {
  7402. u16 szOld;
  7403. Debug.Assert( idx < pPage.nCell );
  7404. rc = sqlite3PagerWrite( pPage.pDbPage );
  7405. if ( rc != 0 )
  7406. {
  7407. goto end_insert;
  7408. }
  7409. oldCell = findCell( pPage, idx );
  7410. if ( 0 == pPage.leaf )
  7411. {
  7412. //memcpy(newCell, oldCell, 4);
  7413. newCell[0] = pPage.aData[oldCell + 0];
  7414. newCell[1] = pPage.aData[oldCell + 1];
  7415. newCell[2] = pPage.aData[oldCell + 2];
  7416. newCell[3] = pPage.aData[oldCell + 3];
  7417. }
  7418. szOld = cellSizePtr( pPage, oldCell );
  7419. rc = clearCell( pPage, oldCell );
  7420. dropCell( pPage, idx, szOld, ref rc );
  7421. if ( rc != 0 )
  7422. goto end_insert;
  7423. }
  7424. else if ( loc < 0 && pPage.nCell > 0 )
  7425. {
  7426. Debug.Assert( pPage.leaf != 0 );
  7427. idx = ++pCur.aiIdx[pCur.iPage];
  7428. }
  7429. else
  7430. {
  7431. Debug.Assert( pPage.leaf != 0 );
  7432. }
  7433. insertCell( pPage, idx, newCell, szNew, null, 0, ref rc );
  7434. Debug.Assert( rc != SQLITE_OK || pPage.nCell > 0 || pPage.nOverflow > 0 );
  7435. /* If no error has occured and pPage has an overflow cell, call balance()
  7436. ** to redistribute the cells within the tree. Since balance() may move
  7437. ** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey
  7438. ** variables.
  7439. **
  7440. ** Previous versions of SQLite called moveToRoot() to move the cursor
  7441. ** back to the root page as balance() used to invalidate the contents
  7442. ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that,
  7443. ** set the cursor state to "invalid". This makes common insert operations
  7444. ** slightly faster.
  7445. **
  7446. ** There is a subtle but important optimization here too. When inserting
  7447. ** multiple records into an intkey b-tree using a single cursor (as can
  7448. ** happen while processing an "INSERT INTO ... SELECT" statement), it
  7449. ** is advantageous to leave the cursor pointing to the last entry in
  7450. ** the b-tree if possible. If the cursor is left pointing to the last
  7451. ** entry in the table, and the next row inserted has an integer key
  7452. ** larger than the largest existing key, it is possible to insert the
  7453. ** row without seeking the cursor. This can be a big performance boost.
  7454. */
  7455. pCur.info.nSize = 0;
  7456. pCur.validNKey = false;
  7457. if ( rc == SQLITE_OK && pPage.nOverflow != 0 )
  7458. {
  7459. rc = balance( pCur );
  7460. /* Must make sure nOverflow is reset to zero even if the balance()
  7461. ** fails. Internal data structure corruption will result otherwise.
  7462. ** Also, set the cursor state to invalid. This stops saveCursorPosition()
  7463. ** from trying to save the current position of the cursor. */
  7464. pCur.apPage[pCur.iPage].nOverflow = 0;
  7465. pCur.eState = CURSOR_INVALID;
  7466. }
  7467. Debug.Assert( pCur.apPage[pCur.iPage].nOverflow == 0 );
  7468. end_insert:
  7469. return rc;
  7470. }
  7471. /*
  7472. ** Delete the entry that the cursor is pointing to. The cursor
  7473. ** is left pointing at a arbitrary location.
  7474. */
  7475. static int sqlite3BtreeDelete( BtCursor pCur )
  7476. {
  7477. Btree p = pCur.pBtree;
  7478. BtShared pBt = p.pBt;
  7479. int rc; /* Return code */
  7480. MemPage pPage; /* Page to delete cell from */
  7481. int pCell; /* Pointer to cell to delete */
  7482. int iCellIdx; /* Index of cell to delete */
  7483. int iCellDepth; /* Depth of node containing pCell */
  7484. Debug.Assert( cursorHoldsMutex( pCur ) );
  7485. Debug.Assert( pBt.inTransaction == TRANS_WRITE );
  7486. Debug.Assert( !pBt.readOnly );
  7487. Debug.Assert( pCur.wrFlag != 0 );
  7488. Debug.Assert( hasSharedCacheTableLock( p, pCur.pgnoRoot, pCur.pKeyInfo != null ? 1 : 0, 2 ) );
  7489. Debug.Assert( !hasReadConflicts( p, pCur.pgnoRoot ) );
  7490. if ( NEVER( pCur.aiIdx[pCur.iPage] >= pCur.apPage[pCur.iPage].nCell )
  7491. || NEVER( pCur.eState != CURSOR_VALID )
  7492. )
  7493. {
  7494. return SQLITE_ERROR; /* Something has gone awry. */
  7495. }
  7496. /* If this is a delete operation to remove a row from a table b-tree,
  7497. ** invalidate any incrblob cursors open on the row being deleted. */
  7498. if ( pCur.pKeyInfo == null )
  7499. {
  7500. invalidateIncrblobCursors( p, pCur.info.nKey, 0 );
  7501. }
  7502. iCellDepth = pCur.iPage;
  7503. iCellIdx = pCur.aiIdx[iCellDepth];
  7504. pPage = pCur.apPage[iCellDepth];
  7505. pCell = findCell( pPage, iCellIdx );
  7506. /* If the page containing the entry to delete is not a leaf page, move
  7507. ** the cursor to the largest entry in the tree that is smaller than
  7508. ** the entry being deleted. This cell will replace the cell being deleted
  7509. ** from the internal node. The 'previous' entry is used for this instead
  7510. ** of the 'next' entry, as the previous entry is always a part of the
  7511. ** sub-tree headed by the child page of the cell being deleted. This makes
  7512. ** balancing the tree following the delete operation easier. */
  7513. if ( 0 == pPage.leaf )
  7514. {
  7515. int notUsed = 0;
  7516. rc = sqlite3BtreePrevious( pCur, ref notUsed );
  7517. if ( rc != 0 )
  7518. return rc;
  7519. }
  7520. /* Save the positions of any other cursors open on this table before
  7521. ** making any modifications. Make the page containing the entry to be
  7522. ** deleted writable. Then free any overflow pages associated with the
  7523. ** entry and finally remove the cell itself from within the page.
  7524. */
  7525. rc = saveAllCursors( pBt, pCur.pgnoRoot, pCur );
  7526. if ( rc != 0 )
  7527. return rc;
  7528. rc = sqlite3PagerWrite( pPage.pDbPage );
  7529. if ( rc != 0 )
  7530. return rc;
  7531. rc = clearCell( pPage, pCell );
  7532. dropCell( pPage, iCellIdx, cellSizePtr( pPage, pCell ), ref rc );
  7533. if ( rc != 0 )
  7534. return rc;
  7535. /* If the cell deleted was not located on a leaf page, then the cursor
  7536. ** is currently pointing to the largest entry in the sub-tree headed
  7537. ** by the child-page of the cell that was just deleted from an internal
  7538. ** node. The cell from the leaf node needs to be moved to the internal
  7539. ** node to replace the deleted cell. */
  7540. if ( 0 == pPage.leaf )
  7541. {
  7542. MemPage pLeaf = pCur.apPage[pCur.iPage];
  7543. int nCell;
  7544. Pgno n = pCur.apPage[iCellDepth + 1].pgno;
  7545. //byte[] pTmp;
  7546. pCell = findCell( pLeaf, pLeaf.nCell - 1 );
  7547. nCell = cellSizePtr( pLeaf, pCell );
  7548. Debug.Assert( MX_CELL_SIZE( pBt ) >= nCell );
  7549. //allocateTempSpace(pBt);
  7550. //pTmp = pBt.pTmpSpace;
  7551. rc = sqlite3PagerWrite( pLeaf.pDbPage );
  7552. byte[] pNext_4 = sqlite3Malloc( nCell + 4 );
  7553. Buffer.BlockCopy( pLeaf.aData, pCell - 4, pNext_4, 0, nCell + 4 );
  7554. insertCell( pPage, iCellIdx, pNext_4, nCell + 4, null, n, ref rc ); //insertCell( pPage, iCellIdx, pCell - 4, nCell + 4, pTmp, n, ref rc );
  7555. dropCell( pLeaf, pLeaf.nCell - 1, nCell, ref rc );
  7556. if ( rc != 0 )
  7557. return rc;
  7558. }
  7559. /* Balance the tree. If the entry deleted was located on a leaf page,
  7560. ** then the cursor still points to that page. In this case the first
  7561. ** call to balance() repairs the tree, and the if(...) condition is
  7562. ** never true.
  7563. **
  7564. ** Otherwise, if the entry deleted was on an internal node page, then
  7565. ** pCur is pointing to the leaf page from which a cell was removed to
  7566. ** replace the cell deleted from the internal node. This is slightly
  7567. ** tricky as the leaf node may be underfull, and the internal node may
  7568. ** be either under or overfull. In this case run the balancing algorithm
  7569. ** on the leaf node first. If the balance proceeds far enough up the
  7570. ** tree that we can be sure that any problem in the internal node has
  7571. ** been corrected, so be it. Otherwise, after balancing the leaf node,
  7572. ** walk the cursor up the tree to the internal node and balance it as
  7573. ** well. */
  7574. rc = balance( pCur );
  7575. if ( rc == SQLITE_OK && pCur.iPage > iCellDepth )
  7576. {
  7577. while ( pCur.iPage > iCellDepth )
  7578. {
  7579. releasePage( pCur.apPage[pCur.iPage--] );
  7580. }
  7581. rc = balance( pCur );
  7582. }
  7583. if ( rc == SQLITE_OK )
  7584. {
  7585. moveToRoot( pCur );
  7586. }
  7587. return rc;
  7588. }
  7589. /*
  7590. ** Create a new BTree table. Write into piTable the page
  7591. ** number for the root page of the new table.
  7592. **
  7593. ** The type of type is determined by the flags parameter. Only the
  7594. ** following values of flags are currently in use. Other values for
  7595. ** flags might not work:
  7596. **
  7597. ** BTREE_INTKEY|BTREE_LEAFDATA Used for SQL tables with rowid keys
  7598. ** BTREE_ZERODATA Used for SQL indices
  7599. */
  7600. static int btreeCreateTable( Btree p, ref int piTable, int createTabFlags )
  7601. {
  7602. BtShared pBt = p.pBt;
  7603. MemPage pRoot = new MemPage();
  7604. Pgno pgnoRoot = 0;
  7605. int rc;
  7606. int ptfFlags; /* Page-type flage for the root page of new table */
  7607. Debug.Assert( sqlite3BtreeHoldsMutex( p ) );
  7608. Debug.Assert( pBt.inTransaction == TRANS_WRITE );
  7609. Debug.Assert( !pBt.readOnly );
  7610. #if SQLITE_OMIT_AUTOVACUUM
  7611. rc = allocateBtreePage(pBt, ref pRoot, ref pgnoRoot, 1, 0);
  7612. if( rc !=0){
  7613. return rc;
  7614. }
  7615. #else
  7616. if ( pBt.autoVacuum )
  7617. {
  7618. Pgno pgnoMove = 0; /* Move a page here to make room for the root-page */
  7619. MemPage pPageMove = new MemPage(); /* The page to move to. */
  7620. /* Creating a new table may probably require moving an existing database
  7621. ** to make room for the new tables root page. In case this page turns
  7622. ** out to be an overflow page, delete all overflow page-map caches
  7623. ** held by open cursors.
  7624. */
  7625. invalidateAllOverflowCache( pBt );
  7626. /* Read the value of meta[3] from the database to determine where the
  7627. ** root page of the new table should go. meta[3] is the largest root-page
  7628. ** created so far, so the new root-page is (meta[3]+1).
  7629. */
  7630. sqlite3BtreeGetMeta( p, BTREE_LARGEST_ROOT_PAGE, ref pgnoRoot );
  7631. pgnoRoot++;
  7632. /* The new root-page may not be allocated on a pointer-map page, or the
  7633. ** PENDING_BYTE page.
  7634. */
  7635. while ( pgnoRoot == PTRMAP_PAGENO( pBt, pgnoRoot ) ||
  7636. pgnoRoot == PENDING_BYTE_PAGE( pBt ) )
  7637. {
  7638. pgnoRoot++;
  7639. }
  7640. Debug.Assert( pgnoRoot >= 3 );
  7641. /* Allocate a page. The page that currently resides at pgnoRoot will
  7642. ** be moved to the allocated page (unless the allocated page happens
  7643. ** to reside at pgnoRoot).
  7644. */
  7645. rc = allocateBtreePage( pBt, ref pPageMove, ref pgnoMove, pgnoRoot, 1 );
  7646. if ( rc != SQLITE_OK )
  7647. {
  7648. return rc;
  7649. }
  7650. if ( pgnoMove != pgnoRoot )
  7651. {
  7652. /* pgnoRoot is the page that will be used for the root-page of
  7653. ** the new table (assuming an error did not occur). But we were
  7654. ** allocated pgnoMove. If required (i.e. if it was not allocated
  7655. ** by extending the file), the current page at position pgnoMove
  7656. ** is already journaled.
  7657. */
  7658. u8 eType = 0;
  7659. Pgno iPtrPage = 0;
  7660. releasePage( pPageMove );
  7661. /* Move the page currently at pgnoRoot to pgnoMove. */
  7662. rc = btreeGetPage( pBt, pgnoRoot, ref pRoot, 0 );
  7663. if ( rc != SQLITE_OK )
  7664. {
  7665. return rc;
  7666. }
  7667. rc = ptrmapGet( pBt, pgnoRoot, ref eType, ref iPtrPage );
  7668. if ( eType == PTRMAP_ROOTPAGE || eType == PTRMAP_FREEPAGE )
  7669. {
  7670. rc = SQLITE_CORRUPT_BKPT();
  7671. }
  7672. if ( rc != SQLITE_OK )
  7673. {
  7674. releasePage( pRoot );
  7675. return rc;
  7676. }
  7677. Debug.Assert( eType != PTRMAP_ROOTPAGE );
  7678. Debug.Assert( eType != PTRMAP_FREEPAGE );
  7679. rc = relocatePage( pBt, pRoot, eType, iPtrPage, pgnoMove, 0 );
  7680. releasePage( pRoot );
  7681. /* Obtain the page at pgnoRoot */
  7682. if ( rc != SQLITE_OK )
  7683. {
  7684. return rc;
  7685. }
  7686. rc = btreeGetPage( pBt, pgnoRoot, ref pRoot, 0 );
  7687. if ( rc != SQLITE_OK )
  7688. {
  7689. return rc;
  7690. }
  7691. rc = sqlite3PagerWrite( pRoot.pDbPage );
  7692. if ( rc != SQLITE_OK )
  7693. {
  7694. releasePage( pRoot );
  7695. return rc;
  7696. }
  7697. }
  7698. else
  7699. {
  7700. pRoot = pPageMove;
  7701. }
  7702. /* Update the pointer-map and meta-data with the new root-page number. */
  7703. ptrmapPut( pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, ref rc );
  7704. if ( rc != 0 )
  7705. {
  7706. releasePage( pRoot );
  7707. return rc;
  7708. }
  7709. /* When the new root page was allocated, page 1 was made writable in
  7710. ** order either to increase the database filesize, or to decrement the
  7711. ** freelist count. Hence, the sqlite3BtreeUpdateMeta() call cannot fail.
  7712. */
  7713. Debug.Assert( sqlite3PagerIswriteable( pBt.pPage1.pDbPage ) );
  7714. rc = sqlite3BtreeUpdateMeta( p, 4, pgnoRoot );
  7715. if ( NEVER( rc != 0 ) )
  7716. {
  7717. releasePage( pRoot );
  7718. return rc;
  7719. }
  7720. }
  7721. else
  7722. {
  7723. rc = allocateBtreePage( pBt, ref pRoot, ref pgnoRoot, 1, 0 );
  7724. if ( rc != 0 )
  7725. return rc;
  7726. }
  7727. #endif
  7728. Debug.Assert( sqlite3PagerIswriteable( pRoot.pDbPage ) );
  7729. if ( ( createTabFlags & BTREE_INTKEY ) != 0 )
  7730. {
  7731. ptfFlags = PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF;
  7732. }
  7733. else
  7734. {
  7735. ptfFlags = PTF_ZERODATA | PTF_LEAF;
  7736. }
  7737. zeroPage( pRoot, ptfFlags );
  7738. sqlite3PagerUnref( pRoot.pDbPage );
  7739. Debug.Assert( ( pBt.openFlags & BTREE_SINGLE ) == 0 || pgnoRoot == 2 );
  7740. piTable = (int)pgnoRoot;
  7741. return SQLITE_OK;
  7742. }
  7743. static int sqlite3BtreeCreateTable( Btree p, ref int piTable, int flags )
  7744. {
  7745. int rc;
  7746. sqlite3BtreeEnter( p );
  7747. rc = btreeCreateTable( p, ref piTable, flags );
  7748. sqlite3BtreeLeave( p );
  7749. return rc;
  7750. }
  7751. /*
  7752. ** Erase the given database page and all its children. Return
  7753. ** the page to the freelist.
  7754. */
  7755. static int clearDatabasePage(
  7756. BtShared pBt, /* The BTree that contains the table */
  7757. Pgno pgno, /* Page number to clear */
  7758. int freePageFlag, /* Deallocate page if true */
  7759. ref int pnChange /* Add number of Cells freed to this counter */
  7760. )
  7761. {
  7762. MemPage pPage = new MemPage();
  7763. int rc;
  7764. byte[] pCell;
  7765. int i;
  7766. Debug.Assert( sqlite3_mutex_held( pBt.mutex ) );
  7767. if ( pgno > btreePagecount( pBt ) )
  7768. {
  7769. return SQLITE_CORRUPT_BKPT();
  7770. }
  7771. rc = getAndInitPage( pBt, pgno, ref pPage );
  7772. if ( rc != 0 )
  7773. return rc;
  7774. for ( i = 0; i < pPage.nCell; i++ )
  7775. {
  7776. int iCell = findCell( pPage, i );
  7777. pCell = pPage.aData; // pCell = findCell( pPage, i );
  7778. if ( 0 == pPage.leaf )
  7779. {
  7780. rc = clearDatabasePage( pBt, sqlite3Get4byte( pCell, iCell ), 1, ref pnChange );
  7781. if ( rc != 0 )
  7782. goto cleardatabasepage_out;
  7783. }
  7784. rc = clearCell( pPage, iCell );
  7785. if ( rc != 0 )
  7786. goto cleardatabasepage_out;
  7787. }
  7788. if ( 0 == pPage.leaf )
  7789. {
  7790. rc = clearDatabasePage( pBt, sqlite3Get4byte( pPage.aData, 8 ), 1, ref pnChange );
  7791. if ( rc != 0 )
  7792. goto cleardatabasepage_out;
  7793. }
  7794. else //if (pnChange != 0)
  7795. {
  7796. //Debug.Assert(pPage.intKey != 0);
  7797. pnChange += pPage.nCell;
  7798. }
  7799. if ( freePageFlag != 0 )
  7800. {
  7801. freePage( pPage, ref rc );
  7802. }
  7803. else if ( ( rc = sqlite3PagerWrite( pPage.pDbPage ) ) == 0 )
  7804. {
  7805. zeroPage( pPage, pPage.aData[0] | PTF_LEAF );
  7806. }
  7807. cleardatabasepage_out:
  7808. releasePage( pPage );
  7809. return rc;
  7810. }
  7811. /*
  7812. ** Delete all information from a single table in the database. iTable is
  7813. ** the page number of the root of the table. After this routine returns,
  7814. ** the root page is empty, but still exists.
  7815. **
  7816. ** This routine will fail with SQLITE_LOCKED if there are any open
  7817. ** read cursors on the table. Open write cursors are moved to the
  7818. ** root of the table.
  7819. **
  7820. ** If pnChange is not NULL, then table iTable must be an intkey table. The
  7821. ** integer value pointed to by pnChange is incremented by the number of
  7822. ** entries in the table.
  7823. */
  7824. static int sqlite3BtreeClearTable( Btree p, int iTable, ref int pnChange )
  7825. {
  7826. int rc;
  7827. BtShared pBt = p.pBt;
  7828. sqlite3BtreeEnter( p );
  7829. Debug.Assert( p.inTrans == TRANS_WRITE );
  7830. /* Invalidate all incrblob cursors open on table iTable (assuming iTable
  7831. ** is the root of a table b-tree - if it is not, the following call is
  7832. ** a no-op). */
  7833. invalidateIncrblobCursors( p, 0, 1 );
  7834. rc = saveAllCursors( pBt, (Pgno)iTable, null );
  7835. if ( SQLITE_OK == rc )
  7836. {
  7837. rc = clearDatabasePage( pBt, (Pgno)iTable, 0, ref pnChange );
  7838. }
  7839. sqlite3BtreeLeave( p );
  7840. return rc;
  7841. }
  7842. /*
  7843. ** Erase all information in a table and add the root of the table to
  7844. ** the freelist. Except, the root of the principle table (the one on
  7845. ** page 1) is never added to the freelist.
  7846. **
  7847. ** This routine will fail with SQLITE_LOCKED if there are any open
  7848. ** cursors on the table.
  7849. **
  7850. ** If AUTOVACUUM is enabled and the page at iTable is not the last
  7851. ** root page in the database file, then the last root page
  7852. ** in the database file is moved into the slot formerly occupied by
  7853. ** iTable and that last slot formerly occupied by the last root page
  7854. ** is added to the freelist instead of iTable. In this say, all
  7855. ** root pages are kept at the beginning of the database file, which
  7856. ** is necessary for AUTOVACUUM to work right. piMoved is set to the
  7857. ** page number that used to be the last root page in the file before
  7858. ** the move. If no page gets moved, piMoved is set to 0.
  7859. ** The last root page is recorded in meta[3] and the value of
  7860. ** meta[3] is updated by this procedure.
  7861. */
  7862. static int btreeDropTable( Btree p, Pgno iTable, ref int piMoved )
  7863. {
  7864. int rc;
  7865. MemPage pPage = null;
  7866. BtShared pBt = p.pBt;
  7867. Debug.Assert( sqlite3BtreeHoldsMutex( p ) );
  7868. Debug.Assert( p.inTrans == TRANS_WRITE );
  7869. /* It is illegal to drop a table if any cursors are open on the
  7870. ** database. This is because in auto-vacuum mode the backend may
  7871. ** need to move another root-page to fill a gap left by the deleted
  7872. ** root page. If an open cursor was using this page a problem would
  7873. ** occur.
  7874. **
  7875. ** This error is caught long before control reaches this point.
  7876. */
  7877. if ( NEVER( pBt.pCursor ) )
  7878. {
  7879. sqlite3ConnectionBlocked( p.db, pBt.pCursor.pBtree.db );
  7880. return SQLITE_LOCKED_SHAREDCACHE;
  7881. }
  7882. rc = btreeGetPage( pBt, (Pgno)iTable, ref pPage, 0 );
  7883. if ( rc != 0 )
  7884. return rc;
  7885. int Dummy0 = 0;
  7886. rc = sqlite3BtreeClearTable( p, (int)iTable, ref Dummy0 );
  7887. if ( rc != 0 )
  7888. {
  7889. releasePage( pPage );
  7890. return rc;
  7891. }
  7892. piMoved = 0;
  7893. if ( iTable > 1 )
  7894. {
  7895. #if SQLITE_OMIT_AUTOVACUUM
  7896. freePage(pPage, ref rc);
  7897. releasePage(pPage);
  7898. #else
  7899. if ( pBt.autoVacuum )
  7900. {
  7901. Pgno maxRootPgno = 0;
  7902. sqlite3BtreeGetMeta( p, BTREE_LARGEST_ROOT_PAGE, ref maxRootPgno );
  7903. if ( iTable == maxRootPgno )
  7904. {
  7905. /* If the table being dropped is the table with the largest root-page
  7906. ** number in the database, put the root page on the free list.
  7907. */
  7908. freePage( pPage, ref rc );
  7909. releasePage( pPage );
  7910. if ( rc != SQLITE_OK )
  7911. {
  7912. return rc;
  7913. }
  7914. }
  7915. else
  7916. {
  7917. /* The table being dropped does not have the largest root-page
  7918. ** number in the database. So move the page that does into the
  7919. ** gap left by the deleted root-page.
  7920. */
  7921. MemPage pMove = new MemPage();
  7922. releasePage( pPage );
  7923. rc = btreeGetPage( pBt, maxRootPgno, ref pMove, 0 );
  7924. if ( rc != SQLITE_OK )
  7925. {
  7926. return rc;
  7927. }
  7928. rc = relocatePage( pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable, 0 );
  7929. releasePage( pMove );
  7930. if ( rc != SQLITE_OK )
  7931. {
  7932. return rc;
  7933. }
  7934. pMove = null;
  7935. rc = btreeGetPage( pBt, maxRootPgno, ref pMove, 0 );
  7936. freePage( pMove, ref rc );
  7937. releasePage( pMove );
  7938. if ( rc != SQLITE_OK )
  7939. {
  7940. return rc;
  7941. }
  7942. piMoved = (int)maxRootPgno;
  7943. }
  7944. /* Set the new 'max-root-page' value in the database header. This
  7945. ** is the old value less one, less one more if that happens to
  7946. ** be a root-page number, less one again if that is the
  7947. ** PENDING_BYTE_PAGE.
  7948. */
  7949. maxRootPgno--;
  7950. while ( maxRootPgno == PENDING_BYTE_PAGE( pBt )
  7951. || PTRMAP_ISPAGE( pBt, maxRootPgno ) )
  7952. {
  7953. maxRootPgno--;
  7954. }
  7955. Debug.Assert( maxRootPgno != PENDING_BYTE_PAGE( pBt ) );
  7956. rc = sqlite3BtreeUpdateMeta( p, 4, maxRootPgno );
  7957. }
  7958. else
  7959. {
  7960. freePage( pPage, ref rc );
  7961. releasePage( pPage );
  7962. }
  7963. #endif
  7964. }
  7965. else
  7966. {
  7967. /* If sqlite3BtreeDropTable was called on page 1.
  7968. ** This really never should happen except in a corrupt
  7969. ** database.
  7970. */
  7971. zeroPage( pPage, PTF_INTKEY | PTF_LEAF );
  7972. releasePage( pPage );
  7973. }
  7974. return rc;
  7975. }
  7976. static int sqlite3BtreeDropTable( Btree p, int iTable, ref int piMoved )
  7977. {
  7978. int rc;
  7979. sqlite3BtreeEnter( p );
  7980. rc = btreeDropTable( p, (u32)iTable, ref piMoved );
  7981. sqlite3BtreeLeave( p );
  7982. return rc;
  7983. }
  7984. /*
  7985. ** This function may only be called if the b-tree connection already
  7986. ** has a read or write transaction open on the database.
  7987. **
  7988. ** Read the meta-information out of a database file. Meta[0]
  7989. ** is the number of free pages currently in the database. Meta[1]
  7990. ** through meta[15] are available for use by higher layers. Meta[0]
  7991. ** is read-only, the others are read/write.
  7992. **
  7993. ** The schema layer numbers meta values differently. At the schema
  7994. ** layer (and the SetCookie and ReadCookie opcodes) the number of
  7995. ** free pages is not visible. So Cookie[0] is the same as Meta[1].
  7996. */
  7997. static void sqlite3BtreeGetMeta( Btree p, int idx, ref u32 pMeta )
  7998. {
  7999. BtShared pBt = p.pBt;
  8000. sqlite3BtreeEnter( p );
  8001. Debug.Assert( p.inTrans > TRANS_NONE );
  8002. Debug.Assert( SQLITE_OK == querySharedCacheTableLock( p, MASTER_ROOT, READ_LOCK ) );
  8003. Debug.Assert( pBt.pPage1 != null );
  8004. Debug.Assert( idx >= 0 && idx <= 15 );
  8005. pMeta = sqlite3Get4byte( pBt.pPage1.aData, 36 + idx * 4 );
  8006. /* If auto-vacuum is disabled in this build and this is an auto-vacuum
  8007. ** database, mark the database as read-only. */
  8008. #if SQLITE_OMIT_AUTOVACUUM
  8009. if( idx==BTREE_LARGEST_ROOT_PAGE && pMeta>0 ) pBt.readOnly = 1;
  8010. #endif
  8011. sqlite3BtreeLeave( p );
  8012. }
  8013. /*
  8014. ** Write meta-information back into the database. Meta[0] is
  8015. ** read-only and may not be written.
  8016. */
  8017. static int sqlite3BtreeUpdateMeta( Btree p, int idx, u32 iMeta )
  8018. {
  8019. BtShared pBt = p.pBt;
  8020. byte[] pP1;
  8021. int rc;
  8022. Debug.Assert( idx >= 1 && idx <= 15 );
  8023. sqlite3BtreeEnter( p );
  8024. Debug.Assert( p.inTrans == TRANS_WRITE );
  8025. Debug.Assert( pBt.pPage1 != null );
  8026. pP1 = pBt.pPage1.aData;
  8027. rc = sqlite3PagerWrite( pBt.pPage1.pDbPage );
  8028. if ( rc == SQLITE_OK )
  8029. {
  8030. sqlite3Put4byte( pP1, 36 + idx * 4, iMeta );
  8031. #if !SQLITE_OMIT_AUTOVACUUM
  8032. if ( idx == BTREE_INCR_VACUUM )
  8033. {
  8034. Debug.Assert( pBt.autoVacuum || iMeta == 0 );
  8035. Debug.Assert( iMeta == 0 || iMeta == 1 );
  8036. pBt.incrVacuum = iMeta != 0;
  8037. }
  8038. #endif
  8039. }
  8040. sqlite3BtreeLeave( p );
  8041. return rc;
  8042. }
  8043. #if !SQLITE_OMIT_BTREECOUNT
  8044. /*
  8045. ** The first argument, pCur, is a cursor opened on some b-tree. Count the
  8046. ** number of entries in the b-tree and write the result to pnEntry.
  8047. **
  8048. ** SQLITE_OK is returned if the operation is successfully executed.
  8049. ** Otherwise, if an error is encountered (i.e. an IO error or database
  8050. ** corruption) an SQLite error code is returned.
  8051. */
  8052. static int sqlite3BtreeCount( BtCursor pCur, ref i64 pnEntry )
  8053. {
  8054. i64 nEntry = 0; /* Value to return in pnEntry */
  8055. int rc; /* Return code */
  8056. rc = moveToRoot( pCur );
  8057. /* Unless an error occurs, the following loop runs one iteration for each
  8058. ** page in the B-Tree structure (not including overflow pages).
  8059. */
  8060. while ( rc == SQLITE_OK )
  8061. {
  8062. int iIdx; /* Index of child node in parent */
  8063. MemPage pPage; /* Current page of the b-tree */
  8064. /* If this is a leaf page or the tree is not an int-key tree, then
  8065. ** this page contains countable entries. Increment the entry counter
  8066. ** accordingly.
  8067. */
  8068. pPage = pCur.apPage[pCur.iPage];
  8069. if ( pPage.leaf != 0 || 0 == pPage.intKey )
  8070. {
  8071. nEntry += pPage.nCell;
  8072. }
  8073. /* pPage is a leaf node. This loop navigates the cursor so that it
  8074. ** points to the first interior cell that it points to the parent of
  8075. ** the next page in the tree that has not yet been visited. The
  8076. ** pCur.aiIdx[pCur.iPage] value is set to the index of the parent cell
  8077. ** of the page, or to the number of cells in the page if the next page
  8078. ** to visit is the right-child of its parent.
  8079. **
  8080. ** If all pages in the tree have been visited, return SQLITE_OK to the
  8081. ** caller.
  8082. */
  8083. if ( pPage.leaf != 0 )
  8084. {
  8085. do
  8086. {
  8087. if ( pCur.iPage == 0 )
  8088. {
  8089. /* All pages of the b-tree have been visited. Return successfully. */
  8090. pnEntry = nEntry;
  8091. return SQLITE_OK;
  8092. }
  8093. moveToParent( pCur );
  8094. } while ( pCur.aiIdx[pCur.iPage] >= pCur.apPage[pCur.iPage].nCell );
  8095. pCur.aiIdx[pCur.iPage]++;
  8096. pPage = pCur.apPage[pCur.iPage];
  8097. }
  8098. /* Descend to the child node of the cell that the cursor currently
  8099. ** points at. This is the right-child if (iIdx==pPage.nCell).
  8100. */
  8101. iIdx = pCur.aiIdx[pCur.iPage];
  8102. if ( iIdx == pPage.nCell )
  8103. {
  8104. rc = moveToChild( pCur, sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 ) );
  8105. }
  8106. else
  8107. {
  8108. rc = moveToChild( pCur, sqlite3Get4byte( pPage.aData, findCell( pPage, iIdx ) ) );
  8109. }
  8110. }
  8111. /* An error has occurred. Return an error code. */
  8112. return rc;
  8113. }
  8114. #endif
  8115. /*
  8116. ** Return the pager associated with a BTree. This routine is used for
  8117. ** testing and debugging only.
  8118. */
  8119. static Pager sqlite3BtreePager( Btree p )
  8120. {
  8121. return p.pBt.pPager;
  8122. }
  8123. #if !SQLITE_OMIT_INTEGRITY_CHECK
  8124. /*
  8125. ** Append a message to the error message string.
  8126. */
  8127. static void checkAppendMsg(
  8128. IntegrityCk pCheck,
  8129. string zMsg1,
  8130. string zFormat,
  8131. params object[] ap
  8132. )
  8133. {
  8134. if ( 0 == pCheck.mxErr )
  8135. return;
  8136. //va_list ap;
  8137. lock ( lock_va_list )
  8138. {
  8139. pCheck.mxErr--;
  8140. pCheck.nErr++;
  8141. va_start( ap, zFormat );
  8142. if ( pCheck.errMsg.zText.Length != 0 )
  8143. {
  8144. sqlite3StrAccumAppend( pCheck.errMsg, "\n", 1 );
  8145. }
  8146. if ( zMsg1.Length > 0 )
  8147. {
  8148. sqlite3StrAccumAppend( pCheck.errMsg, zMsg1.ToString(), -1 );
  8149. }
  8150. sqlite3VXPrintf( pCheck.errMsg, 1, zFormat, ap );
  8151. va_end( ref ap );
  8152. }
  8153. }
  8154. static void checkAppendMsg(
  8155. IntegrityCk pCheck,
  8156. StringBuilder zMsg1,
  8157. string zFormat,
  8158. params object[] ap
  8159. )
  8160. {
  8161. if ( 0 == pCheck.mxErr )
  8162. return;
  8163. //va_list ap;
  8164. lock ( lock_va_list )
  8165. {
  8166. pCheck.mxErr--;
  8167. pCheck.nErr++;
  8168. va_start( ap, zFormat );
  8169. if ( pCheck.errMsg.zText.Length != 0 )
  8170. {
  8171. sqlite3StrAccumAppend( pCheck.errMsg, "\n", 1 );
  8172. }
  8173. if ( zMsg1.Length > 0 )
  8174. {
  8175. sqlite3StrAccumAppend( pCheck.errMsg, zMsg1.ToString(), -1 );
  8176. }
  8177. sqlite3VXPrintf( pCheck.errMsg, 1, zFormat, ap );
  8178. va_end( ref ap );
  8179. }
  8180. //if( pCheck.errMsg.mallocFailed ){
  8181. // pCheck.mallocFailed = 1;
  8182. //}
  8183. }
  8184. #endif //* SQLITE_OMIT_INTEGRITY_CHECK */
  8185. #if !SQLITE_OMIT_INTEGRITY_CHECK
  8186. /*
  8187. ** Add 1 to the reference count for page iPage. If this is the second
  8188. ** reference to the page, add an error message to pCheck.zErrMsg.
  8189. ** Return 1 if there are 2 ore more references to the page and 0 if
  8190. ** if this is the first reference to the page.
  8191. **
  8192. ** Also check that the page number is in bounds.
  8193. */
  8194. static int checkRef( IntegrityCk pCheck, Pgno iPage, string zContext )
  8195. {
  8196. if ( iPage == 0 )
  8197. return 1;
  8198. if ( iPage > pCheck.nPage )
  8199. {
  8200. checkAppendMsg( pCheck, zContext, "invalid page number %d", iPage );
  8201. return 1;
  8202. }
  8203. if ( pCheck.anRef[iPage] == 1 )
  8204. {
  8205. checkAppendMsg( pCheck, zContext, "2nd reference to page %d", iPage );
  8206. return 1;
  8207. }
  8208. return ( ( pCheck.anRef[iPage]++ ) > 1 ) ? 1 : 0;
  8209. }
  8210. #if !SQLITE_OMIT_AUTOVACUUM
  8211. /*
  8212. ** Check that the entry in the pointer-map for page iChild maps to
  8213. ** page iParent, pointer type ptrType. If not, append an error message
  8214. ** to pCheck.
  8215. */
  8216. static void checkPtrmap(
  8217. IntegrityCk pCheck, /* Integrity check context */
  8218. Pgno iChild, /* Child page number */
  8219. u8 eType, /* Expected pointer map type */
  8220. Pgno iParent, /* Expected pointer map parent page number */
  8221. string zContext /* Context description (used for error msg) */
  8222. )
  8223. {
  8224. int rc;
  8225. u8 ePtrmapType = 0;
  8226. Pgno iPtrmapParent = 0;
  8227. rc = ptrmapGet( pCheck.pBt, iChild, ref ePtrmapType, ref iPtrmapParent );
  8228. if ( rc != SQLITE_OK )
  8229. {
  8230. //if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck.mallocFailed = 1;
  8231. checkAppendMsg( pCheck, zContext, "Failed to read ptrmap key=%d", iChild );
  8232. return;
  8233. }
  8234. if ( ePtrmapType != eType || iPtrmapParent != iParent )
  8235. {
  8236. checkAppendMsg( pCheck, zContext,
  8237. "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)",
  8238. iChild, eType, iParent, ePtrmapType, iPtrmapParent );
  8239. }
  8240. }
  8241. #endif
  8242. /*
  8243. ** Check the integrity of the freelist or of an overflow page list.
  8244. ** Verify that the number of pages on the list is N.
  8245. */
  8246. static void checkList(
  8247. IntegrityCk pCheck, /* Integrity checking context */
  8248. int isFreeList, /* True for a freelist. False for overflow page list */
  8249. int iPage, /* Page number for first page in the list */
  8250. int N, /* Expected number of pages in the list */
  8251. string zContext /* Context for error messages */
  8252. )
  8253. {
  8254. int i;
  8255. int expected = N;
  8256. int iFirst = iPage;
  8257. while ( N-- > 0 && pCheck.mxErr != 0 )
  8258. {
  8259. PgHdr pOvflPage = new PgHdr();
  8260. byte[] pOvflData;
  8261. if ( iPage < 1 )
  8262. {
  8263. checkAppendMsg( pCheck, zContext,
  8264. "%d of %d pages missing from overflow list starting at %d",
  8265. N + 1, expected, iFirst );
  8266. break;
  8267. }
  8268. if ( checkRef( pCheck, (u32)iPage, zContext ) != 0 )
  8269. break;
  8270. if ( sqlite3PagerGet( pCheck.pPager, (Pgno)iPage, ref pOvflPage ) != 0 )
  8271. {
  8272. checkAppendMsg( pCheck, zContext, "failed to get page %d", iPage );
  8273. break;
  8274. }
  8275. pOvflData = sqlite3PagerGetData( pOvflPage );
  8276. if ( isFreeList != 0 )
  8277. {
  8278. int n = (int)sqlite3Get4byte( pOvflData, 4 );
  8279. #if !SQLITE_OMIT_AUTOVACUUM
  8280. if ( pCheck.pBt.autoVacuum )
  8281. {
  8282. checkPtrmap( pCheck, (u32)iPage, PTRMAP_FREEPAGE, 0, zContext );
  8283. }
  8284. #endif
  8285. if ( n > (int)pCheck.pBt.usableSize / 4 - 2 )
  8286. {
  8287. checkAppendMsg( pCheck, zContext,
  8288. "freelist leaf count too big on page %d", iPage );
  8289. N--;
  8290. }
  8291. else
  8292. {
  8293. for ( i = 0; i < n; i++ )
  8294. {
  8295. Pgno iFreePage = sqlite3Get4byte( pOvflData, 8 + i * 4 );
  8296. #if !SQLITE_OMIT_AUTOVACUUM
  8297. if ( pCheck.pBt.autoVacuum )
  8298. {
  8299. checkPtrmap( pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext );
  8300. }
  8301. #endif
  8302. checkRef( pCheck, iFreePage, zContext );
  8303. }
  8304. N -= n;
  8305. }
  8306. }
  8307. #if !SQLITE_OMIT_AUTOVACUUM
  8308. else
  8309. {
  8310. /* If this database supports auto-vacuum and iPage is not the last
  8311. ** page in this overflow list, check that the pointer-map entry for
  8312. ** the following page matches iPage.
  8313. */
  8314. if ( pCheck.pBt.autoVacuum && N > 0 )
  8315. {
  8316. i = (int)sqlite3Get4byte( pOvflData );
  8317. checkPtrmap( pCheck, (u32)i, PTRMAP_OVERFLOW2, (u32)iPage, zContext );
  8318. }
  8319. }
  8320. #endif
  8321. iPage = (int)sqlite3Get4byte( pOvflData );
  8322. sqlite3PagerUnref( pOvflPage );
  8323. }
  8324. }
  8325. #endif //* SQLITE_OMIT_INTEGRITY_CHECK */
  8326. #if !SQLITE_OMIT_INTEGRITY_CHECK
  8327. /*
  8328. ** Do various sanity checks on a single page of a tree. Return
  8329. ** the tree depth. Root pages return 0. Parents of root pages
  8330. ** return 1, and so forth.
  8331. **
  8332. ** These checks are done:
  8333. **
  8334. ** 1. Make sure that cells and freeblocks do not overlap
  8335. ** but combine to completely cover the page.
  8336. ** NO 2. Make sure cell keys are in order.
  8337. ** NO 3. Make sure no key is less than or equal to zLowerBound.
  8338. ** NO 4. Make sure no key is greater than or equal to zUpperBound.
  8339. ** 5. Check the integrity of overflow pages.
  8340. ** 6. Recursively call checkTreePage on all children.
  8341. ** 7. Verify that the depth of all children is the same.
  8342. ** 8. Make sure this page is at least 33% full or else it is
  8343. ** the root of the tree.
  8344. */
  8345. static i64 refNULL = 0; //Dummy for C# ref NULL
  8346. static int checkTreePage(
  8347. IntegrityCk pCheck, /* Context for the sanity check */
  8348. int iPage, /* Page number of the page to check */
  8349. string zParentContext, /* Parent context */
  8350. ref i64 pnParentMinKey,
  8351. ref i64 pnParentMaxKey,
  8352. object _pnParentMinKey, /* C# Needed to determine if content passed*/
  8353. object _pnParentMaxKey /* C# Needed to determine if content passed*/
  8354. )
  8355. {
  8356. MemPage pPage = new MemPage();
  8357. int i, rc, depth, d2, pgno, cnt;
  8358. int hdr, cellStart;
  8359. int nCell;
  8360. u8[] data;
  8361. BtShared pBt;
  8362. int usableSize;
  8363. StringBuilder zContext = new StringBuilder( 100 );
  8364. byte[] hit = null;
  8365. i64 nMinKey = 0;
  8366. i64 nMaxKey = 0;
  8367. sqlite3_snprintf( 200, zContext, "Page %d: ", iPage );
  8368. /* Check that the page exists
  8369. */
  8370. pBt = pCheck.pBt;
  8371. usableSize = (int)pBt.usableSize;
  8372. if ( iPage == 0 )
  8373. return 0;
  8374. if ( checkRef( pCheck, (u32)iPage, zParentContext ) != 0 )
  8375. return 0;
  8376. if ( ( rc = btreeGetPage( pBt, (Pgno)iPage, ref pPage, 0 ) ) != 0 )
  8377. {
  8378. checkAppendMsg( pCheck, zContext.ToString(),
  8379. "unable to get the page. error code=%d", rc );
  8380. return 0;
  8381. }
  8382. /* Clear MemPage.isInit to make sure the corruption detection code in
  8383. ** btreeInitPage() is executed. */
  8384. pPage.isInit = 0;
  8385. if ( ( rc = btreeInitPage( pPage ) ) != 0 )
  8386. {
  8387. Debug.Assert( rc == SQLITE_CORRUPT ); /* The only possible error from InitPage */
  8388. checkAppendMsg( pCheck, zContext.ToString(),
  8389. "btreeInitPage() returns error code %d", rc );
  8390. releasePage( pPage );
  8391. return 0;
  8392. }
  8393. /* Check out all the cells.
  8394. */
  8395. depth = 0;
  8396. for ( i = 0; i < pPage.nCell && pCheck.mxErr != 0; i++ )
  8397. {
  8398. u8[] pCell;
  8399. u32 sz;
  8400. CellInfo info = new CellInfo();
  8401. /* Check payload overflow pages
  8402. */
  8403. sqlite3_snprintf( 200, zContext,
  8404. "On tree page %d cell %d: ", iPage, i );
  8405. int iCell = findCell( pPage, i ); //pCell = findCell( pPage, i );
  8406. pCell = pPage.aData;
  8407. btreeParseCellPtr( pPage, iCell, ref info ); //btreeParseCellPtr( pPage, pCell, info );
  8408. sz = info.nData;
  8409. if ( 0 == pPage.intKey )
  8410. sz += (u32)info.nKey;
  8411. /* For intKey pages, check that the keys are in order.
  8412. */
  8413. else if ( i == 0 )
  8414. nMinKey = nMaxKey = info.nKey;
  8415. else
  8416. {
  8417. if ( info.nKey <= nMaxKey )
  8418. {
  8419. checkAppendMsg( pCheck, zContext.ToString(),
  8420. "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey );
  8421. }
  8422. nMaxKey = info.nKey;
  8423. }
  8424. Debug.Assert( sz == info.nPayload );
  8425. if ( ( sz > info.nLocal )
  8426. //&& (pCell[info.iOverflow]<=&pPage.aData[pBt.usableSize])
  8427. )
  8428. {
  8429. int nPage = (int)( sz - info.nLocal + usableSize - 5 ) / ( usableSize - 4 );
  8430. Pgno pgnoOvfl = sqlite3Get4byte( pCell, iCell, info.iOverflow );
  8431. #if !SQLITE_OMIT_AUTOVACUUM
  8432. if ( pBt.autoVacuum )
  8433. {
  8434. checkPtrmap( pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, (u32)iPage, zContext.ToString() );
  8435. }
  8436. #endif
  8437. checkList( pCheck, 0, (int)pgnoOvfl, nPage, zContext.ToString() );
  8438. }
  8439. /* Check sanity of left child page.
  8440. */
  8441. if ( 0 == pPage.leaf )
  8442. {
  8443. pgno = (int)sqlite3Get4byte( pCell, iCell ); //sqlite3Get4byte( pCell );
  8444. #if !SQLITE_OMIT_AUTOVACUUM
  8445. if ( pBt.autoVacuum )
  8446. {
  8447. checkPtrmap( pCheck, (u32)pgno, PTRMAP_BTREE, (u32)iPage, zContext.ToString() );
  8448. }
  8449. #endif
  8450. if ( i == 0 )
  8451. d2 = checkTreePage( pCheck, pgno, zContext.ToString(), ref nMinKey, ref refNULL, pCheck, null );
  8452. else
  8453. d2 = checkTreePage( pCheck, pgno, zContext.ToString(), ref nMinKey, ref nMaxKey, pCheck, pCheck );
  8454. if ( i > 0 && d2 != depth )
  8455. {
  8456. checkAppendMsg( pCheck, zContext, "Child page depth differs" );
  8457. }
  8458. depth = d2;
  8459. }
  8460. }
  8461. if ( 0 == pPage.leaf )
  8462. {
  8463. pgno = (int)sqlite3Get4byte( pPage.aData, pPage.hdrOffset + 8 );
  8464. sqlite3_snprintf( 200, zContext,
  8465. "On page %d at right child: ", iPage );
  8466. #if !SQLITE_OMIT_AUTOVACUUM
  8467. if ( pBt.autoVacuum )
  8468. {
  8469. checkPtrmap( pCheck, (u32)pgno, PTRMAP_BTREE, (u32)iPage, zContext.ToString() );
  8470. }
  8471. #endif
  8472. // checkTreePage(pCheck, pgno, zContext, NULL, !pPage->nCell ? NULL : &nMaxKey);
  8473. if ( 0 == pPage.nCell )
  8474. checkTreePage( pCheck, pgno, zContext.ToString(), ref refNULL, ref refNULL, null, null );
  8475. else
  8476. checkTreePage( pCheck, pgno, zContext.ToString(), ref refNULL, ref nMaxKey, null, pCheck );
  8477. }
  8478. /* For intKey leaf pages, check that the min/max keys are in order
  8479. ** with any left/parent/right pages.
  8480. */
  8481. if ( pPage.leaf != 0 && pPage.intKey != 0 )
  8482. {
  8483. /* if we are a left child page */
  8484. if ( _pnParentMinKey != null )
  8485. {
  8486. /* if we are the left most child page */
  8487. if ( _pnParentMaxKey == null )
  8488. {
  8489. if ( nMaxKey > pnParentMinKey )
  8490. {
  8491. checkAppendMsg( pCheck, zContext,
  8492. "Rowid %lld out of order (max larger than parent min of %lld)",
  8493. nMaxKey, pnParentMinKey );
  8494. }
  8495. }
  8496. else
  8497. {
  8498. if ( nMinKey <= pnParentMinKey )
  8499. {
  8500. checkAppendMsg( pCheck, zContext,
  8501. "Rowid %lld out of order (min less than parent min of %lld)",
  8502. nMinKey, pnParentMinKey );
  8503. }
  8504. if ( nMaxKey > pnParentMaxKey )
  8505. {
  8506. checkAppendMsg( pCheck, zContext,
  8507. "Rowid %lld out of order (max larger than parent max of %lld)",
  8508. nMaxKey, pnParentMaxKey );
  8509. }
  8510. pnParentMinKey = nMaxKey;
  8511. }
  8512. /* else if we're a right child page */
  8513. }
  8514. else if ( _pnParentMaxKey != null )
  8515. {
  8516. if ( nMinKey <= pnParentMaxKey )
  8517. {
  8518. checkAppendMsg( pCheck, zContext,
  8519. "Rowid %lld out of order (min less than parent max of %lld)",
  8520. nMinKey, pnParentMaxKey );
  8521. }
  8522. }
  8523. }
  8524. /* Check for complete coverage of the page
  8525. */
  8526. data = pPage.aData;
  8527. hdr = pPage.hdrOffset;
  8528. hit = sqlite3Malloc( pBt.pageSize );
  8529. //if( hit==null ){
  8530. // pCheck.mallocFailed = 1;
  8531. //}else
  8532. {
  8533. int contentOffset = get2byteNotZero( data, hdr + 5 );
  8534. Debug.Assert( contentOffset <= usableSize ); /* Enforced by btreeInitPage() */
  8535. Array.Clear( hit, contentOffset, usableSize - contentOffset );//memset(hit+contentOffset, 0, usableSize-contentOffset);
  8536. for ( int iLoop = contentOffset - 1; iLoop >= 0; iLoop-- )
  8537. hit[iLoop] = 1;//memset(hit, 1, contentOffset);
  8538. nCell = get2byte( data, hdr + 3 );
  8539. cellStart = hdr + 12 - 4 * pPage.leaf;
  8540. for ( i = 0; i < nCell; i++ )
  8541. {
  8542. int pc = get2byte( data, cellStart + i * 2 );
  8543. u32 size = 65536;
  8544. int j;
  8545. if ( pc <= usableSize - 4 )
  8546. {
  8547. size = cellSizePtr( pPage, data, pc );
  8548. }
  8549. if ( (int)( pc + size - 1 ) >= usableSize )
  8550. {
  8551. checkAppendMsg( pCheck, "",
  8552. "Corruption detected in cell %d on page %d", i, iPage );
  8553. }
  8554. else
  8555. {
  8556. for ( j = (int)( pc + size - 1 ); j >= pc; j-- )
  8557. hit[j]++;
  8558. }
  8559. }
  8560. i = get2byte( data, hdr + 1 );
  8561. while ( i > 0 )
  8562. {
  8563. int size, j;
  8564. Debug.Assert( i <= usableSize - 4 ); /* Enforced by btreeInitPage() */
  8565. size = get2byte( data, i + 2 );
  8566. Debug.Assert( i + size <= usableSize ); /* Enforced by btreeInitPage() */
  8567. for ( j = i + size - 1; j >= i; j-- )
  8568. hit[j]++;
  8569. j = get2byte( data, i );
  8570. Debug.Assert( j == 0 || j > i + size ); /* Enforced by btreeInitPage() */
  8571. Debug.Assert( j <= usableSize - 4 ); /* Enforced by btreeInitPage() */
  8572. i = j;
  8573. }
  8574. for ( i = cnt = 0; i < usableSize; i++ )
  8575. {
  8576. if ( hit[i] == 0 )
  8577. {
  8578. cnt++;
  8579. }
  8580. else if ( hit[i] > 1 )
  8581. {
  8582. checkAppendMsg( pCheck, "",
  8583. "Multiple uses for byte %d of page %d", i, iPage );
  8584. break;
  8585. }
  8586. }
  8587. if ( cnt != data[hdr + 7] )
  8588. {
  8589. checkAppendMsg( pCheck, "",
  8590. "Fragmentation of %d bytes reported as %d on page %d",
  8591. cnt, data[hdr + 7], iPage );
  8592. }
  8593. }
  8594. sqlite3PageFree( ref hit );
  8595. releasePage( pPage );
  8596. return depth + 1;
  8597. }
  8598. #endif //* SQLITE_OMIT_INTEGRITY_CHECK */
  8599. #if !SQLITE_OMIT_INTEGRITY_CHECK
  8600. /*
  8601. ** This routine does a complete check of the given BTree file. aRoot[] is
  8602. ** an array of pages numbers were each page number is the root page of
  8603. ** a table. nRoot is the number of entries in aRoot.
  8604. **
  8605. ** A read-only or read-write transaction must be opened before calling
  8606. ** this function.
  8607. **
  8608. ** Write the number of error seen in pnErr. Except for some memory
  8609. ** allocation errors, an error message held in memory obtained from
  8610. ** malloc is returned if pnErr is non-zero. If pnErr==null then NULL is
  8611. ** returned. If a memory allocation error occurs, NULL is returned.
  8612. */
  8613. static string sqlite3BtreeIntegrityCheck(
  8614. Btree p, /* The btree to be checked */
  8615. int[] aRoot, /* An array of root pages numbers for individual trees */
  8616. int nRoot, /* Number of entries in aRoot[] */
  8617. int mxErr, /* Stop reporting errors after this many */
  8618. ref int pnErr /* Write number of errors seen to this variable */
  8619. )
  8620. {
  8621. Pgno i;
  8622. int nRef;
  8623. IntegrityCk sCheck = new IntegrityCk();
  8624. BtShared pBt = p.pBt;
  8625. sqlite3BtreeEnter( p );
  8626. Debug.Assert( p.inTrans > TRANS_NONE && pBt.inTransaction > TRANS_NONE );
  8627. nRef = sqlite3PagerRefcount( pBt.pPager );
  8628. sCheck.pBt = pBt;
  8629. sCheck.pPager = pBt.pPager;
  8630. sCheck.nPage = btreePagecount( sCheck.pBt );
  8631. sCheck.mxErr = mxErr;
  8632. sCheck.nErr = 0;
  8633. //sCheck.mallocFailed = 0;
  8634. pnErr = 0;
  8635. if ( sCheck.nPage == 0 )
  8636. {
  8637. sqlite3BtreeLeave( p );
  8638. return "";
  8639. }
  8640. sCheck.anRef = sqlite3Malloc( sCheck.anRef, (int)sCheck.nPage + 1 );
  8641. //if( !sCheck.anRef ){
  8642. // pnErr = 1;
  8643. // sqlite3BtreeLeave(p);
  8644. // return 0;
  8645. //}
  8646. // for (i = 0; i <= sCheck.nPage; i++) { sCheck.anRef[i] = 0; }
  8647. i = PENDING_BYTE_PAGE( pBt );
  8648. if ( i <= sCheck.nPage )
  8649. {
  8650. sCheck.anRef[i] = 1;
  8651. }
  8652. sqlite3StrAccumInit( sCheck.errMsg, null, 1000, 20000 );
  8653. //sCheck.errMsg.useMalloc = 2;
  8654. /* Check the integrity of the freelist
  8655. */
  8656. checkList( sCheck, 1, (int)sqlite3Get4byte( pBt.pPage1.aData, 32 ),
  8657. (int)sqlite3Get4byte( pBt.pPage1.aData, 36 ), "Main freelist: " );
  8658. /* Check all the tables.
  8659. */
  8660. for ( i = 0; (int)i < nRoot && sCheck.mxErr != 0; i++ )
  8661. {
  8662. if ( aRoot[i] == 0 )
  8663. continue;
  8664. #if !SQLITE_OMIT_AUTOVACUUM
  8665. if ( pBt.autoVacuum && aRoot[i] > 1 )
  8666. {
  8667. checkPtrmap( sCheck, (u32)aRoot[i], PTRMAP_ROOTPAGE, 0, "" );
  8668. }
  8669. #endif
  8670. checkTreePage( sCheck, aRoot[i], "List of tree roots: ", ref refNULL, ref refNULL, null, null );
  8671. }
  8672. /* Make sure every page in the file is referenced
  8673. */
  8674. for ( i = 1; i <= sCheck.nPage && sCheck.mxErr != 0; i++ )
  8675. {
  8676. #if SQLITE_OMIT_AUTOVACUUM
  8677. if( sCheck.anRef[i]==null ){
  8678. checkAppendMsg(sCheck, 0, "Page %d is never used", i);
  8679. }
  8680. #else
  8681. /* If the database supports auto-vacuum, make sure no tables contain
  8682. ** references to pointer-map pages.
  8683. */
  8684. if ( sCheck.anRef[i] == 0 &&
  8685. ( PTRMAP_PAGENO( pBt, i ) != i || !pBt.autoVacuum ) )
  8686. {
  8687. checkAppendMsg( sCheck, "", "Page %d is never used", i );
  8688. }
  8689. if ( sCheck.anRef[i] != 0 &&
  8690. ( PTRMAP_PAGENO( pBt, i ) == i && pBt.autoVacuum ) )
  8691. {
  8692. checkAppendMsg( sCheck, "", "Pointer map page %d is referenced", i );
  8693. }
  8694. #endif
  8695. }
  8696. /* Make sure this analysis did not leave any unref() pages.
  8697. ** This is an internal consistency check; an integrity check
  8698. ** of the integrity check.
  8699. */
  8700. if ( NEVER( nRef != sqlite3PagerRefcount( pBt.pPager ) ) )
  8701. {
  8702. checkAppendMsg( sCheck, "",
  8703. "Outstanding page count goes from %d to %d during this analysis",
  8704. nRef, sqlite3PagerRefcount( pBt.pPager )
  8705. );
  8706. }
  8707. /* Clean up and report errors.
  8708. */
  8709. sqlite3BtreeLeave( p );
  8710. sCheck.anRef = null;// sqlite3_free( ref sCheck.anRef );
  8711. //if( sCheck.mallocFailed ){
  8712. // sqlite3StrAccumReset(sCheck.errMsg);
  8713. // pnErr = sCheck.nErr+1;
  8714. // return 0;
  8715. //}
  8716. pnErr = sCheck.nErr;
  8717. if ( sCheck.nErr == 0 )
  8718. sqlite3StrAccumReset( sCheck.errMsg );
  8719. return sqlite3StrAccumFinish( sCheck.errMsg );
  8720. }
  8721. #endif //* SQLITE_OMIT_INTEGRITY_CHECK */
  8722. /*
  8723. ** Return the full pathname of the underlying database file.
  8724. **
  8725. ** The pager filename is invariant as long as the pager is
  8726. ** open so it is safe to access without the BtShared mutex.
  8727. */
  8728. static string sqlite3BtreeGetFilename( Btree p )
  8729. {
  8730. Debug.Assert( p.pBt.pPager != null );
  8731. return sqlite3PagerFilename( p.pBt.pPager );
  8732. }
  8733. /*
  8734. ** Return the pathname of the journal file for this database. The return
  8735. ** value of this routine is the same regardless of whether the journal file
  8736. ** has been created or not.
  8737. **
  8738. ** The pager journal filename is invariant as long as the pager is
  8739. ** open so it is safe to access without the BtShared mutex.
  8740. */
  8741. static string sqlite3BtreeGetJournalname( Btree p )
  8742. {
  8743. Debug.Assert( p.pBt.pPager != null );
  8744. return sqlite3PagerJournalname( p.pBt.pPager );
  8745. }
  8746. /*
  8747. ** Return non-zero if a transaction is active.
  8748. */
  8749. static bool sqlite3BtreeIsInTrans( Btree p )
  8750. {
  8751. Debug.Assert( p == null || sqlite3_mutex_held( p.db.mutex ) );
  8752. return ( p != null && ( p.inTrans == TRANS_WRITE ) );
  8753. }
  8754. #if !SQLITE_OMIT_WAL
  8755. /*
  8756. ** Run a checkpoint on the Btree passed as the first argument.
  8757. **
  8758. ** Return SQLITE_LOCKED if this or any other connection has an open
  8759. ** transaction on the shared-cache the argument Btree is connected to.
  8760. **
  8761. ** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
  8762. */
  8763. static int sqlite3BtreeCheckpointBtree *p, int eMode, int *pnLog, int *pnCkpt){
  8764. int rc = SQLITE_OK;
  8765. if( p != null){
  8766. BtShared pBt = p.pBt;
  8767. sqlite3BtreeEnter(p);
  8768. if( pBt.inTransaction!=TRANS_NONE ){
  8769. rc = SQLITE_LOCKED;
  8770. }else{
  8771. rc = sqlite3PagerCheckpoint(pBt.pPager, eMode, pnLog, pnCkpt);
  8772. }
  8773. sqlite3BtreeLeave(p);
  8774. }
  8775. return rc;
  8776. }
  8777. #endif
  8778. /*
  8779. ** Return non-zero if a read (or write) transaction is active.
  8780. */
  8781. static bool sqlite3BtreeIsInReadTrans( Btree p )
  8782. {
  8783. Debug.Assert( p != null );
  8784. Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
  8785. return p.inTrans != TRANS_NONE;
  8786. }
  8787. static bool sqlite3BtreeIsInBackup( Btree p )
  8788. {
  8789. Debug.Assert( p != null );
  8790. Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
  8791. return p.nBackup != 0;
  8792. }
  8793. /*
  8794. ** This function returns a pointer to a blob of memory associated with
  8795. ** a single shared-btree. The memory is used by client code for its own
  8796. ** purposes (for example, to store a high-level schema associated with
  8797. ** the shared-btree). The btree layer manages reference counting issues.
  8798. **
  8799. ** The first time this is called on a shared-btree, nBytes bytes of memory
  8800. ** are allocated, zeroed, and returned to the caller. For each subsequent
  8801. ** call the nBytes parameter is ignored and a pointer to the same blob
  8802. ** of memory returned.
  8803. **
  8804. ** If the nBytes parameter is 0 and the blob of memory has not yet been
  8805. ** allocated, a null pointer is returned. If the blob has already been
  8806. ** allocated, it is returned as normal.
  8807. **
  8808. ** Just before the shared-btree is closed, the function passed as the
  8809. ** xFree argument when the memory allocation was made is invoked on the
  8810. ** blob of allocated memory. The xFree function should not call sqlite3_free()
  8811. ** on the memory, the btree layer does that.
  8812. */
  8813. static Schema sqlite3BtreeSchema( Btree p, int nBytes, dxFreeSchema xFree )
  8814. {
  8815. BtShared pBt = p.pBt;
  8816. sqlite3BtreeEnter( p );
  8817. if ( null == pBt.pSchema && nBytes != 0 )
  8818. {
  8819. pBt.pSchema = new Schema();//sqlite3DbMallocZero(0, nBytes);
  8820. pBt.xFreeSchema = xFree;
  8821. }
  8822. sqlite3BtreeLeave( p );
  8823. return pBt.pSchema;
  8824. }
  8825. /*
  8826. ** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared
  8827. ** btree as the argument handle holds an exclusive lock on the
  8828. ** sqlite_master table. Otherwise SQLITE_OK.
  8829. */
  8830. static int sqlite3BtreeSchemaLocked( Btree p )
  8831. {
  8832. int rc;
  8833. Debug.Assert( sqlite3_mutex_held( p.db.mutex ) );
  8834. sqlite3BtreeEnter( p );
  8835. rc = querySharedCacheTableLock( p, MASTER_ROOT, READ_LOCK );
  8836. Debug.Assert( rc == SQLITE_OK || rc == SQLITE_LOCKED_SHAREDCACHE );
  8837. sqlite3BtreeLeave( p );
  8838. return rc;
  8839. }
  8840. #if !SQLITE_OMIT_SHARED_CACHE
  8841. /*
  8842. ** Obtain a lock on the table whose root page is iTab. The
  8843. ** lock is a write lock if isWritelock is true or a read lock
  8844. ** if it is false.
  8845. */
  8846. int sqlite3BtreeLockTable(Btree p, int iTab, u8 isWriteLock){
  8847. int rc = SQLITE_OK;
  8848. Debug.Assert( p.inTrans!=TRANS_NONE );
  8849. if( p.sharable ){
  8850. u8 lockType = READ_LOCK + isWriteLock;
  8851. Debug.Assert( READ_LOCK+1==WRITE_LOCK );
  8852. Debug.Assert( isWriteLock==null || isWriteLock==1 );
  8853. sqlite3BtreeEnter(p);
  8854. rc = querySharedCacheTableLock(p, iTab, lockType);
  8855. if( rc==SQLITE_OK ){
  8856. rc = setSharedCacheTableLock(p, iTab, lockType);
  8857. }
  8858. sqlite3BtreeLeave(p);
  8859. }
  8860. return rc;
  8861. }
  8862. #endif
  8863. #if !SQLITE_OMIT_INCRBLOB
  8864. /*
  8865. ** Argument pCsr must be a cursor opened for writing on an
  8866. ** INTKEY table currently pointing at a valid table entry.
  8867. ** This function modifies the data stored as part of that entry.
  8868. **
  8869. ** Only the data content may only be modified, it is not possible to
  8870. ** change the length of the data stored. If this function is called with
  8871. ** parameters that attempt to write past the end of the existing data,
  8872. ** no modifications are made and SQLITE_CORRUPT is returned.
  8873. */
  8874. int sqlite3BtreePutData(BtCursor pCsr, u32 offset, u32 amt, void *z){
  8875. int rc;
  8876. Debug.Assert( cursorHoldsMutex(pCsr) );
  8877. Debug.Assert( sqlite3_mutex_held(pCsr.pBtree.db.mutex) );
  8878. Debug.Assert( pCsr.isIncrblobHandle );
  8879. rc = restoreCursorPosition(pCsr);
  8880. if( rc!=SQLITE_OK ){
  8881. return rc;
  8882. }
  8883. Debug.Assert( pCsr.eState!=CURSOR_REQUIRESEEK );
  8884. if( pCsr.eState!=CURSOR_VALID ){
  8885. return SQLITE_ABORT;
  8886. }
  8887. /* Check some assumptions:
  8888. ** (a) the cursor is open for writing,
  8889. ** (b) there is a read/write transaction open,
  8890. ** (c) the connection holds a write-lock on the table (if required),
  8891. ** (d) there are no conflicting read-locks, and
  8892. ** (e) the cursor points at a valid row of an intKey table.
  8893. */
  8894. if( !pCsr.wrFlag ){
  8895. return SQLITE_READONLY;
  8896. }
  8897. Debug.Assert( !pCsr.pBt.readOnly && pCsr.pBt.inTransaction==TRANS_WRITE );
  8898. Debug.Assert( hasSharedCacheTableLock(pCsr.pBtree, pCsr.pgnoRoot, 0, 2) );
  8899. Debug.Assert( !hasReadConflicts(pCsr.pBtree, pCsr.pgnoRoot) );
  8900. Debug.Assert( pCsr.apPage[pCsr.iPage].intKey );
  8901. return accessPayload(pCsr, offset, amt, (byte[] *)z, 1);
  8902. }
  8903. /*
  8904. ** Set a flag on this cursor to cache the locations of pages from the
  8905. ** overflow list for the current row. This is used by cursors opened
  8906. ** for incremental blob IO only.
  8907. **
  8908. ** This function sets a flag only. The actual page location cache
  8909. ** (stored in BtCursor.aOverflow[]) is allocated and used by function
  8910. ** accessPayload() (the worker function for sqlite3BtreeData() and
  8911. ** sqlite3BtreePutData()).
  8912. */
  8913. static void sqlite3BtreeCacheOverflow(BtCursor pCur){
  8914. Debug.Assert( cursorHoldsMutex(pCur) );
  8915. Debug.Assert( sqlite3_mutex_held(pCur.pBtree.db.mutex) );
  8916. invalidateOverflowCache(pCur)
  8917. pCur.isIncrblobHandle = 1;
  8918. }
  8919. #endif
  8920. /*
  8921. ** Set both the "read version" (single byte at byte offset 18) and
  8922. ** "write version" (single byte at byte offset 19) fields in the database
  8923. ** header to iVersion.
  8924. */
  8925. static int sqlite3BtreeSetVersion( Btree pBtree, int iVersion )
  8926. {
  8927. BtShared pBt = pBtree.pBt;
  8928. int rc; /* Return code */
  8929. Debug.Assert( pBtree.inTrans == TRANS_NONE );
  8930. Debug.Assert( iVersion == 1 || iVersion == 2 );
  8931. /* If setting the version fields to 1, do not automatically open the
  8932. ** WAL connection, even if the version fields are currently set to 2.
  8933. */
  8934. pBt.doNotUseWAL = iVersion == 1;
  8935. rc = sqlite3BtreeBeginTrans( pBtree, 0 );
  8936. if ( rc == SQLITE_OK )
  8937. {
  8938. u8[] aData = pBt.pPage1.aData;
  8939. if ( aData[18] != (u8)iVersion || aData[19] != (u8)iVersion )
  8940. {
  8941. rc = sqlite3BtreeBeginTrans( pBtree, 2 );
  8942. if ( rc == SQLITE_OK )
  8943. {
  8944. rc = sqlite3PagerWrite( pBt.pPage1.pDbPage );
  8945. if ( rc == SQLITE_OK )
  8946. {
  8947. aData[18] = (u8)iVersion;
  8948. aData[19] = (u8)iVersion;
  8949. }
  8950. }
  8951. }
  8952. }
  8953. pBt.doNotUseWAL = false;
  8954. return rc;
  8955. }
  8956. }
  8957. }