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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
184df985
Commit
184df985
authored
Aug 28, 2013
by
Sergey Petrunya
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of MDEV-4836 fix into 5.5
parents
1906f138
edd98022
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
156 additions
and
58 deletions
+156
-58
mysql-test/r/join_outer.result
mysql-test/r/join_outer.result
+20
-0
mysql-test/r/join_outer_jcl6.result
mysql-test/r/join_outer_jcl6.result
+20
-0
mysql-test/t/join_outer.test
mysql-test/t/join_outer.test
+20
-0
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+10
-17
sql/sql_select.cc
sql/sql_select.cc
+84
-41
sql/sql_select.h
sql/sql_select.h
+2
-0
No files found.
mysql-test/r/join_outer.result
View file @
184df985
...
@@ -2139,6 +2139,26 @@ id select_type table type possible_keys key key_len ref rows Extra
...
@@ -2139,6 +2139,26 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 Using index
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 Using index
drop table t0, t1;
drop table t0, t1;
#
#
# MDEV-4836: Wrong result on <not null date column> IS NULL (old documented hack stopped working)
# (this is a regression after fix for MDEV-4817)
#
CREATE TABLE t1 (id INT, d DATE NOT NULL);
INSERT INTO t1 VALUES (1,'0000-00-00'),(2,'0000-00-00');
CREATE TABLE t2 (i INT);
SELECT * FROM t1 LEFT JOIN t2 ON (id=i) WHERE NULL OR d IS NULL;
id d i
1 0000-00-00 NULL
2 0000-00-00 NULL
DROP TABLE t1,t2;
CREATE TABLE t1 (i1 INT, d1 DATE NOT NULL);
INSERT INTO t1 VALUES (1,'2012-12-21'),(2,'0000-00-00');
CREATE TABLE t2 (i2 INT, j2 INT);
INSERT INTO t2 VALUES (1,10),(2,20);
SELECT * FROM t1 LEFT JOIN t2 ON i1 = j2 WHERE d1 IS NULL AND 1 OR i1 = i2;
i1 d1 i2 j2
2 0000-00-00 NULL NULL
DROP TABLE t1,t2;
#
# Bug mdev-4942: LEFT JOIN with conjunctive
# Bug mdev-4942: LEFT JOIN with conjunctive
# <non-nullable datetime field> IS NULL in WHERE
# <non-nullable datetime field> IS NULL in WHERE
# causes an assert failure
# causes an assert failure
...
...
mysql-test/r/join_outer_jcl6.result
View file @
184df985
...
@@ -2150,6 +2150,26 @@ id select_type table type possible_keys key key_len ref rows Extra
...
@@ -2150,6 +2150,26 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 Using index
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 Using index
drop table t0, t1;
drop table t0, t1;
#
#
# MDEV-4836: Wrong result on <not null date column> IS NULL (old documented hack stopped working)
# (this is a regression after fix for MDEV-4817)
#
CREATE TABLE t1 (id INT, d DATE NOT NULL);
INSERT INTO t1 VALUES (1,'0000-00-00'),(2,'0000-00-00');
CREATE TABLE t2 (i INT);
SELECT * FROM t1 LEFT JOIN t2 ON (id=i) WHERE NULL OR d IS NULL;
id d i
1 0000-00-00 NULL
2 0000-00-00 NULL
DROP TABLE t1,t2;
CREATE TABLE t1 (i1 INT, d1 DATE NOT NULL);
INSERT INTO t1 VALUES (1,'2012-12-21'),(2,'0000-00-00');
CREATE TABLE t2 (i2 INT, j2 INT);
INSERT INTO t2 VALUES (1,10),(2,20);
SELECT * FROM t1 LEFT JOIN t2 ON i1 = j2 WHERE d1 IS NULL AND 1 OR i1 = i2;
i1 d1 i2 j2
2 0000-00-00 NULL NULL
DROP TABLE t1,t2;
#
# Bug mdev-4942: LEFT JOIN with conjunctive
# Bug mdev-4942: LEFT JOIN with conjunctive
# <non-nullable datetime field> IS NULL in WHERE
# <non-nullable datetime field> IS NULL in WHERE
# causes an assert failure
# causes an assert failure
...
...
mysql-test/t/join_outer.test
View file @
184df985
...
@@ -1686,6 +1686,26 @@ explain select * from t1 left join t0 on t0.a=t1.pk where t0.person_id='fooo' or
...
@@ -1686,6 +1686,26 @@ explain select * from t1 left join t0 on t0.a=t1.pk where t0.person_id='fooo' or
drop
table
t0
,
t1
;
drop
table
t0
,
t1
;
--
echo
#
--
echo
# MDEV-4836: Wrong result on <not null date column> IS NULL (old documented hack stopped working)
--
echo
# (this is a regression after fix for MDEV-4817)
--
echo
#
CREATE
TABLE
t1
(
id
INT
,
d
DATE
NOT
NULL
);
INSERT
INTO
t1
VALUES
(
1
,
'0000-00-00'
),(
2
,
'0000-00-00'
);
CREATE
TABLE
t2
(
i
INT
);
SELECT
*
FROM
t1
LEFT
JOIN
t2
ON
(
id
=
i
)
WHERE
NULL
OR
d
IS
NULL
;
DROP
TABLE
t1
,
t2
;
CREATE
TABLE
t1
(
i1
INT
,
d1
DATE
NOT
NULL
);
INSERT
INTO
t1
VALUES
(
1
,
'2012-12-21'
),(
2
,
'0000-00-00'
);
CREATE
TABLE
t2
(
i2
INT
,
j2
INT
);
INSERT
INTO
t2
VALUES
(
1
,
10
),(
2
,
20
);
SELECT
*
FROM
t1
LEFT
JOIN
t2
ON
i1
=
j2
WHERE
d1
IS
NULL
AND
1
OR
i1
=
i2
;
DROP
TABLE
t1
,
t2
;
--
echo
#
--
echo
#
--
echo
# Bug mdev-4942: LEFT JOIN with conjunctive
--
echo
# Bug mdev-4942: LEFT JOIN with conjunctive
...
...
sql/item_cmpfunc.cc
View file @
184df985
...
@@ -4302,7 +4302,8 @@ Item_cond::fix_fields(THD *thd, Item **ref)
...
@@ -4302,7 +4302,8 @@ Item_cond::fix_fields(THD *thd, Item **ref)
used_tables_cache
|=
item
->
used_tables
();
used_tables_cache
|=
item
->
used_tables
();
if
(
item
->
const_item
())
if
(
item
->
const_item
())
{
{
if
(
!
item
->
is_expensive
()
&&
item
->
val_int
()
==
0
)
if
(
!
item
->
is_expensive
()
&&
!
cond_has_datetime_is_null
(
item
)
&&
item
->
val_int
()
==
0
)
{
{
/*
/*
This is "... OR false_cond OR ..."
This is "... OR false_cond OR ..."
...
@@ -4314,27 +4315,18 @@ Item_cond::fix_fields(THD *thd, Item **ref)
...
@@ -4314,27 +4315,18 @@ Item_cond::fix_fields(THD *thd, Item **ref)
/*
/*
This is "... OR const_cond OR ..."
This is "... OR const_cond OR ..."
In this case, cond_or->not_null_tables()=0, because the condition
In this case, cond_or->not_null_tables()=0, because the condition
some_cond_or might be true regardless of what tables are
const_cond might evaluate to true (regardless of whether some tables
NULL-complemented
.
were NULL-complemented)
.
*/
*/
and_tables_cache
=
(
table_map
)
0
;
and_tables_cache
=
(
table_map
)
0
;
}
}
}
}
else
else
{
{
/*
table_map
tmp_table_map
=
item
->
not_null_tables
();
If an item is a
not_null_tables_cache
|=
tmp_table_map
;
- constant
and_tables_cache
&=
tmp_table_map
;
- inexpensive
- its value is 0
then we don't need to account it in not_null_tables_cache
*/
//if (!(item->const_item() && !item->is_expensive() ))
{
table_map
tmp_table_map
=
item
->
not_null_tables
();
not_null_tables_cache
|=
tmp_table_map
;
and_tables_cache
&=
tmp_table_map
;
}
const_item_cache
=
FALSE
;
const_item_cache
=
FALSE
;
}
}
...
@@ -4363,7 +4355,8 @@ Item_cond::eval_not_null_tables(uchar *opt_arg)
...
@@ -4363,7 +4355,8 @@ Item_cond::eval_not_null_tables(uchar *opt_arg)
table_map
tmp_table_map
;
table_map
tmp_table_map
;
if
(
item
->
const_item
())
if
(
item
->
const_item
())
{
{
if
(
!
item
->
is_expensive
()
&&
item
->
val_int
()
==
0
)
if
(
!
item
->
is_expensive
()
&&
!
cond_has_datetime_is_null
(
item
)
&&
item
->
val_int
()
==
0
)
{
{
/*
/*
This is "... OR false_cond OR ..."
This is "... OR false_cond OR ..."
...
...
sql/sql_select.cc
View file @
184df985
...
@@ -13534,6 +13534,57 @@ void propagate_new_equalities(THD *thd, Item *cond,
...
@@ -13534,6 +13534,57 @@ void propagate_new_equalities(THD *thd, Item *cond,
}
}
}
}
/*
Check if cond_is_datetime_is_null() is true for the condition cond, or
for any of its AND/OR-children
*/
bool
cond_has_datetime_is_null
(
Item
*
cond
)
{
if
(
cond_is_datetime_is_null
(
cond
))
return
true
;
if
(
cond
->
type
()
==
Item
::
COND_ITEM
)
{
List
<
Item
>
*
cond_arg_list
=
((
Item_cond
*
)
cond
)
->
argument_list
();
List_iterator
<
Item
>
li
(
*
cond_arg_list
);
Item
*
item
;
while
((
item
=
li
++
))
{
if
(
cond_has_datetime_is_null
(
item
))
return
true
;
}
}
return
false
;
}
/*
Check if passed condtition has for of
not_null_date_col IS NULL
where not_null_date_col has a datte or datetime type
*/
bool
cond_is_datetime_is_null
(
Item
*
cond
)
{
if
(
cond
->
type
()
==
Item
::
FUNC_ITEM
&&
((
Item_func
*
)
cond
)
->
functype
()
==
Item_func
::
ISNULL_FUNC
)
{
Item
**
args
=
((
Item_func_isnull
*
)
cond
)
->
arguments
();
if
(
args
[
0
]
->
type
()
==
Item
::
FIELD_ITEM
)
{
Field
*
field
=
((
Item_field
*
)
args
[
0
])
->
field
;
if
(((
field
->
type
()
==
MYSQL_TYPE_DATE
)
||
(
field
->
type
()
==
MYSQL_TYPE_DATETIME
))
&&
(
field
->
flags
&
NOT_NULL_FLAG
))
{
return
TRUE
;
}
}
}
return
FALSE
;
}
/**
/**
...
@@ -13802,53 +13853,45 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
...
@@ -13802,53 +13853,45 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
return
item
;
return
item
;
}
}
}
}
else
if
(
cond
->
type
()
==
Item
::
FUNC_ITEM
&&
else
if
(
cond_is_datetime_is_null
(
cond
))
((
Item_func
*
)
cond
)
->
functype
()
==
Item_func
::
ISNULL_FUNC
)
{
{
Item_func_isnull
*
func
=
(
Item_func_isnull
*
)
cond
;
/* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
Item
**
args
=
func
->
arguments
();
/*
if
(
args
[
0
]
->
type
()
==
Item
::
FIELD_ITEM
)
See BUG#12594011
{
Documentation says that
Field
*
field
=
((
Item_field
*
)
args
[
0
])
->
field
;
SELECT datetime_notnull d FROM t1 WHERE d IS NULL
/* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
shall return rows where d=='0000-00-00'
/*
See BUG#12594011
Documentation says that
SELECT datetime_notnull d FROM t1 WHERE d IS NULL
shall return rows where d=='0000-00-00'
Thus, for DATE and DATETIME columns defined as NOT NULL,
Thus, for DATE and DATETIME columns defined as NOT NULL,
"date_notnull IS NULL" has to be modified to
"date_notnull IS NULL" has to be modified to
"date_notnull IS NULL OR date_notnull == 0" (if outer join)
"date_notnull IS NULL OR date_notnull == 0" (if outer join)
"date_notnull == 0" (otherwise)
"date_notnull == 0" (otherwise)
*/
*/
if
(((
field
->
type
()
==
MYSQL_TYPE_DATE
)
||
Item
**
args
=
((
Item_func_isnull
*
)
cond
)
->
arguments
();
(
field
->
type
()
==
MYSQL_TYPE_DATETIME
))
&&
Field
*
field
=
((
Item_field
*
)
args
[
0
])
->
field
;
(
field
->
flags
&
NOT_NULL_FLAG
))
{
Item
*
item0
=
new
(
thd
->
mem_root
)
Item_int
((
longlong
)
0
,
1
);
Item
*
eq_cond
=
new
(
thd
->
mem_root
)
Item_func_eq
(
args
[
0
],
item0
);
if
(
!
eq_cond
)
return
cond
;
if
(
field
->
table
->
pos_in_table_list
->
outer_join
)
Item
*
item0
=
new
(
thd
->
mem_root
)
Item_int
((
longlong
)
0
,
1
);
{
Item
*
eq_cond
=
new
(
thd
->
mem_root
)
Item_func_eq
(
args
[
0
],
item0
);
// outer join: transform "col IS NULL" to "col IS NULL or col=0"
if
(
!
eq_cond
)
Item
*
or_cond
=
new
(
thd
->
mem_root
)
Item_cond_or
(
eq_cond
,
cond
);
return
cond
;
if
(
!
or_cond
)
return
cond
;
cond
=
or_cond
;
}
else
{
// not outer join: transform "col IS NULL" to "col=0"
cond
=
eq_cond
;
}
cond
->
fix_fields
(
thd
,
&
cond
);
if
(
field
->
table
->
pos_in_table_list
->
outer_join
)
}
{
// outer join: transform "col IS NULL" to "col IS NULL or col=0"
Item
*
or_cond
=
new
(
thd
->
mem_root
)
Item_cond_or
(
eq_cond
,
cond
);
if
(
!
or_cond
)
return
cond
;
cond
=
or_cond
;
}
else
{
// not outer join: transform "col IS NULL" to "col=0"
cond
=
eq_cond
;
}
}
cond
->
fix_fields
(
thd
,
&
cond
);
if
(
cond
->
const_item
()
&&
!
cond
->
is_expensive
())
if
(
cond
->
const_item
()
&&
!
cond
->
is_expensive
())
{
{
*
cond_value
=
eval_const_cond
(
cond
)
?
Item
::
COND_TRUE
:
Item
::
COND_FALSE
;
*
cond_value
=
eval_const_cond
(
cond
)
?
Item
::
COND_TRUE
:
Item
::
COND_FALSE
;
...
...
sql/sql_select.h
View file @
184df985
...
@@ -1800,6 +1800,8 @@ ORDER *simple_remove_const(ORDER *order, COND *where);
...
@@ -1800,6 +1800,8 @@ ORDER *simple_remove_const(ORDER *order, COND *where);
bool
const_expression_in_where
(
COND
*
cond
,
Item
*
comp_item
,
bool
const_expression_in_where
(
COND
*
cond
,
Item
*
comp_item
,
Field
*
comp_field
=
NULL
,
Field
*
comp_field
=
NULL
,
Item
**
const_item
=
NULL
);
Item
**
const_item
=
NULL
);
bool
cond_is_datetime_is_null
(
Item
*
cond
);
bool
cond_has_datetime_is_null
(
Item
*
cond
);
/* Table elimination entry point function */
/* Table elimination entry point function */
void
eliminate_tables
(
JOIN
*
join
);
void
eliminate_tables
(
JOIN
*
join
);
...
...
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