mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-09-20 19:27:53 +08:00
fix for like clause in jet4
This commit is contained in:
@@ -377,6 +377,7 @@ extern int mdb_find_end_of_row(MdbHandle *mdb, int row);
|
|||||||
extern int mdb_col_fixed_size(MdbColumn *col);
|
extern int mdb_col_fixed_size(MdbColumn *col);
|
||||||
extern int mdb_col_disp_size(MdbColumn *col);
|
extern int mdb_col_disp_size(MdbColumn *col);
|
||||||
extern void mdb_bind_len(MdbTableDef *table, int col_num, int *len_ptr);
|
extern void mdb_bind_len(MdbTableDef *table, int col_num, int *len_ptr);
|
||||||
|
extern int mdb_unicode2ascii(MdbHandle *mdb, unsigned char *buf, int offset, int len, char *dest);
|
||||||
|
|
||||||
/* dump.c */
|
/* dump.c */
|
||||||
extern void buffer_dump(const unsigned char* buf, int start, int end);
|
extern void buffer_dump(const unsigned char* buf, int start, int end);
|
||||||
@@ -390,7 +391,7 @@ extern char *mdb_get_relationships(MdbHandle *mdb);
|
|||||||
|
|
||||||
/* sargs.c */
|
/* sargs.c */
|
||||||
extern int mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields);
|
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 int mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, void *buf, int len);
|
||||||
extern void mdb_sql_walk_tree(MdbSargNode *node, MdbSargTreeFunc func, gpointer data);
|
extern void mdb_sql_walk_tree(MdbSargNode *node, MdbSargTreeFunc func, gpointer data);
|
||||||
extern int mdb_find_indexable_sargs(MdbSargNode *node, gpointer data);
|
extern int mdb_find_indexable_sargs(MdbSargNode *node, gpointer data);
|
||||||
|
|
||||||
|
@@ -658,7 +658,6 @@ guint16 row_start, row_stop;
|
|||||||
guint8 memo_row;
|
guint8 memo_row;
|
||||||
guint32 lval_pg;
|
guint32 lval_pg;
|
||||||
guint16 len;
|
guint16 len;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (size<MDB_MEMO_OVERHEAD) {
|
if (size<MDB_MEMO_OVERHEAD) {
|
||||||
return "";
|
return "";
|
||||||
@@ -708,6 +707,8 @@ int i;
|
|||||||
strncpy(text, &mdb->pg_buf[row_start], len);
|
strncpy(text, &mdb->pg_buf[row_start], len);
|
||||||
text[len]='\0';
|
text[len]='\0';
|
||||||
} else {
|
} else {
|
||||||
|
mdb_unicode2ascii(mdb, mdb->pg_buf, row_start, len, text);
|
||||||
|
#if 0
|
||||||
if (mdb->pg_buf[row_start]==0xff &&
|
if (mdb->pg_buf[row_start]==0xff &&
|
||||||
mdb->pg_buf[row_start+1]==0xfe) {
|
mdb->pg_buf[row_start+1]==0xfe) {
|
||||||
strncpy(text, &mdb->pg_buf[row_start+2], len-2);
|
strncpy(text, &mdb->pg_buf[row_start+2], len-2);
|
||||||
@@ -718,6 +719,7 @@ int i;
|
|||||||
text[i/2] = mdb->pg_buf[row_start + i];
|
text[i/2] = mdb->pg_buf[row_start + i];
|
||||||
text[len/2]='\0';
|
text[len/2]='\0';
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* make sure to swap page back */
|
/* make sure to swap page back */
|
||||||
mdb_swap_pgbuf(mdb);
|
mdb_swap_pgbuf(mdb);
|
||||||
@@ -951,3 +953,20 @@ int mdb_col_fixed_size(MdbColumn *col)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int
|
||||||
|
mdb_unicode2ascii(MdbHandle *mdb, unsigned char *buf, int offset, int len, char *dest)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (buf[offset]==0xff &&
|
||||||
|
buf[offset+1]==0xfe) {
|
||||||
|
strncpy(dest, &buf[offset+2], len-2);
|
||||||
|
dest[len-2]='\0';
|
||||||
|
} else {
|
||||||
|
/* convert unicode to ascii, rather sloppily */
|
||||||
|
for (i=0;i<len;i+=2)
|
||||||
|
dest[i/2] = buf[offset + i];
|
||||||
|
dest[len/2]='\0';
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
@@ -253,7 +253,7 @@ mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, int offset, int len)
|
|||||||
/* XXX - kludge */
|
/* XXX - kludge */
|
||||||
node.op = sarg->op;
|
node.op = sarg->op;
|
||||||
node.value = sarg->value;
|
node.value = sarg->value;
|
||||||
if (!mdb_test_sarg(col, &node, &mdb->pg_buf[offset + c_offset], c_len)) {
|
if (!mdb_test_sarg(mdb, col, &node, &mdb->pg_buf[offset + c_offset], c_len)) {
|
||||||
/* sarg didn't match, no sense going on */
|
/* sarg didn't match, no sense going on */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -579,7 +579,7 @@ mdb_index_scan_init(MdbHandle *mdb, MdbTableDef *table)
|
|||||||
int use_index=0;
|
int use_index=0;
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
if (s=getenv("MDBOPTS")) {
|
if ((s=getenv("MDBOPTS"))) {
|
||||||
if (!strcmp(s, "use_index")) use_index++;
|
if (!strcmp(s, "use_index")) use_index++;
|
||||||
}
|
}
|
||||||
if (use_index && mdb_choose_index(table, &i) == MDB_INDEX_SCAN) {
|
if (use_index && mdb_choose_index(table, &i) == MDB_INDEX_SCAN) {
|
||||||
|
@@ -20,10 +20,15 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
//#define MDB_DEBUG_LIKE 1
|
||||||
|
|
||||||
int mdb_like_cmp(char *s, char *r)
|
int mdb_like_cmp(char *s, char *r)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
|
#if MDB_DEBUG_LIKE
|
||||||
|
printf("comparing %s and %s\n", s, r);
|
||||||
|
#endif
|
||||||
switch (r[0]) {
|
switch (r[0]) {
|
||||||
case '\0':
|
case '\0':
|
||||||
if (s[0]=='\0') {
|
if (s[0]=='\0') {
|
||||||
@@ -51,7 +56,13 @@ int i, ret;
|
|||||||
if (strncmp(s,r,i)) {
|
if (strncmp(s,r,i)) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
#if MDB_DEBUG_LIKE
|
||||||
|
printf("at pos %d comparing %s and %s\n", i, &s[i], &r[i]);
|
||||||
|
#endif
|
||||||
ret = mdb_like_cmp(&s[i],&r[i]);
|
ret = mdb_like_cmp(&s[i],&r[i]);
|
||||||
|
#if MDB_DEBUG_LIKE
|
||||||
|
printf("returning %d (%s and %s)\n", ret, &s[i], &r[i]);
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -113,7 +113,7 @@ mdb_find_indexable_sargs(MdbSargNode *node, gpointer data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int
|
int
|
||||||
mdb_test_sarg(MdbColumn *col, MdbSargNode *node, void *buf, int len)
|
mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, void *buf, int len)
|
||||||
{
|
{
|
||||||
char tmpbuf[256];
|
char tmpbuf[256];
|
||||||
int lastchar;
|
int lastchar;
|
||||||
@@ -129,9 +129,13 @@ int lastchar;
|
|||||||
return mdb_test_int(node, _mdb_get_int32(buf, 0));
|
return mdb_test_int(node, _mdb_get_int32(buf, 0));
|
||||||
break;
|
break;
|
||||||
case MDB_TEXT:
|
case MDB_TEXT:
|
||||||
|
if (IS_JET4(mdb)) {
|
||||||
|
mdb_unicode2ascii(mdb, buf, 0, len, tmpbuf);
|
||||||
|
} else {
|
||||||
strncpy(tmpbuf, buf,255);
|
strncpy(tmpbuf, buf,255);
|
||||||
lastchar = len > 255 ? 255 : len;
|
lastchar = len > 255 ? 255 : len;
|
||||||
tmpbuf[lastchar]='\0';
|
tmpbuf[lastchar]='\0';
|
||||||
|
}
|
||||||
return mdb_test_string(node, tmpbuf);
|
return mdb_test_string(node, tmpbuf);
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Calling mdb_test_sarg on unknown type. Add code to mdb_test_sarg() for type %d\n",col->col_type);
|
fprintf(stderr, "Calling mdb_test_sarg on unknown type. Add code to mdb_test_sarg() for type %d\n",col->col_type);
|
||||||
@@ -149,7 +153,8 @@ mdb_find_field(int col_num, MdbField *fields, int num_fields)
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
mdb_test_sarg_node(MdbSargNode *node, MdbField *fields, int num_fields)
|
int
|
||||||
|
mdb_test_sarg_node(MdbHandle *mdb, MdbSargNode *node, MdbField *fields, int num_fields)
|
||||||
{
|
{
|
||||||
int elem;
|
int elem;
|
||||||
MdbColumn *col;
|
MdbColumn *col;
|
||||||
@@ -158,7 +163,7 @@ mdb_test_sarg_node(MdbSargNode *node, MdbField *fields, int num_fields)
|
|||||||
if (mdb_is_relational_op(node->op)) {
|
if (mdb_is_relational_op(node->op)) {
|
||||||
col = node->col;
|
col = node->col;
|
||||||
elem = mdb_find_field(col->col_num, fields, num_fields);
|
elem = mdb_find_field(col->col_num, fields, num_fields);
|
||||||
if (!mdb_test_sarg(col,
|
if (!mdb_test_sarg(mdb, col,
|
||||||
node,
|
node,
|
||||||
fields[elem].value,
|
fields[elem].value,
|
||||||
fields[elem].siz))
|
fields[elem].siz))
|
||||||
@@ -166,18 +171,18 @@ mdb_test_sarg_node(MdbSargNode *node, MdbField *fields, int num_fields)
|
|||||||
} else { /* logical op */
|
} else { /* logical op */
|
||||||
switch (node->op) {
|
switch (node->op) {
|
||||||
case MDB_NOT:
|
case MDB_NOT:
|
||||||
rc = mdb_test_sarg_node(node->left, fields, num_fields);
|
rc = mdb_test_sarg_node(mdb, node->left, fields, num_fields);
|
||||||
return !rc;
|
return !rc;
|
||||||
break;
|
break;
|
||||||
case MDB_AND:
|
case MDB_AND:
|
||||||
if (!mdb_test_sarg_node(node->left, fields, num_fields))
|
if (!mdb_test_sarg_node(mdb, node->left, fields, num_fields))
|
||||||
return 0;
|
return 0;
|
||||||
return mdb_test_sarg_node(node->right, fields, num_fields);
|
return mdb_test_sarg_node(mdb, node->right, fields, num_fields);
|
||||||
break;
|
break;
|
||||||
case MDB_OR:
|
case MDB_OR:
|
||||||
if (mdb_test_sarg_node(node->left, fields, num_fields))
|
if (mdb_test_sarg_node(mdb, node->left, fields, num_fields))
|
||||||
return 1;
|
return 1;
|
||||||
return mdb_test_sarg_node(node->right, fields, num_fields);
|
return mdb_test_sarg_node(mdb, node->right, fields, num_fields);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,13 +192,15 @@ int
|
|||||||
mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields)
|
mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields)
|
||||||
{
|
{
|
||||||
MdbSargNode *node;
|
MdbSargNode *node;
|
||||||
|
MdbCatalogEntry *entry = table->entry;
|
||||||
|
MdbHandle *mdb = entry->mdb;
|
||||||
|
|
||||||
node = table->sarg_tree;
|
node = table->sarg_tree;
|
||||||
|
|
||||||
/* there may not be a sarg tree */
|
/* there may not be a sarg tree */
|
||||||
if (!node) return 1;
|
if (!node) return 1;
|
||||||
|
|
||||||
return mdb_test_sarg_node(node, fields, num_fields);
|
return mdb_test_sarg_node(mdb, node, fields, num_fields);
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
int mdb_test_sargs(MdbHandle *mdb, MdbColumn *col, int offset, int len)
|
int mdb_test_sargs(MdbHandle *mdb, MdbColumn *col, int offset, int len)
|
||||||
|
Reference in New Issue
Block a user