summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2004-03-17 14:26:26 +0200
committerunknown <bell@sanja.is.com.ua>2004-03-17 14:26:26 +0200
commitf83cf4144065c12cad4007767e2e70d444fd0e05 (patch)
tree879e13469f1915539666e702fc32401e7f3a61d2 /sql/item_cmpfunc.cc
parent8242d1f19dcc00a8ad393485f19a1b3d806b8100 (diff)
downloadmariadb-git-f83cf4144065c12cad4007767e2e70d444fd0e05.tar.gz
DBUG_ASSERT(fixed == 0) added to fix_fields()
sql/item.cc: layout fixed fixed bug in prepared statements with subqueries and outer references sql/item.h: neg_transformer get thd argument to call fix_fields sql/item_cmpfunc.cc: DBUG_ASSERT(fixed == 0) added to fix_fields() fixed Item_in_optimizer fixed flag neg_arguments(), neg_transformer() call fix_field() on created items to avoid bouble fix field or non-called fixfields() sql/item_cmpfunc.h: neg_transformer get thd argument to call fix_fields fixed forgoten cleanup() call of parent class sql/item_func.cc: DBUG_ASSERT(fixed == 0) and fixed flag check added to fix_fields() sql/item_func.h: DBUG_ASSERT(fixed == 0) added to fix_fields() fixed forgoten cleanup() call of parent class sql/item_row.cc: DBUG_ASSERT(fixed == 0) added to fix_fields() added forgoten 'fixed' flag set sql/item_subselect.cc: DBUG_ASSERT(fixed == 0) added to fix_fields() fixed subquery transformation sql/sql_base.cc: check of fixed flag added sql/sql_derived.cc: fixed cleunup union in derived table during EXPLAIN command processing sql/sql_select.cc: thd argument add to function to allow call fix_fields() of new created items fixed EXPLAIN double preparation check of fixed flag added eliminate_not_funcs fixed for corrcet fix_fields call of new created items sql/sql_select.h: thd argument add to function to allow call fix_fields() of new created items sql/sql_union.cc: union processing fixed tests/client_test.c: layout fixed new test of outer references fron subqueries
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc136
1 files changed, 104 insertions, 32 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index ac1af32388f..23213c8009b 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -502,7 +502,6 @@ bool Item_in_optimizer::fix_left(THD *thd,
not_null_tables_cache= args[0]->not_null_tables();
with_sum_func= args[0]->with_sum_func;
const_item_cache= args[0]->const_item();
- fixed= 1;
return 0;
}
@@ -510,7 +509,8 @@ bool Item_in_optimizer::fix_left(THD *thd,
bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
Item ** ref)
{
- if (fix_left(thd, tables, ref))
+ DBUG_ASSERT(fixed == 0);
+ if (!args[0]->fixed && fix_left(thd, tables, ref))
return 1;
if (args[0]->maybe_null)
maybe_null=1;
@@ -529,6 +529,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables,
used_tables_cache|= args[1]->used_tables();
not_null_tables_cache|= args[1]->not_null_tables();
const_item_cache&= args[1]->const_item();
+ fixed= 1;
return 0;
}
@@ -1755,6 +1756,7 @@ void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item)
bool
Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
+ DBUG_ASSERT(fixed == 0);
List_iterator<Item> li(list);
Item *item;
#ifndef EMBEDDED_LIBRARY
@@ -1878,14 +1880,27 @@ void Item_cond::print(String *str)
}
-void Item_cond::neg_arguments()
+void Item_cond::neg_arguments(THD *thd)
{
List_iterator<Item> li(list);
Item *item;
while ((item= li++)) /* Apply not transformation to the arguments */
{
- Item *new_item= item->neg_transformer();
- VOID(li.replace(new_item ? new_item : new Item_func_not(item)));
+ Item *new_item= item->neg_transformer(thd);
+ if (!new_item)
+ {
+ new_item= new Item_func_not(item);
+ /*
+ We can use 0 as tables list because Item_func_not do not use it
+ on fix_fields and its arguments are already fixed.
+
+ We do not check results of fix_fields, because there are not way
+ to return error in this functions interface, thd->net.report_error
+ will be checked on upper level call.
+ */
+ new_item->fix_fields(thd, 0, &new_item);
+ }
+ VOID(li.replace(new_item));
}
}
@@ -2097,6 +2112,7 @@ Item_func::optimize_type Item_func_like::select_optimize() const
bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
{
+ DBUG_ASSERT(fixed == 0);
if (Item_bool_func2::fix_fields(thd, tlist, ref))
return 1;
@@ -2150,6 +2166,7 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
bool
Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
+ DBUG_ASSERT(fixed == 0);
if (args[0]->fix_fields(thd, tables, args) || args[0]->check_cols(1) ||
args[1]->fix_fields(thd,tables, args + 1) || args[1]->check_cols(1))
return 1; /* purecov: inspected */
@@ -2518,6 +2535,7 @@ longlong Item_cond_xor::val_int()
SYNPOSIS
neg_transformer()
+ thd thread handler
DESCRIPTION
Transform the item using next rules:
@@ -2541,62 +2559,116 @@ longlong Item_cond_xor::val_int()
NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
*/
-Item *Item_func_not::neg_transformer() /* NOT(x) -> x */
+Item *Item_func_not::neg_transformer(THD *thd) /* NOT(x) -> x */
{
- /* We should apply negation elimination to the argument of the NOT function */
- return eliminate_not_funcs(args[0]);
+ // We should apply negation elimination to the argument of the NOT function
+ return eliminate_not_funcs(thd, args[0]);
}
-Item *Item_func_eq::neg_transformer() /* a = b -> a != b */
+
+Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
{
- return new Item_func_ne(args[0], args[1]);
+ Item *item= negated_item();
+ if (item)
+ {
+ /*
+ We can use 0 as tables list because Item_func* family do not use it
+ on fix_fields and its arguments are already fixed.
+
+ We do not check results of fix_fields, because there are not way
+ to return error in this functions interface, thd->net.report_error
+ will be checked on upper level call.
+ */
+ item->fix_fields(thd, 0, &item);
+ }
+ return item;
}
-Item *Item_func_ne::neg_transformer() /* a != b -> a = b */
+
+/* a IS NULL -> a IS NOT NULL */
+Item *Item_func_isnull::neg_transformer(THD *thd)
{
- return new Item_func_eq(args[0], args[1]);
+ Item *item= new Item_func_isnotnull(args[0]);
+ // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
+ if (item)
+ item->fix_fields(thd, 0, &item);
+ return item;
}
-Item *Item_func_lt::neg_transformer() /* a < b -> a >= b */
+
+/* a IS NOT NULL -> a IS NULL */
+Item *Item_func_isnotnull::neg_transformer(THD *thd)
{
- return new Item_func_ge(args[0], args[1]);
+ Item *item= new Item_func_isnull(args[0]);
+ // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
+ if (item)
+ item->fix_fields(thd, 0, &item);
+ return item;
}
-Item *Item_func_ge::neg_transformer() /* a >= b -> a < b */
+
+Item *Item_cond_and::neg_transformer(THD *thd) /* NOT(a AND b AND ...) -> */
+ /* NOT a OR NOT b OR ... */
{
- return new Item_func_lt(args[0], args[1]);
+ neg_arguments(thd);
+ Item *item= new Item_cond_or(list);
+ // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
+ if (item)
+ item->fix_fields(thd, 0, &item);
+ return item;
}
-Item *Item_func_gt::neg_transformer() /* a > b -> a <= b */
+
+Item *Item_cond_or::neg_transformer(THD *thd) /* NOT(a OR b OR ...) -> */
+ /* NOT a AND NOT b AND ... */
{
- return new Item_func_le(args[0], args[1]);
+ neg_arguments(thd);
+ Item *item= new Item_cond_and(list);
+ // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer
+ if (item)
+ item->fix_fields(thd, 0, &item);
+ return item;
}
-Item *Item_func_le::neg_transformer() /* a <= b -> a > b */
+
+Item *Item_func_eq::negated_item() /* a = b -> a != b */
{
- return new Item_func_gt(args[0], args[1]);
+ return new Item_func_ne(args[0], args[1]);
}
-Item *Item_func_isnull::neg_transformer() /* a IS NULL -> a IS NOT NULL */
+
+Item *Item_func_ne::negated_item() /* a != b -> a = b */
{
- return new Item_func_isnotnull(args[0]);
+ return new Item_func_eq(args[0], args[1]);
}
-Item *Item_func_isnotnull::neg_transformer() /* a IS NOT NULL -> a IS NULL */
+
+Item *Item_func_lt::negated_item() /* a < b -> a >= b */
{
- return new Item_func_isnull(args[0]);
+ return new Item_func_ge(args[0], args[1]);
}
-Item *Item_cond_and::neg_transformer() /* NOT(a AND b AND ...) -> */
- /* NOT a OR NOT b OR ... */
+
+Item *Item_func_ge::negated_item() /* a >= b -> a < b */
{
- neg_arguments();
- return new Item_cond_or(list);
+ return new Item_func_lt(args[0], args[1]);
}
-Item *Item_cond_or::neg_transformer() /* NOT(a OR b OR ...) -> */
- /* NOT a AND NOT b AND ... */
+
+Item *Item_func_gt::negated_item() /* a > b -> a <= b */
{
- neg_arguments();
- return new Item_cond_and(list);
+ return new Item_func_le(args[0], args[1]);
+}
+
+
+Item *Item_func_le::negated_item() /* a <= b -> a > b */
+{
+ return new Item_func_gt(args[0], args[1]);
+}
+
+// just fake method, should never be called
+Item *Item_bool_rowready_func2::negated_item()
+{
+ DBUG_ASSERT(0);
+ return 0;
}