mirror of
https://github.com/mdbtools/mdbtools.git
synced 2026-03-10 00:20:54 +08:00
add IS NULL/IS NOT NULL support, patches
This commit is contained in:
@@ -392,7 +392,7 @@ int mdb_read_row(MdbTableDef *table, int row)
|
||||
} else {
|
||||
len=mdb->pg_buf[col_ptr - var_cols_found ] - col_start;
|
||||
}
|
||||
if (len<0)
|
||||
while (len<0)
|
||||
len+=256;
|
||||
}
|
||||
|
||||
@@ -471,7 +471,7 @@ mdb_read_next_dpg_by_map1(MdbTableDef *table)
|
||||
* offset gives us a page offset into the bitmap (must be converted
|
||||
* to bytes and bits).
|
||||
*/
|
||||
pgnum = table->cur_phys_pg + 1;
|
||||
pgnum = table->cur_phys_pg + 1;
|
||||
map_ind = pgnum / ((mdb->fmt->pg_size - 4) * 8);
|
||||
offset = pgnum % ((mdb->fmt->pg_size - 4) * 8);
|
||||
bit_offset = offset % 8;
|
||||
|
||||
@@ -356,7 +356,7 @@ mdb_get_double(unsigned char *buf, int offset)
|
||||
double d;
|
||||
|
||||
|
||||
memcpy(&d, &buf, 8);
|
||||
memcpy(&d, &buf[offset], 8);
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
d2 = d;
|
||||
|
||||
@@ -212,7 +212,7 @@ mdb_index_cache_sarg(MdbColumn *col, MdbSarg *sarg, MdbSarg *idx_sarg)
|
||||
//cache_int = sarg->value.i * -1;
|
||||
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]);
|
||||
printf("int %08x %02x %02x %02x %02x\n", sarg->value.i, c[0], c[1], c[2], c[3]);
|
||||
break;
|
||||
|
||||
case MDB_INT:
|
||||
@@ -259,6 +259,7 @@ mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, int offset, int len)
|
||||
MdbTableDef *table = idx->table;
|
||||
MdbSarg *idx_sarg;
|
||||
MdbSarg *sarg;
|
||||
MdbField field;
|
||||
MdbSargNode node;
|
||||
int c_offset = 0, c_len;
|
||||
|
||||
@@ -298,7 +299,10 @@ mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, int offset, int len)
|
||||
/* XXX - kludge */
|
||||
node.op = sarg->op;
|
||||
node.value = sarg->value;
|
||||
if (!mdb_test_sarg(mdb, col, &node, &mdb->pg_buf[offset + c_offset], c_len)) {
|
||||
field.value = &mdb->pg_buf[offset + c_offset];
|
||||
field.siz = c_len;
|
||||
field.is_null = FALSE;
|
||||
if (!mdb_test_sarg(mdb, col, &node, &field)) {
|
||||
/* sarg didn't match, no sense going on */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -128,27 +128,37 @@ mdb_find_indexable_sargs(MdbSargNode *node, gpointer data)
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, void *buf, int len)
|
||||
mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, MdbField *field)
|
||||
{
|
||||
char tmpbuf[256];
|
||||
int lastchar;
|
||||
|
||||
if (node->op == MDB_ISNULL) {
|
||||
if (field->is_null) return 0;
|
||||
else return 1;
|
||||
} else if (node->op == MDB_NOTNULL) {
|
||||
if (field->is_null) return 1;
|
||||
else return 0;
|
||||
}
|
||||
switch (col->col_type) {
|
||||
case MDB_BOOL:
|
||||
return mdb_test_int(node, field->is_null);
|
||||
break;
|
||||
case MDB_BYTE:
|
||||
return mdb_test_int(node, (gint32)((char *)buf)[0]);
|
||||
return mdb_test_int(node, (gint32)((char *)field->value)[0]);
|
||||
break;
|
||||
case MDB_INT:
|
||||
return mdb_test_int(node, (gint32)mdb_get_int16(buf, 0));
|
||||
return mdb_test_int(node, (gint32)mdb_get_int16(field->value, 0));
|
||||
break;
|
||||
case MDB_LONGINT:
|
||||
return mdb_test_int(node, (gint32)mdb_get_int32(buf, 0));
|
||||
return mdb_test_int(node, (gint32)mdb_get_int32(field->value, 0));
|
||||
break;
|
||||
case MDB_TEXT:
|
||||
if (IS_JET4(mdb)) {
|
||||
mdb_unicode2ascii(mdb, buf, 0, len, tmpbuf);
|
||||
mdb_unicode2ascii(mdb, field->value, 0, field->siz, tmpbuf);
|
||||
} else {
|
||||
strncpy(tmpbuf, buf,255);
|
||||
lastchar = len > 255 ? 255 : len;
|
||||
strncpy(tmpbuf, field->value, 255);
|
||||
lastchar = field->siz > 255 ? 255 : field->siz;
|
||||
tmpbuf[lastchar]='\0';
|
||||
}
|
||||
return mdb_test_string(node, tmpbuf);
|
||||
@@ -178,10 +188,7 @@ mdb_test_sarg_node(MdbHandle *mdb, MdbSargNode *node, MdbField *fields, int num_
|
||||
if (mdb_is_relational_op(node->op)) {
|
||||
col = node->col;
|
||||
elem = mdb_find_field(col->col_num, fields, num_fields);
|
||||
if (!mdb_test_sarg(mdb, col,
|
||||
node,
|
||||
fields[elem].value,
|
||||
fields[elem].siz))
|
||||
if (!mdb_test_sarg(mdb, col, node, &fields[elem]))
|
||||
return 0;
|
||||
} else { /* logical op */
|
||||
switch (node->op) {
|
||||
|
||||
@@ -195,6 +195,7 @@ int col_start, next_col;
|
||||
unsigned char *nullmask;
|
||||
int bitmask_sz;
|
||||
int byte_num, bit_num;
|
||||
int num_of_jumps = 0, jumps_used = 0;
|
||||
int eod, len; /* end of data */
|
||||
|
||||
num_cols = mdb->pg_buf[row_start];
|
||||
@@ -225,6 +226,7 @@ int eod, len; /* end of data */
|
||||
bit_num = i % 8;
|
||||
/* logic on nulls is reverse, 1 is not null, 0 is null */
|
||||
fields[i].is_null = nullmask[byte_num] & 1 << bit_num ? 0 : 1;
|
||||
//printf("col %d is %s\n", i, fields[i].is_null ? "null" : "not null");
|
||||
}
|
||||
|
||||
/* find the end of data pointer */
|
||||
@@ -248,9 +250,37 @@ int eod, len; /* end of data */
|
||||
col_start += col->col_size;
|
||||
}
|
||||
}
|
||||
|
||||
//fprintf(stderr, "col_start: %d\n", col_start);
|
||||
/* if fixed columns add up to more than 256, we need a jump */
|
||||
int col_ptr = row_end - bitmask_sz - num_of_jumps - 1;
|
||||
if (col_start >= 256) {
|
||||
num_of_jumps++;
|
||||
jumps_used++;
|
||||
row_start = row_start + col_start - (col_start % 256);
|
||||
}
|
||||
col_start = row_start;
|
||||
|
||||
while (col_start+256 < row_end-bitmask_sz-1-var_cols-num_of_jumps){
|
||||
col_start += 256;
|
||||
num_of_jumps++;
|
||||
}
|
||||
if (mdb->pg_buf[col_ptr]==0xFF) {
|
||||
col_ptr--;
|
||||
}
|
||||
col_start = mdb->pg_buf[col_ptr];
|
||||
|
||||
for (j=0;j<table->num_cols;j++) {
|
||||
col = g_ptr_array_index(table->columns,j);
|
||||
if (!mdb_is_fixed_col(col) && ++var_cols_found <= var_cols) {
|
||||
|
||||
if (var_cols_found == mdb->pg_buf[row_end-bitmask_sz-jumps_used-1] &&
|
||||
jumps_used < num_of_jumps) {
|
||||
row_start += 256;
|
||||
col_start -= 256;
|
||||
jumps_used++;
|
||||
}
|
||||
|
||||
if (var_cols_found==var_cols) {
|
||||
len=eod - col_start;
|
||||
//printf("len = %d eod %d col_start %d\n",len, eod, col_start);
|
||||
@@ -324,7 +354,7 @@ int i;
|
||||
byte = 0;
|
||||
bit = 0;
|
||||
for (i=0;i<num_fields;i++) {
|
||||
/* column is null is bit is clear (0) */
|
||||
/* column is null if bit is clear (0) */
|
||||
if (!fields[i].is_null) {
|
||||
byte |= 1 << bit;
|
||||
//printf("%d %d %d %d\n", i, bit, 1 << bit, byte);
|
||||
|
||||
Reference in New Issue
Block a user