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
bc591d5c
Commit
bc591d5c
authored
Oct 31, 2003
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WL #1056: Eliminate NOT operators from where condition
parent
72319047
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 @
bc591d5c
...
...
@@ -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 @
bc591d5c
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 @
bc591d5c
...
...
@@ -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 @
bc591d5c
#
# 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 @
bc591d5c
...
...
@@ -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 @
bc591d5c
...
...
@@ -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 @
bc591d5c
...
...
@@ -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 @
bc591d5c
...
...
@@ -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 @
bc591d5c
...
...
@@ -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 @
bc591d5c
...
...
@@ -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