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
59c58f6e
Commit
59c58f6e
authored
Jan 13, 2017
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-9522 Split sql_select.cc:can_change_cond_ref_to_const into virtual methods in Type_handler
parent
306ce497
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
151 additions
and
69 deletions
+151
-69
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+6
-3
sql/sql_select.cc
sql/sql_select.cc
+6
-66
sql/sql_type.cc
sql/sql_type.cc
+93
-0
sql/sql_type.h
sql/sql_type.h
+46
-0
No files found.
sql/item_cmpfunc.h
View file @
59c58f6e
...
@@ -392,7 +392,7 @@ class Item_bool_func2 :public Item_bool_func
...
@@ -392,7 +392,7 @@ class Item_bool_func2 :public Item_bool_func
Specifies which result type the function uses to compare its arguments.
Specifies which result type the function uses to compare its arguments.
This method is used in equal field propagation.
This method is used in equal field propagation.
*/
*/
virtual
Item_result
compare_type
()
const
virtual
const
Type_handler
*
compare_type_handler
()
const
{
{
/*
/*
Have STRING_RESULT by default, which means the function compares
Have STRING_RESULT by default, which means the function compares
...
@@ -400,7 +400,7 @@ class Item_bool_func2 :public Item_bool_func
...
@@ -400,7 +400,7 @@ class Item_bool_func2 :public Item_bool_func
and for Item_func_spatial_rel.
and for Item_func_spatial_rel.
Note, Item_bool_rowready_func2 overrides this default behaviour.
Note, Item_bool_rowready_func2 overrides this default behaviour.
*/
*/
return
STRING_RESULT
;
return
&
type_handler_varchar
;
}
}
SEL_TREE
*
get_mm_tree
(
RANGE_OPT_PARAM
*
param
,
Item
**
cond_ptr
)
SEL_TREE
*
get_mm_tree
(
RANGE_OPT_PARAM
*
param
,
Item
**
cond_ptr
)
{
{
...
@@ -508,7 +508,10 @@ class Item_bool_rowready_func2 :public Item_bool_func2_with_rev
...
@@ -508,7 +508,10 @@ class Item_bool_rowready_func2 :public Item_bool_func2_with_rev
return
cmp
.
set_cmp_func
(
this
,
tmp_arg
,
tmp_arg
+
1
,
true
);
return
cmp
.
set_cmp_func
(
this
,
tmp_arg
,
tmp_arg
+
1
,
true
);
}
}
CHARSET_INFO
*
compare_collation
()
const
{
return
cmp
.
compare_collation
();
}
CHARSET_INFO
*
compare_collation
()
const
{
return
cmp
.
compare_collation
();
}
Item_result
compare_type
()
const
{
return
cmp
.
compare_type
();
}
const
Type_handler
*
compare_type_handler
()
const
{
return
cmp
.
compare_type_handler
();
}
Arg_comparator
*
get_comparator
()
{
return
&
cmp
;
}
Arg_comparator
*
get_comparator
()
{
return
&
cmp
;
}
void
cleanup
()
void
cleanup
()
{
{
...
...
sql/sql_select.cc
View file @
59c58f6e
...
@@ -12927,7 +12927,7 @@ bool Item_func_eq::check_equality(THD *thd, COND_EQUAL *cond_equal,
...
@@ -12927,7 +12927,7 @@ bool Item_func_eq::check_equality(THD *thd, COND_EQUAL *cond_equal,
}
}
return
check_simple_equality
(
thd
,
return
check_simple_equality
(
thd
,
Context
(
ANY_SUBST
,
Context
(
ANY_SUBST
,
compare_type
(),
compare_type
_handler
()
->
cmp_type
(),
compare_collation
()),
compare_collation
()),
left_item
,
right_item
,
cond_equal
);
left_item
,
right_item
,
cond_equal
);
}
}
...
@@ -13995,71 +13995,11 @@ can_change_cond_ref_to_const(Item_bool_func2 *target,
...
@@ -13995,71 +13995,11 @@ can_change_cond_ref_to_const(Item_bool_func2 *target,
Item_bool_func2
*
source
,
Item_bool_func2
*
source
,
Item
*
source_expr
,
Item
*
source_const
)
Item
*
source_expr
,
Item
*
source_const
)
{
{
if
(
!
target_expr
->
eq
(
source_expr
,
0
)
||
return
target_expr
->
eq
(
source_expr
,
0
)
&&
target_value
==
source_const
||
target_value
!=
source_const
&&
target
->
compare_type
()
!=
source
->
compare_type
())
target
->
compare_type_handler
()
->
return
false
;
can_change_cond_ref_to_const
(
target
,
target_expr
,
target_value
,
if
(
target
->
compare_type
()
==
STRING_RESULT
)
source
,
source_expr
,
source_const
);
{
/*
In this example:
SET NAMES utf8 COLLATE utf8_german2_ci;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a CHAR(10) CHARACTER SET utf8);
INSERT INTO t1 VALUES ('o-umlaut'),('oe');
SELECT * FROM t1 WHERE a='oe' COLLATE utf8_german2_ci AND a='oe';
the query should return only the row with 'oe'.
It should not return 'o-umlaut', because 'o-umlaut' does not match
the right part of the condition: a='oe'
('o-umlaut' is not equal to 'oe' in utf8_general_ci,
which is the collation of the field "a").
If we change the right part from:
... AND a='oe'
to
... AND 'oe' COLLATE utf8_german2_ci='oe'
it will be evalulated to TRUE and removed from the condition,
so the overall query will be simplified to:
SELECT * FROM t1 WHERE a='oe' COLLATE utf8_german2_ci;
which will erroneously start to return both 'oe' and 'o-umlaut'.
So changing "expr" to "const" is not possible if the effective
collations of "target" and "source" are not exactly the same.
Note, the code before the fix for MDEV-7152 only checked that
collations of "source_const" and "target_value" are the same.
This was not enough, as the bug report demonstrated.
*/
return
target
->
compare_collation
()
==
source
->
compare_collation
()
&&
target_value
->
collation
.
collation
==
source_const
->
collation
.
collation
;
}
if
(
target
->
compare_type
()
==
TIME_RESULT
)
{
if
(
target_value
->
cmp_type
()
!=
TIME_RESULT
)
{
/*
Can't rewrite:
WHERE COALESCE(time_column)='00:00:00'
AND COALESCE(time_column)=DATE'2015-09-11'
to
WHERE DATE'2015-09-11'='00:00:00'
AND COALESCE(time_column)=DATE'2015-09-11'
because the left part will erroneously try to parse '00:00:00'
as DATE, not as TIME.
TODO: It could still be rewritten to:
WHERE DATE'2015-09-11'=TIME'00:00:00'
AND COALESCE(time_column)=DATE'2015-09-11'
i.e. we need to replace both target_expr and target_value
at the same time. This is not supported yet.
*/
return
false
;
}
}
return
true
;
// Non-string comparison
}
}
...
...
sql/sql_type.cc
View file @
59c58f6e
...
@@ -1057,6 +1057,99 @@ bool Type_handler_temporal_result::set_comparator_func(Arg_comparator *cmp) cons
...
@@ -1057,6 +1057,99 @@ bool Type_handler_temporal_result::set_comparator_func(Arg_comparator *cmp) cons
}
}
/*************************************************************************/
bool
Type_handler_temporal_result
::
can_change_cond_ref_to_const
(
Item_bool_func2
*
target
,
Item
*
target_expr
,
Item
*
target_value
,
Item_bool_func2
*
source
,
Item
*
source_expr
,
Item
*
source_const
)
const
{
if
(
source
->
compare_type_handler
()
->
cmp_type
()
!=
TIME_RESULT
)
return
false
;
/*
Can't rewrite:
WHERE COALESCE(time_column)='00:00:00'
AND COALESCE(time_column)=DATE'2015-09-11'
to
WHERE DATE'2015-09-11'='00:00:00'
AND COALESCE(time_column)=DATE'2015-09-11'
because the left part will erroneously try to parse '00:00:00'
as DATE, not as TIME.
TODO: It could still be rewritten to:
WHERE DATE'2015-09-11'=TIME'00:00:00'
AND COALESCE(time_column)=DATE'2015-09-11'
i.e. we need to replace both target_expr and target_value
at the same time. This is not supported yet.
*/
return
target_value
->
cmp_type
()
==
TIME_RESULT
;
}
bool
Type_handler_string_result
::
can_change_cond_ref_to_const
(
Item_bool_func2
*
target
,
Item
*
target_expr
,
Item
*
target_value
,
Item_bool_func2
*
source
,
Item
*
source_expr
,
Item
*
source_const
)
const
{
if
(
source
->
compare_type_handler
()
->
cmp_type
()
!=
STRING_RESULT
)
return
false
;
/*
In this example:
SET NAMES utf8 COLLATE utf8_german2_ci;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a CHAR(10) CHARACTER SET utf8);
INSERT INTO t1 VALUES ('o-umlaut'),('oe');
SELECT * FROM t1 WHERE a='oe' COLLATE utf8_german2_ci AND a='oe';
the query should return only the row with 'oe'.
It should not return 'o-umlaut', because 'o-umlaut' does not match
the right part of the condition: a='oe'
('o-umlaut' is not equal to 'oe' in utf8_general_ci,
which is the collation of the field "a").
If we change the right part from:
... AND a='oe'
to
... AND 'oe' COLLATE utf8_german2_ci='oe'
it will be evalulated to TRUE and removed from the condition,
so the overall query will be simplified to:
SELECT * FROM t1 WHERE a='oe' COLLATE utf8_german2_ci;
which will erroneously start to return both 'oe' and 'o-umlaut'.
So changing "expr" to "const" is not possible if the effective
collations of "target" and "source" are not exactly the same.
Note, the code before the fix for MDEV-7152 only checked that
collations of "source_const" and "target_value" are the same.
This was not enough, as the bug report demonstrated.
*/
return
target
->
compare_collation
()
==
source
->
compare_collation
()
&&
target_value
->
collation
.
collation
==
source_const
->
collation
.
collation
;
}
bool
Type_handler_numeric
::
can_change_cond_ref_to_const
(
Item_bool_func2
*
target
,
Item
*
target_expr
,
Item
*
target_value
,
Item_bool_func2
*
source
,
Item
*
source_expr
,
Item
*
source_const
)
const
{
/*
The collations of "target" and "source" do not make sense for numeric
data types.
*/
return
target
->
compare_type_handler
()
==
source
->
compare_type_handler
();
}
/*************************************************************************/
/*************************************************************************/
Item_cache
*
Item_cache
*
...
...
sql/sql_type.h
View file @
59c58f6e
...
@@ -32,6 +32,7 @@ class Item_func_hex;
...
@@ -32,6 +32,7 @@ class Item_func_hex;
class
Item_hybrid_func
;
class
Item_hybrid_func
;
class
Item_func_min_max
;
class
Item_func_min_max
;
class
Item_func_hybrid_field_type
;
class
Item_func_hybrid_field_type
;
class
Item_bool_func2
;
class
Item_func_between
;
class
Item_func_between
;
class
Item_func_in
;
class
Item_func_in
;
class
cmp_item
;
class
cmp_item
;
...
@@ -346,6 +347,31 @@ class Type_handler
...
@@ -346,6 +347,31 @@ class Type_handler
virtual
uint32
max_display_length
(
const
Item
*
item
)
const
=
0
;
virtual
uint32
max_display_length
(
const
Item
*
item
)
const
=
0
;
virtual
int
Item_save_in_field
(
Item
*
item
,
Field
*
field
,
virtual
int
Item_save_in_field
(
Item
*
item
,
Field
*
field
,
bool
no_conversions
)
const
=
0
;
bool
no_conversions
)
const
=
0
;
/**
Check if
WHERE expr=value AND expr=const
can be rewritten as:
WHERE const=value AND expr=const
"this" is the comparison handler that is used by "target".
@param target - the predicate expr=value,
whose "expr" argument will be replaced to "const".
@param target_expr - the target's "expr" which will be replaced to "const".
@param target_value - the target's second argument, it will remain unchanged.
@param source - the equality predicate expr=const (or expr<=>const)
that can be used to rewrite the "target" part
(under certain conditions, see the code).
@param source_expr - the source's "expr". It should be exactly equal to
the target's "expr" to make condition rewrite possible.
@param source_const - the source's "const" argument, it will be inserted
into "target" instead of "expr".
*/
virtual
bool
can_change_cond_ref_to_const
(
Item_bool_func2
*
target
,
Item
*
target_expr
,
Item
*
target_value
,
Item_bool_func2
*
source
,
Item
*
source_expr
,
Item
*
source_const
)
const
=
0
;
virtual
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
=
0
;
virtual
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
=
0
;
virtual
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
=
0
;
virtual
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
=
0
;
virtual
bool
Item_hybrid_func_fix_attributes
(
THD
*
thd
,
Item_hybrid_func
*
func
,
virtual
bool
Item_hybrid_func_fix_attributes
(
THD
*
thd
,
Item_hybrid_func
*
func
,
...
@@ -455,6 +481,14 @@ class Type_handler_row: public Type_handler
...
@@ -455,6 +481,14 @@ class Type_handler_row: public Type_handler
DBUG_ASSERT
(
0
);
DBUG_ASSERT
(
0
);
return
1
;
return
1
;
}
}
bool
can_change_cond_ref_to_const
(
Item_bool_func2
*
target
,
Item
*
target_expr
,
Item
*
target_value
,
Item_bool_func2
*
source
,
Item
*
source_expr
,
Item
*
source_const
)
const
{
DBUG_ASSERT
(
0
);
return
false
;
}
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
;
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
;
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
;
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
;
bool
Item_hybrid_func_fix_attributes
(
THD
*
thd
,
Item_hybrid_func
*
func
,
bool
Item_hybrid_func_fix_attributes
(
THD
*
thd
,
Item_hybrid_func
*
func
,
...
@@ -558,6 +592,10 @@ class Type_handler_numeric: public Type_handler
...
@@ -558,6 +592,10 @@ class Type_handler_numeric: public Type_handler
bool
Item_func_min_max_get_date
(
Item_func_min_max
*
,
bool
Item_func_min_max_get_date
(
Item_func_min_max
*
,
MYSQL_TIME
*
,
ulonglong
fuzzydate
)
const
;
MYSQL_TIME
*
,
ulonglong
fuzzydate
)
const
;
virtual
~
Type_handler_numeric
()
{
}
virtual
~
Type_handler_numeric
()
{
}
bool
can_change_cond_ref_to_const
(
Item_bool_func2
*
target
,
Item
*
target_expr
,
Item
*
target_value
,
Item_bool_func2
*
source
,
Item
*
source_expr
,
Item
*
source_const
)
const
;
};
};
...
@@ -699,6 +737,10 @@ class Type_handler_temporal_result: public Type_handler
...
@@ -699,6 +737,10 @@ class Type_handler_temporal_result: public Type_handler
const
Type_std_attributes
*
item
,
const
Type_std_attributes
*
item
,
SORT_FIELD_ATTR
*
attr
)
const
;
SORT_FIELD_ATTR
*
attr
)
const
;
uint32
max_display_length
(
const
Item
*
item
)
const
;
uint32
max_display_length
(
const
Item
*
item
)
const
;
bool
can_change_cond_ref_to_const
(
Item_bool_func2
*
target
,
Item
*
target_expr
,
Item
*
target_value
,
Item_bool_func2
*
source
,
Item
*
source_expr
,
Item
*
source_const
)
const
;
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
;
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
;
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
;
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
;
bool
Item_sum_hybrid_fix_length_and_dec
(
Item_sum_hybrid
*
func
)
const
;
bool
Item_sum_hybrid_fix_length_and_dec
(
Item_sum_hybrid
*
func
)
const
;
...
@@ -746,6 +788,10 @@ class Type_handler_string_result: public Type_handler
...
@@ -746,6 +788,10 @@ class Type_handler_string_result: public Type_handler
SORT_FIELD_ATTR
*
attr
)
const
;
SORT_FIELD_ATTR
*
attr
)
const
;
uint32
max_display_length
(
const
Item
*
item
)
const
;
uint32
max_display_length
(
const
Item
*
item
)
const
;
int
Item_save_in_field
(
Item
*
item
,
Field
*
field
,
bool
no_conversions
)
const
;
int
Item_save_in_field
(
Item
*
item
,
Field
*
field
,
bool
no_conversions
)
const
;
bool
can_change_cond_ref_to_const
(
Item_bool_func2
*
target
,
Item
*
target_expr
,
Item
*
target_value
,
Item_bool_func2
*
source
,
Item
*
source_expr
,
Item
*
source_const
)
const
;
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
;
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
;
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
;
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
;
bool
Item_hybrid_func_fix_attributes
(
THD
*
thd
,
Item_hybrid_func
*
func
,
bool
Item_hybrid_func_fix_attributes
(
THD
*
thd
,
Item_hybrid_func
*
func
,
...
...
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