mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Add the sqlite_btreeinfo eponymous-only table for introspecting the schema
and estimating the sizes of various btrees. FossilOrigin-Name: 1e30f4772db1e1086096f72d32e87c552923be8b264aa13cf822fae754eb083d
This commit is contained in:
425
ext/misc/btreeinfo.c
Normal file
425
ext/misc/btreeinfo.c
Normal file
@ -0,0 +1,425 @@
|
|||||||
|
/*
|
||||||
|
** 2017-10-24
|
||||||
|
**
|
||||||
|
** The author disclaims copyright to this source code. In place of
|
||||||
|
** a legal notice, here is a blessing:
|
||||||
|
**
|
||||||
|
** May you do good and not evil.
|
||||||
|
** May you find forgiveness for yourself and forgive others.
|
||||||
|
** May you share freely, never taking more than you give.
|
||||||
|
**
|
||||||
|
******************************************************************************
|
||||||
|
**
|
||||||
|
** This file contains an implementation of the "sqlite_btreeinfo" virtual table.
|
||||||
|
**
|
||||||
|
** The sqlite_btreeinfo virtual table is a read-only eponymous-only virtual
|
||||||
|
** table that shows information about all btrees in an SQLite database file.
|
||||||
|
** The schema is like this:
|
||||||
|
**
|
||||||
|
** CREATE TABLE sqlite_btreeinfo(
|
||||||
|
** type TEXT, -- "table" or "index"
|
||||||
|
** name TEXT, -- Name of table or index for this btree.
|
||||||
|
** tbl_name TEXT, -- Associated table
|
||||||
|
** rootpage INT, -- The root page of the btree
|
||||||
|
** sql TEXT, -- SQL for this btree - from sqlite_master
|
||||||
|
** hasRowid BOOLEAN, -- True if the btree has a rowid
|
||||||
|
** nEntry INT, -- Estimated number of enteries
|
||||||
|
** nPage INT, -- Estimated number of pages
|
||||||
|
** depth INT, -- Depth of the btree
|
||||||
|
** szPage INT, -- Size of each page in bytes
|
||||||
|
** zSchema TEXT HIDDEN -- The schema to which this btree belongs
|
||||||
|
** );
|
||||||
|
**
|
||||||
|
** The first 5 fields are taken directly from the sqlite_master table.
|
||||||
|
** Considering only the first 5 fields, the only difference between
|
||||||
|
** this virtual table and the sqlite_master table is that this virtual
|
||||||
|
** table omits all entries that have a 0 or NULL rowid - in other words
|
||||||
|
** it omits triggers and views.
|
||||||
|
**
|
||||||
|
** The value added by this table comes in the next 5 fields.
|
||||||
|
**
|
||||||
|
** Note that nEntry and nPage are *estimated*. They are computed doing
|
||||||
|
** a single search from the root to a leaf, counting the number of cells
|
||||||
|
** at each level, and assuming that unvisited pages have a similar number
|
||||||
|
** of cells.
|
||||||
|
**
|
||||||
|
** The sqlite_dbpage virtual table must be available for this virtual table
|
||||||
|
** to operate.
|
||||||
|
**
|
||||||
|
** USAGE EXAMPLES:
|
||||||
|
**
|
||||||
|
** Show the table btrees in a schema order with the tables with the most
|
||||||
|
** rows occuring first:
|
||||||
|
**
|
||||||
|
** SELECT name, nEntry
|
||||||
|
** FROM sqlite_btreeinfo
|
||||||
|
** WHERE type='table'
|
||||||
|
** ORDER BY nEntry DESC, name;
|
||||||
|
**
|
||||||
|
** Show the names of all WITHOUT ROWID tables:
|
||||||
|
**
|
||||||
|
** SELECT name FROM sqlite_btreeinfo
|
||||||
|
** WHERE type='table' AND NOT hasRowid;
|
||||||
|
*/
|
||||||
|
#include <sqlite3ext.h>
|
||||||
|
SQLITE_EXTENSION_INIT1
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/* Columns available in this virtual table */
|
||||||
|
#define BINFO_COLUMN_TYPE 0
|
||||||
|
#define BINFO_COLUMN_NAME 1
|
||||||
|
#define BINFO_COLUMN_TBL_NAME 2
|
||||||
|
#define BINFO_COLUMN_ROOTPAGE 3
|
||||||
|
#define BINFO_COLUMN_SQL 4
|
||||||
|
#define BINFO_COLUMN_HASROWID 5
|
||||||
|
#define BINFO_COLUMN_NENTRY 6
|
||||||
|
#define BINFO_COLUMN_NPAGE 7
|
||||||
|
#define BINFO_COLUMN_DEPTH 8
|
||||||
|
#define BINFO_COLUMN_SZPAGE 9
|
||||||
|
#define BINFO_COLUMN_SCHEMA 10
|
||||||
|
|
||||||
|
/* Forward declarations */
|
||||||
|
typedef struct BinfoTable BinfoTable;
|
||||||
|
typedef struct BinfoCursor BinfoCursor;
|
||||||
|
|
||||||
|
/* A cursor for the sqlite_btreeinfo table */
|
||||||
|
struct BinfoCursor {
|
||||||
|
sqlite3_vtab_cursor base; /* Base class. Must be first */
|
||||||
|
sqlite3_stmt *pStmt; /* Query against sqlite_master */
|
||||||
|
int rc; /* Result of previous sqlite_step() call */
|
||||||
|
int hasRowid; /* hasRowid value. Negative if unknown. */
|
||||||
|
sqlite3_int64 nEntry; /* nEntry value */
|
||||||
|
int nPage; /* nPage value */
|
||||||
|
int depth; /* depth value */
|
||||||
|
int szPage; /* size of a btree page. 0 if unknown */
|
||||||
|
char *zSchema; /* Schema being interrogated */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The sqlite_btreeinfo table */
|
||||||
|
struct BinfoTable {
|
||||||
|
sqlite3_vtab base; /* Base class. Must be first */
|
||||||
|
sqlite3 *db; /* The databse connection */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Connect to the sqlite_btreeinfo virtual table.
|
||||||
|
*/
|
||||||
|
static int binfoConnect(
|
||||||
|
sqlite3 *db,
|
||||||
|
void *pAux,
|
||||||
|
int argc, const char *const*argv,
|
||||||
|
sqlite3_vtab **ppVtab,
|
||||||
|
char **pzErr
|
||||||
|
){
|
||||||
|
BinfoTable *pTab = 0;
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
rc = sqlite3_declare_vtab(db,
|
||||||
|
"CREATE TABLE x(\n"
|
||||||
|
" type TEXT,\n"
|
||||||
|
" name TEXT,\n"
|
||||||
|
" tbl_name TEXT,\n"
|
||||||
|
" rootpage INT,\n"
|
||||||
|
" sql TEXT,\n"
|
||||||
|
" hasRowid BOOLEAN,\n"
|
||||||
|
" nEntry INT,\n"
|
||||||
|
" nPage INT,\n"
|
||||||
|
" depth INT,\n"
|
||||||
|
" szPage INT,\n"
|
||||||
|
" zSchema TEXT HIDDEN\n"
|
||||||
|
")");
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
pTab = (BinfoTable *)sqlite3_malloc64(sizeof(BinfoTable));
|
||||||
|
if( pTab==0 ) rc = SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
assert( rc==SQLITE_OK || pTab==0 );
|
||||||
|
if( pTab ){
|
||||||
|
pTab->db = db;
|
||||||
|
}
|
||||||
|
*ppVtab = (sqlite3_vtab*)pTab;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Disconnect from or destroy a btreeinfo virtual table.
|
||||||
|
*/
|
||||||
|
static int binfoDisconnect(sqlite3_vtab *pVtab){
|
||||||
|
sqlite3_free(pVtab);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** idxNum:
|
||||||
|
**
|
||||||
|
** 0 Use "main" for the schema
|
||||||
|
** 1 Schema identified by parameter ?1
|
||||||
|
*/
|
||||||
|
static int binfoBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||||
|
int i;
|
||||||
|
pIdxInfo->estimatedCost = 10000.0; /* Cost estimate */
|
||||||
|
pIdxInfo->estimatedRows = 100;
|
||||||
|
for(i=0; i<pIdxInfo->nConstraint; i++){
|
||||||
|
struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
|
||||||
|
if( p->usable
|
||||||
|
&& p->iColumn==BINFO_COLUMN_SCHEMA
|
||||||
|
&& p->op==SQLITE_INDEX_CONSTRAINT_EQ
|
||||||
|
){
|
||||||
|
pIdxInfo->estimatedCost = 1000.0;
|
||||||
|
pIdxInfo->idxNum = 1;
|
||||||
|
pIdxInfo->aConstraintUsage[i].argvIndex = 1;
|
||||||
|
pIdxInfo->aConstraintUsage[i].omit = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Open a new btreeinfo cursor.
|
||||||
|
*/
|
||||||
|
static int binfoOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
|
||||||
|
BinfoCursor *pCsr;
|
||||||
|
|
||||||
|
pCsr = (BinfoCursor *)sqlite3_malloc64(sizeof(BinfoCursor));
|
||||||
|
if( pCsr==0 ){
|
||||||
|
return SQLITE_NOMEM;
|
||||||
|
}else{
|
||||||
|
memset(pCsr, 0, sizeof(BinfoCursor));
|
||||||
|
pCsr->base.pVtab = pVTab;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Close a btreeinfo cursor.
|
||||||
|
*/
|
||||||
|
static int binfoClose(sqlite3_vtab_cursor *pCursor){
|
||||||
|
BinfoCursor *pCsr = (BinfoCursor *)pCursor;
|
||||||
|
sqlite3_finalize(pCsr->pStmt);
|
||||||
|
sqlite3_free(pCsr->zSchema);
|
||||||
|
sqlite3_free(pCsr);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Move a btreeinfo cursor to the next entry in the file.
|
||||||
|
*/
|
||||||
|
static int binfoNext(sqlite3_vtab_cursor *pCursor){
|
||||||
|
BinfoCursor *pCsr = (BinfoCursor *)pCursor;
|
||||||
|
pCsr->rc = sqlite3_step(pCsr->pStmt);
|
||||||
|
pCsr->hasRowid = -1;
|
||||||
|
return pCsr->rc==SQLITE_ERROR ? SQLITE_ERROR : SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have reached EOF if previous sqlite3_step() returned
|
||||||
|
** anything other than SQLITE_ROW;
|
||||||
|
*/
|
||||||
|
static int binfoEof(sqlite3_vtab_cursor *pCursor){
|
||||||
|
BinfoCursor *pCsr = (BinfoCursor *)pCursor;
|
||||||
|
return pCsr->rc!=SQLITE_ROW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Position a cursor back to the beginning.
|
||||||
|
*/
|
||||||
|
static int binfoFilter(
|
||||||
|
sqlite3_vtab_cursor *pCursor,
|
||||||
|
int idxNum, const char *idxStr,
|
||||||
|
int argc, sqlite3_value **argv
|
||||||
|
){
|
||||||
|
BinfoCursor *pCsr = (BinfoCursor *)pCursor;
|
||||||
|
BinfoTable *pTab = (BinfoTable *)pCursor->pVtab;
|
||||||
|
char *zSql;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
sqlite3_free(pCsr->zSchema);
|
||||||
|
if( idxNum==1 && sqlite3_value_type(argv[0])!=SQLITE_NULL ){
|
||||||
|
pCsr->zSchema = sqlite3_mprintf("%s", sqlite3_value_text(argv[0]));
|
||||||
|
}else{
|
||||||
|
pCsr->zSchema = sqlite3_mprintf("main");
|
||||||
|
}
|
||||||
|
zSql = sqlite3_mprintf(
|
||||||
|
"SELECT 0, 'table','sqlite_master','sqlite_master',1,NULL "
|
||||||
|
"UNION ALL "
|
||||||
|
"SELECT rowid, type, name, tbl_name, rootpage, sql"
|
||||||
|
" FROM \"%w\".sqlite_master WHERE rootpage>=1",
|
||||||
|
pCsr->zSchema);
|
||||||
|
sqlite3_finalize(pCsr->pStmt);
|
||||||
|
pCsr->pStmt = 0;
|
||||||
|
pCsr->hasRowid = -1;
|
||||||
|
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
|
||||||
|
sqlite3_free(zSql);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = binfoNext(pCursor);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decode big-endian integers */
|
||||||
|
static unsigned int get_uint16(unsigned char *a){
|
||||||
|
return (a[0]<<8)|a[1];
|
||||||
|
}
|
||||||
|
static unsigned int get_uint32(unsigned char *a){
|
||||||
|
return (a[0]<<24)|(a[1]<<16)|(a[2]<<8)|a[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Examine the b-tree rooted at pgno and estimate its size.
|
||||||
|
** Return non-zero if anything goes wrong.
|
||||||
|
*/
|
||||||
|
static int binfoCompute(sqlite3 *db, int pgno, BinfoCursor *pCsr){
|
||||||
|
sqlite3_int64 nEntry = 1;
|
||||||
|
int nPage = 1;
|
||||||
|
unsigned char *aData;
|
||||||
|
sqlite3_stmt *pStmt = 0;
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
int pgsz = 0;
|
||||||
|
int nCell;
|
||||||
|
int iCell;
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(db,
|
||||||
|
"SELECT data FROM sqlite_dbpage('main') WHERE pgno=?1", -1,
|
||||||
|
&pStmt, 0);
|
||||||
|
if( rc ) return rc;
|
||||||
|
pCsr->depth = 1;
|
||||||
|
while(1){
|
||||||
|
sqlite3_bind_int(pStmt, 1, pgno);
|
||||||
|
rc = sqlite3_step(pStmt);
|
||||||
|
if( rc!=SQLITE_ROW ){
|
||||||
|
rc = SQLITE_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pCsr->szPage = pgsz = sqlite3_column_bytes(pStmt, 0);
|
||||||
|
aData = (unsigned char*)sqlite3_column_blob(pStmt, 0);
|
||||||
|
if( aData==0 ){
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( pgno==1 ){
|
||||||
|
aData += 100;
|
||||||
|
pgsz -= 100;
|
||||||
|
}
|
||||||
|
pCsr->hasRowid = aData[0]!=2 && aData[0]!=10;
|
||||||
|
nCell = get_uint16(aData+3);
|
||||||
|
nEntry *= (nCell+1);
|
||||||
|
if( aData[0]==10 || aData[0]==13 ) break;
|
||||||
|
nPage *= (nCell+1);
|
||||||
|
if( nCell<=1 ){
|
||||||
|
pgno = get_uint32(aData+8);
|
||||||
|
}else{
|
||||||
|
iCell = get_uint16(aData+12+2*(nCell/2));
|
||||||
|
if( pgno==1 ) iCell -= 100;
|
||||||
|
if( iCell<=12 || iCell>=pgsz-4 ){
|
||||||
|
rc = SQLITE_CORRUPT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pgno = get_uint32(aData+iCell);
|
||||||
|
}
|
||||||
|
pCsr->depth++;
|
||||||
|
sqlite3_reset(pStmt);
|
||||||
|
}
|
||||||
|
sqlite3_finalize(pStmt);
|
||||||
|
pCsr->nPage = nPage;
|
||||||
|
pCsr->nEntry = nEntry;
|
||||||
|
if( rc==SQLITE_ROW ) rc = SQLITE_OK;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a column for the sqlite_btreeinfo table */
|
||||||
|
static int binfoColumn(
|
||||||
|
sqlite3_vtab_cursor *pCursor,
|
||||||
|
sqlite3_context *ctx,
|
||||||
|
int i
|
||||||
|
){
|
||||||
|
BinfoCursor *pCsr = (BinfoCursor *)pCursor;
|
||||||
|
if( i>=BINFO_COLUMN_HASROWID && i<=BINFO_COLUMN_SZPAGE && pCsr->hasRowid<0 ){
|
||||||
|
int pgno = sqlite3_column_int(pCsr->pStmt, BINFO_COLUMN_ROOTPAGE+1);
|
||||||
|
sqlite3 *db = sqlite3_context_db_handle(ctx);
|
||||||
|
int rc = binfoCompute(db, pgno, pCsr);
|
||||||
|
if( rc ){
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch( i ){
|
||||||
|
case BINFO_COLUMN_NAME:
|
||||||
|
case BINFO_COLUMN_TYPE:
|
||||||
|
case BINFO_COLUMN_TBL_NAME:
|
||||||
|
case BINFO_COLUMN_ROOTPAGE:
|
||||||
|
case BINFO_COLUMN_SQL: {
|
||||||
|
sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pStmt, i+1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BINFO_COLUMN_HASROWID: {
|
||||||
|
sqlite3_result_int(ctx, pCsr->hasRowid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BINFO_COLUMN_NENTRY: {
|
||||||
|
sqlite3_result_int64(ctx, pCsr->nEntry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BINFO_COLUMN_NPAGE: {
|
||||||
|
sqlite3_result_int(ctx, pCsr->nPage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BINFO_COLUMN_DEPTH: {
|
||||||
|
sqlite3_result_int(ctx, pCsr->depth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BINFO_COLUMN_SCHEMA: {
|
||||||
|
sqlite3_result_text(ctx, pCsr->zSchema, -1, SQLITE_STATIC);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the ROWID for the sqlite_btreeinfo table */
|
||||||
|
static int binfoRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
|
||||||
|
BinfoCursor *pCsr = (BinfoCursor *)pCursor;
|
||||||
|
*pRowid = sqlite3_column_int64(pCsr->pStmt, 0);
|
||||||
|
return SQLITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Invoke this routine to register the "sqlite_btreeinfo" virtual table module
|
||||||
|
*/
|
||||||
|
int sqlite3BinfoRegister(sqlite3 *db){
|
||||||
|
static sqlite3_module binfo_module = {
|
||||||
|
0, /* iVersion */
|
||||||
|
0, /* xCreate */
|
||||||
|
binfoConnect, /* xConnect */
|
||||||
|
binfoBestIndex, /* xBestIndex */
|
||||||
|
binfoDisconnect, /* xDisconnect */
|
||||||
|
0, /* xDestroy */
|
||||||
|
binfoOpen, /* xOpen - open a cursor */
|
||||||
|
binfoClose, /* xClose - close a cursor */
|
||||||
|
binfoFilter, /* xFilter - configure scan constraints */
|
||||||
|
binfoNext, /* xNext - advance a cursor */
|
||||||
|
binfoEof, /* xEof - check for end of scan */
|
||||||
|
binfoColumn, /* xColumn - read data */
|
||||||
|
binfoRowid, /* xRowid - read data */
|
||||||
|
0, /* xUpdate */
|
||||||
|
0, /* xBegin */
|
||||||
|
0, /* xSync */
|
||||||
|
0, /* xCommit */
|
||||||
|
0, /* xRollback */
|
||||||
|
0, /* xFindMethod */
|
||||||
|
0, /* xRename */
|
||||||
|
0, /* xSavepoint */
|
||||||
|
0, /* xRelease */
|
||||||
|
0, /* xRollbackTo */
|
||||||
|
};
|
||||||
|
return sqlite3_create_module(db, "sqlite_btreeinfo", &binfo_module, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
__declspec(dllexport)
|
||||||
|
#endif
|
||||||
|
int sqlite3_btreeinfo_init(
|
||||||
|
sqlite3 *db,
|
||||||
|
char **pzErrMsg,
|
||||||
|
const sqlite3_api_routines *pApi
|
||||||
|
){
|
||||||
|
SQLITE_EXTENSION_INIT2(pApi);
|
||||||
|
return sqlite3BinfoRegister(db);
|
||||||
|
}
|
13
manifest
13
manifest
@ -1,5 +1,5 @@
|
|||||||
C Force\sthe\sautoconf\smakefile\sfor\sMSVC\sto\salways\suse\sthe\s'find.exe'\sincluded\swith\sWindows.
|
C Add\sthe\ssqlite_btreeinfo\seponymous-only\stable\sfor\sintrospecting\sthe\sschema\nand\sestimating\sthe\ssizes\sof\svarious\sbtrees.
|
||||||
D 2017-10-24T21:17:12.950
|
D 2017-10-25T01:34:24.293
|
||||||
F Makefile.in e016061b23e60ac9ec27c65cb577292b6bde0307ca55abd874ab3487b3b1beb2
|
F Makefile.in e016061b23e60ac9ec27c65cb577292b6bde0307ca55abd874ab3487b3b1beb2
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc 37740aba9c4bb359c627eadccf1cfd7be4f5f847078723777ea7763969e533b1
|
F Makefile.msc 37740aba9c4bb359c627eadccf1cfd7be4f5f847078723777ea7763969e533b1
|
||||||
@ -258,6 +258,7 @@ F ext/lsm1/test/lsm1_simple.test ca949efefa102f4644231dcd9291d8cda7699a4ce1006b2
|
|||||||
F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2
|
F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2
|
||||||
F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87
|
F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87
|
||||||
F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
|
F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
|
||||||
|
F ext/misc/btreeinfo.c 89488a065f5fc3c54f81c589460d69d83cd2f337ae59ed1cf813b8572b258516 w ext/misc/btreelist.c
|
||||||
F ext/misc/carray.c ed96c218ea940b85c9a274c4d9c59fe9491c299147a38a8bba537687bd6c6005
|
F ext/misc/carray.c ed96c218ea940b85c9a274c4d9c59fe9491c299147a38a8bba537687bd6c6005
|
||||||
F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
|
F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
|
||||||
F ext/misc/completion.c 52c3f01523e3e387eb321b4739a89d1fe47cbe6025aa1f2d8d3685e9e365df0f
|
F ext/misc/completion.c 52c3f01523e3e387eb321b4739a89d1fe47cbe6025aa1f2d8d3685e9e365df0f
|
||||||
@ -1664,7 +1665,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 5ab662b443df17c5ebdadc0bdac2f447c5c7e86f7a32a6943bb4ac8605879441
|
P b76bffd332585e8412a0a994ae6dee79a83213d8b709d7f858c5c05678ab0887
|
||||||
R 54e49932e96b845a01a6eb1a3cc08724
|
R 2cb01c8a7e418d5768c813428fd16a20
|
||||||
U mistachkin
|
U drh
|
||||||
Z 580a702e0e85c423f77f3c922262f566
|
Z 2d2691251ae11d16de493df9f4384426
|
||||||
|
@ -1 +1 @@
|
|||||||
b76bffd332585e8412a0a994ae6dee79a83213d8b709d7f858c5c05678ab0887
|
1e30f4772db1e1086096f72d32e87c552923be8b264aa13cf822fae754eb083d
|
Reference in New Issue
Block a user