From 1c8ca97fd61de53449de644f94bf5bdaf03b16e3 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Oct 2002 22:08:34 +0200 Subject: A fix for bug when comparing a datetime column with timestamp values with BETWEEN clause --- sql/item_cmpfunc.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql/item_cmpfunc.cc') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 79d695eea1e..42cd0a2ee4f 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -360,6 +360,7 @@ void Item_func_between::fix_length_and_dec() if (args[0]->type() == FIELD_ITEM) { Field *field=((Item_field*) args[0])->field; + cmp_type=field->cmp_type(); if (field->store_for_compare()) { if (convert_constant_item(field,&args[1])) -- cgit v1.2.1 From 841fa6f694a5d998b94a6cd4508fe7d26e8407f3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Nov 2002 22:45:42 +0200 Subject: Removed wrong patch to fix DATE BETWEEN TIMESTAMP1 AND TIMESTAMP2 Some simple optimizations Docs/manual.texi: Updted how binary log works mysql-test/mysql-test-run.sh: Added usage of --port to mysqltest mysql-test/r/func_test.result: Moved test of datetime comparison to func_time mysql-test/r/func_time.result: New test mysql-test/t/func_test.test: Moved test of datetime comparison to func_time mysql-test/t/func_time.test: Test of DATE BETWEEN TIMESTAMPS sql/field.h: Removed wrong patch sql/item_cmpfunc.cc: Removed wrong patch (Need to be fixed by taking into account all arguments to between) sql/lock.cc: Removed call to current_thd sql/set_var.cc: Don't show 'socket' variable if sockets are not used sql/sql_base.cc: Simple optimisation --- sql/item_cmpfunc.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'sql/item_cmpfunc.cc') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 42cd0a2ee4f..79d695eea1e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -360,7 +360,6 @@ void Item_func_between::fix_length_and_dec() if (args[0]->type() == FIELD_ITEM) { Field *field=((Item_field*) args[0])->field; - cmp_type=field->cmp_type(); if (field->store_for_compare()) { if (convert_constant_item(field,&args[1])) -- cgit v1.2.1 From c5d4041347524e1e4e415db15071fb7dd6aa79ac Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2002 16:21:41 +0100 Subject: BETWEEN fixed myisam/ft_nlq_search.c: cleanup mysql-test/r/func_time.result: updated --- sql/item_cmpfunc.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'sql/item_cmpfunc.cc') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 79d695eea1e..bf3c0af1ea6 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -350,13 +350,19 @@ void Item_func_between::fix_length_and_dec() */ if (!args[0] || !args[1] || !args[2]) return; - cmp_type=args[0]->result_type(); - if (args[0]->binary) + cmp_type=item_cmp_type(args[0]->result_type(), + item_cmp_type(args[1]->result_type(), + args[2]->result_type())); + if (args[0]->binary | args[1]->binary | args[2]->binary) string_compare=stringcmp; else string_compare=sortcmp; - // Make a special case of compare with fields to get nicer DATE comparisons + /* + Make a special case of compare with date/time and longlong fields. + They are compared as integers, so for const item this time-consuming + conversion can be done only once, not for every single comparison + */ if (args[0]->type() == FIELD_ITEM) { Field *field=((Item_field*) args[0])->field; -- cgit v1.2.1 From b3a8b8bd193dc9b22b8d5bc28c894c49f6153647 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 9 Nov 2002 09:51:03 +0200 Subject: Fixed bug in MAX() optimization when used with JOIN and ON expressions sql/item_cmpfunc.cc: Create an AND expression from two expressions sql/item_cmpfunc.h: Create an AND expression from two expressions --- sql/item_cmpfunc.cc | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'sql/item_cmpfunc.cc') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index bf3c0af1ea6..3cd55934950 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1236,6 +1236,45 @@ longlong Item_cond_or::val_int() return 0; } +/* + Create an AND expression from two expressions + + SYNOPSIS + and_expressions() + a expression or NULL + b expression. + org_item Don't modify a if a == *org_item + If a == NULL, org_item is set to point at b, + to ensure that future calls will not modify b. + + NOTES + This will not modify item pointed to by org_item or b + The idea is that one can call this in a loop and create and + 'and' over all items without modifying any of the original items. + + RETURN + NULL Error + Item +*/ + +Item *and_expressions(Item *a, Item *b, Item **org_item) +{ + if (!a) + return (*org_item= (Item*) b); + if (a == *org_item) + { + Item_cond *res; + if ((res= new Item_cond_and(a, (Item*) b))) + res->used_tables_cache= a->used_tables() | b->used_tables(); + return res; + } + if (((Item_cond_and*) a)->add((Item*) b)) + return 0; + ((Item_cond_and*) a)->used_tables_cache|= b->used_tables(); + return a; +} + + longlong Item_func_isnull::val_int() { /* -- cgit v1.2.1 From 3165440cdec9d1270a2101973cb75e67e334dc5c Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Nov 2002 15:57:35 +0200 Subject: Fixed that NULL and 0 returns 0 instead of NULL This is coded to not cause a speed impact on top level AND expressions where we don't care if an AND expression returns 0 or NULL mysql-test/r/bdb.result: Fix results after serges last patch mysql-test/r/innodb.result: Fix results after serges last patch mysql-test/r/null.result: Update for new AND handling of NULL scripts/mysqld_safe.sh: Fix 'isroot' test to work even if user is not root sql/item.h: Fixed that NULL and 0 returns 0 instead of NULL sql/item_cmpfunc.cc: Fixed that NULL and 0 returns 0 instead of NULL sql/item_cmpfunc.h: Fixed that NULL and 0 returns 0 instead of NULL sql/sql_base.cc: Fixed that NULL and 0 returns 0 instead of NULL sql/sql_parse.cc: Fixed that NULL and 0 returns 0 instead of NULL sql/sql_select.cc: Fixed that NULL and 0 returns 0 instead of NULL sql/sql_yacc.yy: Fixed that NULL and 0 returns 0 instead of NULL --- sql/item_cmpfunc.cc | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) (limited to 'sql/item_cmpfunc.cc') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3cd55934950..93e24525d06 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -26,8 +26,8 @@ /* Test functions - These returns 0LL if false and 1LL if true and null if some arg is null - 'AND' and 'OR' never return null + Most of these returns 0LL if false and 1LL if true and + NULL if some arg is NULL. */ longlong Item_func_not::val_int() @@ -533,6 +533,7 @@ Item_func_if::fix_length_and_dec() else cached_result_type=arg1_type; // Should be INT_RESULT } + args[0]->top_level_item(); } @@ -1128,6 +1129,8 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables) const_item_cache&=item->const_item(); if (item->maybe_null) maybe_null=1; + if (abort_on_null) + item->top_level_item(); } if (thd) thd->cond_count+=list.elements; @@ -1196,28 +1199,41 @@ void Item_cond::print(String *str) str->append(')'); } +/* + Evalution of AND(expr, expr, expr ...) + + NOTES: + abort_if_null is set for AND expressions for which we don't care if the + result is NULL or 0. This is set for: + - WHERE clause + - HAVING clause + - IF(expression) + + RETURN VALUES + 1 If all expressions are true + 0 If all expressions are false or if we find a NULL expression and + 'abort_on_null' is set. + NULL if all expression are either 1 or NULL +*/ + longlong Item_cond_and::val_int() { List_iterator_fast li(list); Item *item; + null_value= 0; while ((item=li++)) { if (item->val_int() == 0) { - /* - TODO: In case of NULL, ANSI would require us to continue evaluation - until we get a FALSE value or run out of values; This would - require a lot of unnecessary evaluation, which we skip for now - */ - null_value=item->null_value; - return 0; + if (abort_on_null || !(null_value= item->null_value)) + return 0; // return FALSE } } - null_value=0; - return 1; + return null_value ? 0 : 1; } + longlong Item_cond_or::val_int() { List_iterator_fast li(list); @@ -1260,15 +1276,15 @@ longlong Item_cond_or::val_int() Item *and_expressions(Item *a, Item *b, Item **org_item) { if (!a) - return (*org_item= (Item*) b); + return (*org_item= b); if (a == *org_item) { Item_cond *res; - if ((res= new Item_cond_and(a, (Item*) b))) + if ((res= new Item_cond_and(a, b))) res->used_tables_cache= a->used_tables() | b->used_tables(); return res; } - if (((Item_cond_and*) a)->add((Item*) b)) + if (((Item_cond_and*) a)->add(b)) return 0; ((Item_cond_and*) a)->used_tables_cache|= b->used_tables(); return a; -- cgit v1.2.1 From e1c1abd0e189e4581b9a22aed923df37e535e89b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Nov 2002 12:42:42 +0200 Subject: Extended WEEK() to be able to handle ISO weeks. unlink socket file if mysqld dies on startup Some optimization of AND expressions mysql-test/r/func_time.result: Update for new week() handling mysql-test/t/func_time.test: Update for new week() handling sql/item_cmpfunc.cc: Optimization of IF( and-expression,,) sql/item_cmpfunc.h: Optimization of AND expressions sql/item_timefunc.cc: Extended WEEK() to be able to handle ISO weeks. sql/mysqld.cc: unlink socket file if mysqld dies on startup sql/sql_base.cc: Fixed problem with SIGHUP and INSERT DELAYED tests/Makefile.am: Added missing myisam-big-rows.tst file to source distribution --- sql/item_cmpfunc.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'sql/item_cmpfunc.cc') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 93e24525d06..ee587289168 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -533,7 +533,6 @@ Item_func_if::fix_length_and_dec() else cached_result_type=arg1_type; // Should be INT_RESULT } - args[0]->top_level_item(); } @@ -1122,6 +1121,8 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables) #endif item= *li.ref(); // new current item } + if (abort_on_null) + item->top_level_item(); if (item->fix_fields(thd,tables)) return 1; /* purecov: inspected */ used_tables_cache|=item->used_tables(); @@ -1129,8 +1130,6 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables) const_item_cache&=item->const_item(); if (item->maybe_null) maybe_null=1; - if (abort_on_null) - item->top_level_item(); } if (thd) thd->cond_count+=list.elements; -- cgit v1.2.1