sync up, see ChangeLog for details

This commit is contained in:
brianb
2004-02-06 02:34:20 +00:00
parent ede5601bf2
commit a74094c667
15 changed files with 539 additions and 200 deletions

View File

@@ -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];

View File

@@ -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';

View File

@@ -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)
{

View File

@@ -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)) {

View File

@@ -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? */

View File

@@ -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;
}

View File

@@ -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()

View File

@@ -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; }

View File

@@ -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; }