summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2010-12-24 15:30:23 -0800
committerIgor Babaev <igor@askmonty.org>2010-12-24 15:30:23 -0800
commitefbb3c6c90279f2bed8dda9c48dbaaf8b09a8cae (patch)
tree810a57db5c728ce6174626cb58404765d8e2a0d6 /sql
parent46c7fb2722d3e0088c2a05acd202e4ebb48b44c0 (diff)
downloadmariadb-git-efbb3c6c90279f2bed8dda9c48dbaaf8b09a8cae.tar.gz
Fixed LP bug #639935 (bug #58727).
When the optimizer creates items out of other items it does not have to call the fix_fields method. Usually in these cases it calls quick_fix_field() that just marks the created item as fixed. If the created item is an Item_func object then calling quick_fix_field() works fine if the arguments of the created functional item are already fixed. Otherwise some unfixed nodes remain in the item tree and it triggers an assertion failure whenever the item is evaluated. Fixed the problem by making the method quick_fix_field virtual and providing an implementation for the class Item_func objects that recursively calls the method for unfixed arguments of any functional item.
Diffstat (limited to 'sql')
-rw-r--r--sql/item.h13
-rw-r--r--sql/item_func.cc15
-rw-r--r--sql/item_func.h1
3 files changed, 26 insertions, 3 deletions
diff --git a/sql/item.h b/sql/item.h
index f66892a76cc..4bee370642e 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -556,10 +556,17 @@ public:
Field *make_string_field(TABLE *table);
virtual bool fix_fields(THD *, Item **);
/*
- should be used in case where we are sure that we do not need
+ This method should be used in case where we are sure that we do not need
complete fix_fields() procedure.
- */
- inline void quick_fix_field() { fixed= 1; }
+ Usually this method is used by the optimizer when it has to create a new
+ item out of other already fixed items. For example, if the optimizer has
+ to create a new Item_func for an inferred equality whose left and right
+ parts are already fixed items. In some cases the optimizer cannot use
+ directly fixed items as the arguments of the created functional item,
+ but rather uses intermediate type conversion items. Then the method is
+ supposed to be applied recursively.
+ */
+ virtual inline void quick_fix_field() { fixed= 1; }
/* Function returns 1 on overflow and -1 on fatal errors */
int save_in_field_no_warnings(Field *field, bool no_conversions);
virtual int save_in_field(Field *field, bool no_conversions);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index c35db7ad1cb..ab84303101c 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -202,6 +202,21 @@ Item_func::fix_fields(THD *thd, Item **ref)
return FALSE;
}
+void
+Item_func::quick_fix_field()
+{
+ Item **arg,**arg_end;
+ if (arg_count)
+ {
+ for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
+ {
+ if (!(*arg)->fixed)
+ (*arg)->quick_fix_field();
+ }
+ }
+ fixed= 1;
+}
+
bool Item_func::walk(Item_processor processor, bool walk_subquery,
uchar *argument)
diff --git a/sql/item_func.h b/sql/item_func.h
index e45638472e4..3d2cb709ce3 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -117,6 +117,7 @@ public:
// Constructor used for Item_cond_and/or (see Item comment)
Item_func(THD *thd, Item_func *item);
bool fix_fields(THD *, Item **ref);
+ void quick_fix_field();
table_map used_tables() const;
table_map not_null_tables() const;
void update_used_tables();