2 ** This utility program decodes and displays the content of the
3 ** sqlite_stat4 table in the database file named on the command
12 #define ISPRINT(X) isprint((unsigned char)(X))
14 typedef sqlite3_int64 i64
; /* 64-bit signed integer type */
18 ** Convert the var-int format into i64. Return the number of bytes
19 ** in the var-int. Write the var-int value into *pVal.
21 static int decodeVarint(const unsigned char *z
, i64
*pVal
){
25 v
= (v
<<7) + (z
[i
]&0x7f);
26 if( (z
[i
]&0x80)==0 ){ *pVal
= v
; return i
+1; }
28 v
= (v
<<8) + (z
[i
]&0xff);
35 int main(int argc
, char **argv
){
39 int rc
, j
, x
, y
, mxHdr
;
40 const unsigned char *aSample
;
47 fprintf(stderr
, "Usage: %s DATABASE-FILE\n", argv
[0]);
50 rc
= sqlite3_open(argv
[1], &db
);
51 if( rc
!=SQLITE_OK
|| db
==0 ){
52 fprintf(stderr
, "Cannot open database file [%s]\n", argv
[1]);
55 rc
= sqlite3_prepare_v2(db
,
56 "SELECT tbl||'.'||idx, nEq, nLT, nDLt, sample "
57 "FROM sqlite_stat4 ORDER BY 1", -1,
59 if( rc
!=SQLITE_OK
|| pStmt
==0 ){
60 fprintf(stderr
, "%s\n", sqlite3_errmsg(db
));
64 while( SQLITE_ROW
==sqlite3_step(pStmt
) ){
65 if( zIdx
==0 || strcmp(zIdx
, (const char*)sqlite3_column_text(pStmt
,0))!=0 ){
66 if( zIdx
) printf("\n**************************************"
67 "**************\n\n");
69 zIdx
= sqlite3_mprintf("%s", sqlite3_column_text(pStmt
,0));
72 printf("%s sample %d ------------------------------------\n", zIdx
, ++iRow
);
73 printf(" nEq = %s\n", sqlite3_column_text(pStmt
,1));
74 printf(" nLt = %s\n", sqlite3_column_text(pStmt
,2));
75 printf(" nDLt = %s\n", sqlite3_column_text(pStmt
,3));
76 printf(" sample = x'");
77 aSample
= sqlite3_column_blob(pStmt
,4);
78 nSample
= sqlite3_column_bytes(pStmt
,4);
79 for(j
=0; j
<nSample
; j
++) printf("%02x", aSample
[j
]);
82 x
= decodeVarint(aSample
, &iVal
);
83 if( iVal
<x
|| iVal
>nSample
){
87 y
= mxHdr
= (int)iVal
;
91 x
+= decodeVarint(aSample
+x
, &iVal
);
95 case 0: sz
= 0; break;
96 case 1: sz
= 1; break;
97 case 2: sz
= 2; break;
98 case 3: sz
= 3; break;
99 case 4: sz
= 4; break;
100 case 5: sz
= 6; break;
101 case 6: sz
= 8; break;
102 case 7: sz
= 8; break;
103 case 8: sz
= 0; break;
104 case 9: sz
= 0; break;
106 case 11: sz
= 0; break;
107 default: sz
= (int)(iVal
-12)/2; break;
109 if( y
+sz
>nSample
) break;
111 printf("%sNULL", zSep
);
112 }else if( iVal
==8 || iVal
==9 ){
113 printf("%s%d", zSep
, ((int)iVal
)-8);
115 v
= (signed char)aSample
[y
];
117 v
= (v
<<8) + aSample
[y
+j
];
122 memcpy(&r
, &v
, sizeof(r
));
123 z
= sqlite3_mprintf("%s%!.15g", zSep
, r
);
127 printf("%s%lld", zSep
, v
);
129 }else if( (iVal
&1)==0 ){
130 printf("%sx'", zSep
);
132 printf("%02x", aSample
[y
+j
]);
138 char c
= (char)aSample
[y
+j
];
140 if( c
=='\'' || c
=='\\' ) putchar('\\');
160 sqlite3_finalize(pStmt
);