Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
90ffe1be
Commit
90ffe1be
authored
Oct 31, 2003
by
ram@gw.mysql.r18.ru
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WL #1056: Eliminate NOT operators from where condition
parent
d6d6c5e1
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
638 additions
and
8 deletions
+638
-8
mysql-test/r/bool.result
mysql-test/r/bool.result
+0
-3
mysql-test/r/negation_elimination.result
mysql-test/r/negation_elimination.result
+382
-0
mysql-test/t/bool.test
mysql-test/t/bool.test
+0
-1
mysql-test/t/negation_elimination.test
mysql-test/t/negation_elimination.test
+68
-0
sql/item.h
sql/item.h
+3
-0
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+103
-0
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+21
-2
sql/item_func.h
sql/item_func.h
+2
-1
sql/sql_select.cc
sql/sql_select.cc
+58
-1
sql/sql_select.h
sql/sql_select.h
+1
-0
No files found.
mysql-test/r/bool.result
View file @
90ffe1be
...
...
@@ -42,9 +42,6 @@ SELECT * FROM t1 WHERE a=2 OR (NULL AND (@a:=@a+1));
a
SELECT * FROM t1 WHERE NOT(a=2 OR (NULL AND (@b:=@b+1)));
a
SELECT @a, @b;
@a @b
0 6
DROP TABLE t1;
create table t1 (a int, b int);
insert into t1 values(null, null), (0, null), (1, null), (null, 0), (null, 1), (0, 0), (0, 1), (1, 0), (1, 1);
...
...
mysql-test/r/negation_elimination.result
0 → 100644
View file @
90ffe1be
drop table if exists t1;
create table t1 (a int, key (a));
insert into t1 values (NULL), (0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(10), (11), (12), (13), (14), (15), (16), (17), (18), (19);
explain select * from t1 where not(not(a));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 21 Using where; Using index
select * from t1 where not(not(a));
a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
explain select * from t1 where not(not(not(a > 10)));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 10 Using where; Using index
select * from t1 where not(not(not(a > 10)));
a
0
1
2
3
4
5
6
7
8
9
10
explain select * from t1 where not(not(not(a < 5) and not(a > 10)));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 5 Using where; Using index
select * from t1 where not(not(not(a < 5) and not(a > 10)));
a
5
6
7
8
9
10
explain select * from t1 where not(a = 10);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 21 Using where; Using index
select * from t1 where not(a = 10);
a
0
1
2
3
4
5
6
7
8
9
11
12
13
14
15
16
17
18
19
explain select * from t1 where not(a != 10);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 5 const 1 Using where; Using index
select * from t1 where not(a != 1);
a
1
explain select * from t1 where not(a < 10);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 11 Using where; Using index
select * from t1 where not(a < 10);
a
10
11
12
13
14
15
16
17
18
19
explain select * from t1 where not(a >= 10);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 9 Using where; Using index
select * from t1 where not(a >= 10);
a
0
1
2
3
4
5
6
7
8
9
explain select * from t1 where not(a > 10);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 10 Using where; Using index
select * from t1 where not(a > 10);
a
0
1
2
3
4
5
6
7
8
9
10
explain select * from t1 where not(a <= 10);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 10 Using where; Using index
select * from t1 where not(a <= 10);
a
11
12
13
14
15
16
17
18
19
explain select * from t1 where not(a is null);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 20 Using where; Using index
select * from t1 where not(a is null);
a
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
explain select * from t1 where not(a is not null);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 5 const 1 Using where; Using index
select * from t1 where not(a is not null);
a
NULL
explain select * from t1 where not(a < 5 or a > 15);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 10 Using where; Using index
select * from t1 where not(a < 5 or a > 15);
a
5
6
7
8
9
10
11
12
13
14
15
explain select * from t1 where not(a < 15 and a > 5);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 12 Using where; Using index
select * from t1 where not(a < 15 and a > 5);
a
0
1
2
3
4
5
15
16
17
18
19
explain select * from t1 where a = 2 or not(a < 10);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 12 Using where; Using index
select * from t1 where a = 2 or not(a < 10);
a
2
10
11
12
13
14
15
16
17
18
19
explain select * from t1 where a > 5 and not(a > 10);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index
select * from t1 where a > 5 and not(a > 10);
a
6
7
8
9
10
explain select * from t1 where a > 5 xor a < 10;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 21 Using where; Using index
select * from t1 where a > 5 xor a < 10;
a
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
explain select * from t1 where a = 2 or not(a < 5 or a > 15);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 11 Using where; Using index
select * from t1 where a = 2 or not(a < 5 or a > 15);
a
2
5
6
7
8
9
10
11
12
13
14
15
explain select * from t1 where a = 7 or not(a < 15 and a > 5);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 13 Using where; Using index
select * from t1 where a = 7 or not(a < 15 and a > 5);
a
0
1
2
3
4
5
7
15
16
17
18
19
explain select * from t1 where NULL or not(a < 15 and a > 5);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 12 Using where; Using index
select * from t1 where NULL or not(a < 15 and a > 5);
a
0
1
2
3
4
5
15
16
17
18
19
explain select * from t1 where not(NULL and a > 5);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 6 Using where; Using index
select * from t1 where not(NULL and a > 5);
a
0
1
2
3
4
5
explain select * from t1 where not(NULL or a);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
select * from t1 where not(NULL or a);
a
explain select * from t1 where not(NULL and a);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 21 Using where; Using index
select * from t1 where not(NULL and a);
a
0
explain select * from t1 where not((a < 5 or a < 10) and (not(a > 16) or a > 17));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 11 Using where; Using index
select * from t1 where not((a < 5 or a < 10) and (not(a > 16) or a > 17));
a
10
11
12
13
14
15
16
17
18
19
explain select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 15 Using where; Using index
select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17));
a
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
explain select * from t1 where ((a between 5 and 15) and (not(a like 10)));
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 10 Using where; Using index
select * from t1 where ((a between 5 and 15) and (not(a like 10)));
a
5
6
7
8
9
11
12
13
14
15
drop table t1;
mysql-test/t/bool.test
View file @
90ffe1be
...
...
@@ -26,7 +26,6 @@ SELECT * FROM t1 WHERE NULL AND (@a:=@a+1);
SELECT
*
FROM
t1
WHERE
NOT
(
a
>=
0
AND
NULL
AND
(
@
b
:=@
b
+
1
));
SELECT
*
FROM
t1
WHERE
a
=
2
OR
(
NULL
AND
(
@
a
:=@
a
+
1
));
SELECT
*
FROM
t1
WHERE
NOT
(
a
=
2
OR
(
NULL
AND
(
@
b
:=@
b
+
1
)));
SELECT
@
a
,
@
b
;
DROP
TABLE
t1
;
...
...
mysql-test/t/negation_elimination.test
0 → 100644
View file @
90ffe1be
#
# Test negation elimination
#
--
disable_warnings
drop
table
if
exists
t1
;
--
enable_warnings
create
table
t1
(
a
int
,
key
(
a
));
insert
into
t1
values
(
NULL
),
(
0
),
(
1
),
(
2
),
(
3
),
(
4
),
(
5
),
(
6
),
(
7
),
(
8
),
(
9
),
(
10
),
(
11
),
(
12
),
(
13
),
(
14
),
(
15
),
(
16
),
(
17
),
(
18
),
(
19
);
explain
select
*
from
t1
where
not
(
not
(
a
));
select
*
from
t1
where
not
(
not
(
a
));
explain
select
*
from
t1
where
not
(
not
(
not
(
a
>
10
)));
select
*
from
t1
where
not
(
not
(
not
(
a
>
10
)));
explain
select
*
from
t1
where
not
(
not
(
not
(
a
<
5
)
and
not
(
a
>
10
)));
select
*
from
t1
where
not
(
not
(
not
(
a
<
5
)
and
not
(
a
>
10
)));
explain
select
*
from
t1
where
not
(
a
=
10
);
select
*
from
t1
where
not
(
a
=
10
);
explain
select
*
from
t1
where
not
(
a
!=
10
);
select
*
from
t1
where
not
(
a
!=
1
);
explain
select
*
from
t1
where
not
(
a
<
10
);
select
*
from
t1
where
not
(
a
<
10
);
explain
select
*
from
t1
where
not
(
a
>=
10
);
select
*
from
t1
where
not
(
a
>=
10
);
explain
select
*
from
t1
where
not
(
a
>
10
);
select
*
from
t1
where
not
(
a
>
10
);
explain
select
*
from
t1
where
not
(
a
<=
10
);
select
*
from
t1
where
not
(
a
<=
10
);
explain
select
*
from
t1
where
not
(
a
is
null
);
select
*
from
t1
where
not
(
a
is
null
);
explain
select
*
from
t1
where
not
(
a
is
not
null
);
select
*
from
t1
where
not
(
a
is
not
null
);
explain
select
*
from
t1
where
not
(
a
<
5
or
a
>
15
);
select
*
from
t1
where
not
(
a
<
5
or
a
>
15
);
explain
select
*
from
t1
where
not
(
a
<
15
and
a
>
5
);
select
*
from
t1
where
not
(
a
<
15
and
a
>
5
);
explain
select
*
from
t1
where
a
=
2
or
not
(
a
<
10
);
select
*
from
t1
where
a
=
2
or
not
(
a
<
10
);
explain
select
*
from
t1
where
a
>
5
and
not
(
a
>
10
);
select
*
from
t1
where
a
>
5
and
not
(
a
>
10
);
explain
select
*
from
t1
where
a
>
5
xor
a
<
10
;
select
*
from
t1
where
a
>
5
xor
a
<
10
;
explain
select
*
from
t1
where
a
=
2
or
not
(
a
<
5
or
a
>
15
);
select
*
from
t1
where
a
=
2
or
not
(
a
<
5
or
a
>
15
);
explain
select
*
from
t1
where
a
=
7
or
not
(
a
<
15
and
a
>
5
);
select
*
from
t1
where
a
=
7
or
not
(
a
<
15
and
a
>
5
);
explain
select
*
from
t1
where
NULL
or
not
(
a
<
15
and
a
>
5
);
select
*
from
t1
where
NULL
or
not
(
a
<
15
and
a
>
5
);
explain
select
*
from
t1
where
not
(
NULL
and
a
>
5
);
select
*
from
t1
where
not
(
NULL
and
a
>
5
);
explain
select
*
from
t1
where
not
(
NULL
or
a
);
select
*
from
t1
where
not
(
NULL
or
a
);
explain
select
*
from
t1
where
not
(
NULL
and
a
);
select
*
from
t1
where
not
(
NULL
and
a
);
explain
select
*
from
t1
where
not
((
a
<
5
or
a
<
10
)
and
(
not
(
a
>
16
)
or
a
>
17
));
select
*
from
t1
where
not
((
a
<
5
or
a
<
10
)
and
(
not
(
a
>
16
)
or
a
>
17
));
explain
select
*
from
t1
where
not
((
a
<
5
and
a
<
10
)
and
(
not
(
a
>
16
)
or
a
>
17
));
select
*
from
t1
where
not
((
a
<
5
and
a
<
10
)
and
(
not
(
a
>
16
)
or
a
>
17
));
explain
select
*
from
t1
where
((
a
between
5
and
15
)
and
(
not
(
a
like
10
)));
select
*
from
t1
where
((
a
between
5
and
15
)
and
(
not
(
a
like
10
)));
drop
table
t1
;
sql/item.h
View file @
90ffe1be
...
...
@@ -212,6 +212,9 @@ class Item {
virtual
void
bring_value
()
{}
Field
*
tmp_table_field_from_field_type
(
TABLE
*
table
);
/* Used in sql_select.cc:eliminate_not_funcs() */
virtual
Item
*
neg_transformer
()
{
return
NULL
;
}
};
...
...
sql/item_cmpfunc.cc
View file @
90ffe1be
...
...
@@ -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
)
{
...
...
@@ -476,6 +477,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
()
...
...
@@ -1721,6 +1723,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 ...)
...
...
@@ -2334,3 +2349,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
);
}
sql/item_cmpfunc.h
View file @
90ffe1be
...
...
@@ -153,7 +153,9 @@ class Item_func_not :public Item_bool_func
public:
Item_func_not
(
Item
*
a
)
:
Item_bool_func
(
a
)
{}
longlong
val_int
();
enum
Functype
functype
()
const
{
return
NOT_FUNC
;
}
const
char
*
func_name
()
const
{
return
"not"
;
}
Item
*
neg_transformer
();
};
class
Item_func_not_all
:
public
Item_func_not
...
...
@@ -164,6 +166,8 @@ class Item_func_not_all :public Item_func_not
virtual
void
top_level_item
()
{
abort_on_null
=
1
;
}
bool
top_level
()
{
return
abort_on_null
;
}
longlong
val_int
();
enum
Functype
functype
()
const
{
return
NOT_ALL_FUNC
;
}
const
char
*
func_name
()
const
{
return
"not_all"
;
}
};
class
Item_func_eq
:
public
Item_bool_rowready_func2
...
...
@@ -175,6 +179,7 @@ class Item_func_eq :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
EQ_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
const
char
*
func_name
()
const
{
return
"="
;
}
Item
*
neg_transformer
();
};
class
Item_func_equal
:
public
Item_bool_rowready_func2
...
...
@@ -199,6 +204,7 @@ class Item_func_ge :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
LE_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
const
char
*
func_name
()
const
{
return
">="
;
}
Item
*
neg_transformer
();
};
...
...
@@ -211,6 +217,7 @@ class Item_func_gt :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
LT_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_FALSE
;
}
const
char
*
func_name
()
const
{
return
">"
;
}
Item
*
neg_transformer
();
};
...
...
@@ -223,6 +230,7 @@ class Item_func_le :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
GE_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_TRUE
;
}
const
char
*
func_name
()
const
{
return
"<="
;
}
Item
*
neg_transformer
();
};
...
...
@@ -235,6 +243,7 @@ class Item_func_lt :public Item_bool_rowready_func2
enum
Functype
rev_functype
()
const
{
return
GT_FUNC
;
}
cond_result
eq_cmp_result
()
const
{
return
COND_FALSE
;
}
const
char
*
func_name
()
const
{
return
"<"
;
}
Item
*
neg_transformer
();
};
...
...
@@ -247,6 +256,7 @@ class Item_func_ne :public Item_bool_rowready_func2
cond_result
eq_cmp_result
()
const
{
return
COND_FALSE
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_NONE
;
}
const
char
*
func_name
()
const
{
return
"<>"
;
}
Item
*
neg_transformer
();
};
...
...
@@ -690,6 +700,7 @@ class Item_func_isnull :public Item_bool_func
}
table_map
not_null_tables
()
const
{
return
0
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_NULL
;
}
Item
*
neg_transformer
();
};
/* Functions used by HAVING for rewriting IN subquery */
...
...
@@ -722,6 +733,7 @@ class Item_func_isnotnull :public Item_bool_func
const
char
*
func_name
()
const
{
return
"isnotnull"
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_NULL
;
}
table_map
not_null_tables
()
const
{
return
0
;
}
Item
*
neg_transformer
();
};
...
...
@@ -801,7 +813,8 @@ class Item_cond :public Item_bool_func
public:
/* Item_cond() is only used to create top level items */
Item_cond
()
:
Item_bool_func
(),
abort_on_null
(
1
)
{
const_item_cache
=
0
;
}
Item_cond
()
:
Item_bool_func
(),
abort_on_null
(
1
)
{
const_item_cache
=
0
;
}
Item_cond
(
Item
*
i1
,
Item
*
i2
)
:
Item_bool_func
(),
abort_on_null
(
0
)
{
...
...
@@ -809,6 +822,8 @@ class Item_cond :public Item_bool_func
list
.
push_back
(
i2
);
}
Item_cond
(
THD
*
thd
,
Item_cond
&
item
);
Item_cond
(
List
<
Item
>
&
nlist
)
:
Item_bool_func
(),
list
(
nlist
),
abort_on_null
(
0
)
{}
~
Item_cond
()
{
list
.
delete_elements
();
}
bool
add
(
Item
*
item
)
{
return
list
.
push_back
(
item
);
}
bool
fix_fields
(
THD
*
,
struct
st_table_list
*
,
Item
**
ref
);
...
...
@@ -822,8 +837,8 @@ class Item_cond :public Item_bool_func
friend
int
setup_conds
(
THD
*
thd
,
TABLE_LIST
*
tables
,
COND
**
conds
);
void
top_level_item
()
{
abort_on_null
=
1
;
}
void
copy_andor_arguments
(
THD
*
thd
,
Item_cond
*
item
);
bool
walk
(
Item_processor
processor
,
byte
*
arg
);
void
neg_arguments
();
};
...
...
@@ -833,6 +848,7 @@ class Item_cond_and :public Item_cond
Item_cond_and
()
:
Item_cond
()
{}
Item_cond_and
(
Item
*
i1
,
Item
*
i2
)
:
Item_cond
(
i1
,
i2
)
{}
Item_cond_and
(
THD
*
thd
,
Item_cond_and
&
item
)
:
Item_cond
(
thd
,
item
)
{}
Item_cond_and
(
List
<
Item
>
&
list
)
:
Item_cond
(
list
)
{}
enum
Functype
functype
()
const
{
return
COND_AND_FUNC
;
}
longlong
val_int
();
const
char
*
func_name
()
const
{
return
"and"
;
}
...
...
@@ -843,6 +859,7 @@ class Item_cond_and :public Item_cond
item
->
copy_andor_arguments
(
thd
,
this
);
return
item
;
}
Item
*
neg_transformer
();
};
class
Item_cond_or
:
public
Item_cond
...
...
@@ -851,6 +868,7 @@ class Item_cond_or :public Item_cond
Item_cond_or
()
:
Item_cond
()
{}
Item_cond_or
(
Item
*
i1
,
Item
*
i2
)
:
Item_cond
(
i1
,
i2
)
{}
Item_cond_or
(
THD
*
thd
,
Item_cond_or
&
item
)
:
Item_cond
(
thd
,
item
)
{}
Item_cond_or
(
List
<
Item
>
&
list
)
:
Item_cond
(
list
)
{}
enum
Functype
functype
()
const
{
return
COND_OR_FUNC
;
}
longlong
val_int
();
const
char
*
func_name
()
const
{
return
"or"
;
}
...
...
@@ -862,6 +880,7 @@ class Item_cond_or :public Item_cond
item
->
copy_andor_arguments
(
thd
,
this
);
return
item
;
}
Item
*
neg_transformer
();
};
...
...
sql/item_func.h
View file @
90ffe1be
...
...
@@ -46,7 +46,8 @@ class Item_func :public Item_result_field
SP_TOUCHES_FUNC
,
SP_CROSSES_FUNC
,
SP_WITHIN_FUNC
,
SP_CONTAINS_FUNC
,
SP_OVERLAPS_FUNC
,
SP_STARTPOINT
,
SP_ENDPOINT
,
SP_EXTERIORRING
,
SP_POINTN
,
SP_GEOMETRYN
,
SP_INTERIORRINGN
};
SP_POINTN
,
SP_GEOMETRYN
,
SP_INTERIORRINGN
,
NOT_FUNC
,
NOT_ALL_FUNC
};
enum
optimize_type
{
OPTIMIZE_NONE
,
OPTIMIZE_KEY
,
OPTIMIZE_OP
,
OPTIMIZE_NULL
};
enum
Type
type
()
const
{
return
FUNC_ITEM
;
}
virtual
enum
Functype
functype
()
const
{
return
UNKNOWN_FUNC
;
}
...
...
sql/sql_select.cc
View file @
90ffe1be
...
...
@@ -4161,6 +4161,60 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father,
}
/*
Eliminate NOT functions from the condition tree.
SYNPOSIS
eliminate_not_funcs()
cond condition tree
DESCRIPTION
Eliminate NOT functions from the condition tree where it's possible.
Recursively traverse condition tree to find all NOT functions.
Call neg_transformer() method for negated arguments.
NOTE
If neg_transformer() returned a new condition we call fix_fields().
We don't delete any items as it's not needed. They will be deleted
later at once.
RETURN
New condition tree
*/
COND
*
eliminate_not_funcs
(
COND
*
cond
)
{
if
(
!
cond
)
return
cond
;
if
(
cond
->
type
()
==
Item
::
COND_ITEM
)
/* OR or AND */
{
List_iterator
<
Item
>
li
(
*
((
Item_cond
*
)
cond
)
->
argument_list
());
Item
*
item
;
while
((
item
=
li
++
))
{
Item
*
new_item
=
eliminate_not_funcs
(
item
);
if
(
item
!=
new_item
)
VOID
(
li
.
replace
(
new_item
));
/* replace item with a new condition */
}
}
else
if
(
cond
->
type
()
==
Item
::
FUNC_ITEM
&&
/* 'NOT' operation? */
((
Item_func
*
)
cond
)
->
functype
()
==
Item_func
::
NOT_FUNC
)
{
COND
*
new_cond
=
((
Item_func
*
)
cond
)
->
arguments
()[
0
]
->
neg_transformer
();
if
(
new_cond
)
{
/*
Here we can delete the NOT function. Something like: delete cond;
But we don't need to do it. All items will be deleted later at once.
*/
new_cond
->
fix_fields
(
current_thd
,
0
,
&
new_cond
);
cond
=
new_cond
;
}
}
return
cond
;
}
static
COND
*
optimize_cond
(
COND
*
conds
,
Item
::
cond_result
*
cond_value
)
{
...
...
@@ -4169,8 +4223,11 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
*
cond_value
=
Item
::
COND_TRUE
;
return
conds
;
}
/* change field = field to field = const for each found field = const */
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"original"
););
/* eliminate NOT operators */
conds
=
eliminate_not_funcs
(
conds
);
DBUG_EXECUTE
(
"where"
,
print_where
(
conds
,
"after negation elimination"
););
/* change field = field to field = const for each found field = const */
propagate_cond_constants
((
I_List
<
COND_CMP
>
*
)
0
,
conds
,
conds
);
/*
Remove all instances of item == item
...
...
sql/sql_select.h
View file @
90ffe1be
...
...
@@ -414,3 +414,4 @@ bool error_if_full_join(JOIN *join);
void
relink_tables
(
SELECT_LEX
*
select_lex
);
int
report_error
(
TABLE
*
table
,
int
error
);
int
safe_index_read
(
JOIN_TAB
*
tab
);
COND
*
eliminate_not_funcs
(
COND
*
cond
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment