From fed589b2e72b8a96dbb772f97234552e3807728d Mon Sep 17 00:00:00 2001 From: brianb Date: Sun, 8 Feb 2004 21:54:20 +0000 Subject: [PATCH] rework of patch #879693 to support 0=1 in where clause --- ChangeLog | 9 +++ include/mdbsql.h | 10 +++- include/mdbtools.h | 2 +- src/gmdb2/sql.c | 2 +- src/libmdb/backend.c | 2 + src/libmdb/sargs.c | 6 +- src/odbc/odbc.c | 6 +- src/sql/lexer.l | 6 +- src/sql/mdbsql.c | 133 +++++++++++++++++++++++++++---------------- src/sql/parser.y | 15 ++++- src/util/mdb-sql.c | 2 +- 11 files changed, 129 insertions(+), 64 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7e24b1f..cafb5e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,15 @@ Sun Feb 8 13:02:56 EST 2004 Brian Bruns * 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 diff --git a/include/mdbsql.h b/include/mdbsql.h index eba38eb..9d61d25 100644 --- a/include/mdbsql.h +++ b/include/mdbsql.h @@ -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 diff --git a/include/mdbtools.h b/include/mdbtools.h index c000dcd..718fb91 100644 --- a/include/mdbtools.h +++ b/include/mdbtools.h @@ -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; diff --git a/src/gmdb2/sql.c b/src/gmdb2/sql.c index 073a928..1622b2e 100644 --- a/src/gmdb2/sql.c +++ b/src/gmdb2/sql.c @@ -428,7 +428,7 @@ long row, maxrow; for (i=0;inum_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); diff --git a/src/libmdb/backend.c b/src/libmdb/backend.c index 5e6fb83..02208fe 100644 --- a/src/libmdb/backend.c +++ b/src/libmdb/backend.c @@ -27,6 +27,8 @@ #include "dmalloc.h" #endif +GHashTable *mdb_backends; + /* Access data types */ MdbBackendType mdb_access_types[] = { {"Unknown 0x00", 0,0,0 }, diff --git a/src/libmdb/sargs.c b/src/libmdb/sargs.c index d828945..ddb8e9c 100644 --- a/src/libmdb/sargs.c +++ b/src/libmdb/sargs.c @@ -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; diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c index a1d09b5..ac2d1cb 100644 --- a/src/odbc/odbc.c +++ b/src/odbc/odbc.c @@ -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 ? */ diff --git a/src/sql/lexer.l b/src/sql/lexer.l index 60215b9..9b3d084 100644 --- a/src/sql/lexer.l +++ b/src/sql/lexer.l @@ -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; } diff --git a/src/sql/mdbsql.c b/src/sql/mdbsql.c index bf4e0be..d453493 100644 --- a/src/sql/mdbsql.c +++ b/src/sql/mdbsql.c @@ -31,6 +31,8 @@ void mdb_dump_results(MdbSQL *sql); #include #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;inum_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;inum_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;inum_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;inum_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;inum_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;inum_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; diff --git a/src/sql/parser.y b/src/sql/parser.y index 2f068cd..fa67664 100644 --- a/src/sql/parser.y +++ b/src/sql/parser.y @@ -49,6 +49,7 @@ static MdbSQL *g_sql; %type constant %type operator %type nulloperator +%type 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; } diff --git a/src/util/mdb-sql.c b/src/util/mdb-sql.c index 845edd3..5ece925 100644 --- a/src/util/mdb-sql.c +++ b/src/util/mdb-sql.c @@ -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