query planner stuff

some gcc -Wall fixes
added suport for _ in identifier names in SQL
gmdb2 manual additions
This commit is contained in:
brianb 2003-01-20 16:04:24 +00:00
parent bafa51bd88
commit 092e2b79af
34 changed files with 1143 additions and 382 deletions

View File

@ -16,6 +16,8 @@ typedef struct {
int num_sargs;
GPtrArray *sargs;
MdbTableDef *cur_table;
MdbSargNode *sarg_tree;
GList *sarg_stack;
/* FIX ME */
char *bound_values[256];
} MdbSQL;
@ -50,7 +52,7 @@ MdbSQLColumn *mdb_sql_alloc_column();
MdbSQLTable *mdb_sql_alloc_table();
MdbHandle *mdb_sql_open(MdbSQL *sql, char *db_name);
int mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant);
int mdb_sql_all_columns(MdbSQL *sql);
void mdb_sql_all_columns(MdbSQL *sql);
int mdb_sql_add_column(MdbSQL *sql, char *column_name);
int mdb_sql_add_table(MdbSQL *sql, char *table_name);
void mdb_sql_dump(MdbSQL *sql);

View File

@ -85,7 +85,10 @@ enum {
/* SARG operators */
enum {
MDB_EQUAL = 1,
MDB_OR = 1,
MDB_AND,
MDB_NOT,
MDB_EQUAL,
MDB_GT,
MDB_LT,
MDB_GTEQ,
@ -95,6 +98,25 @@ enum {
MDB_NOTNULL
};
typedef enum {
MDB_TABLE_SCAN,
MDB_LEAF_SCAN,
MDB_INDEX_SCAN
} MdbStrategy;
#define mdb_is_logical_op(x) (x == MDB_OR || \
x == MDB_AND || \
x == MDB_NOT )
#define mdb_is_relational_op(x) (x == MDB_EQUAL || \
x == MDB_GT || \
x == MDB_LT || \
x == MDB_GTEQ || \
x == MDB_LTEQ || \
x == MDB_LIKE || \
x == MDB_ISNULL || \
x == MDB_NOTNULL )
enum {
MDB_ASC,
MDB_DESC
@ -112,6 +134,9 @@ enum {
/* hash to store registered backends */
GHashTable *mdb_backends;
/* forward declarations */
typedef struct mdbindex MdbIndex;
typedef struct {
char **types_table;
} MdbBackend;
@ -158,7 +183,7 @@ typedef struct {
typedef struct {
MdbFile *f;
guint16 cur_pg;
guint32 cur_pg;
guint16 row_num;
unsigned int cur_pos;
unsigned char pg_buf[MDB_PGSIZE];
@ -183,63 +208,11 @@ typedef struct {
GArray *columns;
} MdbCatalogEntry;
typedef struct {
MdbCatalogEntry *entry;
char name[MDB_MAX_OBJ_NAME+1];
int num_cols;
GPtrArray *columns;
int num_rows;
int index_start;
int num_real_idxs;
int num_idxs;
GPtrArray *indices;
int first_data_pg;
int cur_pg_num;
int cur_phys_pg;
int cur_row;
int noskip_del; /* don't skip deleted rows */
/* object allocation map */
int map_base_pg;
int map_sz;
unsigned char *usage_map;
/* */
int idxmap_base_pg;
int idxmap_sz;
unsigned char *idx_usage_map;
} MdbTableDef;
typedef struct {
int index_num;
char name[MDB_MAX_OBJ_NAME+1];
unsigned char index_type;
int first_pg;
int num_rows; /* number rows in index */
int num_keys;
short key_col_num[MDB_MAX_IDX_COLS];
unsigned char key_col_order[MDB_MAX_IDX_COLS];
unsigned char flags;
MdbTableDef *table;
} MdbIndex;
typedef struct {
guint32 pg;
int mask_pos;
unsigned char mask_byte;
int mask_bit;
int offset;
int len;
} MdbIndexPage;
#define MDB_MAX_INDEX_DEPTH 10
typedef struct {
int cur_depth;
MdbIndexPage pages[MDB_MAX_INDEX_DEPTH];
} MdbIndexChain;
typedef struct {
char name[MDB_MAX_OBJ_NAME+1];
} MdbColumnProp;
typedef union {
int i;
double d;
char s[256];
} MdbAny;
typedef struct {
char name[MDB_MAX_OBJ_NAME+1];
@ -261,6 +234,81 @@ typedef struct {
int col_scale;
} MdbColumn;
typedef struct _mdbsargtree {
int op;
MdbColumn *col;
MdbAny value;
void *parent;
struct _mdbsargtree *left;
struct _mdbsargtree *right;
} MdbSargNode;
typedef struct {
guint32 pg;
int mask_pos;
unsigned char mask_byte;
int mask_bit;
int offset;
int len;
} MdbIndexPage;
typedef int MdbSargTreeFunc(MdbSargNode *, gpointer);
#define MDB_MAX_INDEX_DEPTH 10
typedef struct {
int cur_depth;
MdbIndexPage pages[MDB_MAX_INDEX_DEPTH];
} MdbIndexChain;
typedef struct {
MdbCatalogEntry *entry;
char name[MDB_MAX_OBJ_NAME+1];
int num_cols;
GPtrArray *columns;
int num_rows;
int index_start;
int num_real_idxs;
int num_idxs;
GPtrArray *indices;
guint32 first_data_pg;
guint32 cur_pg_num;
guint32 cur_phys_pg;
int cur_row;
int noskip_del; /* don't skip deleted rows */
/* object allocation map */
guint32 map_base_pg;
int map_sz;
unsigned char *usage_map;
/* pages with free space left */
guint32 freemap_base_pg;
int freemap_sz;
unsigned char *free_usage_map;
/* query planner */
MdbSargNode *sarg_tree;
MdbStrategy strategy;
MdbIndex *scan_idx;
MdbHandle *mdbidx;
MdbIndexChain *chain;
} MdbTableDef;
struct mdbindex {
int index_num;
char name[MDB_MAX_OBJ_NAME+1];
unsigned char index_type;
guint32 first_pg;
int num_rows; /* number rows in index */
int num_keys;
short key_col_num[MDB_MAX_IDX_COLS];
unsigned char key_col_order[MDB_MAX_IDX_COLS];
unsigned char flags;
MdbTableDef *table;
};
typedef struct {
char name[MDB_MAX_OBJ_NAME+1];
} MdbColumnProp;
typedef struct {
void *value;
int siz;
@ -271,18 +319,11 @@ typedef struct {
int offset;
} MdbField;
typedef union {
int i;
double d;
char s[256];
} MdbAny;
typedef struct {
int op;
MdbAny value;
} MdbSarg;
/* mem.c */
extern void mdb_init();
extern void mdb_exit();
@ -293,6 +334,8 @@ extern MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry);
extern void mdb_alloc_catalog(MdbHandle *mdb);
extern MdbFile *mdb_alloc_file();
extern void mdb_free_file(MdbFile *f);
extern void mdb_append_index(GPtrArray *indices, MdbIndex *in_idx);
extern MdbStatistics *mdb_alloc_stats(MdbHandle *mdb);
/* file.c */
extern size_t mdb_read_pg(MdbHandle *mdb, unsigned long pg);
@ -304,8 +347,11 @@ extern long mdb_get_int32(MdbHandle *mdb, int offset);
extern float mdb_get_single(MdbHandle *mdb, int offset);
extern double mdb_get_double(MdbHandle *mdb, int offset);
extern MdbHandle *mdb_open(char *filename);
extern void mdb_close(MdbHandle *mdb);
extern MdbHandle *mdb_clone_handle(MdbHandle *mdb);
extern void mdb_swap_pgbuf(MdbHandle *mdb);
extern long _mdb_get_int32(unsigned char *buf, int offset);
extern gint32 mdb_get_int24_msb(MdbHandle *mdb, int offset);
/* catalog.c */
GPtrArray *mdb_read_catalog(MdbHandle *mdb, int obj_type);
@ -313,11 +359,12 @@ extern void mdb_catalog_dump(MdbHandle *mdb, int obj_type);
extern int mdb_catalog_rows(MdbHandle *mdb);
extern MdbCatalogEntry *mdb_get_catalog_entry(MdbHandle *mdb, int rowid, MdbCatalogEntry *entry);
extern char *mdb_get_objtype_string(int obj_type);
extern void mdb_dump_catalog(MdbHandle *mdb, int obj_type);
/* table.c */
extern MdbTableDef *mdb_read_table(MdbCatalogEntry *entry);
extern GPtrArray *mdb_read_columns(MdbTableDef *table);
extern void mdb_table_dump(MdbCatalogEntry *entry);
/* data.c */
extern void mdb_data_dump(MdbTableDef *table);
@ -327,7 +374,9 @@ extern int mdb_fetch_row(MdbTableDef *table);
extern int mdb_is_fixed_col(MdbColumn *col);
extern char *mdb_col_to_string(MdbHandle *mdb, int start, int datatype, int size);
extern int mdb_find_end_of_row(MdbHandle *mdb, int row);
extern int mdb_col_fixed_size(MdbColumn *col);
extern int mdb_col_disp_size(MdbColumn *col);
extern void mdb_bind_len(MdbTableDef *table, int col_num, int *len_ptr);
/* dump.c */
extern void buffer_dump(const unsigned char* buf, int start, int end);
@ -340,9 +389,21 @@ extern int mdb_set_default_backend(MdbHandle *mdb, char *backend_name);
extern char *mdb_get_relationships(MdbHandle *mdb);
/* sargs.c */
extern int mdb_test_sargs(MdbHandle *mdb, MdbColumn *col, int offset, int len);
extern int mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields);
extern int mdb_test_sarg(MdbColumn *col, MdbSargNode *node, void *buf, int len);
extern void mdb_sql_walk_tree(MdbSargNode *node, MdbSargTreeFunc func, gpointer data);
extern int mdb_find_indexable_sargs(MdbSargNode *node, gpointer data);
/* index.c */
extern GPtrArray *mdb_read_indices(MdbTableDef *table);
extern void mdb_index_dump(MdbTableDef *table, MdbIndex *idx);
/* stats.c */
extern void mdb_stats_on(MdbHandle *mdb);
extern void mdb_stats_off(MdbHandle *mdb);
extern void mdb_dump_stats(MdbHandle *mdb);
/* like.c */
extern int mdb_like_cmp(char *s, char *r);
#endif /* _mdbtools_h_ */

View File

@ -1,5 +1,6 @@
figs = \
figures/gmdb2_window.png
figures/gmdb2_sql_window.png
docname = gmdb
lang = C
omffile = gmdb-C.omf

View File

@ -240,6 +240,26 @@ Choose <menuchoice> <guimenu>Tools</guimenu> <guimenuitem>Debug Window </guimenu
</orderedlist>
</sect2>
</sect1>
<!-- ============= Preferences Window ============================= -->
<sect1 id="gmdb-prefs">
<title>Preferences</title>
<para>To view or set Preferences choose
<menuchoice> <guimenu>Edit</guimenu> <guimenuitem>Preferences</guimenuitem> </menuchoice> from the menu.</para>
<sect2 id="gmdb-prefs-maxrows">
<title>Maximum Rows to Display</title>
<para>This option limits the number of rows that will be returned when
<orderedlist>
<listitem>Clicking the <guilabel>Data</guilabel> button on the <guilabel>Tables</guilabel> tab window, or</listitem>
<listitem>Running a SQL select in the <guilabel>Query Window</guilabel></listitem>
</orderedlist>
</para>
<para>
By extension, this also affects the number of rows saved when saving the results of a SQL query.</para>
<para>
If no value is set, the default number of rows displayed is 1,000. This option may be disabled by setting the value to 0, but be warned that attempting to display a large number of rows will result in an increased delay proportional to the number of rows.
</para>
</sect2>
</sect1>
<!-- ============= Tables Window ============================= -->
<sect1 id="gmdb-tables">
<title>Table Actions</title>
@ -307,4 +327,92 @@ Click on the <guibutton>Export</guibutton> button from the right hand side of th
<para>Checking the <guilabel>Include Headers</guilabel> box will write a single row at the top of the file with the names of the columns.</para>
</sect2>
</sect1>
<sect1 id="gmdb-sql-main">
<title>Query Window</title>
<para>To open the SQL query window choose <menuchoice> <guimenu>Tools</guimenu> <guimenuitem>SQL Window </guimenuitem> </menuchoice></para>
<!-- ==== Figure ==== -->
<figure id="gmdb-sql-window">
<title>&app; Query Window</title>
<screenshot>
<mediaobject>
<imageobject>
<imagedata fileref="figures/gmdb2_sql_window.png" format="PNG"/>
</imageobject>
<textobject> <phrase>Screenshot of the gmdb2 query window.</phrase>
</textobject> </mediaobject>
</screenshot>
</figure>
<!-- ==== End of Figure ==== -->
<para>The <application>&app;</application> Query window contains the following
elements: </para>
<variablelist>
<varlistentry> <term>Menubar. </term>
<listitem>
<para>The menus on the menubar contain all of the commands you need
to work with SQL queries and their results in <application>&app;</application>.</para>
</listitem>
</varlistentry>
<varlistentry> <term>Toolbar. </term>
<listitem>
<para> The toolbar contains a subset of the commands that you can
access from the menubar.</para>
</listitem>
</varlistentry>
<varlistentry> <term>Table List. </term>
<listitem>
<para> The table list contains a list of tables for the current database that can be dragged into the query editor.</para>
</listitem>
</varlistentry>
<varlistentry> <term>Query Editor. </term>
<listitem>
<para> The query editor is a text editing window where you can write your SQL select.</para>
</listitem>
</varlistentry>
<varlistentry> <term>Recent Queries List. </term>
<listitem>
<para> The recent queries list can be used to bring a previously run query back into the query editor.</para>
</listitem>
</varlistentry>
<varlistentry> <term>Results Window. </term>
<listitem>
<para> The results window shows the results of the last SQL query executed.</para>
</listitem>
</varlistentry>
</variablelist>
<!-- ============= To Open a New Query Window ============================= -->
<sect2 id="gmdb-sql-new">
<title>To Open a New Query Window</title>
<para>To open a new query window, choose
<menuchoice> <guimenu>Query</guimenu> <guimenuitem>New</guimenuitem>
</menuchoice>
</para>
</sect2>
<!-- ============= To Load a Query from File ============================= -->
<sect2 id="gmdb-sql-open">
<title>To Load a Query from a File</title>
<para>To load a query from a text file, choose
<menuchoice> <guimenu>Query</guimenu> <guimenuitem>Open</guimenuitem>
</menuchoice>
</para>
</sect2>
<!-- ============= To Save a Query to File ============================= -->
<sect2 id="gmdb-sql-save">
<title>To Save a Query to a File</title>
<para>To save the current query to a text file, choose
<menuchoice> <guimenu>Query</guimenu> <guimenuitem>Save</guimenuitem>
</menuchoice>
</para>
<para>
The active file can be found in the title bar of the window. If this is not the desired file, choose the <guilabel>Save As</guilabel> menu item.
</para>
</sect2>
<!-- ============= To Save a Query from File As ============================= -->
<sect2 id="gmdb-sql-saveas">
<title>To Load a Query from a File</title>
<para>To load a query from a text file, choose
<menuchoice> <guimenu>Query</guimenu> <guimenuitem>Open</guimenuitem>
</menuchoice>
</para>
</sect2>
</sect1>
</article>

View File

@ -35,6 +35,18 @@ gmdb_prefs_get_maxrows()
}
/* callbacks */
void
gmdb_prefs_help_cb(GtkWidget *w, gpointer data)
{
GError *error = NULL;
gnome_help_display("gmdb.xml", "gmdb-prefs", &error);
if (error != NULL) {
g_warning (error->message);
g_error_free (error);
}
}
void
gmdb_prefs_save_cb(GtkWidget *w, GladeXML *xml)
{
@ -82,6 +94,10 @@ gmdb_prefs_new()
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (gmdb_prefs_save_cb), prefswin_xml);
button = glade_xml_get_widget (prefswin_xml, "help_button");
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (gmdb_prefs_help_cb), prefswin_xml);
str = gnome_config_get_string("/gmdb/prefs/maxrows");
if (!str || !strlen(str)) {
str = "1000";
@ -89,4 +105,7 @@ gmdb_prefs_new()
gnome_config_sync();
}
gtk_entry_set_text(GTK_ENTRY(entry), str);
prefswin = glade_xml_get_widget (prefswin_xml, "prefs_dialog");
return prefswin;
}

View File

@ -112,7 +112,8 @@ int did_first;
char *mdb_get_coltype_string(MdbBackend *backend, int col_type)
{
char buf[100];
static char buf[100];
if (col_type > 0x10) {
// return NULL;
sprintf(buf,"type %04x", col_type);
@ -167,10 +168,11 @@ MdbBackend *backend;
}
}
static void do_first (MdbHandle *mdb)
static void
do_first (MdbHandle *mdb)
{
int i, j, k;
static char text[255];
int i, k;
mdb_read_catalog (mdb, MDB_TABLE);
/* loop over each entry in the catalog */

View File

@ -27,6 +27,7 @@ char *mdb_money_to_string(MdbHandle *mdb, int start, char *s);
static int _mdb_attempt_bind(MdbHandle *mdb,
MdbColumn *col, unsigned char isnull, int offset, int len);
char *mdb_num_to_string(MdbHandle *mdb, int start, int datatype, int prec, int scale);
int mdb_copy_ole(MdbHandle *mdb, char *dest, int start, int size);
void mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr)
@ -170,6 +171,8 @@ int bitmask_sz;
int col_ptr, deleted_columns=0;
unsigned char null_mask[33]; /* 256 columns max / 8 bits per byte */
unsigned char isnull;
MdbField fields[256];
int num_fields;
row_start = mdb_get_int16(mdb, (fmt->row_count_offset + 2) + (row*2));
row_end = mdb_find_end_of_row(mdb, row);
@ -184,6 +187,13 @@ unsigned char isnull;
lookupflag ? "[lookup]" : "",
delflag ? "[delflag]" : "");
#endif
num_fields = mdb_crack_row(table, row_start, row_end, &fields);
if (!mdb_test_sargs(table, &fields, num_fields)) return 0;
for (i=0; i < num_fields; i++) {
//col = g_ptr_array_index (table->columns, fields[i].colnum - 1);
//rc = _mdb_attempt_bind(mdb, col, fields[i].is_null,
//row_start + col_start, col->col_size);
}
//if (!table->noskip_del && (delflag || lookupflag)) {
if (!table->noskip_del && delflag) {
row_end = row_start-1;
@ -357,9 +367,9 @@ static int _mdb_attempt_bind(MdbHandle *mdb,
} else if (isnull) {
mdb_xfer_bound_data(mdb, 0, col, 0);
} else {
if (!mdb_test_sargs(mdb, col, offset, len)) {
return 0;
}
//if (!mdb_test_sargs(mdb, col, offset, len)) {
//return 0;
//}
mdb_xfer_bound_data(mdb, offset, col, len);
}
return 1;
@ -395,7 +405,6 @@ mdb_read_next_dpg_by_map1(MdbTableDef *table)
MdbCatalogEntry *entry = table->entry;
MdbHandle *mdb = entry->mdb;
guint32 pgnum, i, j, bitn, map_pg;
unsigned char map_byte;
pgnum = 0;
//printf("map size %ld\n", table->map_sz);
@ -468,6 +477,7 @@ MdbHandle *mdb = table->entry->mdb;
MdbFormatConstants *fmt = mdb->fmt;
int rows;
int rc;
guint32 pg;
if (table->num_rows==0)
return 0;
@ -476,10 +486,19 @@ int rc;
if (!table->cur_pg_num) {
table->cur_pg_num=1;
table->cur_row=0;
mdb_read_next_dpg(table);
if (table->strategy!=MDB_INDEX_SCAN)
if (!mdb_read_next_dpg(table)) return 0;
}
do {
if (table->strategy==MDB_INDEX_SCAN) {
if (!mdb_index_find_next(table->mdbidx, table->scan_idx, table->chain, &pg, &(table->cur_row))) {
mdb_index_scan_free(table);
return 0;
}
mdb_read_pg(mdb, pg);
} else {
rows = mdb_get_int16(mdb,fmt->row_count_offset);
/* if at end of page, find a new page */
@ -490,6 +509,7 @@ int rc;
return 0;
}
}
}
/* printf("page %d row %d\n",table->cur_phys_pg, table->cur_row); */
rc = mdb_read_row(table, table->cur_row);
@ -500,9 +520,7 @@ int rc;
}
void mdb_data_dump(MdbTableDef *table)
{
MdbHandle *mdb = table->entry->mdb;
int i, j, pg_num;
int rows;
int i, j;
char *bound_values[MDB_MAX_COLS];
for (i=0;i<table->num_cols;i++) {
@ -524,6 +542,7 @@ int mdb_is_fixed_col(MdbColumn *col)
{
return col->is_fixed;
}
#if 0
static char *mdb_data_to_hex(MdbHandle *mdb, char *text, int start, int size)
{
int i;
@ -535,6 +554,7 @@ int i;
return text;
}
#endif
int mdb_copy_ole(MdbHandle *mdb, char *dest, int start, int size)
{
guint16 ole_len;
@ -751,20 +771,21 @@ int i;
return text;
#endif
}
char *mdb_num_to_string(MdbHandle *mdb, int start, int datatype, int prec, int scale)
char *
mdb_num_to_string(MdbHandle *mdb, int start, int datatype, int prec, int scale)
{
/* FIX ME -- not thread safe */
static char text[MDB_BIND_SIZE];
char tmpbuf[MDB_BIND_SIZE];
char mask[20];
gint32 l, whole, fraction;
gint32 l;
l = mdb->pg_buf[start+16] * 256 * 256 * 256 +
mdb->pg_buf[start+15] * 256 * 256 +
mdb->pg_buf[start+14] * 256 +
mdb->pg_buf[start+13];
sprintf(mask,"%%0%ldld",prec);
sprintf(mask,"%%0%dld",prec);
sprintf(tmpbuf,mask,l);
//strcpy(text, tmpbuf);
//return text;
@ -776,21 +797,14 @@ gint32 l, whole, fraction;
strcat(text,".");
strcat(text,&tmpbuf[strlen(tmpbuf)-scale]);
}
/*
for (i=0;i<size;i++) {
fprintf(stdout, "%c %02x ", isprint(mdb->pg_buf[start+i]) ? mdb->pg_buf[start+i] : '.', mdb->pg_buf[start+i]);
}
fprintf(stdout, "\n");
*/
return text;
}
char *mdb_col_to_string(MdbHandle *mdb, int start, int datatype, int size)
{
/* FIX ME -- not thread safe */
static char text[MDB_BIND_SIZE];
char tmpbuf[10];
time_t t;
int i,j;
int i;
switch (datatype) {
case MDB_BOOL:

View File

@ -138,7 +138,8 @@ MdbHandle *mdb_open(char *filename)
return _mdb_open(filename, FALSE);
}
void mdb_close(MdbHandle *mdb)
void
mdb_close(MdbHandle *mdb)
{
if (mdb->f) {
mdb->f->refs--;
@ -173,7 +174,11 @@ size_t mdb_read_pg(MdbHandle *mdb, unsigned long pg)
{
size_t len;
if (pg && mdb->cur_pg == pg) return mdb->fmt->pg_size;
len = _mdb_read_pg(mdb, mdb->pg_buf, pg);
//fprintf(stderr, "read page %d type %02x\n", pg, mdb->pg_buf[0]);
mdb->cur_pg = pg;
/* kan - reset the cur_pos on a new page read */
mdb->cur_pos = 0; /* kan */
return len;

View File

@ -58,7 +58,7 @@ mdb_read_indices(MdbTableDef *table)
{
MdbHandle *mdb = table->entry->mdb;
MdbIndex idx, *pidx;
int len, i, j;
int i, j;
int idx_num, key_num, col_num;
int cur_pos;
int name_sz;
@ -127,6 +127,7 @@ int name_sz;
cur_pos += 4;
pidx->flags = mdb->pg_buf[cur_pos++];
}
return NULL;
}
void
mdb_index_hash_text(guchar *text, guchar *hash)
@ -147,8 +148,8 @@ mdb_index_swap_int32(guint32 l)
unsigned char *c, *c2;
guint32 l2;
c = &l;
c2 = &l2;
c = (unsigned char *) &l;
c2 = (unsigned char *) &l2;
c2[0]=c[3];
c2[1]=c[2];
c2[2]=c[1];
@ -156,9 +157,10 @@ mdb_index_swap_int32(guint32 l)
return l2;
}
void mdb_index_cache_sarg(MdbColumn *col, MdbSarg *sarg, MdbSarg *idx_sarg)
void
mdb_index_cache_sarg(MdbColumn *col, MdbSarg *sarg, MdbSarg *idx_sarg)
{
guint32 cache_int;
//guint32 cache_int;
unsigned char *c;
switch (col->col_type) {
@ -169,7 +171,7 @@ void mdb_index_cache_sarg(MdbColumn *col, MdbSarg *sarg, MdbSarg *idx_sarg)
case MDB_LONGINT:
idx_sarg->value.i = mdb_index_swap_int32(sarg->value.i);
//cache_int = sarg->value.i * -1;
c = &(idx_sarg->value.i);
c = (unsigned char *) &(idx_sarg->value.i);
c[0] |= 0x80;
//printf("int %08x %02x %02x %02x %02x\n", sarg->value.i, c[0], c[1], c[2], c[3]);
break;
@ -182,6 +184,33 @@ void mdb_index_cache_sarg(MdbColumn *col, MdbSarg *sarg, MdbSarg *idx_sarg)
}
}
int
mdb_index_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSarg *sarg, int offset, int len)
{
char tmpbuf[256];
int lastchar;
switch (col->col_type) {
case MDB_BYTE:
return mdb_test_int(sarg, mdb_get_byte(mdb, offset));
break;
case MDB_INT:
return mdb_test_int(sarg, mdb_get_int16(mdb, offset));
break;
case MDB_LONGINT:
return mdb_test_int(sarg, mdb_get_int32(mdb, offset));
break;
case MDB_TEXT:
strncpy(tmpbuf, &mdb->pg_buf[offset],255);
lastchar = len > 255 ? 255 : len;
tmpbuf[lastchar]='\0';
return mdb_test_string(sarg, tmpbuf);
default:
fprintf(stderr, "Calling mdb_test_sarg on unknown type. Add code to mdb_test_sarg() for type %d\n",col->col_type);
break;
}
return 1;
}
int
mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, int offset, int len)
{
int i, j;
@ -189,6 +218,7 @@ mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, int offset, int len)
MdbTableDef *table = idx->table;
MdbSarg *idx_sarg;
MdbSarg *sarg;
MdbSargNode node;
int c_offset = 0, c_len;
for (i=0;i<idx->num_keys;i++) {
@ -220,7 +250,10 @@ mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, int offset, int len)
for (j=0;j<col->num_sargs;j++) {
sarg = g_ptr_array_index (col->idx_sarg_cache, j);
if (!mdb_test_sarg(mdb, col, sarg, offset + c_offset, c_len)) {
/* XXX - kludge */
node.op = sarg->op;
node.value = sarg->value;
if (!mdb_test_sarg(col, &node, &mdb->pg_buf[offset + c_offset], c_len)) {
/* sarg didn't match, no sense going on */
return 0;
}
@ -300,7 +333,7 @@ mdb_find_next_leaf(MdbHandle *mdb, MdbIndexChain *chain)
*/
chain->cur_depth++;
if (chain->cur_depth > MDB_MAX_INDEX_DEPTH) {
fprintf(stderr,"Error! maximum index depth of %d exceeded. This is probably due to a programming bug, If you are confident that your indexes really are this deep, adjust MDB_MAX_INDEX_DEPTH in mdbtools.h and recompile.\n");
fprintf(stderr,"Error! maximum index depth of %d exceeded. This is probably due to a programming bug, If you are confident that your indexes really are this deep, adjust MDB_MAX_INDEX_DEPTH in mdbtools.h and recompile.\n", MDB_MAX_INDEX_DEPTH);
exit(1);
}
newipg = &(chain->pages[chain->cur_depth - 1]);
@ -403,7 +436,7 @@ int i;
for (i=0;i<idx->num_keys;i++) {
marker = mdb->pg_buf[cur_pos++];
col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
printf("column %d coltype %d col_size %d (%d)\n",i,col->col_type, mdb_col_fixed_size(col), col->col_size);
//printf("column %d coltype %d col_size %d (%d)\n",i,col->col_type, mdb_col_fixed_size(col), col->col_size);
}
}
void
@ -428,3 +461,145 @@ mdb_index_dump(MdbTableDef *table, MdbIndex *idx)
}
mdb_index_walk(table, idx);
}
int mdb_index_compute_cost(MdbTableDef *table, MdbIndex *idx)
{
int i;
MdbColumn *col;
MdbSarg *sarg;
int not_all_equal = 0;
if (!idx->num_keys) return 0;
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 (!sarg || sarg->op != MDB_EQUAL) not_all_equal++;
}
}
col=g_ptr_array_index(table->columns,idx->key_col_num[0]-1);
/*
* if this is the first key column and there are no sargs,
* then this index is useless.
*/
if (!col->num_sargs) return 0;
sarg = g_ptr_array_index (col->sargs, 0);
/*
* a like with a wild card first is useless as a sarg */
if (sarg->op == MDB_LIKE && sarg->value.s[0]=='%')
return 0;
/*
* this needs a lot of tweaking.
*/
if (idx->flags & MDB_IDX_UNIQUE) {
if (idx->num_keys == 1) {
//printf("op is %d\n", sarg->op);
switch (sarg->op) {
case MDB_EQUAL:
return 1; break;
case MDB_LIKE:
return 4; break;
case MDB_ISNULL:
return 12; break;
default:
return 8; break;
}
} else {
switch (sarg->op) {
case MDB_EQUAL:
if (not_all_equal) return 2;
else return 1;
break;
case MDB_LIKE:
return 6; break;
case MDB_ISNULL:
return 12; break;
default:
return 9; break;
}
}
} else {
if (idx->num_keys == 1) {
switch (sarg->op) {
case MDB_EQUAL:
return 2; break;
case MDB_LIKE:
return 5; break;
case MDB_ISNULL:
return 12; break;
default:
return 10; break;
}
} else {
switch (sarg->op) {
case MDB_EQUAL:
if (not_all_equal) return 3;
else return 2;
break;
case MDB_LIKE:
return 7; break;
case MDB_ISNULL:
return 12; break;
default:
return 11; break;
}
}
}
return 0;
}
MdbStrategy
mdb_choose_index(MdbTableDef *table, int *choice)
{
int i;
MdbIndex *idx;
int cost = 0;
int least = 99;
*choice = -1;
for (i=0;i<table->num_idxs;i++) {
idx = g_ptr_array_index (table->indices, i);
cost = mdb_index_compute_cost(table, idx);
//printf("cost for %s is %d\n", idx->name, cost);
if (cost && cost < least) {
least = cost;
*choice = i;
}
}
/* and the winner is: *choice */
if (!least) return MDB_TABLE_SCAN;
return MDB_INDEX_SCAN;
}
void
mdb_index_scan_init(MdbHandle *mdb, MdbTableDef *table)
{
int i;
int use_index=0;
char *s;
if (s=getenv("MDBOPTS")) {
if (!strcmp(s, "use_index")) use_index++;
}
if (use_index && mdb_choose_index(table, &i) == MDB_INDEX_SCAN) {
table->strategy = MDB_INDEX_SCAN;
table->scan_idx = g_ptr_array_index (table->indices, i);
table->chain = g_malloc0(sizeof(MdbIndexChain));
table->mdbidx = mdb_clone_handle(mdb);
mdb_read_pg(table->mdbidx, table->scan_idx->first_pg);
//printf("best index is %s\n",table->scan_idx->name);
}
}
void
mdb_index_scan_free(MdbTableDef *table)
{
if (table->chain) {
g_free(table->chain);
table->chain = NULL;
}
if (table->mdbidx) {
mdb_close(table->mdbidx);
table->mdbidx = NULL;
}
}

View File

@ -18,8 +18,9 @@
*/
#include <stdio.h>
#include <string.h>
int likecmp(char *s, char *r)
int mdb_like_cmp(char *s, char *r)
{
int i, ret;
@ -32,13 +33,13 @@ int i, ret;
}
case '_':
/* skip one character */
return likecmp(&s[1],&r[1]);
return mdb_like_cmp(&s[1],&r[1]);
case '%':
/* skip any number of characters */
/* the strlen(s)+1 is important so the next call can */
/* if there are trailing characters */
for(i=0;i<strlen(s)+1;i++) {
if (likecmp(&s[i],&r[1])) {
if (mdb_like_cmp(&s[i],&r[1])) {
return 1;
}
}
@ -50,7 +51,7 @@ int i, ret;
if (strncmp(s,r,i)) {
return 0;
} else {
ret = likecmp(&s[i],&r[i]);
ret = mdb_like_cmp(&s[i],&r[i]);
return ret;
}
}

View File

@ -125,4 +125,6 @@ int top, i, j;
s[j++]=array[i]+'0';
}
s[j]='\0';
return s;
}

View File

@ -19,15 +19,24 @@
#include "mdbtools.h"
int mdb_test_string(MdbSarg *sarg, char *s)
void
mdb_sql_walk_tree(MdbSargNode *node, MdbSargTreeFunc func, gpointer data)
{
if (func(node, data))
return;
if (node->left) mdb_sql_walk_tree(node->left, func, data);
if (node->right) mdb_sql_walk_tree(node->right, func, data);
}
int
mdb_test_string(MdbSargNode *node, char *s)
{
int rc;
if (sarg->op == MDB_LIKE) {
return likecmp(s,sarg->value.s);
if (node->op == MDB_LIKE) {
return mdb_like_cmp(s,node->value.s);
}
rc = strncmp(sarg->value.s, s, 255);
switch (sarg->op) {
rc = strncmp(node->value.s, s, 255);
switch (node->op) {
case MDB_EQUAL:
if (rc==0) return 1;
break;
@ -44,61 +53,149 @@ int rc;
if (rc>=0) return 1;
break;
default:
fprintf(stderr, "Calling mdb_test_sarg on unknown operator. Add code to mdb_test_string() for operator %d\n",sarg->op);
fprintf(stderr, "Calling mdb_test_sarg on unknown operator. Add code to mdb_test_string() for operator %d\n",node->op);
break;
}
return 0;
}
int mdb_test_int(MdbSarg *sarg, gint32 i)
int mdb_test_int(MdbSargNode *node, gint32 i)
{
switch (sarg->op) {
switch (node->op) {
case MDB_EQUAL:
if (sarg->value.i == i) return 1;
if (node->value.i == i) return 1;
break;
case MDB_GT:
if (sarg->value.i < i) return 1;
if (node->value.i < i) return 1;
break;
case MDB_LT:
if (sarg->value.i > i) return 1;
if (node->value.i > i) return 1;
break;
case MDB_GTEQ:
if (sarg->value.i <= i) return 1;
if (node->value.i <= i) return 1;
break;
case MDB_LTEQ:
if (sarg->value.i >= i) return 1;
if (node->value.i >= i) return 1;
break;
default:
fprintf(stderr, "Calling mdb_test_sarg on unknown operator. Add code to mdb_test_int() for operator %d\n",sarg->op);
fprintf(stderr, "Calling mdb_test_sarg on unknown operator. Add code to mdb_test_int() for operator %d\n",node->op);
break;
}
return 0;
}
int mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSarg *sarg, int offset, int len)
#if 0
#endif
int
mdb_find_indexable_sargs(MdbSargNode *node, gpointer data)
{
MdbSarg sarg;
if (node->op == MDB_OR || node->op == MDB_NOT) return 1;
/*
* right now all we do is look for sargs that are anded together from
* the root. Later we may put together OR ops into a range, and then
* range scan the leaf pages. That is col1 = 2 or col1 = 4 becomes
* col1 >= 2 and col1 <= 4 for the purpose of index scans, and then
* extra rows are thrown out when the row is tested against the main
* sarg tree. range scans are generally only a bit better than table
* scanning anyway.
*
* also, later we should support the NOT operator, but it's generally
* a pretty worthless test for indexes, ie NOT col1 = 3, we are
* probably better off table scanning.
*/
if (mdb_is_relational_op(node->op)) {
//printf("op = %d value = %s\n", node->op, node->value.s);
sarg.op = node->op;
sarg.value = node->value;
mdb_add_sarg(node->col, &sarg);
}
return 0;
}
int
mdb_test_sarg(MdbColumn *col, MdbSargNode *node, void *buf, int len)
{
char tmpbuf[256];
int lastchar;
switch (col->col_type) {
case MDB_BYTE:
return mdb_test_int(sarg, mdb_get_byte(mdb, offset));
return mdb_test_int(node, (int)((char *)buf)[0]);
break;
case MDB_INT:
return mdb_test_int(sarg, mdb_get_int16(mdb, offset));
return mdb_test_int(node, _mdb_get_int16(buf, 0));
break;
case MDB_LONGINT:
return mdb_test_int(sarg, mdb_get_int32(mdb, offset));
return mdb_test_int(node, _mdb_get_int32(buf, 0));
break;
case MDB_TEXT:
strncpy(tmpbuf, &mdb->pg_buf[offset],255);
strncpy(tmpbuf, buf,255);
lastchar = len > 255 ? 255 : len;
tmpbuf[lastchar]='\0';
return mdb_test_string(sarg, tmpbuf);
return mdb_test_string(node, tmpbuf);
default:
fprintf(stderr, "Calling mdb_test_sarg on unknown type. Add code to mdb_test_sarg() for type %d\n",col->col_type);
break;
}
return 1;
}
int
mdb_find_field(int col_num, MdbField *fields, int num_fields)
{
int i;
for (i=0;i<num_fields;i++) {
if (fields[i].colnum == col_num) return i;
}
return -1;
}
mdb_test_sarg_node(MdbSargNode *node, MdbField *fields, int num_fields)
{
int elem;
MdbColumn *col;
int rc;
if (mdb_is_relational_op(node->op)) {
col = node->col;
elem = mdb_find_field(col->col_num, fields, num_fields);
if (!mdb_test_sarg(col,
node,
fields[elem].value,
fields[elem].siz))
return 0;
} else { /* logical op */
switch (node->op) {
case MDB_NOT:
rc = mdb_test_sarg_node(node->left, fields, num_fields);
return !rc;
break;
case MDB_AND:
if (!mdb_test_sarg_node(node->left, fields, num_fields))
return 0;
return mdb_test_sarg_node(node->right, fields, num_fields);
break;
case MDB_OR:
if (mdb_test_sarg_node(node->left, fields, num_fields))
return 1;
return mdb_test_sarg_node(node->right, fields, num_fields);
break;
}
}
return 1;
}
int
mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields)
{
MdbSargNode *node;
node = table->sarg_tree;
/* there may not be a sarg tree */
if (!node) return 1;
return mdb_test_sarg_node(node, fields, num_fields);
}
#if 0
int mdb_test_sargs(MdbHandle *mdb, MdbColumn *col, int offset, int len)
{
MdbSarg *sarg;
@ -114,6 +211,7 @@ int i;
return 1;
}
#endif
int mdb_add_sarg(MdbColumn *col, MdbSarg *in_sarg)
{
MdbSarg *sarg;

View File

@ -233,14 +233,13 @@ int coln;
MdbIndex *idx;
MdbHandle *mdb = entry->mdb;
int i,bitn;
int pgnum;
guint32 pgnum;
table = mdb_read_table(entry);
fprintf(stdout,"definition page = %lu\n",entry->table_pg);
fprintf(stdout,"number of datarows = %d\n",table->num_rows);
fprintf(stdout,"number of columns = %d\n",table->num_cols);
fprintf(stdout,"number of indices = %d\n",table->num_real_idxs);
fprintf(stdout,"first data page = %lu\n",table->first_data_pg);
mdb_read_columns(table);
mdb_read_indices(table);
@ -259,7 +258,7 @@ int pgnum;
mdb_index_dump(table, idx);
}
if (table->usage_map) {
printf("pages reserved by this object\n",pgnum);
printf("pages reserved by this object\n");
pgnum = _mdb_get_int32(table->usage_map,1);
/* the first 5 bytes of the usage map mean something */
coln = 0;
@ -267,7 +266,7 @@ int pgnum;
for (bitn=0;bitn<8;bitn++) {
if (table->usage_map[i] & 1 << bitn) {
coln++;
printf("%6ld ",pgnum);
printf("%6lu ",(long unsigned) pgnum);
if (coln==10) {
printf("\n");
coln = 0;

View File

@ -227,7 +227,8 @@ int i;
}
/* EOD */
row_buffer[pos++] = pos;
row_buffer[pos] = pos;
pos++;
for (i=num_fields-1;i>=num_fields - var_cols;i--) {
row_buffer[pos++] = fields[i].offset % 256;
@ -295,7 +296,7 @@ int old_row_size, new_row_size, delta, num_fields;
row_start &= 0x0FFF; /* remove flags */
#if MDB_DEBUG_WRITE
printf("page %lu row %d start %d end %d\n", table->cur_phys_pg, table->cur_row-1, row_start, row_end);
printf("page %lu row %d start %d end %d\n", (unsigned long) table->cur_phys_pg, table->cur_row-1, row_start, row_end);
buffer_dump(mdb->pg_buf, row_start, row_end);
#endif
@ -333,6 +334,7 @@ int old_row_size, new_row_size, delta, num_fields;
}
/* do it! */
mdb_replace_row(table, table->cur_row-1, row_buffer, new_row_size);
return 0;
}
int
mdb_replace_row(MdbTableDef *table, int row, unsigned char *new_row, int new_row_size)
@ -348,7 +350,7 @@ int i, pos;
#if MDB_DEBUG_WRITE
buffer_dump(mdb->pg_buf, 0, 39);
buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
printf("updating row %d on page %lu\n", row, table->cur_phys_pg);
printf("updating row %d on page %lu\n", row, (unsigned long) table->cur_phys_pg);
#endif
new_pg = (unsigned char *) g_malloc0(fmt->pg_size);
g_free(new_pg);
@ -400,5 +402,5 @@ int i, pos;
fprintf(stderr, "write failed! exiting...\n");
exit(1);
}
return 0;
}

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.5 2002/12/27 15:09:02 brianb Exp $
* $Header: /Users/brian/cvs/mdbtools/mdbtools/src/sql/Attic/lexer.c,v 1.6 2003/01/20 16:04:31 brianb Exp $
*/
#define FLEX_SCANNER
@ -282,19 +282,21 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
*yy_cp = '\0'; \
yy_c_buf_p = yy_cp;
#define YY_NUM_RULES 22
#define YY_END_OF_BUFFER 23
static yyconst short int yy_accept[89] =
#define YY_NUM_RULES 24
#define YY_END_OF_BUFFER 25
static yyconst short int yy_accept[95] =
{ 0,
19, 19, 23, 21, 15, 22, 21, 21, 20, 21,
19, 21, 21, 17, 17, 17, 17, 17, 17, 17,
17, 17, 21, 0, 0, 18, 0, 20, 0, 20,
20, 19, 12, 13, 17, 17, 17, 17, 17, 17,
17, 17, 17, 5, 17, 0, 16, 0, 19, 19,
8, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 2, 14, 6, 17, 17, 17, 17,
17, 17, 17, 10, 7, 17, 17, 17, 1, 9,
3, 17, 17, 11, 17, 17, 4, 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
} ;
static yyconst int yy_ec[256] =
@ -305,14 +307,14 @@ static yyconst int yy_ec[256] =
1, 4, 1, 5, 1, 1, 1, 1, 6, 7,
7, 1, 8, 1, 9, 10, 11, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 1, 1, 13,
14, 15, 1, 1, 16, 16, 16, 16, 17, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
17, 16, 16, 16, 16, 16, 18, 19, 20, 21,
14, 15, 1, 1, 17, 18, 19, 20, 21, 22,
23, 24, 25, 23, 26, 27, 28, 29, 30, 23,
23, 31, 32, 33, 23, 23, 34, 23, 23, 23,
7, 1, 1, 1, 16, 1, 17, 18, 19, 20,
22, 23, 16, 24, 25, 16, 26, 27, 28, 29,
30, 16, 16, 31, 32, 33, 16, 16, 34, 16,
16, 16, 1, 1, 1, 35, 1, 1, 1, 1,
21, 22, 23, 24, 25, 23, 26, 27, 28, 29,
30, 23, 23, 31, 32, 33, 23, 23, 34, 23,
23, 23, 1, 1, 1, 35, 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,
@ -332,119 +334,117 @@ static yyconst int yy_ec[256] =
static yyconst int yy_meta[36] =
{ 0,
1, 1, 2, 3, 3, 1, 4, 4, 1, 5,
5, 6, 1, 1, 1, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 1
5, 6, 1, 1, 1, 7, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 1
} ;
static yyconst short int yy_base[94] =
static yyconst short int yy_base[101] =
{ 0,
0, 0, 129, 295, 295, 295, 0, 116, 29, 31,
37, 104, 84, 42, 44, 46, 49, 51, 53, 55,
57, 59, 69, 85, 80, 74, 76, 79, 82, 87,
93, 0, 295, 295, 96, 98, 101, 103, 106, 110,
113, 115, 117, 121, 133, 67, 295, 46, 38, 92,
123, 136, 138, 140, 142, 146, 151, 153, 156, 161,
163, 166, 168, 170, 176, 178, 180, 183, 185, 191,
193, 198, 202, 204, 206, 209, 211, 214, 218, 221,
223, 227, 229, 234, 236, 242, 244, 295, 36, 275,
279, 282, 287
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
} ;
static yyconst short int yy_def[94] =
static yyconst short int yy_def[101] =
{ 0,
88, 1, 88, 88, 88, 88, 89, 90, 91, 91,
91, 88, 88, 92, 92, 92, 92, 92, 92, 92,
92, 92, 11, 93, 90, 90, 88, 11, 11, 11,
11, 11, 88, 88, 92, 92, 92, 92, 92, 92,
92, 92, 92, 92, 92, 93, 88, 88, 88, 11,
92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
92, 92, 92, 92, 92, 92, 92, 0, 88, 88,
88, 88, 88
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,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
99, 94, 94, 94, 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, 17, 17, 0, 94, 94, 94, 94, 94, 94
} ;
static yyconst short int yy_nxt[331] =
static yyconst short int yy_nxt[321] =
{ 0,
4, 5, 6, 5, 7, 8, 4, 4, 4, 9,
10, 11, 12, 4, 13, 14, 14, 15, 14, 16,
17, 14, 18, 14, 14, 14, 19, 14, 14, 14,
14, 20, 21, 22, 23, 27, 27, 88, 88, 29,
30, 88, 24, 88, 88, 30, 31, 29, 32, 49,
30, 28, 29, 28, 29, 28, 29, 49, 28, 29,
28, 29, 28, 29, 28, 29, 28, 29, 28, 29,
38, 47, 36, 39, 43, 37, 42, 41, 28, 26,
28, 40, 45, 48, 48, 26, 44, 49, 28, 47,
28, 28, 88, 28, 48, 48, 28, 34, 50, 27,
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,
27, 28, 28, 50, 30, 28, 29, 28, 29, 30,
28, 29, 28, 29, 30, 28, 29, 33, 51, 28,
29, 26, 28, 29, 28, 29, 28, 29, 88, 52,
28, 29, 28, 29, 53, 59, 88, 54, 56, 55,
88, 58, 28, 29, 57, 28, 29, 28, 29, 28,
29, 28, 29, 88, 60, 28, 29, 62, 88, 63,
28, 29, 28, 29, 61, 28, 29, 65, 88, 64,
28, 29, 28, 29, 67, 28, 29, 28, 29, 28,
29, 88, 68, 66, 70, 28, 29, 28, 29, 28,
29, 69, 28, 29, 28, 29, 71, 72, 88, 73,
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,
28, 29, 28, 29, 74, 88, 75, 28, 29, 88,
76, 28, 29, 28, 29, 28, 29, 77, 28, 29,
28, 29, 88, 28, 29, 88, 78, 28, 29, 82,
28, 29, 28, 29, 79, 80, 28, 29, 28, 29,
88, 81, 83, 28, 29, 28, 29, 88, 84, 88,
85, 28, 29, 28, 29, 86, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 87, 25, 88, 25, 25, 25,
25, 25, 28, 28, 28, 28, 35, 35, 35, 46,
88, 88, 46, 46, 3, 88, 88, 88, 88, 88,
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,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88
94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
94, 94, 94, 94, 94, 94, 94, 94, 94, 94
} ;
static yyconst short int yy_chk[331] =
static yyconst short int yy_chk[321] =
{ 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, 89, 11, 11, 9, 11, 11, 11, 49,
9, 14, 14, 15, 15, 16, 16, 48, 17, 17,
18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
17, 46, 15, 17, 21, 16, 20, 19, 23, 26,
23, 18, 22, 27, 27, 25, 21, 27, 28, 24,
28, 29, 29, 29, 30, 30, 30, 13, 30, 31,
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,
31, 50, 31, 50, 31, 35, 35, 36, 36, 31,
37, 37, 38, 38, 31, 39, 39, 12, 36, 40,
40, 8, 41, 41, 42, 42, 43, 43, 3, 37,
44, 44, 51, 51, 38, 43, 0, 39, 41, 40,
0, 42, 45, 45, 41, 52, 52, 53, 53, 54,
54, 55, 55, 0, 45, 56, 56, 53, 0, 54,
57, 57, 58, 58, 52, 59, 59, 56, 0, 55,
60, 60, 61, 61, 58, 62, 62, 63, 63, 64,
64, 0, 59, 57, 61, 65, 65, 66, 66, 67,
67, 60, 68, 68, 69, 69, 62, 63, 0, 67,
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,
70, 70, 71, 71, 68, 0, 69, 72, 72, 0,
70, 73, 73, 74, 74, 75, 75, 71, 76, 76,
77, 77, 0, 78, 78, 0, 72, 79, 79, 77,
80, 80, 81, 81, 73, 74, 82, 82, 83, 83,
0, 76, 78, 84, 84, 85, 85, 0, 82, 0,
83, 86, 86, 87, 87, 85, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 86, 90, 0, 90, 90, 90,
90, 90, 91, 91, 91, 91, 92, 92, 92, 93,
0, 0, 93, 93, 88, 88, 88, 88, 88, 88,
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,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88
94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
94, 94, 94, 94, 94, 94, 94, 94, 94, 94
} ;
static yy_state_type yy_last_accepting_state;
@ -687,13 +687,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 >= 89 )
if ( yy_current_state >= 95 )
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] != 295 );
while ( yy_base[yy_current_state] != 285 );
yy_find_action:
yy_act = yy_accept[yy_current_state];
@ -757,85 +757,95 @@ YY_RULE_SETUP
case 8:
YY_RULE_SETUP
#line 34 "lexer.l"
{ return AND; }
{ return TABLES; }
YY_BREAK
case 9:
YY_RULE_SETUP
#line 35 "lexer.l"
{ return TABLES; }
{ return TABLE; }
YY_BREAK
case 10:
YY_RULE_SETUP
#line 36 "lexer.l"
{ return TABLE; }
{ return DESCRIBE; }
YY_BREAK
case 11:
YY_RULE_SETUP
#line 37 "lexer.l"
{ return DESCRIBE; }
{ return AND; }
YY_BREAK
case 12:
YY_RULE_SETUP
#line 38 "lexer.l"
{ return LTEQ; }
{ return OR; }
YY_BREAK
case 13:
YY_RULE_SETUP
#line 39 "lexer.l"
{ return GTEQ; }
{ return NOT; }
YY_BREAK
case 14:
YY_RULE_SETUP
#line 40 "lexer.l"
{ return LIKE; }
{ return LTEQ; }
YY_BREAK
case 15:
YY_RULE_SETUP
#line 41 "lexer.l"
;
{ return GTEQ; }
YY_BREAK
case 16:
YY_RULE_SETUP
#line 42 "lexer.l"
{ return LIKE; }
YY_BREAK
case 17:
YY_RULE_SETUP
#line 43 "lexer.l"
;
YY_BREAK
case 18:
YY_RULE_SETUP
#line 44 "lexer.l"
{
yylval.name = strdup(&yytext[1]);
yylval.name[strlen(yylval.name)-1]='\0';
return IDENT;
}
YY_BREAK
case 17:
YY_RULE_SETUP
#line 47 "lexer.l"
{ yylval.name = strdup(yytext); return NAME; }
YY_BREAK
case 18:
YY_RULE_SETUP
#line 49 "lexer.l"
{ yylval.name = strdup(yytext); return STRING; }
YY_BREAK
case 19:
YY_RULE_SETUP
#line 50 "lexer.l"
#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; }
YY_BREAK
case 21:
YY_RULE_SETUP
#line 52 "lexer.l"
{
yylval.name = strdup(yytext); return NUMBER;
}
YY_BREAK
case 20:
YY_RULE_SETUP
#line 53 "lexer.l"
{ yylval.name = strdup(yytext); return PATH; }
YY_BREAK
case 21:
YY_RULE_SETUP
#line 54 "lexer.l"
{ return yytext[0]; }
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]; }
YY_BREAK
case 24:
YY_RULE_SETUP
#line 57 "lexer.l"
ECHO;
YY_BREAK
#line 839 "lexer.c"
#line 849 "lexer.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@ -1127,7 +1137,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 >= 89 )
if ( yy_current_state >= 95 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@ -1162,11 +1172,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 >= 89 )
if ( yy_current_state >= 95 )
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 == 88);
yy_is_jam = (yy_current_state == 94);
return yy_is_jam ? 0 : yy_current_state;
}
@ -1716,7 +1726,7 @@ int main()
return 0;
}
#endif
#line 55 "lexer.l"
#line 57 "lexer.l"
int yywrap()

View File

@ -31,20 +31,22 @@ disconnect { return DISCONNECT; }
to { return TO; }
list { return LIST; }
where { return WHERE; }
and { return AND; }
tables { return TABLES; }
table { return TABLE; }
describe { return DESCRIBE; }
and { return AND; }
or { return OR; }
not { return NOT; }
(<=) { return LTEQ; }
(>=) { return GTEQ; }
like { return LIKE; }
[ \t\r] ;
\"[A-z][A-z0-9 ]*\" {
\"[A-z][A-z0-9 _]*\" {
yylval.name = strdup(&yytext[1]);
yylval.name[strlen(yylval.name)-1]='\0';
return IDENT;
}
[A-z][A-z0-9]* { yylval.name = strdup(yytext); return NAME; }
[A-z][A-z0-9_]* { yylval.name = strdup(yytext); return NAME; }
'.*' { yylval.name = strdup(yytext); return STRING; }
([0-9]+|([0-9]*\.[0-9+)([eE][-+]?[0-9]+)?) {

View File

@ -27,6 +27,7 @@ void mdb_dump_results(MdbSQL *sql);
#include <wordexp.h>
#endif
void
mdb_sql_error(char *fmt, ...)
{
va_list ap;
@ -58,6 +59,8 @@ MdbSQL *sql;
sql->columns = g_ptr_array_new();
sql->tables = g_ptr_array_new();
sql->sargs = g_ptr_array_new();
sql->sarg_tree = NULL;
sql->sarg_stack = NULL;
return sql;
}
@ -88,7 +91,8 @@ MdbSQLTable *t;
return t;
}
MdbHandle *mdb_sql_close(MdbSQL *sql)
void
mdb_sql_close(MdbSQL *sql)
{
if (sql->mdb) {
mdb_close(sql->mdb);
@ -137,14 +141,162 @@ wordexp_t words;
return sql->mdb;
}
int mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant)
MdbSargNode *
mdb_sql_alloc_node()
{
MdbSargNode *node;
node = g_malloc0(sizeof(MdbSargNode));
return node;
}
void
mdb_sql_free_tree(MdbSargNode *tree)
{
if (tree->left) mdb_sql_free_tree(tree->left);
if (tree->right) mdb_sql_free_tree(tree->right);
g_free(tree);
}
void
mdb_sql_push_node(MdbSQL *sql, MdbSargNode *node)
{
sql->sarg_stack = g_list_append(sql->sarg_stack, node);
/*
* Tree builds from bottom to top, so we should be left with
* the correct tree root when done
*/
sql->sarg_tree = node;
}
MdbSargNode *
mdb_sql_pop_node(MdbSQL *sql)
{
GList *glist;
MdbSargNode *node;
glist = g_list_last(sql->sarg_stack);
if (!glist) return NULL;
node = glist->data;
#if 0
if (node->op==MDB_EQUAL)
printf("popping %d\n", node->value.i);
else
printf("popping %s\n", node->op == MDB_OR ? "OR" : "AND");
#endif
sql->sarg_stack = g_list_remove(sql->sarg_stack, node);
return node;
}
void
mdb_sql_add_not(MdbSQL *sql)
{
MdbSargNode *node, *left;
left = mdb_sql_pop_node(sql);
if (!left) {
mdb_sql_error("parse error near 'NOT'");
mdb_sql_reset(sql);
return;
}
node = mdb_sql_alloc_node();
node->op = MDB_NOT;
node->left = left;
mdb_sql_push_node(sql, node);
}
void
mdb_sql_add_or(MdbSQL *sql)
{
MdbSargNode *node, *left, *right;
left = mdb_sql_pop_node(sql);
right = mdb_sql_pop_node(sql);
if (!left || !right) {
mdb_sql_error("parse error near 'OR'");
mdb_sql_reset(sql);
return;
}
node = mdb_sql_alloc_node();
node->op = MDB_OR;
node->left = left;
node->right = right;
mdb_sql_push_node(sql, node);
}
void
mdb_sql_add_and(MdbSQL *sql)
{
MdbSargNode *node, *left, *right;
left = mdb_sql_pop_node(sql);
right = mdb_sql_pop_node(sql);
if (!left || !right) {
mdb_sql_error("parse error near 'AND'");
mdb_sql_reset(sql);
return;
}
node = mdb_sql_alloc_node();
node->op = MDB_AND;
node->left = left;
node->right = right;
mdb_sql_push_node(sql, node);
}
void
mdb_sql_dump_node(MdbSargNode *node, int level)
{
int i;
int mylevel = level+1;
if (!level)
printf("root ");
for (i=0;i<mylevel;i++) printf("--->");
switch (node->op) {
case MDB_OR:
printf(" or\n");
break;
case MDB_AND:
printf(" and\n");
break;
case MDB_NOT:
printf(" not\n");
break;
case MDB_LT:
printf(" < %d\n", node->value.i);
break;
case MDB_GT:
printf(" < %d\n", node->value.i);
break;
case MDB_LIKE:
printf(" like %s\n", node->value.s);
break;
case MDB_EQUAL:
printf(" = %d\n", node->value.i);
break;
}
if (node->left) {
printf("left ");
mdb_sql_dump_node(node->left, mylevel);
}
if (node->right) {
printf("right ");
mdb_sql_dump_node(node->right, mylevel);
}
}
int
mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant)
{
MdbSQLSarg *sql_sarg;
int lastchar;
MdbSargNode *node;
node = mdb_sql_alloc_node();
node->op = op;
/* stash the column name until we finish with the grammar */
node->parent = (void *) g_strdup(col_name);
sql_sarg = mdb_sql_alloc_sarg();
sql_sarg->col_name = g_strdup(col_name);
sql_sarg->sarg->op = op;
/* FIX ME -- we should probably just be storing the ascii value until the
** column definition can be checked for validity
*/
@ -152,19 +304,27 @@ int lastchar;
lastchar = strlen(constant) > 256 ? 256 : strlen(constant);
strncpy(sql_sarg->sarg->value.s, &constant[1], lastchar - 2);
sql_sarg->sarg->value.s[lastchar - 1]='\0';
strncpy(node->value.s, &constant[1], lastchar - 2);;
node->value.s[lastchar - 1]='\0';
} else {
sql_sarg->sarg->value.i = atoi(constant);
node->value.i = atoi(constant);
}
g_ptr_array_add(sql->sargs, sql_sarg);
sql->num_sargs++;
mdb_sql_push_node(sql, node);
return 0;
}
int mdb_sql_all_columns(MdbSQL *sql)
void
mdb_sql_all_columns(MdbSQL *sql)
{
sql->all_columns=1;
}
int mdb_sql_add_column(MdbSQL *sql, char *column_name)
{
MdbSQLColumn *c, *cp;
MdbSQLColumn *c;
c = mdb_sql_alloc_column();
c->name = g_strdup(column_name);
@ -218,6 +378,12 @@ MdbSQLSarg *sql_sarg;
if (sql_sarg->col_name) g_free(sql_sarg->col_name);
if (sql_sarg->sarg) g_free(sql_sarg->sarg);
}
if (sql->sarg_tree) {
mdb_sql_free_tree(sql->sarg_tree);
sql->sarg_tree = NULL;
}
g_list_free(sql->sarg_stack);
sql->sarg_stack = NULL;
g_ptr_array_free(sql->columns,TRUE);
g_ptr_array_free(sql->tables,TRUE);
g_ptr_array_free(sql->sargs,TRUE);
@ -230,6 +396,7 @@ MdbSQLTable *t;
MdbSQLSarg *sql_sarg;
if (sql->cur_table) {
mdb_index_scan_free(sql->cur_table);
mdb_free_tabledef(sql->cur_table);
sql->cur_table = NULL;
}
@ -246,6 +413,12 @@ MdbSQLSarg *sql_sarg;
if (sql_sarg->col_name) g_free(sql_sarg->col_name);
if (sql_sarg->sarg) g_free(sql_sarg->sarg);
}
if (sql->sarg_tree) {
mdb_sql_free_tree(sql);
sql->sarg_tree = NULL;
}
g_list_free(sql->sarg_stack);
sql->sarg_stack = NULL;
g_ptr_array_free(sql->columns,TRUE);
g_ptr_array_free(sql->tables,TRUE);
g_ptr_array_free(sql->sargs,TRUE);
@ -382,7 +555,26 @@ char colsize[11];
/* the column and table names are no good now */
mdb_sql_reset(sql);
}
void mdb_sql_select(MdbSQL *sql)
int mdb_sql_find_sargcol(MdbSargNode *node, gpointer data)
{
MdbTableDef *table = data;
int i;
MdbColumn *col;
if (!mdb_is_relational_op(node->op)) return 0;
for (i=0;i<table->num_cols;i++) {
col=g_ptr_array_index(table->columns,i);
if (!strcmp(col->name, (char *)node->parent)) {
node->col = col;
break;
}
}
return 0;
}
void
mdb_sql_select(MdbSQL *sql)
{
int i,j;
MdbCatalogEntry *entry;
@ -391,7 +583,6 @@ MdbTableDef *table = NULL;
MdbSQLTable *sql_tab;
MdbColumn *col;
MdbSQLColumn *sqlcol;
MdbSQLSarg *sql_sarg;
int found = 0;
if (!mdb) {
@ -418,6 +609,7 @@ int found = 0;
return;
}
mdb_read_columns(table);
mdb_read_indices(table);
mdb_rewind_table(table);
if (sql->all_columns) {
@ -448,14 +640,29 @@ int found = 0;
}
}
#if 0
/* now add back the sargs */
for (i=0;i<sql->num_sargs;i++) {
sql_sarg=g_ptr_array_index(sql->sargs,i);
mdb_add_sarg_by_name(table,sql_sarg->col_name, sql_sarg->sarg);
//mdb_add_sarg_by_name(table,sql_sarg->col_name, sql_sarg->sarg);
}
#endif
/*
* resolve column names to MdbColumn structs
*/
if (sql->sarg_tree) {
mdb_sql_walk_tree(sql->sarg_tree, mdb_sql_find_sargcol, table);
mdb_sql_walk_tree(sql->sarg_tree, mdb_find_indexable_sargs, NULL);
}
/*
* move the sarg_tree.
* XXX - this won't work when we implement joins
*/
table->sarg_tree = sql->sarg_tree;
sql->sarg_tree = NULL;
sql->cur_table = table;
mdb_index_scan_init(mdb, table);
}
void mdbsql_bind_column(MdbSQL *sql, int colnum, char *varaddr)
@ -463,7 +670,7 @@ void mdbsql_bind_column(MdbSQL *sql, int colnum, char *varaddr)
MdbTableDef *table = sql->cur_table;
MdbSQLColumn *sqlcol;
MdbColumn *col;
int i, j;
int j;
/* sql columns are traditionally 1 based, so decrement colnum */
sqlcol = g_ptr_array_index(sql->columns,colnum - 1);
@ -481,7 +688,7 @@ void mdbsql_bind_len(MdbSQL *sql, int colnum, int *len_ptr)
MdbTableDef *table = sql->cur_table;
MdbSQLColumn *sqlcol;
MdbColumn *col;
int i, j;
int j;
/* sql columns are traditionally 1 based, so decrement colnum */
sqlcol = g_ptr_array_index(sql->columns,colnum - 1);

View File

@ -26,9 +26,8 @@ static MdbSQL *g_sql;
if (sql) {
g_sql = sql;
} else {
return g_sql;
}
return g_sql;
}
%}
@ -42,7 +41,7 @@ static MdbSQL *g_sql;
%token <name> IDENT NAME PATH STRING NUMBER
%token SELECT FROM WHERE CONNECT DISCONNECT TO LIST TABLES WHERE AND
%token SELECT FROM WHERE CONNECT DISCONNECT TO LIST TABLES WHERE AND OR NOT
%token DESCRIBE TABLE
%token LTEQ GTEQ LIKE
@ -52,6 +51,11 @@ static MdbSQL *g_sql;
%%
stmt:
query
| error { yyclearin; mdb_sql_reset(_mdb_sql(NULL)); }
;
query:
SELECT column_list FROM table where_clause {
mdb_sql_select(_mdb_sql(NULL));
@ -77,7 +81,10 @@ where_clause:
sarg_list:
sarg
| sarg AND sarg_list
| '(' sarg_list ')'
| NOT sarg_list { mdb_sql_add_not(_mdb_sql(NULL)); }
| sarg_list OR sarg_list { mdb_sql_add_or(_mdb_sql(NULL)); }
| sarg_list AND sarg_list { mdb_sql_add_and(_mdb_sql(NULL)); }
;
sarg:
@ -109,6 +116,7 @@ constant:
database:
PATH
| NAME
;
table:
NAME { mdb_sql_add_table(_mdb_sql(NULL), $1); free($1); }

View File

@ -23,9 +23,9 @@
#include "mdbtools.h"
int
main (int argc, char **argv)
{
int rows;
int i, j;
MdbHandle *mdb;
MdbCatalogEntry *entry;

View File

@ -21,11 +21,10 @@
#include "mdbtools.h"
#define is_text_type(x) (x==MDB_TEXT || x==MDB_MEMO || x==MDB_SDATETIME)
int
main(int argc, char **argv)
{
int rows;
int i, j;
unsigned char buf[2048];
MdbHandle *mdb;
MdbCatalogEntry *entry;
MdbTableDef *table;

View File

@ -29,6 +29,7 @@ void copy_header (FILE *f)
fprintf (f, "/******************************************************************/\n");
}
int
main (int argc, char **argv)
{
int i, j, k;

View File

@ -21,6 +21,8 @@
/* generates an array of type FOO */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FILENAMESIZE 128
#define BUFFERSIZE 4096
@ -36,6 +38,7 @@ void copy_header (FILE *f)
fprintf (f, "/******************************************************************/\n");
}
int
main (int argc, char **argv)
{
char txt_filename [FILENAMESIZE];

View File

@ -20,9 +20,10 @@
#include "mdbtools.h"
int
main (int argc, char **argv)
{
int i, j, k;
int i, k;
MdbHandle *mdb;
MdbCatalogEntry *entry;
MdbTableDef *table;

View File

@ -33,6 +33,8 @@ int headers = 1;
int footers = 1;
int pretty_print = 1;
char *delimiter;
int showplan = 0;
int noexec = 0;
#ifndef HAVE_READLINE
char *readline(char *prompt)
@ -88,15 +90,78 @@ do_set_cmd(MdbSQL *sql, char *s)
} else {
printf("Unknown stats option %s\n", level2);
}
} else if (!strcmp(level1,"showplan")) {
level2 = strtok(NULL, " \t");
if (!strcmp(level2,"on")) {
showplan=1;
} else if (!strcmp(level2,"off")) {
showplan=0;
} else {
printf("Unknown showplan option %s\n", level2);
}
} else if (!strcmp(level1,"noexec")) {
level2 = strtok(NULL, " \t");
if (!strcmp(level2,"on")) {
noexec=1;
} else if (!strcmp(level2,"off")) {
noexec=0;
} else {
printf("Unknown showplan option %s\n", level2);
}
} else {
printf("Unknown set command %s\n", level1);
}
}
int
read_file(char *s, int line, int *bufsz, char *mybuf)
{
char *fname;
FILE *in;
char buf[256];
int cursz = 0;
int lines = 0;
fname = s;
while (*fname && *fname==' ') fname++;
if (! (in = fopen(fname, "r"))) {
fprintf(stderr,"Unable to open file %s\n", fname);
mybuf[0]=0;
return 0;
}
while (fgets(buf, 255, in)) {
cursz += strlen(buf) + 1;
if (cursz > (*bufsz)) {
(*bufsz) *= 2;
mybuf = (char *) realloc(mybuf, *bufsz);
}
strcat(mybuf, buf);
add_history(buf);
strcat(mybuf, "\n");
lines++;
printf("%d => %s",line+lines, buf);
}
return lines;
}
void
run_query(MdbSQL *sql, char *mybuf)
{
MdbTableDef *table;
if (!parse(sql, mybuf) && sql->cur_table) {
if (showplan) {
table = sql->cur_table;
if (tabl->sarg_tree) mdb_sql_dump_node(table->sarg_tree, 0);
if (sql->cur_table->strategy == MDB_TABLE_SCAN)
printf("Table scanning %s\n", table->name);
else
printf("Index scanning %s using %s\n", table->name, table->scan_idx->name);
}
if (noexec) {
mdb_sql_reset(sql);
return;
}
mdbsql_bind_all(sql);
if (pretty_print)
dump_results_pp(sql);
@ -233,6 +298,7 @@ void myexit(int r)
free(delimiter);
exit(r);
}
int
main(int argc, char **argv)
{
char *s;
@ -303,6 +369,8 @@ FILE *in = NULL, *out = NULL;
} else {
sprintf(prompt,"1 => ");
s=readline(prompt);
if (!strcmp(s,"exit") || !strcmp(s,"quit") || !strcmp(s,"bye"))
done = 1;
}
while (!done) {
if (line==1 && !strncmp(s,"set ", 4)) {
@ -315,6 +383,8 @@ FILE *in = NULL, *out = NULL;
} else if (!strcmp(s,"reset")) {
line = 0;
mybuf[0]='\0';
} else if (!strncmp(s,":r",2)) {
line += read_file(&s[2], line, &bufsz, mybuf);
} else {
while (strlen(mybuf) + strlen(s) > bufsz) {
bufsz *= 2;
@ -346,6 +416,8 @@ FILE *in = NULL, *out = NULL;
mdb_sql_exit(sql);
myexit(0);
return 0; /* make gcc -Wall happy */
}
#else
int main(int argc, char **argv)

View File

@ -20,13 +20,12 @@
#include "mdbtools.h"
int
main (int argc, char **argv)
{
int i, j, k;
int i;
MdbHandle *mdb;
MdbCatalogEntry *entry;
MdbTableDef *table;
MdbColumn *col;
char *delimiter = NULL;
int line_break=0;
int skip_sys=1;

View File

@ -20,21 +20,11 @@
#include "mdbtools.h"
int
main(int argc, char **argv)
{
int rows;
int i, j;
unsigned char buf[2048];
MdbHandle *mdb;
MdbCatalogEntry entry;
MdbTableDef *table;
MdbColumn *col;
/* doesn't handle tables > 256 columns. Can that happen? */
char *bound_values[256];
char *delimiter = ",";
char header_row = 1;
char quote_text = 1;
int opt;
/*
** optind is now the position of the first non-option arg,

View File

@ -18,15 +18,9 @@
#include "mdbtools.h"
int
main(int argc, char **argv)
{
off_t offset=0;
int fd, i, j;
char xdigit;
short digit;
struct stat status;
int rows, cur, off;
unsigned char buf[2048];
MdbHandle *mdb;

View File

@ -20,16 +20,13 @@
#include "mdbtools.h"
int
main(int argc, char **argv)
{
int rows;
int i;
unsigned char buf[2048];
MdbHandle *mdb;
MdbCatalogEntry *entry;
MdbTableDef *table;
GList *l;
if (argc<2) {
fprintf(stderr,"Usage: %s <file> <table>\n",argv[0]);

View File

@ -20,15 +20,10 @@
#include "mdbtools.h"
int
main(int argc, char **argv)
{
int rows;
int i;
unsigned char buf[2048];
MdbHandle *mdb;
MdbCatalogEntry entry;
MdbTableDef *table;
GList *l;
int j;
int page, start, stop;

View File

@ -22,9 +22,10 @@
extern char idx_to_text[];
void walk_index(MdbHandle *mdb, MdbIndex *idx);
int
main(int argc, char **argv)
{
int rows;
int i, j;
MdbHandle *mdb;
MdbCatalogEntry *entry;
@ -84,6 +85,7 @@ page_name(int page_type)
case 0x03: return "Index"; break;
case 0x04: return "Index Leaf"; break;
case 0x05: return "Page Usage"; break;
default: return "Unknown";
}
}
void check_row(MdbHandle *mdb, MdbIndex *idx, guint32 pg, int row, unsigned char *idxrow, int len)
@ -94,7 +96,7 @@ void check_row(MdbHandle *mdb, MdbIndex *idx, guint32 pg, int row, unsigned char
int row_start, row_end;
MdbColumn *col;
guchar buf[256], key[256];
int elem, pos;
int elem;
MdbTableDef *table = idx->table;
fmt = mdb->fmt;
@ -127,7 +129,6 @@ void
walk_index(MdbHandle *mdb, MdbIndex *idx)
{
int start, len;
unsigned char byte;
guint32 pg;
guint16 row;
MdbHandle *mdbidx;

View File

@ -18,15 +18,14 @@
#include "mdbtools.h"
int
main(int argc, char **argv)
{
int rows;
int i;
unsigned char buf[2048];
MdbHandle *mdb;
MdbCatalogEntry entry;
#if 0
int i;
MdbCatalogEntry entry;
if (argc<2) {
fprintf(stderr,"Usage: %s <file> <table>\n",argv[0]);
exit(1);

View File

@ -22,15 +22,13 @@
void dump_ole(MdbTableDef *table, char *colname, char *sargname);
int
main(int argc, char **argv)
{
int rows;
int i;
unsigned char buf[2048];
MdbHandle *mdb;
MdbCatalogEntry *entry;
MdbTableDef *table;
GList *l;
char *dot, *colname, *tabname;
char *sargname = NULL;

View File

@ -20,14 +20,12 @@
#include "mdbtools.h"
int
main(int argc, char **argv)
{
int rows;
int i;
unsigned char buf[2048];
MdbHandle *mdb;
MdbCatalogEntry *entry;
GList *l;
int found = 0;

View File

@ -22,17 +22,15 @@
void read_to_row(MdbTableDef *table, char *sargname);
int
main(int argc, char **argv)
{
int rows;
int i;
unsigned char buf[2048];
MdbHandle *mdb;
MdbCatalogEntry *entry;
MdbTableDef *table;
GList *l;
char *dot, *colname, *tabname;
char *colop, *colval;
char *colname, *tabname;
char *colval;
char *sargname = NULL;
char *updstr = NULL;
unsigned char data[255];