Below is the list of changes that have just been committed into a local
5.1 repository of tkatchaounov. When tkatchaounov does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-12-06 16:29:07+02:00, timour@stripped +2 -0
Fix for BUG#32694 "NOT NULL table field in a subquery produces invalid results"
The problem was that when convert_constant_item is called for subqueries,
this happens when we already started executing the top-level query, and
the field argument of convert_constant_item pointed to a valid table row.
In turn convert_constant_item used the field buffer to compute the value
of its item argument. This copied the item's value into the field,
and made equalities with outer references always true.
The fix saves/restores the original field's value when it belongs to an
outer table.
BitKeeper/etc/ignore@stripped, 2007-12-06 16:29:04+02:00, timour@stripped +1 -0
Added ylwrap to the ignore list
sql/item_cmpfunc.cc@stripped, 2007-12-06 16:29:05+02:00, timour@stripped +40 -22
- Changed convert_constant_item() so that it doesn't destroy the contents
of its field argument when the field originates from table in an outer
query.
diff -Nrup a/BitKeeper/etc/ignore b/BitKeeper/etc/ignore
--- a/BitKeeper/etc/ignore 2007-11-20 12:35:39 +02:00
+++ b/BitKeeper/etc/ignore 2007-12-06 16:29:04 +02:00
@@ -3008,3 +3008,4 @@ win/vs71cache.txt
win/vs8cache.txt
zlib/*.ds?
zlib/*.vcproj
+ylwrap
diff -Nrup a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
--- a/sql/item_cmpfunc.cc 2007-11-18 14:54:44 +02:00
+++ b/sql/item_cmpfunc.cc 2007-12-06 16:29:05 +02:00
@@ -24,7 +24,8 @@
#include <m_ctype.h>
#include "sql_select.h"
-static bool convert_constant_item(THD *thd, Field *field, Item **item);
+static bool convert_constant_item(THD *thd, Item_field *field_item,
+ Item **item);
static Item_result item_store_type(Item_result a, Item *item,
my_bool unsigned_flag)
@@ -351,7 +352,7 @@ longlong Item_func_nop_all::val_int()
SYNOPSIS
convert_constant_item()
thd thread handle
- field item will be converted using the type of this field
+ field_item item will be converted using the type of this field
item [in/out] reference to the item to convert
DESCRIPTION
@@ -374,8 +375,10 @@ longlong Item_func_nop_all::val_int()
1 Item was replaced with an integer version of the item
*/
-static bool convert_constant_item(THD *thd, Field *field, Item **item)
+static bool convert_constant_item(THD *thd, Item_field *field_item,
+ Item **item)
{
+ Field *field= field_item->field;
int result= 0;
if (!(*item)->with_subselect && (*item)->const_item())
@@ -385,6 +388,7 @@ static bool convert_constant_item(THD *t
enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
my_bitmap_map *old_write_map;
my_bitmap_map *old_read_map;
+ ulonglong org_field_val; /* original field value if valid */
LINT_INIT(old_write_map);
LINT_INIT(old_read_map);
@@ -398,6 +402,14 @@ static bool convert_constant_item(THD *t
thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
MODE_INVALID_DATES;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
+
+ /*
+ Store the value of the field if it references an outer field because
+ the call to save_in_field below overrides that value.
+ */
+ if (field_item->depended_from)
+ org_field_val= field->val_int();
+
if (!(*item)->is_null() && !(*item)->save_in_field(field, 1))
{
Item *tmp= new Item_int_with_ref(field->val_int(), *item,
@@ -406,6 +418,14 @@ static bool convert_constant_item(THD *t
thd->change_item_tree(item, tmp);
result= 1; // Item was replaced
}
+ /* Restore the original field value. */
+ if (field_item->depended_from)
+ {
+ result= field->store(org_field_val, TRUE);
+ /* field->can_be_compared_as_longlong() should guarantee success. */
+ DBUG_ASSERT(!result);
+ }
+
thd->variables.sql_mode= orig_sql_mode;
thd->count_cuted_fields= orig_count_cuted_fields;
if (table)
@@ -462,15 +482,14 @@ void Item_bool_func2::fix_length_and_dec
thd= current_thd;
if (!thd->is_context_analysis_only())
{
- Item *arg_real_item= args[0]->real_item();
- if (arg_real_item->type() == FIELD_ITEM)
+ if (args[0]->real_item()->type() == FIELD_ITEM)
{
- Field *field=((Item_field*) arg_real_item)->field;
- if (field->can_be_compared_as_longlong() &&
- !(arg_real_item->is_datetime() &&
+ Item_field *field_item= (Item_field*) (args[0]->real_item());
+ if (field_item->field->can_be_compared_as_longlong() &&
+ !(field_item->is_datetime() &&
args[1]->result_type() == STRING_RESULT))
{
- if (convert_constant_item(thd, field,&args[1]))
+ if (convert_constant_item(thd, field_item, &args[1]))
{
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
@@ -479,15 +498,14 @@ void Item_bool_func2::fix_length_and_dec
}
}
}
- arg_real_item= args[1]->real_item();
- if (arg_real_item->type() == FIELD_ITEM)
+ if (args[1]->real_item()->type() == FIELD_ITEM)
{
- Field *field=((Item_field*) arg_real_item)->field;
- if (field->can_be_compared_as_longlong() &&
- !(arg_real_item->is_datetime() &&
+ Item_field *field_item= (Item_field*) (args[1]->real_item());
+ if (field_item->field->can_be_compared_as_longlong() &&
+ !(field_item->is_datetime() &&
args[0]->result_type() == STRING_RESULT))
{
- if (convert_constant_item(thd, field,&args[0]))
+ if (convert_constant_item(thd, field_item, &args[0]))
{
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
@@ -1943,16 +1961,16 @@ void Item_func_between::fix_length_and_d
thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
thd->lex->sql_command != SQLCOM_SHOW_CREATE)
{
- Field *field=((Item_field*) (args[0]->real_item()))->field;
- if (field->can_be_compared_as_longlong())
+ Item_field *field_item= (Item_field*) (args[0]->real_item());
+ if (field_item->field->can_be_compared_as_longlong())
{
/*
The following can't be recoded with || as convert_constant_item
changes the argument
*/
- if (convert_constant_item(thd, field,&args[1]))
+ if (convert_constant_item(thd, field_item, &args[1]))
cmp_type=INT_RESULT; // Works for all types.
- if (convert_constant_item(thd, field,&args[2]))
+ if (convert_constant_item(thd, field_item, &args[2]))
cmp_type=INT_RESULT; // Works for all types.
}
}
@@ -3563,13 +3581,13 @@ void Item_func_in::fix_length_and_dec()
thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
cmp_type != INT_RESULT)
{
- Field *field= ((Item_field*) (args[0]->real_item()))->field;
- if (field->can_be_compared_as_longlong())
+ Item_field *field_item= (Item_field*) (args[0]->real_item());
+ if (field_item->field->can_be_compared_as_longlong())
{
bool all_converted= TRUE;
for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
{
- if (!convert_constant_item (thd, field, &arg[0]))
+ if (!convert_constant_item (thd, field_item, &arg[0]))
all_converted= FALSE;
}
if (all_converted)
| Thread |
|---|
| • bk commit into 5.1 tree (timour:1.2670) BUG#32694 | timour | 6 Dec |