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
3d34cada
Commit
3d34cada
authored
May 19, 2011
by
Igor Babaev
Browse files
Options
Browse Files
Download
Plain Diff
Merge
parents
d7fb598c
8e33aa9a
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
125 additions
and
22 deletions
+125
-22
mysql-test/r/view.result
mysql-test/r/view.result
+30
-0
mysql-test/t/view.test
mysql-test/t/view.test
+28
-0
sql/item.cc
sql/item.cc
+27
-12
sql/item.h
sql/item.h
+15
-4
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+4
-1
sql/item_func.cc
sql/item_func.cc
+4
-2
sql/item_func.h
sql/item_func.h
+15
-0
sql/sql_select.cc
sql/sql_select.cc
+2
-3
No files found.
mysql-test/r/view.result
View file @
3d34cada
...
...
@@ -4138,3 +4138,33 @@ Warning 1292 Truncated incorrect INTEGER value: 'VV'
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > 'JJ')
DROP VIEW v1;
DROP TABLE t1;
#
# Bug#777745: crash with equality propagation
# over view fields
#
CREATE TABLE t1 (a int NOT NULL ) ;
INSERT INTO t1 VALUES (2), (1);
CREATE TABLE t2 (a int NOT NULL , b int NOT NULL) ;
INSERT INTO t2 VALUES (2,20),(2,30);
CREATE VIEW v2 AS SELECT * FROM t2;
EXPLAIN
SELECT * FROM t1,v2
WHERE v2.a = t1.a AND v2.a = 2 AND v2.a IS NULL AND t1.a != 0;
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,v2
WHERE v2.a = t1.a AND v2.a = 2 AND v2.a IS NULL AND t1.a != 0;
a a b
EXPLAIN
SELECT * FROM t1,v2
WHERE v2.a = t1.a AND v2.a = 2 AND v2.a+1 > 2 AND t1.a != 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
SELECT * FROM t1,v2
WHERE v2.a = t1.a AND v2.a = 2 AND v2.a+1 > 2 AND t1.a != 0;
a a b
2 2 20
2 2 30
DROP VIEW v2;
DROP TABLE t1,t2;
mysql-test/t/view.test
View file @
3d34cada
...
...
@@ -4085,3 +4085,31 @@ SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV';
DROP
VIEW
v1
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# Bug#777745: crash with equality propagation
--
echo
# over view fields
--
echo
#
CREATE
TABLE
t1
(
a
int
NOT
NULL
)
;
INSERT
INTO
t1
VALUES
(
2
),
(
1
);
CREATE
TABLE
t2
(
a
int
NOT
NULL
,
b
int
NOT
NULL
)
;
INSERT
INTO
t2
VALUES
(
2
,
20
),(
2
,
30
);
CREATE
VIEW
v2
AS
SELECT
*
FROM
t2
;
EXPLAIN
SELECT
*
FROM
t1
,
v2
WHERE
v2
.
a
=
t1
.
a
AND
v2
.
a
=
2
AND
v2
.
a
IS
NULL
AND
t1
.
a
!=
0
;
SELECT
*
FROM
t1
,
v2
WHERE
v2
.
a
=
t1
.
a
AND
v2
.
a
=
2
AND
v2
.
a
IS
NULL
AND
t1
.
a
!=
0
;
EXPLAIN
SELECT
*
FROM
t1
,
v2
WHERE
v2
.
a
=
t1
.
a
AND
v2
.
a
=
2
AND
v2
.
a
+
1
>
2
AND
t1
.
a
!=
0
;
SELECT
*
FROM
t1
,
v2
WHERE
v2
.
a
=
t1
.
a
AND
v2
.
a
=
2
AND
v2
.
a
+
1
>
2
AND
t1
.
a
!=
0
;
DROP
VIEW
v2
;
DROP
TABLE
t1
,
t2
;
sql/item.cc
View file @
3d34cada
...
...
@@ -4733,7 +4733,7 @@ Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
The function checks whether a substitution of a field item for
an equal item is valid.
@param arg *arg != NULL
&& **arg
<-> the field is in the context
@param arg *arg != NULL <-> the field is in the context
where substitution for an equal item is valid
@note
...
...
@@ -4759,8 +4759,10 @@ Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal)
bool
Item_field
::
subst_argument_checker
(
uchar
**
arg
)
{
return
(
!
(
*
arg
)
&&
(
result_type
()
!=
STRING_RESULT
))
||
((
*
arg
)
&&
(
**
arg
));
return
*
arg
&&
(
*
arg
==
(
uchar
*
)
Item
::
ANY_SUBST
||
result_type
()
!=
STRING_RESULT
||
(
field
->
flags
&
BINARY_FLAG
));
}
...
...
@@ -6437,9 +6439,11 @@ Item* Item_ref::transform(Item_transformer transformer, uchar *arg)
First the function applies the analyzer to the Item_ref object. Then
if the analizer succeeeds we first applies the compile method to the
object the Item_ref object is referencing.
If this returns a new
object the Item_ref object is referencing. If this returns a new
item the old item is substituted for a new one. After this the
transformer is applied to the Item_ref object itself.
The compile function is not called if the analyzer returns NULL
in the parameter arg_p.
@param analyzer the analyzer callback function to be applied to the
nodes of the tree of the object
...
...
@@ -6460,10 +6464,13 @@ Item* Item_ref::compile(Item_analyzer analyzer, uchar **arg_p,
/* Compile the Item we are referencing. */
DBUG_ASSERT
((
*
ref
)
!=
NULL
);
uchar
*
arg_v
=
*
arg_p
;
Item
*
new_item
=
(
*
ref
)
->
compile
(
analyzer
,
&
arg_v
,
transformer
,
arg_t
);
if
(
new_item
&&
*
ref
!=
new_item
)
current_thd
->
change_item_tree
(
ref
,
new_item
);
if
(
*
arg_p
)
{
uchar
*
arg_v
=
*
arg_p
;
Item
*
new_item
=
(
*
ref
)
->
compile
(
analyzer
,
&
arg_v
,
transformer
,
arg_t
);
if
(
new_item
&&
*
ref
!=
new_item
)
current_thd
->
change_item_tree
(
ref
,
new_item
);
}
/* Transform this Item object. */
return
(
this
->*
transformer
)(
arg_t
);
...
...
@@ -7365,7 +7372,7 @@ Item_equal *Item_direct_view_ref::find_item_equal(COND_EQUAL *cond_equal)
The function checks whether a substitution of a reference to field item for
an equal item is valid.
@param arg *arg != NULL
&& **arg
<-> the reference is in the context
@param arg *arg != NULL <-> the reference is in the context
where substitution for an equal item is valid
@note
...
...
@@ -7378,11 +7385,19 @@ Item_equal *Item_direct_view_ref::find_item_equal(COND_EQUAL *cond_equal)
*/
bool
Item_direct_view_ref
::
subst_argument_checker
(
uchar
**
arg
)
{
bool
res
=
(
!
(
*
arg
)
&&
(
result_type
()
!=
STRING_RESULT
))
||
((
*
arg
)
&&
(
**
arg
));
bool
res
=
FALSE
;
if
(
*
arg
)
{
Item
*
item
=
real_item
();
if
(
item
->
type
()
==
FIELD_ITEM
&&
(
*
arg
==
(
uchar
*
)
Item
::
ANY_SUBST
||
result_type
()
!=
STRING_RESULT
||
(((
Item_field
*
)
item
)
->
field
->
flags
&
BINARY_FLAG
)))
res
=
TRUE
;
}
/* Block any substitution into the wrapped object */
if
(
*
arg
)
*
*
arg
=
(
uchar
)
0
;
*
arg
=
NULL
;
return
res
;
}
...
...
sql/item.h
View file @
3d34cada
...
...
@@ -1094,12 +1094,23 @@ class Item {
return
FALSE
;
}
/*
The enumeration Subst_constraint is currently used only in implementations
of the virtual function subst_argument_checker.
*/
enum
Subst_constraint
{
NO_SUBST
=
0
,
/* No substitution for a field is allowed */
ANY_SUBST
,
/* Any substitution for a field is allowed */
IDENTITY_SUBST
/* Substitution for a field is allowed if any two
different values of the field type are not equal */
};
virtual
bool
subst_argument_checker
(
uchar
**
arg
)
{
if
(
*
arg
)
*
arg
=
NULL
;
return
TRUE
;
{
return
(
*
arg
!=
NULL
);
}
/*
@brief
Processor used to check acceptability of an item in the defining
...
...
sql/item_cmpfunc.h
View file @
3d34cada
...
...
@@ -397,7 +397,10 @@ class Item_bool_rowready_func2 :public Item_bool_func2
}
Item
*
neg_transformer
(
THD
*
thd
);
virtual
Item
*
negated_item
();
bool
subst_argument_checker
(
uchar
**
arg
)
{
return
TRUE
;
}
bool
subst_argument_checker
(
uchar
**
arg
)
{
return
(
*
arg
!=
NULL
);
}
};
class
Item_func_not
:
public
Item_bool_func
...
...
sql/item_func.cc
View file @
3d34cada
...
...
@@ -352,6 +352,8 @@ Item *Item_func::transform(Item_transformer transformer, uchar *argument)
the old item is substituted for a new one.
After this the transformer is applied to the root node
of the Item_func object.
The compile function is not called if the analyzer returns NULL
in the parameter arg_p.
@param analyzer the analyzer callback function to be applied to the
nodes of the tree of the object
...
...
@@ -369,7 +371,7 @@ Item *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
{
if
(
!
(
this
->*
analyzer
)(
arg_p
))
return
0
;
if
(
arg_count
)
if
(
*
arg_p
&&
arg_count
)
{
Item
**
arg
,
**
arg_end
;
for
(
arg
=
args
,
arg_end
=
args
+
arg_count
;
arg
!=
arg_end
;
arg
++
)
...
...
@@ -377,7 +379,7 @@ Item *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
/*
The same parameter value of arg_p must be passed
to analyze any argument of the condition formula.
*/
*/
uchar
*
arg_v
=
*
arg_p
;
Item
*
new_item
=
(
*
arg
)
->
compile
(
analyzer
,
&
arg_v
,
transformer
,
arg_t
);
if
(
new_item
&&
*
arg
!=
new_item
)
...
...
sql/item_func.h
View file @
3d34cada
...
...
@@ -251,6 +251,21 @@ class Item_func :public Item_result_field
return
FALSE
;
}
/*
By default only substitution for a field whose two different values
are never equal is allowed in the arguments of a function.
This is overruled for the direct arguments of comparison functions.
*/
bool
subst_argument_checker
(
uchar
**
arg
)
{
if
(
*
arg
)
{
*
arg
=
(
uchar
*
)
Item
::
IDENTITY_SUBST
;
return
TRUE
;
}
return
FALSE
;
}
/*
We assume the result of any function that has a TIMESTAMP argument to be
timezone-dependent, since a TIMESTAMP value in both numeric and string
...
...
sql/sql_select.cc
View file @
3d34cada
...
...
@@ -9902,10 +9902,9 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
as soon the field is not of a string type or the field reference is
an argument of a comparison predicate.
*/
uchar
is_subst_valid
=
(
uchar
)
1
;
uchar
*
is_subst_valid_ptr
=
&
is_subst_valid
;
uchar
*
is_subst_valid
=
(
uchar
*
)
Item
::
ANY_SUBST
;
cond
=
cond
->
compile
(
&
Item
::
subst_argument_checker
,
&
is_subst_valid
_ptr
,
&
is_subst_valid
,
&
Item
::
equal_fields_propagator
,
(
uchar
*
)
inherited
);
cond
->
update_used_tables
();
...
...
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