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
26fa7232
Commit
26fa7232
authored
May 06, 2017
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-12707 Split resolve_const_item() into virtual methods in Type_handler
parent
ac53b49b
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
234 additions
and
170 deletions
+234
-170
mysql-test/r/func_debug.result
mysql-test/r/func_debug.result
+40
-40
sql/item.cc
sql/item.cc
+6
-93
sql/item.h
sql/item.h
+4
-17
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+12
-12
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+2
-1
sql/sql_type.cc
sql/sql_type.cc
+138
-5
sql/sql_type.h
sql/sql_type.h
+32
-2
No files found.
mysql-test/r/func_debug.result
View file @
26fa7232
...
...
@@ -173,29 +173,29 @@ SELECT DATE'2001-01-01' IN ('2001-01-01','2001-02-02');
DATE'2001-01-01' IN ('2001-01-01','2001-02-02')
1
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=0 (date
time
)
Note 1105 DBUG: [0] arg=1 handler=0 (date)
Note 1105 DBUG: [1] arg=2 handler=0 (date)
Note 1105 DBUG: types_compatible=yes bisect=yes
SELECT DATE'2001-01-01' IN ('2001-01-01','2001-02-02',NULL);
DATE'2001-01-01' IN ('2001-01-01','2001-02-02',NULL)
1
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=0 (date
time
)
Note 1105 DBUG: [0] arg=1 handler=0 (date)
Note 1105 DBUG: [1] arg=2 handler=0 (date)
Note 1105 DBUG: types_compatible=yes bisect=yes
SELECT DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02');
DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02')
0
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=0 (date
time
)
Note 1105 DBUG: [0] arg=1 handler=0 (date)
Note 1105 DBUG: [1] arg=2 handler=0 (date)
Note 1105 DBUG: types_compatible=yes bisect=yes
SELECT DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02',NULL);
DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02',NULL)
0
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=0 (date
time
)
Note 1105 DBUG: [0] arg=1 handler=0 (date)
Note 1105 DBUG: [1] arg=2 handler=0 (date)
Note 1105 DBUG: types_compatible=yes bisect=yes
# Column predicant, compatible types, bisect
CREATE TABLE t1 (a INT UNSIGNED);
...
...
@@ -354,38 +354,38 @@ CREATE TABLE t1 (a DATE);
SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1;
a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0)
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=0 (date
time
)
Note 1105 DBUG: [2] arg=3 handler=0 (date
time
)
Note 1105 DBUG: [3] arg=4 handler=0 (date
time
)
Note 1105 DBUG: [4] arg=5 handler=0 (date
time
)
Note 1105 DBUG: [0] arg=1 handler=0 (date)
Note 1105 DBUG: [1] arg=2 handler=0 (date)
Note 1105 DBUG: [2] arg=3 handler=0 (date)
Note 1105 DBUG: [3] arg=4 handler=0 (date)
Note 1105 DBUG: [4] arg=5 handler=0 (date)
Note 1105 DBUG: types_compatible=yes bisect=yes
SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1;
a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL)
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=0 (date
time
)
Note 1105 DBUG: [2] arg=3 handler=0 (date
time
)
Note 1105 DBUG: [3] arg=4 handler=0 (date
time
)
Note 1105 DBUG: [4] arg=5 handler=0 (date
time
)
Note 1105 DBUG: [0] arg=1 handler=0 (date)
Note 1105 DBUG: [1] arg=2 handler=0 (date)
Note 1105 DBUG: [2] arg=3 handler=0 (date)
Note 1105 DBUG: [3] arg=4 handler=0 (date)
Note 1105 DBUG: [4] arg=5 handler=0 (date)
Note 1105 DBUG: types_compatible=yes bisect=yes
SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1;
a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0)
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=0 (date
time
)
Note 1105 DBUG: [2] arg=3 handler=0 (date
time
)
Note 1105 DBUG: [3] arg=4 handler=0 (date
time
)
Note 1105 DBUG: [4] arg=5 handler=0 (date
time
)
Note 1105 DBUG: [0] arg=1 handler=0 (date)
Note 1105 DBUG: [1] arg=2 handler=0 (date)
Note 1105 DBUG: [2] arg=3 handler=0 (date)
Note 1105 DBUG: [3] arg=4 handler=0 (date)
Note 1105 DBUG: [4] arg=5 handler=0 (date)
Note 1105 DBUG: types_compatible=yes bisect=yes
SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1;
a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL)
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=0 (date
time
)
Note 1105 DBUG: [2] arg=3 handler=0 (date
time
)
Note 1105 DBUG: [3] arg=4 handler=0 (date
time
)
Note 1105 DBUG: [4] arg=5 handler=0 (date
time
)
Note 1105 DBUG: [0] arg=1 handler=0 (date)
Note 1105 DBUG: [1] arg=2 handler=0 (date)
Note 1105 DBUG: [2] arg=3 handler=0 (date)
Note 1105 DBUG: [3] arg=4 handler=0 (date)
Note 1105 DBUG: [4] arg=5 handler=0 (date)
Note 1105 DBUG: types_compatible=yes bisect=yes
DROP TABLE t1;
CREATE TABLE t1 (a TIME);
...
...
@@ -610,26 +610,26 @@ CREATE TABLE t1 (a DATE);
SELECT DATE'2001-01-01' IN (a,'2001-01-01') FROM t1;
DATE'2001-01-01' IN (a,'2001-01-01')
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=0 (date
time
)
Note 1105 DBUG: [0] arg=1 handler=0 (date)
Note 1105 DBUG: [1] arg=2 handler=0 (date)
Note 1105 DBUG: types_compatible=yes bisect=no
SELECT DATE'2001-01-01' IN (a,'2001-01-01',NULL) FROM t1;
DATE'2001-01-01' IN (a,'2001-01-01',NULL)
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=0 (date
time
)
Note 1105 DBUG: [0] arg=1 handler=0 (date)
Note 1105 DBUG: [1] arg=2 handler=0 (date)
Note 1105 DBUG: types_compatible=yes bisect=no
SELECT DATE'2001-01-01' NOT IN (a,'2001-01-01') FROM t1;
DATE'2001-01-01' NOT IN (a,'2001-01-01')
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=0 (date
time
)
Note 1105 DBUG: [0] arg=1 handler=0 (date)
Note 1105 DBUG: [1] arg=2 handler=0 (date)
Note 1105 DBUG: types_compatible=yes bisect=no
SELECT DATE'2001-01-01' NOT IN (a,'2001-01-01',NULL) FROM t1;
DATE'2001-01-01' NOT IN (a,'2001-01-01',NULL)
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=0 (date
time
)
Note 1105 DBUG: [0] arg=1 handler=0 (date)
Note 1105 DBUG: [1] arg=2 handler=0 (date)
Note 1105 DBUG: types_compatible=yes bisect=no
DROP TABLE t1;
CREATE TABLE t1 (a TIME);
...
...
@@ -1147,25 +1147,25 @@ SELECT a IN (1,DATE'2001-01-01') FROM t1;
a IN (1,DATE'2001-01-01')
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (double)
Note 1105 DBUG: [1] arg=2 handler=1 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=1 (date)
Note 1105 DBUG: types_compatible=no bisect=no
SELECT a IN (1,DATE'2001-01-01',NULL) FROM t1;
a IN (1,DATE'2001-01-01',NULL)
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (double)
Note 1105 DBUG: [1] arg=2 handler=1 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=1 (date)
Note 1105 DBUG: types_compatible=no bisect=no
SELECT a NOT IN (1,DATE'2001-01-01') FROM t1;
a NOT IN (1,DATE'2001-01-01')
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (double)
Note 1105 DBUG: [1] arg=2 handler=1 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=1 (date)
Note 1105 DBUG: types_compatible=no bisect=no
SELECT a NOT IN (1,DATE'2001-01-01',NULL) FROM t1;
a NOT IN (1,DATE'2001-01-01',NULL)
Warnings:
Note 1105 DBUG: [0] arg=1 handler=0 (double)
Note 1105 DBUG: [1] arg=2 handler=1 (date
time
)
Note 1105 DBUG: [1] arg=2 handler=1 (date)
Note 1105 DBUG: types_compatible=no bisect=no
SELECT a IN (1,TIMESTAMP'2001-01-01 10:20:30') FROM t1;
a IN (1,TIMESTAMP'2001-01-01 10:20:30')
...
...
sql/item.cc
View file @
26fa7232
...
...
@@ -9101,101 +9101,14 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
Item
*
item
=
*
ref
;
if
(
item
->
basic_const_item
())
return
;
// Can't be better
Item
*
new_item
=
NULL
;
Item_result
res_type
=
item_cmp_type
(
comp_item
,
item
);
const
char
*
name
=
item
->
name
.
str
;
// Alloced on THD::mem_root
MEM_ROOT
*
mem_root
=
thd
->
mem_root
;
switch
(
res_type
)
{
case
TIME_RESULT
:
{
bool
is_null
;
Item
**
ref_copy
=
ref
;
/* the following call creates a constant and puts it in new_item */
enum_field_types
type
=
item
->
field_type_for_temporal_comparison
(
comp_item
);
get_datetime_value
(
thd
,
&
ref_copy
,
&
new_item
,
type
,
&
is_null
);
if
(
is_null
)
new_item
=
new
(
mem_root
)
Item_null
(
thd
,
name
);
break
;
}
case
STRING_RESULT
:
{
char
buff
[
MAX_FIELD_WIDTH
];
String
tmp
(
buff
,
sizeof
(
buff
),
&
my_charset_bin
),
*
result
;
result
=
item
->
val_str
(
&
tmp
);
if
(
item
->
null_value
)
new_item
=
new
(
mem_root
)
Item_null
(
thd
,
name
);
else
{
uint
length
=
result
->
length
();
char
*
tmp_str
=
thd
->
strmake
(
result
->
ptr
(),
length
);
new_item
=
new
(
mem_root
)
Item_string
(
thd
,
name
,
tmp_str
,
length
,
result
->
charset
());
}
break
;
}
case
INT_RESULT
:
Type_handler_hybrid_field_type
cmp
(
comp_item
->
type_handler_for_comparison
());
if
(
!
cmp
.
aggregate_for_comparison
(
item
->
type_handler_for_comparison
()))
{
longlong
result
=
item
->
val_int
();
uint
length
=
item
->
max_length
;
bool
null_value
=
item
->
null_value
;
new_item
=
(
null_value
?
(
Item
*
)
new
(
mem_root
)
Item_null
(
thd
,
name
)
:
(
Item
*
)
new
(
mem_root
)
Item_int
(
thd
,
name
,
result
,
length
));
break
;
}
case
ROW_RESULT
:
if
(
item
->
type
()
==
Item
::
ROW_ITEM
&&
comp_item
->
type
()
==
Item
::
ROW_ITEM
)
{
/*
Substitute constants only in Item_row's. Don't affect other Items
with ROW_RESULT (eg Item_singlerow_subselect).
For such Items more optimal is to detect if it is constant and replace
it with Item_row. This would optimize queries like this:
SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1);
*/
Item_row
*
item_row
=
(
Item_row
*
)
item
;
Item_row
*
comp_item_row
=
(
Item_row
*
)
comp_item
;
uint
col
;
new_item
=
0
;
/*
If item and comp_item are both Item_row's and have same number of cols
then process items in Item_row one by one.
We can't ignore NULL values here as this item may be used with <=>, in
which case NULL's are significant.
*/
DBUG_ASSERT
(
item
->
result_type
()
==
comp_item
->
result_type
());
DBUG_ASSERT
(
item_row
->
cols
()
==
comp_item_row
->
cols
());
col
=
item_row
->
cols
();
while
(
col
--
>
0
)
resolve_const_item
(
thd
,
item_row
->
addr
(
col
),
comp_item_row
->
element_index
(
col
));
break
;
}
/* Fallthrough */
case
REAL_RESULT
:
{
// It must REAL_RESULT
double
result
=
item
->
val_real
();
uint
length
=
item
->
max_length
,
decimals
=
item
->
decimals
;
bool
null_value
=
item
->
null_value
;
new_item
=
(
null_value
?
(
Item
*
)
new
(
mem_root
)
Item_null
(
thd
,
name
)
:
(
Item
*
)
new
(
mem_root
)
Item_float
(
thd
,
name
,
result
,
decimals
,
length
));
break
;
}
case
DECIMAL_RESULT
:
{
my_decimal
decimal_value
;
my_decimal
*
result
=
item
->
val_decimal
(
&
decimal_value
);
uint
length
=
item
->
max_length
,
decimals
=
item
->
decimals
;
bool
null_value
=
item
->
null_value
;
new_item
=
(
null_value
?
(
Item
*
)
new
(
mem_root
)
Item_null
(
thd
,
name
)
:
(
Item
*
)
new
(
mem_root
)
Item_decimal
(
thd
,
name
,
result
,
length
,
decimals
));
break
;
}
Item
*
new_item
=
cmp
.
type_handler
()
->
make_const_item_for_comparison
(
thd
,
item
,
comp_item
);
if
(
new_item
)
thd
->
change_item_tree
(
ref
,
new_item
);
}
if
(
new_item
)
thd
->
change_item_tree
(
ref
,
new_item
);
}
/**
...
...
sql/item.h
View file @
26fa7232
...
...
@@ -733,6 +733,10 @@ class Item: public Value_source,
{
return
Type_handler
::
get_handler_by_field_type
(
field_type
());
}
const
Type_handler
*
type_handler_for_comparison
()
const
{
return
type_handler
()
->
type_handler_for_comparison
();
}
virtual
const
Type_handler
*
real_type_handler
()
const
{
return
type_handler
();
...
...
@@ -1317,23 +1321,6 @@ class Item: public Value_source,
return
f_type
==
MYSQL_TYPE_TIME
?
val_time_packed
()
:
val_datetime_packed
();
}
enum_field_types
field_type_for_temporal_comparison
(
const
Item
*
other
)
const
{
if
(
cmp_type
()
==
TIME_RESULT
)
{
if
(
other
->
cmp_type
()
==
TIME_RESULT
)
return
Field
::
field_type_merge
(
field_type
(),
other
->
field_type
());
else
return
field_type
();
}
else
{
if
(
other
->
cmp_type
()
==
TIME_RESULT
)
return
other
->
field_type
();
DBUG_ASSERT
(
0
);
// Two non-temporal data types, we should not get to here
return
MYSQL_TYPE_DATETIME
;
}
}
bool
get_seconds
(
ulonglong
*
sec
,
ulong
*
sec_part
);
virtual
bool
get_date_result
(
MYSQL_TIME
*
ltime
,
ulonglong
fuzzydate
)
{
return
get_date
(
ltime
,
fuzzydate
);
}
...
...
sql/item_cmpfunc.cc
View file @
26fa7232
...
...
@@ -552,20 +552,20 @@ bool Arg_comparator::set_cmp_func_string()
}
bool
Arg_comparator
::
set_cmp_func_t
emporal
()
bool
Arg_comparator
::
set_cmp_func_t
ime
()
{
enum_field_types
f_type
=
a
[
0
]
->
field_type_for_temporal_comparison
(
b
[
0
]);
m_compare_collation
=
&
my_charset_numeric
;
if
(
f_type
==
MYSQL_TYPE_TIME
)
{
func
=
is_owner_equal_func
()
?
&
Arg_comparator
::
compare_e_time
:
&
Arg_comparator
::
compare_time
;
}
else
{
func
=
is_owner_equal_func
()
?
&
Arg_comparator
::
compare_e_datetime
:
&
Arg_comparator
::
compare_datetime
;
}
func
=
is_owner_equal_func
()
?
&
Arg_comparator
::
compare_e_time
:
&
Arg_comparator
::
compare_time
;
return
false
;
}
bool
Arg_comparator
::
set_cmp_func_datetime
()
{
m_compare_collation
=
&
my_charset_numeric
;
func
=
is_owner_equal_func
()
?
&
Arg_comparator
::
compare_e_datetime
:
&
Arg_comparator
::
compare_datetime
;
return
false
;
}
...
...
sql/item_cmpfunc.h
View file @
26fa7232
...
...
@@ -82,7 +82,8 @@ class Arg_comparator: public Sql_alloc
bool
set_cmp_func_for_row_arguments
();
bool
set_cmp_func_row
();
bool
set_cmp_func_string
();
bool
set_cmp_func_temporal
();
bool
set_cmp_func_time
();
bool
set_cmp_func_datetime
();
bool
set_cmp_func_int
();
bool
set_cmp_func_real
();
bool
set_cmp_func_decimal
();
...
...
sql/sql_type.cc
View file @
26fa7232
...
...
@@ -457,7 +457,19 @@ const Type_handler *Type_handler_time_common::type_handler_for_comparison() cons
return
&
type_handler_time
;
}
const
Type_handler
*
Type_handler_temporal_with_date
::
type_handler_for_comparison
()
const
const
Type_handler
*
Type_handler_date_common
::
type_handler_for_comparison
()
const
{
return
&
type_handler_newdate
;
}
const
Type_handler
*
Type_handler_datetime_common
::
type_handler_for_comparison
()
const
{
return
&
type_handler_datetime
;
}
const
Type_handler
*
Type_handler_timestamp_common
::
type_handler_for_comparison
()
const
{
return
&
type_handler_datetime
;
}
...
...
@@ -652,9 +664,14 @@ Type_handler_hybrid_field_type::aggregate_for_comparison(const Type_handler *h)
{
/*
We're here if both m_type_handler and h are temporal data types.
- If both data types are TIME, we preserve TIME.
- If both data types are DATE, we preserve DATE.
Preserving DATE is needed for EXPLAIN FORMAT=JSON,
to print DATE constants using proper format:
'YYYY-MM-DD' rather than 'YYYY-MM-DD 00:00:00'.
*/
if
(
field_type
()
!=
MYSQL_TYPE_TIME
||
h
->
field_type
()
!=
MYSQL_TYPE_TIME
)
m_type_handler
=
&
type_handler_datetime
;
// DATETIME bits TIME
if
(
field_type
()
!=
h
->
field_type
()
)
m_type_handler
=
&
type_handler_datetime
;
}
}
else
if
((
a
==
INT_RESULT
||
a
==
DECIMAL_RESULT
)
&&
...
...
@@ -1917,9 +1934,15 @@ bool Type_handler_string_result::set_comparator_func(Arg_comparator *cmp) const
return
cmp
->
set_cmp_func_string
();
}
bool
Type_handler_t
emporal_result
::
set_comparator_func
(
Arg_comparator
*
cmp
)
const
bool
Type_handler_t
ime_common
::
set_comparator_func
(
Arg_comparator
*
cmp
)
const
{
return
cmp
->
set_cmp_func_temporal
();
return
cmp
->
set_cmp_func_time
();
}
bool
Type_handler_temporal_with_date
::
set_comparator_func
(
Arg_comparator
*
cmp
)
const
{
return
cmp
->
set_cmp_func_datetime
();
}
...
...
@@ -4211,3 +4234,113 @@ bool Type_handler::
}
/***************************************************************************/
Item
*
Type_handler_int_result
::
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
item
,
Item
*
cmp
)
const
{
longlong
result
=
item
->
val_int
();
if
(
item
->
null_value
)
return
new
(
thd
->
mem_root
)
Item_null
(
thd
,
item
->
name
.
str
);
return
new
(
thd
->
mem_root
)
Item_int
(
thd
,
item
->
name
.
str
,
result
,
item
->
max_length
);
}
Item
*
Type_handler_real_result
::
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
item
,
Item
*
cmp
)
const
{
double
result
=
item
->
val_real
();
if
(
item
->
null_value
)
return
new
(
thd
->
mem_root
)
Item_null
(
thd
,
item
->
name
.
str
);
return
new
(
thd
->
mem_root
)
Item_float
(
thd
,
item
->
name
.
str
,
result
,
item
->
decimals
,
item
->
max_length
);
}
Item
*
Type_handler_decimal_result
::
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
item
,
Item
*
cmp
)
const
{
my_decimal
decimal_value
;
my_decimal
*
result
=
item
->
val_decimal
(
&
decimal_value
);
if
(
item
->
null_value
)
return
new
(
thd
->
mem_root
)
Item_null
(
thd
,
item
->
name
.
str
);
return
new
(
thd
->
mem_root
)
Item_decimal
(
thd
,
item
->
name
.
str
,
result
,
item
->
max_length
,
item
->
decimals
);
}
Item
*
Type_handler_string_result
::
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
item
,
Item
*
cmp
)
const
{
StringBuffer
<
MAX_FIELD_WIDTH
>
tmp
;
String
*
result
=
item
->
val_str
(
&
tmp
);
if
(
item
->
null_value
)
return
new
(
thd
->
mem_root
)
Item_null
(
thd
,
item
->
name
.
str
);
uint
length
=
result
->
length
();
char
*
tmp_str
=
thd
->
strmake
(
result
->
ptr
(),
length
);
return
new
(
thd
->
mem_root
)
Item_string
(
thd
,
item
->
name
.
str
,
tmp_str
,
length
,
result
->
charset
());
}
Item
*
Type_handler_time_common
::
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
item
,
Item
*
cmp
)
const
{
Item_cache_temporal
*
cache
;
longlong
value
=
item
->
val_time_packed
();
if
(
item
->
null_value
)
return
new
(
thd
->
mem_root
)
Item_null
(
thd
,
item
->
name
.
str
);
cache
=
new
(
thd
->
mem_root
)
Item_cache_temporal
(
thd
,
field_type
());
if
(
cache
)
cache
->
store_packed
(
value
,
item
);
return
cache
;
}
Item
*
Type_handler_temporal_with_date
::
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
item
,
Item
*
cmp
)
const
{
Item_cache_temporal
*
cache
;
longlong
value
=
item
->
val_datetime_packed
();
if
(
item
->
null_value
)
return
new
(
thd
->
mem_root
)
Item_null
(
thd
,
item
->
name
.
str
);
cache
=
new
(
thd
->
mem_root
)
Item_cache_temporal
(
thd
,
field_type
());
if
(
cache
)
cache
->
store_packed
(
value
,
item
);
return
cache
;
}
Item
*
Type_handler_row
::
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
item
,
Item
*
cmp
)
const
{
if
(
item
->
type
()
==
Item
::
ROW_ITEM
&&
cmp
->
type
()
==
Item
::
ROW_ITEM
)
{
/*
Substitute constants only in Item_row's. Don't affect other Items
with ROW_RESULT (eg Item_singlerow_subselect).
For such Items more optimal is to detect if it is constant and replace
it with Item_row. This would optimize queries like this:
SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1);
*/
Item_row
*
item_row
=
(
Item_row
*
)
item
;
Item_row
*
comp_item_row
=
(
Item_row
*
)
cmp
;
uint
col
;
/*
If item and comp_item are both Item_row's and have same number of cols
then process items in Item_row one by one.
We can't ignore NULL values here as this item may be used with <=>, in
which case NULL's are significant.
*/
DBUG_ASSERT
(
item
->
result_type
()
==
cmp
->
result_type
());
DBUG_ASSERT
(
item_row
->
cols
()
==
comp_item_row
->
cols
());
col
=
item_row
->
cols
();
while
(
col
--
>
0
)
resolve_const_item
(
thd
,
item_row
->
addr
(
col
),
comp_item_row
->
element_index
(
col
));
}
return
NULL
;
}
/***************************************************************************/
sql/sql_type.h
View file @
26fa7232
...
...
@@ -746,6 +746,26 @@ class Type_handler
virtual
bool
subquery_type_allows_materialization
(
const
Item
*
inner
,
const
Item
*
outer
)
const
=
0
;
/**
Make a simple constant replacement item for a constant "src",
so the new item can futher be used for comparison with "cmp", e.g.:
src = cmp -> replacement = cmp
"this" is the type handler that is used to compare "src" and "cmp".
@param thd - current thread, for mem_root
@param src - The item that we want to replace. It's a const item,
but it can be complex enough to calculate on every row.
@param cmp - The src's comparand.
@retval - a pointer to the created replacement Item
@retval - NULL, if could not create a replacement (e.g. on EOM).
NULL is also returned for ROWs, because instead of replacing
a Item_row to a new Item_row, Type_handler_row just replaces
its elements.
*/
virtual
Item
*
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
src
,
Item
*
cmp
)
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
Item_hybrid_func_fix_attributes
(
THD
*
thd
,
Item_hybrid_func
*
func
,
...
...
@@ -935,6 +955,7 @@ class Type_handler_row: public Type_handler
DBUG_ASSERT
(
0
);
return
false
;
}
Item
*
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
src
,
Item
*
cmp
)
const
;
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
;
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
;
bool
Item_hybrid_func_fix_attributes
(
THD
*
thd
,
Item_hybrid_func
*
func
,
...
...
@@ -1137,6 +1158,7 @@ class Type_handler_real_result: public Type_handler_numeric
SORT_FIELD_ATTR
*
attr
)
const
;
bool
Item_save_in_value
(
Item
*
item
,
st_value
*
value
)
const
;
int
Item_save_in_field
(
Item
*
item
,
Field
*
field
,
bool
no_conversions
)
const
;
Item
*
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
src
,
Item
*
cmp
)
const
;
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
;
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
;
bool
Item_hybrid_func_fix_attributes
(
THD
*
thd
,
Item_hybrid_func
*
func
,
...
...
@@ -1201,6 +1223,7 @@ class Type_handler_decimal_result: public Type_handler_numeric
return
Item_send_str
(
item
,
protocol
,
buf
);
}
int
Item_save_in_field
(
Item
*
item
,
Field
*
field
,
bool
no_conversions
)
const
;
Item
*
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
src
,
Item
*
cmp
)
const
;
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
;
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
;
bool
Item_hybrid_func_fix_attributes
(
THD
*
thd
,
Item_hybrid_func
*
func
,
...
...
@@ -1257,6 +1280,7 @@ class Type_handler_int_result: public Type_handler_numeric
SORT_FIELD_ATTR
*
attr
)
const
;
bool
Item_save_in_value
(
Item
*
item
,
st_value
*
value
)
const
;
int
Item_save_in_field
(
Item
*
item
,
Field
*
field
,
bool
no_conversions
)
const
;
Item
*
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
src
,
Item
*
cmp
)
const
;
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
;
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
;
bool
Item_hybrid_func_fix_attributes
(
THD
*
thd
,
Item_hybrid_func
*
func
,
...
...
@@ -1318,7 +1342,6 @@ class Type_handler_temporal_result: public Type_handler
bool
subquery_type_allows_materialization
(
const
Item
*
inner
,
const
Item
*
outer
)
const
;
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
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_sum_fix_length_and_dec
(
Item_sum_sum
*
)
const
;
bool
Item_sum_avg_fix_length_and_dec
(
Item_sum_avg
*
)
const
;
...
...
@@ -1401,6 +1424,7 @@ class Type_handler_string_result: public Type_handler
Item
*
source_expr
,
Item
*
source_const
)
const
;
bool
subquery_type_allows_materialization
(
const
Item
*
inner
,
const
Item
*
outer
)
const
;
Item
*
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
src
,
Item
*
cmp
)
const
;
Item_cache
*
Item_get_cache
(
THD
*
thd
,
const
Item
*
item
)
const
;
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
;
bool
Item_hybrid_func_fix_attributes
(
THD
*
thd
,
Item_hybrid_func
*
func
,
...
...
@@ -1693,6 +1717,8 @@ class Type_handler_time_common: public Type_handler_temporal_result
String
*
print_item_value
(
THD
*
thd
,
Item
*
item
,
String
*
str
)
const
;
bool
Item_hybrid_func_fix_attributes
(
THD
*
thd
,
Item_hybrid_func
*
func
,
Item
**
items
,
uint
nitems
)
const
;
Item
*
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
src
,
Item
*
cmp
)
const
;
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
;
cmp_item
*
make_cmp_item
(
THD
*
thd
,
CHARSET_INFO
*
cs
)
const
;
in_vector
*
make_in_vector
(
THD
*
,
const
Item_func_in
*
,
uint
nargs
)
const
;
};
...
...
@@ -1729,13 +1755,14 @@ class Type_handler_temporal_with_date: public Type_handler_temporal_result
{
public:
virtual
~
Type_handler_temporal_with_date
()
{}
const
Type_handler
*
type_handler_for_comparison
()
const
;
bool
Item_save_in_value
(
Item
*
item
,
st_value
*
value
)
const
;
bool
Item_send
(
Item
*
item
,
Protocol
*
protocol
,
st_value
*
buf
)
const
{
return
Item_send_date
(
item
,
protocol
,
buf
);
}
int
Item_save_in_field
(
Item
*
item
,
Field
*
field
,
bool
no_conversions
)
const
;
Item
*
make_const_item_for_comparison
(
THD
*
thd
,
Item
*
src
,
Item
*
cmp
)
const
;
bool
set_comparator_func
(
Arg_comparator
*
cmp
)
const
;
cmp_item
*
make_cmp_item
(
THD
*
thd
,
CHARSET_INFO
*
cs
)
const
;
in_vector
*
make_in_vector
(
THD
*
,
const
Item_func_in
*
,
uint
nargs
)
const
;
};
...
...
@@ -1747,6 +1774,7 @@ class Type_handler_date_common: public Type_handler_temporal_with_date
public:
virtual
~
Type_handler_date_common
()
{}
const
Name
name
()
const
{
return
m_name_date
;
}
const
Type_handler
*
type_handler_for_comparison
()
const
;
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_DATE
;
}
enum_mysql_timestamp_type
mysql_timestamp_type
()
const
{
...
...
@@ -1790,6 +1818,7 @@ class Type_handler_datetime_common: public Type_handler_temporal_with_date
public:
virtual
~
Type_handler_datetime_common
()
{}
const
Name
name
()
const
{
return
m_name_datetime
;
}
const
Type_handler
*
type_handler_for_comparison
()
const
;
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_DATETIME
;
}
enum_mysql_timestamp_type
mysql_timestamp_type
()
const
{
...
...
@@ -1846,6 +1875,7 @@ class Type_handler_timestamp_common: public Type_handler_temporal_with_date
public:
virtual
~
Type_handler_timestamp_common
()
{}
const
Name
name
()
const
{
return
m_name_timestamp
;
}
const
Type_handler
*
type_handler_for_comparison
()
const
;
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_TIMESTAMP
;
}
enum_mysql_timestamp_type
mysql_timestamp_type
()
const
{
...
...
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