diff --git a/ChangeLog b/ChangeLog index 5ab82ab..bfc4e2c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Fri Feb 6 18:08:59 EST 2004 Brian Bruns + + * include/mdbtools.h: + * src/sql/mdbsql.c: + * src/libmdb/sargs.c: change signature of mdb_test_sarg to test for nulls + * src/mdbsql/lexer.l: add NULL token + * src/libmdb/data.c: memo patch from + * src/libmdb/file.c: patch #889589 + * src/libmdb/write.c: patch #889586 + Thu Feb 5 20:45:00 EST 2004 Brian Bruns * HACKING: added information on indexes diff --git a/include/mdbtools.h b/include/mdbtools.h index d94a1ef..c000dcd 100644 --- a/include/mdbtools.h +++ b/include/mdbtools.h @@ -428,7 +428,7 @@ extern char *mdb_get_relationships(MdbHandle *mdb); /* sargs.c */ extern int mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields); -extern int mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, void *buf, int len); +extern int mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, MdbField *field); 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_add_sarg_by_name(MdbTableDef *table, char *colname, MdbSarg *in_sarg); diff --git a/src/libmdb/data.c b/src/libmdb/data.c index db14951..0aa5a74 100644 --- a/src/libmdb/data.c +++ b/src/libmdb/data.c @@ -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; diff --git a/src/libmdb/file.c b/src/libmdb/file.c index 1ebc097..867a577 100644 --- a/src/libmdb/file.c +++ b/src/libmdb/file.c @@ -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; diff --git a/src/libmdb/index.c b/src/libmdb/index.c index 3c353ac..1b6ec81 100644 --- a/src/libmdb/index.c +++ b/src/libmdb/index.c @@ -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; } diff --git a/src/libmdb/sargs.c b/src/libmdb/sargs.c index 00adc6e..5fb93e6 100644 --- a/src/libmdb/sargs.c +++ b/src/libmdb/sargs.c @@ -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) { diff --git a/src/libmdb/write.c b/src/libmdb/write.c index fadfb8d..17c7650 100644 --- a/src/libmdb/write.c +++ b/src/libmdb/write.c @@ -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;jnum_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= 97 ) + if ( yy_current_state >= 100 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 289 ); + while ( yy_base[yy_current_state] != 297 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -796,65 +798,70 @@ YY_RULE_SETUP case 15: YY_RULE_SETUP #line 41 "lexer.l" -{ return LTEQ; } +{ return NULL; } YY_BREAK case 16: YY_RULE_SETUP #line 42 "lexer.l" -{ return GTEQ; } +{ return LTEQ; } YY_BREAK case 17: YY_RULE_SETUP #line 43 "lexer.l" -{ return LIKE; } +{ return GTEQ; } YY_BREAK case 18: YY_RULE_SETUP #line 44 "lexer.l" -; +{ return LIKE; } YY_BREAK case 19: YY_RULE_SETUP #line 45 "lexer.l" +; + YY_BREAK +case 20: +YY_RULE_SETUP +#line 46 "lexer.l" { yylval.name = strdup(&yytext[1]); yylval.name[strlen(yylval.name)-1]='\0'; return IDENT; } YY_BREAK -case 20: -YY_RULE_SETUP -#line 50 "lexer.l" -{ yylval.name = strdup(yytext); return NAME; } - YY_BREAK case 21: YY_RULE_SETUP -#line 52 "lexer.l" -{ yylval.name = strdup(yytext); return STRING; } +#line 51 "lexer.l" +{ yylval.name = strdup(yytext); return NAME; } YY_BREAK case 22: YY_RULE_SETUP #line 53 "lexer.l" +{ yylval.name = strdup(yytext); return STRING; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 54 "lexer.l" { yylval.name = strdup(yytext); return NUMBER; } YY_BREAK -case 23: -YY_RULE_SETUP -#line 56 "lexer.l" -{ yylval.name = strdup(yytext); return PATH; } - YY_BREAK case 24: YY_RULE_SETUP #line 57 "lexer.l" -{ return yytext[0]; } +{ yylval.name = strdup(yytext); return PATH; } YY_BREAK case 25: YY_RULE_SETUP #line 58 "lexer.l" +{ return yytext[0]; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 59 "lexer.l" ECHO; YY_BREAK -#line 858 "lexer.c" +#line 865 "lexer.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1146,7 +1153,7 @@ static yy_state_type yy_get_previous_state() while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 97 ) + if ( yy_current_state >= 100 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1181,11 +1188,11 @@ yy_state_type yy_current_state; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 97 ) + if ( yy_current_state >= 100 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 96); + yy_is_jam = (yy_current_state == 99); return yy_is_jam ? 0 : yy_current_state; } @@ -1735,7 +1742,7 @@ int main() return 0; } #endif -#line 58 "lexer.l" +#line 59 "lexer.l" int yywrap() diff --git a/src/sql/lexer.l b/src/sql/lexer.l index 18e5c58..b08a2de 100644 --- a/src/sql/lexer.l +++ b/src/sql/lexer.l @@ -38,6 +38,7 @@ and { return AND; } or { return OR; } not { return NOT; } is { return IS; } +null { return NULL; } (<=) { return LTEQ; } (>=) { return GTEQ; } like { return LIKE; } diff --git a/src/sql/mdbsql.c b/src/sql/mdbsql.c index 3a42c70..d27573c 100644 --- a/src/sql/mdbsql.c +++ b/src/sql/mdbsql.c @@ -311,6 +311,13 @@ mdb_sql_add_sarg(MdbSQL *sql, char *col_name, int op, char *constant) 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; + } /* FIX ME -- we should probably just be storing the ascii value until the ** column definition can be checked for validity */