mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-10-21 02:57:42 +08:00
rework of patch #879693 to support 0=1 in where clause
This commit is contained in:
@@ -3,6 +3,15 @@ Sun Feb 8 13:02:56 EST 2004 Brian Bruns <brian@bruns.com>
|
||||
* doc/faq.html: update email addy
|
||||
* doc/userguide.sgml: fix typo
|
||||
* src/libmdb/backend.c: mysql patch
|
||||
* src/odbc/odbc.c:
|
||||
* src/util/mdb-sql.c:
|
||||
* src/gmdb2/sql.c: change mdbsql_bind_col to mdb_sql_bind_col to match other functions
|
||||
* include/mdbtools.h: move mdb_backends to .c file
|
||||
* src/sql/lexer.l: fix STRING token from overreading
|
||||
* include/mdbsql.h:
|
||||
* src/sql/parser.y:
|
||||
* src/sql/mdbsql.c: added mdb_sql_eval_expr() to support 0=1 literal comparison
|
||||
* src/libmdb/sargs.c: check for null node->col (literal comparision)
|
||||
|
||||
Fri Feb 6 18:08:59 EST 2004 Brian Bruns <brian@bruns.com>
|
||||
|
||||
|
@@ -13,14 +13,15 @@ typedef struct {
|
||||
GPtrArray *columns;
|
||||
int num_tables;
|
||||
GPtrArray *tables;
|
||||
int num_sargs;
|
||||
GPtrArray *sargs;
|
||||
//int num_sargs;
|
||||
//GPtrArray *sargs;
|
||||
MdbTableDef *cur_table;
|
||||
MdbSargNode *sarg_tree;
|
||||
GList *sarg_stack;
|
||||
/* FIX ME */
|
||||
char *bound_values[256];
|
||||
unsigned char *kludge_ttable_pg;
|
||||
long max_rows;
|
||||
} MdbSQL;
|
||||
|
||||
typedef struct {
|
||||
@@ -42,7 +43,7 @@ typedef struct {
|
||||
MdbSarg *sarg;
|
||||
} MdbSQLSarg;
|
||||
|
||||
char *g_input_ptr;
|
||||
extern char *g_input_ptr;
|
||||
|
||||
#undef YY_INPUT
|
||||
#define YY_INPUT(b, r, ms) (r = mdb_sql_yyinput(b, ms));
|
||||
@@ -70,5 +71,8 @@ extern void mdb_sql_add_and(MdbSQL *sql);
|
||||
extern void mdb_sql_listtables(MdbSQL *sql);
|
||||
extern void mdb_sql_add_not(MdbSQL *sql);
|
||||
extern void mdb_sql_describe_table(MdbSQL *sql);
|
||||
extern int mdb_sql_run_query(MdbSQL *sql, char *query);
|
||||
extern void mdb_sql_set_maxrow(MdbSQL *sql, int maxrow);
|
||||
extern int mdb_sql_eval_expr(MdbSQL *sql, char *const1, int op, char *const2);
|
||||
|
||||
#endif
|
||||
|
@@ -132,7 +132,7 @@ enum {
|
||||
#define IS_JET3(mdb) (mdb->f->jet_version==MDB_VER_JET3)
|
||||
|
||||
/* hash to store registered backends */
|
||||
GHashTable *mdb_backends;
|
||||
extern GHashTable *mdb_backends;
|
||||
|
||||
/* forward declarations */
|
||||
typedef struct mdbindex MdbIndex;
|
||||
|
@@ -428,7 +428,7 @@ long row, maxrow;
|
||||
for (i=0;i<sql->num_columns;i++) {
|
||||
bound_data[i] = (char *) malloc(MDB_BIND_SIZE);
|
||||
bound_data[i][0] = '\0';
|
||||
mdbsql_bind_column(sql, i+1, bound_data[i]);
|
||||
mdb_sql_bind_column(sql, i+1, bound_data[i]);
|
||||
sqlcol = g_ptr_array_index(sql->columns,i);
|
||||
column = gtk_tree_view_column_new_with_attributes(sqlcol->name, renderer, "text", i, NULL);
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW (treeview), column);
|
||||
|
@@ -27,6 +27,8 @@
|
||||
#include "dmalloc.h"
|
||||
#endif
|
||||
|
||||
GHashTable *mdb_backends;
|
||||
|
||||
/* Access data types */
|
||||
MdbBackendType mdb_access_types[] = {
|
||||
{"Unknown 0x00", 0,0,0 },
|
||||
|
@@ -119,7 +119,7 @@ mdb_find_indexable_sargs(MdbSargNode *node, gpointer data)
|
||||
* a pretty worthless test for indexes, ie NOT col1 = 3, we are
|
||||
* probably better off table scanning.
|
||||
*/
|
||||
if (mdb_is_relational_op(node->op)) {
|
||||
if (mdb_is_relational_op(node->op) && node->col) {
|
||||
//printf("op = %d value = %s\n", node->op, node->value.s);
|
||||
sarg.op = node->op;
|
||||
sarg.value = node->value;
|
||||
@@ -187,6 +187,10 @@ mdb_test_sarg_node(MdbHandle *mdb, MdbSargNode *node, MdbField *fields, int num_
|
||||
|
||||
if (mdb_is_relational_op(node->op)) {
|
||||
col = node->col;
|
||||
/* for const = const expressions */
|
||||
if (!col) {
|
||||
return (node->value.i);
|
||||
}
|
||||
elem = mdb_find_field(col->col_num, fields, num_fields);
|
||||
if (!mdb_test_sarg(mdb, col, node, &fields[elem]))
|
||||
return 0;
|
||||
|
@@ -32,7 +32,7 @@
|
||||
|
||||
#include "connectparams.h"
|
||||
|
||||
static char software_version[] = "$Id: odbc.c,v 1.11 2004/01/06 03:18:19 brianb Exp $";
|
||||
static char software_version[] = "$Id: odbc.c,v 1.12 2004/02/08 21:54:20 brianb Exp $";
|
||||
static void *no_unused_var_warn[] = {software_version,
|
||||
no_unused_var_warn};
|
||||
|
||||
@@ -789,10 +789,10 @@ struct _sql_bind_info *cur;
|
||||
while (cur) {
|
||||
if (cur->column_number>0 &&
|
||||
cur->column_number <= env->sql->num_columns) {
|
||||
mdbsql_bind_column(env->sql,
|
||||
mdb_sql_bind_column(env->sql,
|
||||
cur->column_number, cur->varaddr);
|
||||
if (cur->column_lenbind)
|
||||
mdbsql_bind_len(env->sql,
|
||||
mdb_sql_bind_len(env->sql,
|
||||
cur->column_number, cur->column_lenbind);
|
||||
} else {
|
||||
/* log error ? */
|
||||
|
@@ -43,14 +43,14 @@ null { return NUL; }
|
||||
(>=) { 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; }
|
||||
'[A-z0-9 !@#$%^&*()-_+={}[\];:",.<>/?`~|\\]*' { yylval.name = strdup(yytext); return STRING; }
|
||||
([0-9]+|([0-9]*\.[0-9+)([eE][-+]?[0-9]+)?) {
|
||||
yylval.name = strdup(yytext); return NUMBER;
|
||||
}
|
||||
|
133
src/sql/mdbsql.c
133
src/sql/mdbsql.c
@@ -31,6 +31,8 @@ void mdb_dump_results(MdbSQL *sql);
|
||||
#include <wordexp.h>
|
||||
#endif
|
||||
|
||||
char *g_input_ptr;
|
||||
|
||||
void
|
||||
mdb_sql_error(char *fmt, ...)
|
||||
{
|
||||
@@ -62,21 +64,37 @@ MdbSQL *sql;
|
||||
sql = (MdbSQL *) g_malloc0(sizeof(MdbSQL));
|
||||
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;
|
||||
}
|
||||
|
||||
MdbSQLSarg *mdb_sql_alloc_sarg()
|
||||
int _parse(MdbSQL *sql, char *buf)
|
||||
{
|
||||
MdbSQLSarg *sql_sarg;
|
||||
sql_sarg = (MdbSQLSarg *) malloc(sizeof(MdbSQLSarg));
|
||||
memset(sql_sarg,0,sizeof(MdbSQLSarg));
|
||||
sql_sarg->sarg = (MdbSarg *) malloc(sizeof(MdbSarg));
|
||||
memset(sql_sarg->sarg,0,sizeof(MdbSarg));
|
||||
return sql_sarg;
|
||||
g_input_ptr = buf;
|
||||
/* begin unsafe */
|
||||
_mdb_sql(sql);
|
||||
if (yyparse()) {
|
||||
/* end unsafe */
|
||||
mdb_sql_reset(sql);
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
int mdb_run_query(MdbSQL *sql, char *query)
|
||||
{
|
||||
if (_parse(sql,query) && sql->cur_table) {
|
||||
mdb_sql_bind_all(sql);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
void mdb_sql_set_maxrow(MdbSQL *sql, int maxrow)
|
||||
{
|
||||
sql->max_rows = maxrow;
|
||||
}
|
||||
void mdb_sql_free_column(MdbSQLColumn *c)
|
||||
{
|
||||
@@ -295,10 +313,58 @@ mdb_sql_dump_node(MdbSargNode *node, int level)
|
||||
mdb_sql_dump_node(node->right, mylevel);
|
||||
}
|
||||
}
|
||||
/* evaluate a expression involving 2 constants and add answer to the stack */
|
||||
int
|
||||
mdb_sql_eval_expr(MdbSQL *sql, char *const1, int op, char *const2)
|
||||
{
|
||||
long val1, val2, value, compar;
|
||||
unsigned char illop = 0;
|
||||
MdbSargNode *node;
|
||||
|
||||
if (const1[0]=='\'' && const2[0]=='\'') {
|
||||
value = strcmp(const1, const2);
|
||||
switch (op) {
|
||||
case MDB_EQUAL: compar = (value ? 0 : 1); break;
|
||||
case MDB_GT: compar = (value > 0); break;
|
||||
case MDB_GTEQ: compar = (value >= 0); break;
|
||||
case MDB_LT: compar = (value < 0); break;
|
||||
case MDB_LTEQ: compar = (value <= 0); break;
|
||||
case MDB_LIKE: compar = mdb_like_cmp(const1,const2); break;
|
||||
default: illop = 1;
|
||||
}
|
||||
} else if (const1[0]!='\'' && const2[0]!='\'') {
|
||||
val1 = atol(const1);
|
||||
val2 = atol(const2);
|
||||
switch (op) {
|
||||
case MDB_EQUAL: compar = (val1 == val2); break;
|
||||
case MDB_GT: compar = (val1 > val2); break;
|
||||
case MDB_GTEQ: compar = (val1 >= val2); break;
|
||||
case MDB_LT: compar = (val1 < val2); break;
|
||||
case MDB_LTEQ: compar = (val1 <= val2); break;
|
||||
default: illop = 1;
|
||||
}
|
||||
} else {
|
||||
mdb_sql_error("Comparison of strings and numbers not allowed.");
|
||||
/* the column and table names are no good now */
|
||||
mdb_sql_reset(sql);
|
||||
return 1;
|
||||
}
|
||||
if (illop) {
|
||||
mdb_sql_error("Illegal operator used for comparision of literals.");
|
||||
/* the column and table names are no good now */
|
||||
mdb_sql_reset(sql);
|
||||
return 1;
|
||||
}
|
||||
node = mdb_sql_alloc_node();
|
||||
node->op = MDB_EQUAL;
|
||||
node->col = NULL;
|
||||
node->value.i = (compar ? 1 : 0);
|
||||
mdb_sql_push_node(sql, node);
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant)
|
||||
{
|
||||
MdbSQLSarg *sql_sarg;
|
||||
int lastchar;
|
||||
MdbSargNode *node;
|
||||
|
||||
@@ -307,14 +373,8 @@ mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant)
|
||||
/* 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;
|
||||
|
||||
if (!constant) {
|
||||
/* XXX - do we need to check operator? */
|
||||
g_ptr_array_add(sql->sargs, sql_sarg);
|
||||
sql->num_sargs++;
|
||||
mdb_sql_push_node(sql, node);
|
||||
return 0;
|
||||
}
|
||||
@@ -323,16 +383,11 @@ mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant)
|
||||
*/
|
||||
if (constant[0]=='\'') {
|
||||
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);
|
||||
|
||||
@@ -384,7 +439,6 @@ void mdb_sql_exit(MdbSQL *sql)
|
||||
int i;
|
||||
MdbSQLColumn *c;
|
||||
MdbSQLTable *t;
|
||||
MdbSQLSarg *sql_sarg;
|
||||
|
||||
for (i=0;i<sql->num_columns;i++) {
|
||||
c = g_ptr_array_index(sql->columns,i);
|
||||
@@ -394,11 +448,6 @@ MdbSQLSarg *sql_sarg;
|
||||
t = g_ptr_array_index(sql->tables,i);
|
||||
if (t->name) g_free(t->name);
|
||||
}
|
||||
for (i=0;i<sql->num_sargs;i++) {
|
||||
sql_sarg = g_ptr_array_index(sql->sargs,i);
|
||||
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;
|
||||
@@ -407,7 +456,6 @@ MdbSQLSarg *sql_sarg;
|
||||
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);
|
||||
if (sql->mdb) {
|
||||
mdb_close(sql->mdb);
|
||||
mdb_free_handle(sql->mdb);
|
||||
@@ -418,7 +466,6 @@ void mdb_sql_reset(MdbSQL *sql)
|
||||
int i;
|
||||
MdbSQLColumn *c;
|
||||
MdbSQLTable *t;
|
||||
MdbSQLSarg *sql_sarg;
|
||||
|
||||
if (sql->cur_table) {
|
||||
mdb_index_scan_free(sql->cur_table);
|
||||
@@ -437,11 +484,6 @@ MdbSQLSarg *sql_sarg;
|
||||
t = g_ptr_array_index(sql->tables,i);
|
||||
mdb_sql_free_table(t);
|
||||
}
|
||||
for (i=0;i<sql->num_sargs;i++) {
|
||||
sql_sarg = g_ptr_array_index(sql->sargs,i);
|
||||
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;
|
||||
@@ -450,15 +492,12 @@ MdbSQLSarg *sql_sarg;
|
||||
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);
|
||||
|
||||
sql->all_columns = 0;
|
||||
sql->num_columns = 0;
|
||||
sql->columns = g_ptr_array_new();
|
||||
sql->num_tables = 0;
|
||||
sql->tables = g_ptr_array_new();
|
||||
sql->num_sargs = 0;
|
||||
sql->sargs = g_ptr_array_new();
|
||||
}
|
||||
static void print_break(int sz, int first)
|
||||
{
|
||||
@@ -668,6 +707,7 @@ int mdb_sql_find_sargcol(MdbSargNode *node, gpointer data)
|
||||
MdbColumn *col;
|
||||
|
||||
if (!mdb_is_relational_op(node->op)) return 0;
|
||||
if (!node->parent) return 0;
|
||||
|
||||
for (i=0;i<table->num_cols;i++) {
|
||||
col=g_ptr_array_index(table->columns,i);
|
||||
@@ -745,13 +785,6 @@ 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);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* resolve column names to MdbColumn structs
|
||||
*/
|
||||
@@ -770,7 +803,8 @@ int found = 0;
|
||||
mdb_index_scan_init(mdb, table);
|
||||
}
|
||||
|
||||
void mdbsql_bind_column(MdbSQL *sql, int colnum, char *varaddr)
|
||||
void
|
||||
mdb_sql_bind_column(MdbSQL *sql, int colnum, char *varaddr)
|
||||
{
|
||||
MdbTableDef *table = sql->cur_table;
|
||||
MdbSQLColumn *sqlcol;
|
||||
@@ -788,7 +822,8 @@ int j;
|
||||
}
|
||||
}
|
||||
}
|
||||
void mdbsql_bind_len(MdbSQL *sql, int colnum, int *len_ptr)
|
||||
void
|
||||
mdb_sql_bind_len(MdbSQL *sql, int colnum, int *len_ptr)
|
||||
{
|
||||
MdbTableDef *table = sql->cur_table;
|
||||
MdbSQLColumn *sqlcol;
|
||||
@@ -806,17 +841,19 @@ int j;
|
||||
}
|
||||
}
|
||||
}
|
||||
void mdbsql_bind_all(MdbSQL *sql)
|
||||
void
|
||||
mdb_sql_bind_all(MdbSQL *sql)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<sql->num_columns;i++) {
|
||||
sql->bound_values[i] = (char *) malloc(MDB_BIND_SIZE);
|
||||
sql->bound_values[i][0] = '\0';
|
||||
mdbsql_bind_column(sql, i+1, sql->bound_values[i]);
|
||||
mdb_sql_bind_column(sql, i+1, sql->bound_values[i]);
|
||||
}
|
||||
}
|
||||
void mdbsql_dump_results(MdbSQL *sql)
|
||||
void
|
||||
mdb_sql_dump_results(MdbSQL *sql)
|
||||
{
|
||||
int j;
|
||||
MdbSQLColumn *sqlcol;
|
||||
|
@@ -49,6 +49,7 @@ static MdbSQL *g_sql;
|
||||
%type <name> constant
|
||||
%type <ival> operator
|
||||
%type <ival> nulloperator
|
||||
%type <name> identifier
|
||||
|
||||
%%
|
||||
|
||||
@@ -89,22 +90,30 @@ sarg_list:
|
||||
;
|
||||
|
||||
sarg:
|
||||
NAME operator constant {
|
||||
identifier operator constant {
|
||||
mdb_sql_add_sarg(_mdb_sql(NULL), $1, $2, $3);
|
||||
free($1);
|
||||
free($3);
|
||||
}
|
||||
| constant operator NAME {
|
||||
| constant operator identifier {
|
||||
mdb_sql_add_sarg(_mdb_sql(NULL), $3, $2, $1);
|
||||
free($1);
|
||||
free($3);
|
||||
}
|
||||
| NAME nulloperator {
|
||||
| constant operator constant {
|
||||
mdb_sql_eval_expr(_mdb_sql(NULL), $1, $2, $3);
|
||||
}
|
||||
| identifier nulloperator {
|
||||
mdb_sql_add_sarg(_mdb_sql(NULL), $1, $2, NULL);
|
||||
free($1);
|
||||
}
|
||||
;
|
||||
|
||||
identifier:
|
||||
NAME
|
||||
| IDENT
|
||||
;
|
||||
|
||||
operator:
|
||||
'=' { $$ = MDB_EQUAL; }
|
||||
| '>' { $$ = MDB_GT; }
|
||||
|
@@ -185,7 +185,7 @@ run_query(MdbSQL *sql, char *mybuf)
|
||||
mdb_sql_reset(sql);
|
||||
return;
|
||||
}
|
||||
mdbsql_bind_all(sql);
|
||||
mdb_sql_bind_all(sql);
|
||||
if (pretty_print)
|
||||
dump_results_pp(sql);
|
||||
else
|
||||
|
Reference in New Issue
Block a user