mirror of
https://github.com/mdbtools/mdbtools.git
synced 2026-03-10 00:20:54 +08:00
sync up, see ChangeLog for details
This commit is contained in:
@@ -110,6 +110,26 @@ MdbBackendType mdb_postgres_types[] = {
|
||||
{"Serial",0,0,0},
|
||||
{"Postgres_Unknown 0x10",0,0,0},
|
||||
};
|
||||
/* MySQL data types */
|
||||
MdbBackendType mdb_mysql_types[] = {
|
||||
{"Mysql_Unknown 0x00",0,0,0},
|
||||
{"bit",0,0,0},
|
||||
{"char",1,0,1},
|
||||
{"smallint",0,0,0},
|
||||
{"int",0,0,0},
|
||||
{"money",0,0,0},
|
||||
{"real",0,0,0},
|
||||
{"float",0,0,0},
|
||||
{"smalldatetime",0,0,0},
|
||||
{"Mysql_Unknown 0x09",0,0,0},
|
||||
{"varchar",1,0,1},
|
||||
{"varbinary",1,0,1},
|
||||
{"text",1,0,1},
|
||||
{"Mysql_Unknown 0x0d",0,0,0},
|
||||
{"Mysql_Unknown 0x0e",0,0,0},
|
||||
{"Mysql_Unknown 0x0f",0,0,0},
|
||||
{"numeric",1,1,0},
|
||||
};
|
||||
|
||||
char *bound_values[MDB_MAX_COLS];
|
||||
char *relationships[4];
|
||||
|
||||
@@ -897,17 +897,19 @@ guint16 len;
|
||||
}
|
||||
/* swap the alt and regular page buffers, so we can call get_int16 */
|
||||
mdb_swap_pgbuf(mdb);
|
||||
row_stop = 0;
|
||||
if (memo_row) {
|
||||
row_stop = mdb_pg_get_int16(mdb, fmt->row_count_offset + 2 + (memo_row - 1) * 2) & 0x0FFF;
|
||||
} else {
|
||||
}
|
||||
if (row_stop == 0)
|
||||
row_stop = fmt->pg_size - 1;
|
||||
}
|
||||
|
||||
row_start = mdb_pg_get_int16(mdb, fmt->row_count_offset + 2 + memo_row * 2);
|
||||
len = row_stop - row_start;
|
||||
#if MDB_DEBUG
|
||||
printf("row num %d row start %d row stop %d\n", memo_row, row_start, row_stop);
|
||||
buffer_dump(mdb->pg_buf,row_start, row_start + len);
|
||||
#endif
|
||||
len = row_stop - row_start;
|
||||
if (IS_JET3(mdb)) {
|
||||
strncpy(text, &mdb->pg_buf[row_start], len);
|
||||
text[len]='\0';
|
||||
|
||||
@@ -262,6 +262,10 @@ mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, int offset, int len)
|
||||
MdbSargNode node;
|
||||
int c_offset = 0, c_len;
|
||||
|
||||
//fprintf(stderr,"mdb_index_test_sargs called on ");
|
||||
//for (i=0;i<len;i++)
|
||||
//fprintf(stderr,"%02x ",mdb->pg_buf[offset+i]);
|
||||
//fprintf(stderr,"\n");
|
||||
for (i=0;i<idx->num_keys;i++) {
|
||||
c_offset++; /* the per column null indicator/flags */
|
||||
col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
|
||||
@@ -326,14 +330,18 @@ mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg)
|
||||
|
||||
return ipg->len;
|
||||
}
|
||||
void mdb_index_page_init(MdbIndexPage *ipg)
|
||||
void mdb_index_page_reset(MdbIndexPage *ipg)
|
||||
{
|
||||
memset(ipg, 0, sizeof(MdbIndexPage));
|
||||
ipg->offset = 0xf8; /* start byte of the index entries */
|
||||
ipg->mask_pos = 0x16;
|
||||
ipg->mask_bit=0;
|
||||
ipg->len = 0;
|
||||
}
|
||||
void mdb_index_page_init(MdbIndexPage *ipg)
|
||||
{
|
||||
memset(ipg, 0, sizeof(MdbIndexPage));
|
||||
mdb_index_page_reset(ipg);
|
||||
}
|
||||
/*
|
||||
* find the next leaf page if any given a chain. Assumes any exhausted leaf
|
||||
* pages at the end of the chain have been peeled off before the call.
|
||||
@@ -361,8 +369,10 @@ mdb_find_next_leaf(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
|
||||
do {
|
||||
ipg->len = 0;
|
||||
//printf("finding next on pg %lu\n", ipg->pg);
|
||||
if (!mdb_index_find_next_on_page(mdb, ipg))
|
||||
if (!mdb_index_find_next_on_page(mdb, ipg)) {
|
||||
//printf("find_next_on_page returned 0\n");
|
||||
return 0;
|
||||
}
|
||||
pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 3);
|
||||
//printf("Looking at pg %lu at %lu %d\n", pg, ipg->offset, ipg->len);
|
||||
ipg->offset += ipg->len;
|
||||
@@ -373,7 +383,7 @@ mdb_find_next_leaf(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
|
||||
*/
|
||||
newipg = mdb_chain_add_page(mdb, chain, pg);
|
||||
newipg = mdb_find_next_leaf(mdb, idx, chain);
|
||||
//printf("returning pg %lu\n",newipg->pg);
|
||||
printf("returning pg %lu\n",newipg->pg);
|
||||
return newipg;
|
||||
} while (!passed);
|
||||
/* no more pages */
|
||||
@@ -396,6 +406,10 @@ mdb_chain_add_page(MdbHandle *mdb, MdbIndexChain *chain, guint32 pg)
|
||||
|
||||
return ipg;
|
||||
}
|
||||
/*
|
||||
* returns the bottom page of the IndexChain, if IndexChain is empty it
|
||||
* initializes it by reading idx->first_pg (the root page)
|
||||
*/
|
||||
MdbIndexPage *
|
||||
mdb_index_read_bottom_pg(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
|
||||
{
|
||||
@@ -451,8 +465,65 @@ mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32
|
||||
*/
|
||||
if (!mdb_index_find_next_on_page(mdb, ipg)) {
|
||||
//printf("page %lu finished\n",ipg->pg);
|
||||
if (chain->cur_depth==1) {
|
||||
//printf("cur_depth == 1 we're out\n");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* unwind the stack until we find something or reach
|
||||
* the top.
|
||||
*/
|
||||
ipg = 0;
|
||||
while (chain->cur_depth>1 && ipg==0) {
|
||||
//printf("chain depth %d\n", chain->cur_depth);
|
||||
chain->cur_depth--;
|
||||
ipg = mdb_find_next_leaf(mdb, idx, chain);
|
||||
if (ipg) mdb_index_find_next_on_page(mdb, ipg);
|
||||
}
|
||||
if (chain->cur_depth==1)
|
||||
return 0;
|
||||
}
|
||||
*row = mdb->pg_buf[ipg->offset + ipg->len - 1];
|
||||
*pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 4);
|
||||
//printf("row = %d pg = %lu ipg->pg = %lu offset = %lu len = %d\n", *row, *pg, ipg->pg, ipg->offset, ipg->len);
|
||||
|
||||
passed = mdb_index_test_sargs(mdb, idx, ipg->offset, ipg->len);
|
||||
|
||||
ipg->offset += ipg->len;
|
||||
} while (!passed);
|
||||
|
||||
//fprintf(stdout,"len = %d pos %d\n", ipg->len, ipg->mask_pos);
|
||||
//buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
|
||||
|
||||
return ipg->len;
|
||||
}
|
||||
/*
|
||||
* XXX - FIX ME
|
||||
* This function is grossly inefficient. It scans the entire index building
|
||||
* an IndexChain to a specific row. We should be checking the index pages
|
||||
* for matches against the indexed fields to find the proper leaf page, but
|
||||
* getting it working first and then make it fast!
|
||||
*/
|
||||
int
|
||||
mdb_index_find_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 pg, guint16 row)
|
||||
{
|
||||
MdbIndexPage *ipg;
|
||||
int passed = 0;
|
||||
guint32 datapg;
|
||||
guint16 datarow;
|
||||
|
||||
ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
|
||||
|
||||
do {
|
||||
ipg->len = 0;
|
||||
/*
|
||||
* if no more rows on this leaf, try to find a new leaf
|
||||
*/
|
||||
if (!mdb_index_find_next_on_page(mdb, ipg)) {
|
||||
/* back to top? We're done */
|
||||
if (chain->cur_depth==1)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* unwind the stack until we find something or reach
|
||||
* the top.
|
||||
@@ -466,19 +537,20 @@ mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32
|
||||
if (chain->cur_depth==1)
|
||||
return 0;
|
||||
}
|
||||
*row = mdb->pg_buf[ipg->offset + ipg->len - 1];
|
||||
*pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 4);
|
||||
|
||||
passed = mdb_index_test_sargs(mdb, idx, ipg->offset, ipg->len);
|
||||
/* test row and pg */
|
||||
datarow = mdb->pg_buf[ipg->offset + ipg->len - 1];
|
||||
datapg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 4);
|
||||
|
||||
if (datapg == pg && datarow == row) {
|
||||
passed = 1;
|
||||
}
|
||||
ipg->offset += ipg->len;
|
||||
} while (!passed);
|
||||
|
||||
//fprintf(stdout,"len = %d pos %d\n", ipg->len, ipg->mask_pos);
|
||||
//buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
|
||||
|
||||
return ipg->len;
|
||||
/* index chain from root to leaf should now be in "chain" */
|
||||
return 1;
|
||||
}
|
||||
|
||||
void mdb_index_walk(MdbTableDef *table, MdbIndex *idx)
|
||||
{
|
||||
MdbHandle *mdb = table->entry->mdb;
|
||||
@@ -520,6 +592,14 @@ mdb_index_dump(MdbTableDef *table, MdbIndex *idx)
|
||||
}
|
||||
mdb_index_walk(table, idx);
|
||||
}
|
||||
/*
|
||||
* compute_cost tries to assign a cost to a given index using the sargs
|
||||
* available in this query.
|
||||
*
|
||||
* Indexes with no matching sargs are assigned 0
|
||||
* Unique indexes are preferred over non-uniques
|
||||
* Operator preference is equal, like, isnull, others
|
||||
*/
|
||||
int mdb_index_compute_cost(MdbTableDef *table, MdbIndex *idx)
|
||||
{
|
||||
int i;
|
||||
@@ -531,7 +611,7 @@ int mdb_index_compute_cost(MdbTableDef *table, MdbIndex *idx)
|
||||
if (idx->num_keys > 1) {
|
||||
for (i=0;i<idx->num_keys;i++) {
|
||||
col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
|
||||
sarg = g_ptr_array_index (col->sargs, 0);
|
||||
if (col->sargs) sarg = g_ptr_array_index (col->sargs, 0);
|
||||
if (!sarg || sarg->op != MDB_EQUAL) not_all_equal++;
|
||||
}
|
||||
}
|
||||
@@ -609,6 +689,12 @@ int mdb_index_compute_cost(MdbTableDef *table, MdbIndex *idx)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* choose_index runs mdb_index_compute_cost for each available index and picks
|
||||
* the best.
|
||||
*
|
||||
* Returns strategy to use (table scan, or index scan)
|
||||
*/
|
||||
MdbStrategy
|
||||
mdb_choose_index(MdbTableDef *table, int *choice)
|
||||
{
|
||||
|
||||
@@ -17,6 +17,16 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* code for handling searchable arguments (sargs) used primary by the sql
|
||||
* engine to support where clause handling. The sargs are configured in
|
||||
* a tree with AND/OR operators connecting the child nodes. NOT operations
|
||||
* have only one child on the left side. Logical operators (=,<,>,etc..)
|
||||
* have no children.
|
||||
*
|
||||
* datatype support is a bit weak at this point. To add more types create
|
||||
* a mdb_test_[type]() function and invoke it from mdb_test_sarg()
|
||||
*/
|
||||
#include "mdbtools.h"
|
||||
|
||||
#ifdef DMALLOC
|
||||
@@ -66,6 +76,7 @@ int mdb_test_int(MdbSargNode *node, gint32 i)
|
||||
{
|
||||
switch (node->op) {
|
||||
case MDB_EQUAL:
|
||||
//fprintf(stderr, "comparing %ld and %ld\n", i, node->value.i);
|
||||
if (node->value.i == i) return 1;
|
||||
break;
|
||||
case MDB_GT:
|
||||
@@ -124,13 +135,13 @@ int lastchar;
|
||||
|
||||
switch (col->col_type) {
|
||||
case MDB_BYTE:
|
||||
return mdb_test_int(node, (int)((char *)buf)[0]);
|
||||
return mdb_test_int(node, (gint32)((char *)buf)[0]);
|
||||
break;
|
||||
case MDB_INT:
|
||||
return mdb_test_int(node, mdb_get_int16(buf, 0));
|
||||
return mdb_test_int(node, (gint32)mdb_get_int16(buf, 0));
|
||||
break;
|
||||
case MDB_LONGINT:
|
||||
return mdb_test_int(node, mdb_get_int32(buf, 0));
|
||||
return mdb_test_int(node, (gint32)mdb_get_int32(buf, 0));
|
||||
break;
|
||||
case MDB_TEXT:
|
||||
if (IS_JET4(mdb)) {
|
||||
|
||||
@@ -189,7 +189,7 @@ GPtrArray *mdb_read_columns(MdbTableDef *table)
|
||||
read_pg_if(mdb, &cur_col, 0);
|
||||
col.col_type = mdb->pg_buf[cur_col];
|
||||
|
||||
read_pg_if(mdb, &cur_col, fmt->col_num_offset); // col_num_offset == 1
|
||||
read_pg_if(mdb, &cur_col, fmt->col_num_offset); // col_num_offset == 1 or 5
|
||||
col.col_num = mdb->pg_buf[cur_col + fmt->col_num_offset];
|
||||
|
||||
/* FIXME: can this be right in Jet3 and Jet4? */
|
||||
|
||||
@@ -86,13 +86,13 @@ MdbIndex *idx;
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
|
||||
mdb_crack_row4(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
|
||||
{
|
||||
MdbCatalogEntry *entry = table->entry;
|
||||
MdbHandle *mdb = entry->mdb;
|
||||
MdbColumn *col;
|
||||
int i, j;
|
||||
int var_cols, fixed_cols, num_cols, totcols;
|
||||
int var_cols = 0, fixed_cols = 0, num_cols, totcols = 0;
|
||||
int var_cols_found, fixed_cols_found, var_entry_pos;
|
||||
int col_start, next_col;
|
||||
unsigned char *nullmask;
|
||||
@@ -100,15 +100,8 @@ int bitmask_sz;
|
||||
int byte_num, bit_num;
|
||||
int eod, len; /* end of data */
|
||||
|
||||
if (IS_JET4(mdb)) {
|
||||
num_cols = mdb_pg_get_int16(mdb, row_start);
|
||||
} else {
|
||||
num_cols = mdb->pg_buf[row_start];
|
||||
}
|
||||
num_cols = mdb_pg_get_int16(mdb, row_start);
|
||||
|
||||
totcols = 0;
|
||||
var_cols = 0; /* mdb->pg_buf[row_end-1]; */
|
||||
fixed_cols = 0; /* num_cols - var_cols; */
|
||||
for (i = 0; i < table->num_cols; i++) {
|
||||
col = g_ptr_array_index (table->columns, i);
|
||||
if (mdb_is_fixed_col(col)) {
|
||||
@@ -139,12 +132,7 @@ int eod, len; /* end of data */
|
||||
}
|
||||
|
||||
/* find the end of data pointer */
|
||||
if (IS_JET4(mdb)) {
|
||||
eod = mdb_pg_get_int16(mdb, row_end - 3 - var_cols*2 - bitmask_sz);
|
||||
} else {
|
||||
eod = mdb->pg_buf[row_end-1-var_cols-bitmask_sz];
|
||||
}
|
||||
//printf("eod is %d\n", eod);
|
||||
eod = mdb_pg_get_int16(mdb, row_end - 3 - var_cols*2 - bitmask_sz);
|
||||
|
||||
if (IS_JET4(mdb)) {
|
||||
col_start = 2;
|
||||
@@ -174,23 +162,14 @@ int eod, len; /* end of data */
|
||||
len=eod - col_start;
|
||||
//printf("len = %d eod %d col_start %d\n",len, eod, col_start);
|
||||
} else {
|
||||
if (IS_JET4(mdb)) {
|
||||
/* position of the var table
|
||||
* entry for this column */
|
||||
var_entry_pos =
|
||||
row_end -
|
||||
bitmask_sz -
|
||||
var_cols_found * 2 - 2 - 1;
|
||||
next_col = mdb_pg_get_int16(mdb, var_entry_pos);
|
||||
len = next_col - col_start;
|
||||
} else {
|
||||
var_entry_pos =
|
||||
row_end -
|
||||
bitmask_sz -
|
||||
var_cols_found - 1;
|
||||
len=mdb->pg_buf[var_entry_pos] - mdb->pg_buf[var_entry_pos+1];
|
||||
//printf("%d %d %d %d\n", mdb->pg_buf[var_entry_pos-1],mdb->pg_buf[var_entry_pos],len, col_start);
|
||||
}
|
||||
/* position of the var table
|
||||
* entry for this column */
|
||||
var_entry_pos =
|
||||
row_end -
|
||||
bitmask_sz -
|
||||
var_cols_found * 2 - 2 - 1;
|
||||
next_col = mdb_pg_get_int16(mdb, var_entry_pos);
|
||||
len = next_col - col_start;
|
||||
} /* if found==var_cols */
|
||||
if (len<0) len+=256;
|
||||
fields[totcols].start = row_start + col_start;
|
||||
@@ -203,6 +182,108 @@ int eod, len; /* end of data */
|
||||
return num_cols;
|
||||
|
||||
}
|
||||
static int
|
||||
mdb_crack_row3(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
|
||||
{
|
||||
MdbCatalogEntry *entry = table->entry;
|
||||
MdbHandle *mdb = entry->mdb;
|
||||
MdbColumn *col;
|
||||
int i, j;
|
||||
int var_cols = 0, fixed_cols = 0, num_cols, totcols = 0;
|
||||
int var_cols_found, fixed_cols_found, var_entry_pos;
|
||||
int col_start, next_col;
|
||||
unsigned char *nullmask;
|
||||
int bitmask_sz;
|
||||
int byte_num, bit_num;
|
||||
int eod, len; /* end of data */
|
||||
|
||||
num_cols = mdb->pg_buf[row_start];
|
||||
|
||||
for (i = 0; i < table->num_cols; i++) {
|
||||
col = g_ptr_array_index (table->columns, i);
|
||||
if (mdb_is_fixed_col(col)) {
|
||||
fixed_cols++;
|
||||
fields[totcols].colnum = i;
|
||||
fields[totcols].siz = col->col_size;
|
||||
fields[totcols++].is_fixed = 1;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < table->num_cols; i++) {
|
||||
col = g_ptr_array_index (table->columns, i);
|
||||
if (!mdb_is_fixed_col(col)) {
|
||||
var_cols++;
|
||||
fields[totcols].colnum = i;
|
||||
fields[totcols++].is_fixed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bitmask_sz = (num_cols - 1) / 8 + 1;
|
||||
nullmask = &mdb->pg_buf[row_end - bitmask_sz + 1];
|
||||
|
||||
for (i=0;i<num_cols;i++) {
|
||||
byte_num = i / 8;
|
||||
bit_num = i % 8;
|
||||
/* logic on nulls is reverse, 1 is not null, 0 is null */
|
||||
fields[i].is_null = nullmask[byte_num] & 1 << bit_num ? 0 : 1;
|
||||
}
|
||||
|
||||
/* find the end of data pointer */
|
||||
eod = mdb->pg_buf[row_end-1-var_cols-bitmask_sz];
|
||||
|
||||
/* data starts at 1 */
|
||||
col_start = 1;
|
||||
|
||||
/* actual cols on this row */
|
||||
fixed_cols_found = 0;
|
||||
var_cols_found = 0;
|
||||
|
||||
totcols = 0;
|
||||
/* loop through fixed columns and add values to fields[] */
|
||||
for (j=0;j<table->num_cols;j++) {
|
||||
col = g_ptr_array_index(table->columns,j);
|
||||
if (mdb_is_fixed_col(col) && ++fixed_cols_found <= fixed_cols) {
|
||||
fields[totcols].start = row_start + col_start;
|
||||
fields[totcols++].value = &mdb->pg_buf[row_start + col_start];
|
||||
if (col->col_type != MDB_BOOL)
|
||||
col_start += col->col_size;
|
||||
}
|
||||
}
|
||||
for (j=0;j<table->num_cols;j++) {
|
||||
col = g_ptr_array_index(table->columns,j);
|
||||
if (!mdb_is_fixed_col(col) && ++var_cols_found <= var_cols) {
|
||||
if (var_cols_found==var_cols) {
|
||||
len=eod - col_start;
|
||||
//printf("len = %d eod %d col_start %d\n",len, eod, col_start);
|
||||
} else {
|
||||
var_entry_pos =
|
||||
row_end -
|
||||
bitmask_sz -
|
||||
var_cols_found - 1;
|
||||
len=mdb->pg_buf[var_entry_pos] - mdb->pg_buf[var_entry_pos+1];
|
||||
} /* if found==var_cols */
|
||||
if (len<0) len+=256;
|
||||
fields[totcols].start = row_start + col_start;
|
||||
fields[totcols].value = &mdb->pg_buf[row_start +col_start];
|
||||
fields[totcols++].siz = len;
|
||||
col_start += len;
|
||||
} /* if !fixed */
|
||||
} /* for */
|
||||
|
||||
return num_cols;
|
||||
|
||||
}
|
||||
int
|
||||
mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
|
||||
{
|
||||
MdbCatalogEntry *entry = table->entry;
|
||||
MdbHandle *mdb = entry->mdb;
|
||||
|
||||
if (IS_JET4(mdb)) {
|
||||
return mdb_crack_row4(table, row_start, row_end, fields);
|
||||
} else {
|
||||
return mdb_crack_row3(table, row_start, row_end, fields);
|
||||
}
|
||||
}
|
||||
/* fields must be ordered with fixed columns first, then vars, subsorted by
|
||||
* column number */
|
||||
int
|
||||
@@ -277,6 +358,20 @@ int rows, free_start, free_end;
|
||||
return (free_end - free_start + 1);
|
||||
}
|
||||
unsigned char *
|
||||
mdb_new_leaf_pg(MdbCatalogEntry *entry)
|
||||
{
|
||||
MdbHandle *mdb = entry->mdb;
|
||||
unsigned char *new_pg;
|
||||
|
||||
new_pg = (unsigned char *) g_malloc0(mdb->fmt->pg_size);
|
||||
|
||||
new_pg[0]=0x04;
|
||||
new_pg[1]=0x01;
|
||||
_mdb_put_int32(new_pg, 4, entry->table_pg);
|
||||
|
||||
return new_pg;
|
||||
}
|
||||
unsigned char *
|
||||
mdb_new_data_pg(MdbCatalogEntry *entry)
|
||||
{
|
||||
MdbHandle *mdb = entry->mdb;
|
||||
@@ -292,7 +387,7 @@ mdb_new_data_pg(MdbCatalogEntry *entry)
|
||||
}
|
||||
|
||||
int
|
||||
mdb_update_indexes(MdbTableDef *table, int num_fields, MdbField *fields)
|
||||
mdb_update_indexes(MdbTableDef *table, int num_fields, MdbField *fields, guint32 pgnum, guint16 rownum)
|
||||
{
|
||||
int i;
|
||||
MdbIndex *idx;
|
||||
@@ -303,7 +398,7 @@ mdb_update_indexes(MdbTableDef *table, int num_fields, MdbField *fields)
|
||||
fprintf(stderr,"Updating %s (%d).\n", idx->name, idx->index_type);
|
||||
#endif
|
||||
if (idx->index_type==1) {
|
||||
mdb_update_index(table, idx, num_fields, fields);
|
||||
mdb_update_index(table, idx, num_fields, fields, pgnum, rownum);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@@ -322,11 +417,15 @@ mdb_init_index_chain(MdbTableDef *table, MdbIndex *idx)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
mdb_update_index(MdbTableDef *table, MdbIndex *idx, int num_fields, MdbField *fields)
|
||||
mdb_update_index(MdbTableDef *table, MdbIndex *idx, int num_fields, MdbField *fields, guint32 pgnum, guint16 rownum)
|
||||
{
|
||||
MdbCatalogEntry *entry = table->entry;
|
||||
MdbHandle *mdb = entry->mdb;
|
||||
int idx_xref[16];
|
||||
int i, j;
|
||||
MdbIndexChain *chain;
|
||||
|
||||
for (i = 0; i < idx->num_keys; i++) {
|
||||
for (j = 0; j < num_fields; j++) {
|
||||
@@ -345,7 +444,13 @@ mdb_update_index(MdbTableDef *table, MdbIndex *idx, int num_fields, MdbField *fi
|
||||
i, fields[i].colnum,
|
||||
fields[i].siz);
|
||||
}
|
||||
//mdb_find_leaf_pg();
|
||||
|
||||
chain = g_malloc0(sizeof(MdbIndexChain));
|
||||
|
||||
mdb_index_find_row(mdb, idx, chain, pgnum, rownum);
|
||||
printf("chain depth = %d\n", chain->cur_depth);
|
||||
printf("pg = %lu\n", chain->pages[chain->cur_depth-1].pg);
|
||||
mdb_copy_index_pg(table, &chain->pages[chain->cur_depth-1]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -359,6 +464,8 @@ mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields)
|
||||
MdbHandle *mdb = entry->mdb;
|
||||
MdbFormatConstants *fmt = mdb->fmt;
|
||||
guint32 pgnum;
|
||||
guint16 rownum;
|
||||
unsigned char *new_pg;
|
||||
|
||||
if (!mdb->f->writable) {
|
||||
fprintf(stderr, "File is not open for writing\n");
|
||||
@@ -374,7 +481,7 @@ mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields)
|
||||
return 0;
|
||||
}
|
||||
|
||||
mdb_add_row_to_pg(table, row_buffer, new_row_size);
|
||||
rownum = mdb_add_row_to_pg(table, row_buffer, new_row_size);
|
||||
|
||||
#if MDB_DEBUG_WRITE
|
||||
buffer_dump(mdb->pg_buf, 0, 39);
|
||||
@@ -386,15 +493,15 @@ mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mdb_update_indexes(table, num_fields, fields);
|
||||
|
||||
mdb_update_indexes(table, num_fields, fields, pgnum, rownum);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* Assumes caller has verfied space is available on page and adds the new
|
||||
* row to the current pg_buf.
|
||||
*/
|
||||
void
|
||||
guint16
|
||||
mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_size)
|
||||
{
|
||||
unsigned char *new_pg;
|
||||
@@ -434,6 +541,8 @@ mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_siz
|
||||
|
||||
/* update the freespace */
|
||||
_mdb_put_int16(mdb->pg_buf, 2, mdb_pg_get_freespace(mdb));
|
||||
|
||||
return num_rows;
|
||||
}
|
||||
int
|
||||
mdb_update_row(MdbTableDef *table)
|
||||
@@ -564,3 +673,26 @@ int i, pos;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
mdb_copy_index_pg(MdbTableDef *table, MdbIndexPage *ipg)
|
||||
{
|
||||
MdbCatalogEntry *entry = table->entry;
|
||||
MdbHandle *mdb = entry->mdb;
|
||||
guint32 pg;
|
||||
unsigned char *new_pg;
|
||||
|
||||
new_pg = mdb_new_leaf_pg(entry);
|
||||
|
||||
mdb_index_page_reset(ipg);
|
||||
mdb_read_pg(mdb, ipg->pg);
|
||||
while (mdb_index_find_next_on_page(mdb, ipg)) {
|
||||
pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 3);
|
||||
printf("length = %d\n", ipg->len);
|
||||
buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset + ipg->len - 1);
|
||||
ipg->offset += ipg->len;
|
||||
ipg->len = 0;
|
||||
}
|
||||
g_free(new_pg);
|
||||
|
||||
return ipg->len;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user