summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorunknown <ram@gw.mysql.r18.ru>2003-10-31 13:03:12 +0400
committerunknown <ram@gw.mysql.r18.ru>2003-10-31 13:03:12 +0400
commitbd4261d9afdde856185c991889890e3486b65946 (patch)
tree52981f51b6e137cf447fd4b30d2fe8a868c374d2 /sql/item_cmpfunc.cc
parentff182082576e4c23fe5049597b2d5ae9b4158526 (diff)
parent506631e771ad3f0a62a96ac790bad1da0e7d6845 (diff)
downloadmariadb-git-bd4261d9afdde856185c991889890e3486b65946.tar.gz
Merge rkalimullin@bk-internal.mysql.com:/home/bk/mysql-4.1
into gw.mysql.r18.ru:/usr/home/ram/work/4.1.wl1056 sql/item.h: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_cmpfunc.h: Auto merged sql/item_func.h: Auto merged sql/sql_select.cc: Auto merged
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc103
1 files changed, 103 insertions, 0 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 2680d5de017..d6c05f47964 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -23,6 +23,7 @@
#include "mysql_priv.h"
#include <m_ctype.h>
+#include "sql_select.h"
static Item_result item_store_type(Item_result a,Item_result b)
{
@@ -477,6 +478,7 @@ longlong Item_func_eq::val_int()
return value == 0 ? 1 : 0;
}
+
/* Same as Item_func_eq, but NULL = NULL */
void Item_func_equal::fix_length_and_dec()
@@ -1722,6 +1724,19 @@ void Item_cond::print(String *str)
str->append(')');
}
+
+void Item_cond::neg_arguments()
+{
+ 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)));
+ }
+}
+
+
/*
Evalution of AND(expr, expr, expr ...)
@@ -2335,3 +2350,91 @@ longlong Item_cond_xor::val_int()
}
return (longlong) result;
}
+
+/*
+ Apply NOT transformation to the item and return a new one.
+
+ SYNPOSIS
+ neg_transformer()
+
+ DESCRIPTION
+ Transform the item using next rules:
+ a AND b AND ... -> NOT(a) OR NOT(b) OR ...
+ a OR b OR ... -> NOT(a) AND NOT(b) AND ...
+ NOT(a) -> a
+ a = b -> a != b
+ a != b -> a = b
+ a < b -> a >= b
+ a >= b -> a < b
+ a > b -> a <= b
+ a <= b -> a > b
+ IS NULL(a) -> IS NOT NULL(a)
+ IS NOT NULL(a) -> IS NULL(a)
+
+ NOTE
+ This method is used in the eliminate_not_funcs() function.
+
+ RETURN
+ New item or
+ NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
+*/
+
+Item *Item_func_not::neg_transformer() /* NOT(x) -> x */
+{
+ /* We should apply negation elimination to the argument of the NOT function */
+ return eliminate_not_funcs(args[0]);
+}
+
+Item *Item_func_eq::neg_transformer() /* a = b -> a != b */
+{
+ return new Item_func_ne(args[0], args[1]);
+}
+
+Item *Item_func_ne::neg_transformer() /* a != b -> a = b */
+{
+ return new Item_func_eq(args[0], args[1]);
+}
+
+Item *Item_func_lt::neg_transformer() /* a < b -> a >= b */
+{
+ return new Item_func_ge(args[0], args[1]);
+}
+
+Item *Item_func_ge::neg_transformer() /* a >= b -> a < b */
+{
+ return new Item_func_lt(args[0], args[1]);
+}
+
+Item *Item_func_gt::neg_transformer() /* a > b -> a <= b */
+{
+ return new Item_func_le(args[0], args[1]);
+}
+
+Item *Item_func_le::neg_transformer() /* a <= b -> a > b */
+{
+ return new Item_func_gt(args[0], args[1]);
+}
+
+Item *Item_func_isnull::neg_transformer() /* a IS NULL -> a IS NOT NULL */
+{
+ return new Item_func_isnotnull(args[0]);
+}
+
+Item *Item_func_isnotnull::neg_transformer() /* a IS NOT NULL -> a IS NULL */
+{
+ return new Item_func_isnull(args[0]);
+}
+
+Item *Item_cond_and::neg_transformer() /* NOT(a AND b AND ...) -> */
+ /* NOT a OR NOT b OR ... */
+{
+ neg_arguments();
+ return new Item_cond_or(list);
+}
+
+Item *Item_cond_or::neg_transformer() /* NOT(a OR b OR ...) -> */
+ /* NOT a AND NOT b AND ... */
+{
+ neg_arguments();
+ return new Item_cond_and(list);
+}