Merge branch 'dev' of github.com:mdbtools/mdbtools into merge-166

This commit is contained in:
Evan Miller
2020-11-01 07:55:53 -05:00
111 changed files with 750 additions and 10234 deletions

View File

@@ -3,7 +3,7 @@ BUILT_SOURCES = parser.h
AM_YFLAGS = -d -o parser.c
lib_LTLIBRARIES = libmdbsql.la
libmdbsql_la_SOURCES= mdbsql.c parser.y lexer.l
libmdbsql_la_LDFLAGS = -version-info 2:0:0 -export-symbols-regex '^mdb_sql_'
libmdbsql_la_LDFLAGS = -version-info $(VERSION_INFO) -export-symbols-regex '^mdb_sql_'
CLEANFILES = parser.c parser.h lexer.c
AM_CFLAGS = -I$(top_srcdir)/include $(GLIB_CFLAGS)
LIBS = $(GLIB_LIBS)

View File

@@ -72,6 +72,8 @@ null { return NUL; }
">" { return GT; }
like { return LIKE; }
limit { return LIMIT; }
top { return TOP; }
percent { return PERCENT; }
count { return COUNT; }
strptime { return STRPTIME; }
[ \t\r] ;

View File

@@ -73,6 +73,7 @@ MdbSQL *sql;
sql->sarg_stack = NULL;
sql->max_rows = -1;
sql->limit = -1;
sql->limit_percent = 0;
return sql;
}
@@ -189,12 +190,26 @@ MdbHandle *mdb_sql_open(MdbSQL *sql, char *db_name)
#ifdef HAVE_WORDEXP
wordexp_t words;
int need_free_words = 0;
if (wordexp(db_name, &words, 0)==0) {
if (words.we_wordc>0)
db_namep = words.we_wordv[0];
switch (wordexp(db_name, &words, 0))
{
case 0:
if (words.we_wordc>0)
{
db_namep = words.we_wordv[0];
}
need_free_words = 1;
break;
case WRDE_NOSPACE:
// If the error was WRDE_NOSPACE, then perhaps part of the result was allocated.
need_free_words = 1;
break;
default:
// Some other error
need_free_words = 0;
break;
}
#endif
sql->mdb = mdb_open(db_namep, MDB_NOFLAGS);
@@ -208,7 +223,10 @@ MdbHandle *mdb_sql_open(MdbSQL *sql, char *db_name)
}
#ifdef HAVE_WORDEXP
wordfree(&words);
if ( need_free_words )
{
wordfree(&words);
}
#endif
return sql->mdb;
@@ -502,12 +520,23 @@ int mdb_sql_add_column(MdbSQL *sql, char *column_name)
sql->num_columns++;
return 0;
}
int mdb_sql_add_limit(MdbSQL *sql, char *limit)
int mdb_sql_add_limit(MdbSQL *sql, char *limit, int percent)
{
sql->limit = atoi(limit);
sql->limit_percent = percent;
if (sql->limit_percent && (sql->limit < 0 || sql->limit > 100)) {
return 1;
}
return 0;
}
int mdb_sql_get_limit(MdbSQL *sql)
{
return sql->limit;
}
int mdb_sql_add_function1(MdbSQL *sql, char *func_name, char *arg1)
{
fprintf(stderr, "calling function %s with %s", func_name, arg1);
@@ -833,6 +862,13 @@ int found = 0;
sql->cur_table = table;
mdb_index_scan_init(mdb, table);
/* We know how many rows there are, so convert limit percentage
* to an row count */
if (sql->limit != -1 && sql->limit_percent) {
sql->limit = (int)((double)table->num_rows / 100 * sql->limit);
sql->limit_percent = 0;
}
}
void

View File

@@ -62,7 +62,7 @@ typedef struct sql_context
%token <name> IDENT NAME PATH STRING NUMBER
%token SELECT FROM WHERE CONNECT DISCONNECT TO LIST TABLES AND OR NOT LIMIT COUNT STRPTIME
%token DESCRIBE TABLE
%token DESCRIBE TABLE TOP PERCENT
%token LTEQ GTEQ LIKE IS NUL
%type <name> database
@@ -91,7 +91,7 @@ stmt:
;
query:
SELECT column_list FROM table where_clause limit_clause {
SELECT top_clause column_list FROM table where_clause limit_clause {
mdb_sql_select(parser_ctx->mdb);
}
| CONNECT TO database {
@@ -108,6 +108,17 @@ query:
}
;
top_clause:
/* empty */
| TOP NUMBER { mdb_sql_add_limit(parser_ctx->mdb, $2, 0); free($2); }
| TOP NUMBER PERCENT {
if (mdb_sql_add_limit(parser_ctx->mdb, $2, 1)) {
yyerror(NULL, parser_ctx, "Percent values must be between 0 and 100");
}
free($2);
}
;
where_clause:
/* empty */
| WHERE sarg_list
@@ -115,7 +126,14 @@ where_clause:
limit_clause:
/* empty */
| LIMIT NUMBER { mdb_sql_add_limit(parser_ctx->mdb, $2); free($2); }
| LIMIT NUMBER {
if (mdb_sql_get_limit(parser_ctx->mdb) != -1) {
yyerror(NULL, parser_ctx, "Can not have TOP and LIMIT clauses");
} else {
mdb_sql_add_limit(parser_ctx->mdb, $2, 0);
}
free($2);
}
;
sarg_list: