mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-09-19 02:27:55 +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;
|
||||
}
|
||||
|
245
src/sql/lexer.c
245
src/sql/lexer.c
@@ -1,7 +1,7 @@
|
||||
/* A lexical scanner generated by flex */
|
||||
|
||||
/* Scanner skeleton version:
|
||||
* $Header: /Users/brian/cvs/mdbtools/mdbtools/src/sql/Attic/lexer.c,v 1.6 2003/01/20 16:04:31 brianb Exp $
|
||||
* $Header: /Users/brian/cvs/mdbtools/mdbtools/src/sql/Attic/lexer.c,v 1.7 2004/02/06 02:34:22 brianb Exp $
|
||||
*/
|
||||
|
||||
#define FLEX_SCANNER
|
||||
@@ -282,20 +282,20 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
|
||||
*yy_cp = '\0'; \
|
||||
yy_c_buf_p = yy_cp;
|
||||
|
||||
#define YY_NUM_RULES 24
|
||||
#define YY_END_OF_BUFFER 25
|
||||
static yyconst short int yy_accept[95] =
|
||||
#define YY_NUM_RULES 25
|
||||
#define YY_END_OF_BUFFER 26
|
||||
static yyconst short int yy_accept[97] =
|
||||
{ 0,
|
||||
21, 21, 25, 23, 17, 24, 23, 23, 22, 23,
|
||||
21, 23, 23, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 23, 0, 0, 20, 0, 22,
|
||||
0, 22, 22, 21, 14, 15, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 12, 19, 19, 5, 19,
|
||||
0, 18, 0, 21, 21, 11, 19, 19, 19, 19,
|
||||
19, 19, 13, 19, 19, 19, 19, 19, 19, 2,
|
||||
16, 6, 19, 19, 19, 19, 19, 19, 19, 9,
|
||||
7, 19, 19, 19, 1, 8, 3, 19, 19, 10,
|
||||
19, 19, 4, 0
|
||||
22, 22, 26, 24, 18, 25, 24, 24, 23, 24,
|
||||
22, 24, 24, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 24, 0, 0, 21, 0,
|
||||
23, 0, 23, 23, 22, 15, 16, 20, 20, 20,
|
||||
20, 20, 20, 20, 14, 20, 20, 12, 20, 20,
|
||||
5, 20, 0, 19, 0, 22, 22, 11, 20, 20,
|
||||
20, 20, 20, 20, 13, 20, 20, 20, 20, 20,
|
||||
20, 2, 17, 6, 20, 20, 20, 20, 20, 20,
|
||||
20, 9, 7, 20, 20, 20, 1, 8, 3, 20,
|
||||
20, 10, 20, 20, 4, 0
|
||||
|
||||
} ;
|
||||
|
||||
@@ -339,112 +339,116 @@ static yyconst int yy_meta[36] =
|
||||
8, 8, 8, 8, 1
|
||||
} ;
|
||||
|
||||
static yyconst short int yy_base[101] =
|
||||
static yyconst short int yy_base[103] =
|
||||
{ 0,
|
||||
0, 0, 158, 285, 285, 285, 0, 149, 29, 31,
|
||||
36, 132, 115, 41, 43, 45, 52, 51, 24, 39,
|
||||
53, 46, 62, 64, 81, 113, 90, 75, 86, 87,
|
||||
90, 95, 101, 0, 285, 285, 65, 0, 94, 91,
|
||||
85, 100, 103, 105, 102, 113, 115, 123, 118, 124,
|
||||
75, 285, 54, 53, 140, 126, 132, 135, 143, 138,
|
||||
144, 146, 149, 151, 156, 157, 159, 164, 166, 165,
|
||||
172, 173, 180, 179, 181, 188, 187, 189, 190, 195,
|
||||
196, 201, 207, 208, 210, 215, 217, 218, 220, 223,
|
||||
228, 225, 230, 285, 50, 258, 263, 267, 273, 276
|
||||
0, 0, 177, 289, 289, 289, 0, 156, 29, 31,
|
||||
36, 126, 111, 41, 43, 45, 52, 51, 39, 24,
|
||||
44, 58, 59, 69, 67, 75, 114, 92, 75, 88,
|
||||
83, 91, 96, 102, 0, 289, 289, 86, 0, 95,
|
||||
92, 97, 103, 106, 105, 112, 118, 120, 121, 129,
|
||||
128, 131, 73, 289, 55, 54, 122, 134, 136, 139,
|
||||
147, 142, 148, 150, 153, 155, 160, 161, 163, 168,
|
||||
170, 169, 176, 177, 184, 183, 185, 192, 191, 193,
|
||||
194, 199, 200, 205, 211, 212, 214, 219, 221, 222,
|
||||
224, 227, 232, 229, 234, 289, 50, 262, 267, 271,
|
||||
|
||||
277, 280
|
||||
} ;
|
||||
|
||||
static yyconst short int yy_def[101] =
|
||||
static yyconst short int yy_def[103] =
|
||||
{ 0,
|
||||
94, 1, 94, 94, 94, 94, 95, 96, 97, 97,
|
||||
97, 94, 94, 98, 98, 98, 98, 17, 17, 17,
|
||||
17, 17, 17, 17, 11, 99, 96, 96, 94, 11,
|
||||
11, 11, 11, 11, 94, 94, 17, 100, 17, 17,
|
||||
96, 1, 96, 96, 96, 96, 97, 98, 99, 99,
|
||||
99, 96, 96, 100, 100, 100, 100, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 11, 101, 98, 98, 96,
|
||||
11, 11, 11, 11, 11, 96, 96, 17, 102, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
99, 94, 94, 94, 11, 17, 17, 17, 17, 17,
|
||||
17, 17, 101, 96, 96, 96, 11, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 0, 94, 94, 94, 94, 94, 94
|
||||
17, 17, 17, 17, 17, 0, 96, 96, 96, 96,
|
||||
|
||||
96, 96
|
||||
} ;
|
||||
|
||||
static yyconst short int yy_nxt[321] =
|
||||
static yyconst short int yy_nxt[325] =
|
||||
{ 0,
|
||||
4, 5, 6, 5, 7, 8, 4, 4, 4, 9,
|
||||
10, 11, 12, 4, 13, 4, 14, 15, 16, 17,
|
||||
15, 18, 15, 15, 15, 15, 19, 15, 20, 21,
|
||||
15, 22, 23, 24, 25, 29, 29, 94, 94, 31,
|
||||
32, 94, 94, 94, 37, 33, 31, 34, 44, 32,
|
||||
30, 31, 30, 31, 30, 31, 38, 26, 38, 37,
|
||||
38, 30, 31, 37, 54, 54, 47, 38, 45, 39,
|
||||
37, 37, 41, 37, 40, 37, 42, 37, 48, 52,
|
||||
28, 43, 37, 46, 37, 37, 37, 50, 37, 37,
|
||||
30, 49, 30, 53, 53, 28, 30, 54, 30, 30,
|
||||
15, 18, 15, 15, 19, 15, 20, 15, 21, 22,
|
||||
15, 23, 24, 25, 26, 30, 30, 96, 96, 32,
|
||||
33, 96, 96, 96, 38, 34, 32, 35, 46, 33,
|
||||
31, 32, 31, 32, 31, 32, 39, 27, 39, 38,
|
||||
39, 31, 32, 38, 38, 56, 56, 39, 38, 40,
|
||||
45, 38, 42, 47, 41, 38, 43, 54, 38, 49,
|
||||
29, 44, 38, 38, 31, 50, 31, 38, 48, 38,
|
||||
52, 38, 31, 38, 31, 55, 55, 29, 51, 56,
|
||||
|
||||
94, 30, 53, 53, 30, 37, 55, 29, 29, 37,
|
||||
30, 37, 32, 56, 37, 37, 58, 52, 37, 57,
|
||||
37, 32, 37, 37, 37, 37, 37, 37, 36, 37,
|
||||
61, 59, 60, 37, 63, 37, 62, 37, 37, 37,
|
||||
65, 64, 37, 37, 66, 35, 37, 37, 37, 30,
|
||||
37, 55, 37, 68, 28, 37, 37, 94, 37, 37,
|
||||
67, 69, 37, 37, 71, 70, 37, 37, 37, 37,
|
||||
37, 73, 94, 37, 94, 37, 37, 37, 72, 76,
|
||||
37, 37, 74, 37, 37, 37, 37, 75, 37, 37,
|
||||
37, 94, 37, 37, 77, 78, 37, 37, 79, 80,
|
||||
31, 96, 31, 55, 55, 31, 38, 57, 30, 30,
|
||||
38, 31, 38, 33, 58, 38, 38, 38, 54, 38,
|
||||
59, 38, 33, 38, 37, 38, 38, 38, 60, 38,
|
||||
38, 31, 38, 57, 61, 62, 38, 63, 38, 36,
|
||||
38, 38, 38, 64, 38, 38, 67, 66, 38, 38,
|
||||
65, 68, 38, 38, 38, 38, 38, 70, 38, 38,
|
||||
38, 29, 38, 38, 69, 71, 38, 38, 73, 72,
|
||||
38, 38, 38, 38, 38, 75, 96, 38, 96, 38,
|
||||
38, 38, 74, 78, 38, 38, 76, 38, 38, 38,
|
||||
38, 77, 38, 38, 38, 96, 38, 38, 79, 80,
|
||||
|
||||
37, 81, 94, 37, 37, 37, 82, 37, 37, 37,
|
||||
37, 83, 37, 37, 37, 37, 37, 84, 94, 37,
|
||||
37, 37, 85, 94, 88, 37, 86, 37, 37, 94,
|
||||
37, 37, 37, 87, 37, 37, 89, 37, 90, 37,
|
||||
91, 37, 37, 37, 37, 37, 92, 37, 37, 37,
|
||||
37, 94, 37, 94, 37, 94, 94, 93, 27, 94,
|
||||
27, 27, 27, 27, 27, 27, 30, 30, 30, 94,
|
||||
30, 37, 37, 37, 37, 51, 94, 94, 51, 51,
|
||||
51, 38, 38, 38, 3, 94, 94, 94, 94, 94,
|
||||
94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
|
||||
38, 38, 81, 82, 38, 83, 96, 38, 38, 38,
|
||||
84, 38, 38, 38, 38, 85, 38, 38, 38, 38,
|
||||
38, 86, 96, 38, 38, 38, 87, 96, 90, 38,
|
||||
88, 38, 38, 96, 38, 38, 38, 89, 38, 38,
|
||||
91, 38, 92, 38, 93, 38, 38, 38, 38, 38,
|
||||
94, 38, 38, 38, 38, 96, 38, 96, 38, 96,
|
||||
96, 95, 28, 96, 28, 28, 28, 28, 28, 28,
|
||||
31, 31, 31, 96, 31, 38, 38, 38, 38, 53,
|
||||
96, 96, 53, 53, 53, 39, 39, 39, 3, 96,
|
||||
96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
|
||||
|
||||
94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
|
||||
94, 94, 94, 94, 94, 94, 94, 94, 94, 94
|
||||
96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
|
||||
96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
|
||||
96, 96, 96, 96
|
||||
} ;
|
||||
|
||||
static yyconst short int yy_chk[321] =
|
||||
static yyconst short int yy_chk[325] =
|
||||
{ 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 9, 9, 10, 10, 9,
|
||||
9, 10, 11, 11, 19, 11, 11, 11, 19, 9,
|
||||
14, 14, 15, 15, 16, 16, 14, 95, 15, 20,
|
||||
16, 17, 17, 20, 54, 53, 22, 17, 20, 14,
|
||||
22, 18, 17, 21, 16, 18, 17, 21, 23, 51,
|
||||
28, 18, 23, 21, 24, 37, 23, 24, 24, 37,
|
||||
25, 23, 25, 29, 29, 27, 30, 29, 30, 31,
|
||||
9, 10, 11, 11, 20, 11, 11, 11, 20, 9,
|
||||
14, 14, 15, 15, 16, 16, 14, 97, 15, 19,
|
||||
16, 17, 17, 19, 21, 56, 55, 17, 21, 14,
|
||||
19, 18, 17, 21, 16, 18, 17, 53, 22, 23,
|
||||
29, 18, 22, 23, 26, 24, 26, 25, 22, 24,
|
||||
25, 25, 31, 24, 31, 30, 30, 28, 24, 30,
|
||||
|
||||
31, 31, 32, 32, 32, 41, 32, 33, 33, 41,
|
||||
33, 40, 33, 39, 39, 40, 41, 26, 39, 40,
|
||||
42, 33, 45, 43, 42, 44, 45, 43, 13, 44,
|
||||
44, 42, 43, 46, 45, 47, 44, 46, 49, 47,
|
||||
48, 47, 49, 48, 50, 12, 56, 48, 50, 55,
|
||||
56, 55, 57, 58, 8, 58, 57, 3, 60, 58,
|
||||
57, 59, 60, 59, 61, 60, 62, 59, 61, 63,
|
||||
62, 64, 0, 63, 0, 64, 65, 66, 62, 67,
|
||||
65, 66, 65, 67, 68, 70, 69, 66, 68, 70,
|
||||
69, 0, 71, 72, 68, 69, 71, 72, 73, 74,
|
||||
32, 32, 32, 33, 33, 33, 38, 33, 34, 34,
|
||||
38, 34, 41, 34, 40, 40, 41, 42, 27, 40,
|
||||
41, 42, 34, 43, 13, 45, 44, 43, 42, 45,
|
||||
44, 57, 46, 57, 43, 44, 46, 46, 47, 12,
|
||||
48, 49, 47, 46, 48, 49, 50, 49, 51, 50,
|
||||
47, 52, 51, 50, 58, 52, 59, 60, 58, 60,
|
||||
59, 8, 62, 60, 59, 61, 62, 61, 63, 62,
|
||||
64, 61, 63, 65, 64, 66, 3, 65, 0, 66,
|
||||
67, 68, 64, 69, 67, 68, 67, 69, 70, 72,
|
||||
71, 68, 70, 72, 71, 0, 73, 74, 70, 71,
|
||||
|
||||
73, 75, 0, 74, 73, 75, 76, 77, 76, 78,
|
||||
79, 77, 76, 78, 79, 80, 81, 78, 0, 80,
|
||||
81, 82, 79, 0, 83, 82, 80, 83, 84, 0,
|
||||
85, 83, 84, 82, 85, 86, 84, 87, 88, 86,
|
||||
89, 87, 88, 90, 89, 92, 91, 90, 91, 92,
|
||||
93, 0, 91, 0, 93, 0, 0, 92, 96, 0,
|
||||
96, 96, 96, 96, 96, 96, 97, 97, 97, 0,
|
||||
97, 98, 98, 98, 98, 99, 0, 0, 99, 99,
|
||||
99, 100, 100, 100, 94, 94, 94, 94, 94, 94,
|
||||
94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
|
||||
73, 74, 75, 76, 75, 77, 0, 76, 75, 77,
|
||||
78, 79, 78, 80, 81, 79, 78, 80, 81, 82,
|
||||
83, 80, 0, 82, 83, 84, 81, 0, 85, 84,
|
||||
82, 85, 86, 0, 87, 85, 86, 84, 87, 88,
|
||||
86, 89, 90, 88, 91, 89, 90, 92, 91, 94,
|
||||
93, 92, 93, 94, 95, 0, 93, 0, 95, 0,
|
||||
0, 94, 98, 0, 98, 98, 98, 98, 98, 98,
|
||||
99, 99, 99, 0, 99, 100, 100, 100, 100, 101,
|
||||
0, 0, 101, 101, 101, 102, 102, 102, 96, 96,
|
||||
96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
|
||||
|
||||
94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
|
||||
94, 94, 94, 94, 94, 94, 94, 94, 94, 94
|
||||
96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
|
||||
96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
|
||||
96, 96, 96, 96
|
||||
} ;
|
||||
|
||||
static yy_state_type yy_last_accepting_state;
|
||||
@@ -483,7 +487,7 @@ char *yytext;
|
||||
#include "mdbsql.h"
|
||||
#include "parser.h"
|
||||
|
||||
#line 487 "lexer.c"
|
||||
#line 491 "lexer.c"
|
||||
|
||||
/* Macros after this point can all be overridden by user definitions in
|
||||
* section 1.
|
||||
@@ -636,7 +640,7 @@ YY_DECL
|
||||
|
||||
#line 26 "lexer.l"
|
||||
|
||||
#line 640 "lexer.c"
|
||||
#line 644 "lexer.c"
|
||||
|
||||
if ( yy_init )
|
||||
{
|
||||
@@ -687,13 +691,13 @@ yy_match:
|
||||
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
|
||||
{
|
||||
yy_current_state = (int) yy_def[yy_current_state];
|
||||
if ( yy_current_state >= 95 )
|
||||
if ( yy_current_state >= 97 )
|
||||
yy_c = yy_meta[(unsigned int) yy_c];
|
||||
}
|
||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
|
||||
++yy_cp;
|
||||
}
|
||||
while ( yy_base[yy_current_state] != 285 );
|
||||
while ( yy_base[yy_current_state] != 289 );
|
||||
|
||||
yy_find_action:
|
||||
yy_act = yy_accept[yy_current_state];
|
||||
@@ -787,65 +791,70 @@ YY_RULE_SETUP
|
||||
case 14:
|
||||
YY_RULE_SETUP
|
||||
#line 40 "lexer.l"
|
||||
{ return LTEQ; }
|
||||
{ return IS; }
|
||||
YY_BREAK
|
||||
case 15:
|
||||
YY_RULE_SETUP
|
||||
#line 41 "lexer.l"
|
||||
{ return GTEQ; }
|
||||
{ return LTEQ; }
|
||||
YY_BREAK
|
||||
case 16:
|
||||
YY_RULE_SETUP
|
||||
#line 42 "lexer.l"
|
||||
{ return LIKE; }
|
||||
{ return GTEQ; }
|
||||
YY_BREAK
|
||||
case 17:
|
||||
YY_RULE_SETUP
|
||||
#line 43 "lexer.l"
|
||||
;
|
||||
{ return LIKE; }
|
||||
YY_BREAK
|
||||
case 18:
|
||||
YY_RULE_SETUP
|
||||
#line 44 "lexer.l"
|
||||
;
|
||||
YY_BREAK
|
||||
case 19:
|
||||
YY_RULE_SETUP
|
||||
#line 45 "lexer.l"
|
||||
{
|
||||
yylval.name = strdup(&yytext[1]);
|
||||
yylval.name[strlen(yylval.name)-1]='\0';
|
||||
return IDENT;
|
||||
}
|
||||
YY_BREAK
|
||||
case 19:
|
||||
YY_RULE_SETUP
|
||||
#line 49 "lexer.l"
|
||||
{ yylval.name = strdup(yytext); return NAME; }
|
||||
YY_BREAK
|
||||
case 20:
|
||||
YY_RULE_SETUP
|
||||
#line 51 "lexer.l"
|
||||
{ yylval.name = strdup(yytext); return STRING; }
|
||||
#line 50 "lexer.l"
|
||||
{ yylval.name = strdup(yytext); return NAME; }
|
||||
YY_BREAK
|
||||
case 21:
|
||||
YY_RULE_SETUP
|
||||
#line 52 "lexer.l"
|
||||
{ yylval.name = strdup(yytext); return STRING; }
|
||||
YY_BREAK
|
||||
case 22:
|
||||
YY_RULE_SETUP
|
||||
#line 53 "lexer.l"
|
||||
{
|
||||
yylval.name = strdup(yytext); return NUMBER;
|
||||
}
|
||||
YY_BREAK
|
||||
case 22:
|
||||
YY_RULE_SETUP
|
||||
#line 55 "lexer.l"
|
||||
{ yylval.name = strdup(yytext); return PATH; }
|
||||
YY_BREAK
|
||||
case 23:
|
||||
YY_RULE_SETUP
|
||||
#line 56 "lexer.l"
|
||||
{ return yytext[0]; }
|
||||
{ yylval.name = strdup(yytext); return PATH; }
|
||||
YY_BREAK
|
||||
case 24:
|
||||
YY_RULE_SETUP
|
||||
#line 57 "lexer.l"
|
||||
{ return yytext[0]; }
|
||||
YY_BREAK
|
||||
case 25:
|
||||
YY_RULE_SETUP
|
||||
#line 58 "lexer.l"
|
||||
ECHO;
|
||||
YY_BREAK
|
||||
#line 849 "lexer.c"
|
||||
#line 858 "lexer.c"
|
||||
case YY_STATE_EOF(INITIAL):
|
||||
yyterminate();
|
||||
|
||||
@@ -1137,7 +1146,7 @@ static yy_state_type yy_get_previous_state()
|
||||
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
|
||||
{
|
||||
yy_current_state = (int) yy_def[yy_current_state];
|
||||
if ( yy_current_state >= 95 )
|
||||
if ( yy_current_state >= 97 )
|
||||
yy_c = yy_meta[(unsigned int) yy_c];
|
||||
}
|
||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
|
||||
@@ -1172,11 +1181,11 @@ yy_state_type yy_current_state;
|
||||
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
|
||||
{
|
||||
yy_current_state = (int) yy_def[yy_current_state];
|
||||
if ( yy_current_state >= 95 )
|
||||
if ( yy_current_state >= 97 )
|
||||
yy_c = yy_meta[(unsigned int) yy_c];
|
||||
}
|
||||
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
|
||||
yy_is_jam = (yy_current_state == 94);
|
||||
yy_is_jam = (yy_current_state == 96);
|
||||
|
||||
return yy_is_jam ? 0 : yy_current_state;
|
||||
}
|
||||
@@ -1726,7 +1735,7 @@ int main()
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#line 57 "lexer.l"
|
||||
#line 58 "lexer.l"
|
||||
|
||||
|
||||
int yywrap()
|
||||
|
@@ -37,6 +37,7 @@ describe { return DESCRIBE; }
|
||||
and { return AND; }
|
||||
or { return OR; }
|
||||
not { return NOT; }
|
||||
is { return IS; }
|
||||
(<=) { return LTEQ; }
|
||||
(>=) { return GTEQ; }
|
||||
like { return LIKE; }
|
||||
|
@@ -43,11 +43,12 @@ static MdbSQL *g_sql;
|
||||
%token <name> IDENT NAME PATH STRING NUMBER
|
||||
%token SELECT FROM WHERE CONNECT DISCONNECT TO LIST TABLES WHERE AND OR NOT
|
||||
%token DESCRIBE TABLE
|
||||
%token LTEQ GTEQ LIKE
|
||||
%token LTEQ GTEQ LIKE IS NULL
|
||||
|
||||
%type <name> database
|
||||
%type <name> constant
|
||||
%type <ival> operator
|
||||
%type <ival> nulloperator
|
||||
|
||||
%%
|
||||
|
||||
@@ -98,6 +99,10 @@ sarg:
|
||||
free($1);
|
||||
free($3);
|
||||
}
|
||||
| NAME nulloperator {
|
||||
mdb_sql_add_sarg(_mdb_sql(NULL), $1, $2, NULL);
|
||||
free($1);
|
||||
}
|
||||
;
|
||||
|
||||
operator:
|
||||
@@ -108,6 +113,12 @@ operator:
|
||||
| GTEQ { $$ = MDB_GTEQ; }
|
||||
| LIKE { $$ = MDB_LIKE; }
|
||||
;
|
||||
|
||||
nulloperator:
|
||||
IS NULL { $$ = MDB_ISNULL; }
|
||||
| IS NOT NULL { $$ = MDB_NOTNULL; }
|
||||
;
|
||||
|
||||
constant:
|
||||
NUMBER { $$ = $1; }
|
||||
| STRING { $$ = $1; }
|
||||
|
Reference in New Issue
Block a user