mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-06-28 15:39:02 +08:00
query planner stuff
some gcc -Wall fixes added suport for _ in identifier names in SQL gmdb2 manual additions
This commit is contained in:
parent
bafa51bd88
commit
092e2b79af
@ -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);
|
||||
|
@ -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_ */
|
||||
|
@ -1,5 +1,6 @@
|
||||
figs = \
|
||||
figures/gmdb2_window.png
|
||||
figures/gmdb2_sql_window.png
|
||||
docname = gmdb
|
||||
lang = C
|
||||
omffile = gmdb-C.omf
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -112,10 +112,11 @@ 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);
|
||||
sprintf(buf,"type %04x", col_type);
|
||||
return buf;
|
||||
} else {
|
||||
return backend->types_table[col_type];
|
||||
@ -167,11 +168,12 @@ MdbBackend *backend;
|
||||
}
|
||||
}
|
||||
|
||||
static void do_first (MdbHandle *mdb)
|
||||
static void
|
||||
do_first (MdbHandle *mdb)
|
||||
{
|
||||
int i, j, k;
|
||||
static char text[255];
|
||||
mdb_read_catalog (mdb, MDB_TABLE);
|
||||
int i, k;
|
||||
|
||||
mdb_read_catalog (mdb, MDB_TABLE);
|
||||
|
||||
/* loop over each entry in the catalog */
|
||||
for (i=0; i < mdb->num_catalog; i++) {
|
||||
|
@ -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)
|
||||
@ -155,21 +156,23 @@ int ret;
|
||||
}
|
||||
int mdb_read_row(MdbTableDef *table, int row)
|
||||
{
|
||||
MdbHandle *mdb = table->entry->mdb;
|
||||
MdbFormatConstants *fmt = mdb->fmt;
|
||||
MdbColumn *col;
|
||||
int i, j, rc;
|
||||
int num_cols, var_cols, fixed_cols;
|
||||
int row_start, row_end;
|
||||
int fixed_cols_found, var_cols_found;
|
||||
int col_start, len, next_col;
|
||||
int num_of_jumps=0, jumps_used=0;
|
||||
int eod; /* end of data */
|
||||
int delflag, lookupflag;
|
||||
int bitmask_sz;
|
||||
int col_ptr, deleted_columns=0;
|
||||
unsigned char null_mask[33]; /* 256 columns max / 8 bits per byte */
|
||||
unsigned char isnull;
|
||||
MdbHandle *mdb = table->entry->mdb;
|
||||
MdbFormatConstants *fmt = mdb->fmt;
|
||||
MdbColumn *col;
|
||||
int i, j, rc;
|
||||
int num_cols, var_cols, fixed_cols;
|
||||
int row_start, row_end;
|
||||
int fixed_cols_found, var_cols_found;
|
||||
int col_start, len, next_col;
|
||||
int num_of_jumps=0, jumps_used=0;
|
||||
int eod; /* end of data */
|
||||
int delflag, lookupflag;
|
||||
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,19 +486,29 @@ 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 {
|
||||
rows = mdb_get_int16(mdb,fmt->row_count_offset);
|
||||
|
||||
/* if at end of page, find a new page */
|
||||
if (table->cur_row >= rows) {
|
||||
table->cur_row=0;
|
||||
|
||||
if (!mdb_read_next_dpg(table)) {
|
||||
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 */
|
||||
if (table->cur_row >= rows) {
|
||||
table->cur_row=0;
|
||||
|
||||
if (!mdb_read_next_dpg(table)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* printf("page %d row %d\n",table->cur_phys_pg, 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;
|
||||
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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
@ -181,6 +183,33 @@ void mdb_index_cache_sarg(MdbColumn *col, MdbSarg *sarg, MdbSarg *idx_sarg)
|
||||
break;
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -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,9 +250,12 @@ 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)) {
|
||||
/* sarg didn't match, no sense going on */
|
||||
return 0;
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -125,4 +125,6 @@ int top, i, j;
|
||||
s[j++]=array[i]+'0';
|
||||
}
|
||||
s[j]='\0';
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
298
src/sql/lexer.c
298
src/sql/lexer.c
@ -1,7 +1,7 @@
|
||||
/* A lexical scanner generated by flex */
|
||||
|
||||
/* Scanner skeleton version:
|
||||
* $Header: /Users/brian/cvs/mdbtools/mdbtools/src/sql/Attic/lexer.c,v 1.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()
|
||||
|
@ -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]+)?) {
|
||||
|
231
src/sql/mdbsql.c
231
src/sql/mdbsql.c
@ -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()
|
||||
{
|
||||
MdbSQLSarg *sql_sarg;
|
||||
int lastchar;
|
||||
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);
|
||||
|
@ -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));
|
||||
@ -76,8 +80,11 @@ where_clause:
|
||||
;
|
||||
|
||||
sarg_list:
|
||||
sarg
|
||||
| sarg AND sarg_list
|
||||
sarg
|
||||
| '(' 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); }
|
||||
|
@ -23,9 +23,9 @@
|
||||
|
||||
#include "mdbtools.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int rows;
|
||||
int i, j;
|
||||
MdbHandle *mdb;
|
||||
MdbCatalogEntry *entry;
|
||||
|
@ -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;
|
||||
|
@ -29,6 +29,7 @@ void copy_header (FILE *f)
|
||||
fprintf (f, "/******************************************************************/\n");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int i, j, k;
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -18,16 +18,10 @@
|
||||
|
||||
#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;
|
||||
MdbHandle *mdb;
|
||||
|
||||
|
||||
if (argc<2) {
|
||||
|
@ -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]);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user