blob: 615c9601dc2ad3cdff79cf488f332c77f2c737c2 [file] [log] [blame]
drh16a9b832007-05-05 18:39:25 +00001/*
2** 2007 May 05
3**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
10**
11*************************************************************************
12** Code for testing the btree.c module in SQLite. This code
13** is not included in the SQLite library. It is used for automated
14** testing of the SQLite library.
15**
drh93a960a2008-07-10 00:32:42 +000016** $Id: test_btree.c,v 1.4 2008/07/10 00:32:42 drh Exp $
drh16a9b832007-05-05 18:39:25 +000017*/
18#include "btreeInt.h"
19#include <tcl.h>
20
21/*
drh16a9b832007-05-05 18:39:25 +000022** Usage: sqlite3_shared_cache_report
23**
24** Return a list of file that are shared and the number of
25** references to each file.
26*/
27int sqlite3BtreeSharedCacheReport(
28 void * clientData,
29 Tcl_Interp *interp,
30 int objc,
31 Tcl_Obj *CONST objv[]
32){
33#ifndef SQLITE_OMIT_SHARED_CACHE
drhe53831d2007-08-17 01:14:38 +000034 extern BtShared *sqlite3SharedCacheList;
35 BtShared *pBt;
36 Tcl_Obj *pRet = Tcl_NewObj();
37 for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){
38 const char *zFile = sqlite3PagerFilename(pBt->pPager);
39 Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zFile, -1));
40 Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(pBt->nRef));
drh16a9b832007-05-05 18:39:25 +000041 }
drhe53831d2007-08-17 01:14:38 +000042 Tcl_SetObjResult(interp, pRet);
drh16a9b832007-05-05 18:39:25 +000043#endif
44 return TCL_OK;
45}
46
47/*
48** Print debugging information about all cursors to standard output.
49*/
50void sqlite3BtreeCursorList(Btree *p){
51 BtCursor *pCur;
52 BtShared *pBt = p->pBt;
53 for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
54 MemPage *pPage = pCur->pPage;
55 char *zMode = pCur->wrFlag ? "rw" : "ro";
56 sqlite3DebugPrintf("CURSOR %p rooted at %4d(%s) currently at %d.%d%s\n",
57 pCur, pCur->pgnoRoot, zMode,
58 pPage ? pPage->pgno : 0, pCur->idx,
59 (pCur->eState==CURSOR_VALID) ? "" : " eof"
60 );
61 }
62}
63
64
65/*
66** Fill aResult[] with information about the entry and page that the
67** cursor is pointing to.
68**
69** aResult[0] = The page number
70** aResult[1] = The entry number
71** aResult[2] = Total number of entries on this page
72** aResult[3] = Cell size (local payload + header)
73** aResult[4] = Number of free bytes on this page
74** aResult[5] = Number of free blocks on the page
75** aResult[6] = Total payload size (local + overflow)
76** aResult[7] = Header size in bytes
77** aResult[8] = Local payload size
78** aResult[9] = Parent page number
79** aResult[10]= Page number of the first overflow page
80**
81** This routine is used for testing and debugging only.
82*/
83int sqlite3BtreeCursorInfo(BtCursor *pCur, int *aResult, int upCnt){
84 int cnt, idx;
85 MemPage *pPage = pCur->pPage;
86 BtCursor tmpCur;
drh7a7364c2007-05-08 11:27:15 +000087 int rc;
drh16a9b832007-05-05 18:39:25 +000088
drh7a7364c2007-05-08 11:27:15 +000089 if( pCur->eState==CURSOR_REQUIRESEEK ){
90 rc = sqlite3BtreeRestoreOrClearCursorPosition(pCur);
91 if( rc!=SQLITE_OK ){
92 return rc;
93 }
drh16a9b832007-05-05 18:39:25 +000094 }
95
96 assert( pPage->isInit );
97 sqlite3BtreeGetTempCursor(pCur, &tmpCur);
98 while( upCnt-- ){
99 sqlite3BtreeMoveToParent(&tmpCur);
100 }
101 pPage = tmpCur.pPage;
102 aResult[0] = sqlite3PagerPagenumber(pPage->pDbPage);
103 assert( aResult[0]==pPage->pgno );
104 aResult[1] = tmpCur.idx;
105 aResult[2] = pPage->nCell;
106 if( tmpCur.idx>=0 && tmpCur.idx<pPage->nCell ){
107 sqlite3BtreeParseCell(tmpCur.pPage, tmpCur.idx, &tmpCur.info);
108 aResult[3] = tmpCur.info.nSize;
109 aResult[6] = tmpCur.info.nData;
110 aResult[7] = tmpCur.info.nHeader;
111 aResult[8] = tmpCur.info.nLocal;
112 }else{
113 aResult[3] = 0;
114 aResult[6] = 0;
115 aResult[7] = 0;
116 aResult[8] = 0;
117 }
118 aResult[4] = pPage->nFree;
119 cnt = 0;
120 idx = get2byte(&pPage->aData[pPage->hdrOffset+1]);
121 while( idx>0 && idx<pPage->pBt->usableSize ){
122 cnt++;
123 idx = get2byte(&pPage->aData[idx]);
124 }
125 aResult[5] = cnt;
126 if( pPage->pParent==0 || sqlite3BtreeIsRootPage(pPage) ){
127 aResult[9] = 0;
128 }else{
129 aResult[9] = pPage->pParent->pgno;
130 }
131 if( tmpCur.info.iOverflow ){
132 aResult[10] = get4byte(&tmpCur.info.pCell[tmpCur.info.iOverflow]);
133 }else{
134 aResult[10] = 0;
135 }
136 sqlite3BtreeReleaseTempCursor(&tmpCur);
137 return SQLITE_OK;
138}