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
01b308c3
Commit
01b308c3
authored
May 04, 2017
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-12617 CASE and CASE-alike hybrid functions do not preserve exact data types
parent
78a891c8
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
275 additions
and
149 deletions
+275
-149
mysql-test/r/func_hybrid_type.result
mysql-test/r/func_hybrid_type.result
+123
-88
mysql-test/r/null.result
mysql-test/r/null.result
+48
-48
mysql-test/t/func_hybrid_type.test
mysql-test/t/func_hybrid_type.test
+23
-0
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+1
-1
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+9
-11
sql/item_func.h
sql/item_func.h
+36
-0
sql/sql_type.cc
sql/sql_type.cc
+34
-1
sql/sql_type.h
sql/sql_type.h
+1
-0
No files found.
mysql-test/r/func_hybrid_type.result
View file @
01b308c3
This diff is collapsed.
Click to expand it.
mysql-test/r/null.result
View file @
01b308c3
...
@@ -613,22 +613,22 @@ FROM t1;
...
@@ -613,22 +613,22 @@ FROM t1;
SHOW CREATE TABLE t2;
SHOW CREATE TABLE t2;
Table Create Table
Table Create Table
t2 CREATE TABLE `t2` (
t2 CREATE TABLE `t2` (
`NULLIF(c_tinyint, 1)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, 1)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_smallint)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_smallint)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_tinyint)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_tinyint)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_int)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_int)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_bigint)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_bigint)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_float)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_float)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_double)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_double)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_decimal103)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_decimal103)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_varchar10)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_varchar10)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_text)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_text)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_blob)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_blob)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_enum)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_enum)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_datetime3)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_datetime3)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_timestamp3)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_timestamp3)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_date)` int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_date)`
tiny
int(4) DEFAULT NULL,
`NULLIF(c_tinyint, c_time)` int(4) DEFAULT NULL
`NULLIF(c_tinyint, c_time)`
tiny
int(4) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
CREATE TABLE t2 AS SELECT
...
@@ -652,22 +652,22 @@ FROM t1;
...
@@ -652,22 +652,22 @@ FROM t1;
SHOW CREATE TABLE t2;
SHOW CREATE TABLE t2;
Table Create Table
Table Create Table
t2 CREATE TABLE `t2` (
t2 CREATE TABLE `t2` (
`NULLIF(c_smallint, 1)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, 1)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_smallint)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_smallint)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_tinyint)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_tinyint)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_int)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_int)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_bigint)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_bigint)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_float)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_float)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_double)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_double)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_decimal103)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_decimal103)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_varchar10)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_varchar10)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_text)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_text)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_blob)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_blob)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_enum)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_enum)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_datetime3)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_datetime3)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_timestamp3)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_timestamp3)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_date)` int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_date)`
small
int(6) DEFAULT NULL,
`NULLIF(c_smallint, c_time)` int(6) DEFAULT NULL
`NULLIF(c_smallint, c_time)`
small
int(6) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
CREATE TABLE t2 AS SELECT
...
@@ -769,22 +769,22 @@ FROM t1;
...
@@ -769,22 +769,22 @@ FROM t1;
SHOW CREATE TABLE t2;
SHOW CREATE TABLE t2;
Table Create Table
Table Create Table
t2 CREATE TABLE `t2` (
t2 CREATE TABLE `t2` (
`NULLIF(c_float, 1)`
double
DEFAULT NULL,
`NULLIF(c_float, 1)`
float
DEFAULT NULL,
`NULLIF(c_float, c_smallint)`
double
DEFAULT NULL,
`NULLIF(c_float, c_smallint)`
float
DEFAULT NULL,
`NULLIF(c_float, c_tinyint)`
double
DEFAULT NULL,
`NULLIF(c_float, c_tinyint)`
float
DEFAULT NULL,
`NULLIF(c_float, c_int)`
double
DEFAULT NULL,
`NULLIF(c_float, c_int)`
float
DEFAULT NULL,
`NULLIF(c_float, c_bigint)`
double
DEFAULT NULL,
`NULLIF(c_float, c_bigint)`
float
DEFAULT NULL,
`NULLIF(c_float, c_float)`
double
DEFAULT NULL,
`NULLIF(c_float, c_float)`
float
DEFAULT NULL,
`NULLIF(c_float, c_double)`
double
DEFAULT NULL,
`NULLIF(c_float, c_double)`
float
DEFAULT NULL,
`NULLIF(c_float, c_decimal103)`
double
DEFAULT NULL,
`NULLIF(c_float, c_decimal103)`
float
DEFAULT NULL,
`NULLIF(c_float, c_varchar10)`
double
DEFAULT NULL,
`NULLIF(c_float, c_varchar10)`
float
DEFAULT NULL,
`NULLIF(c_float, c_text)`
double
DEFAULT NULL,
`NULLIF(c_float, c_text)`
float
DEFAULT NULL,
`NULLIF(c_float, c_blob)`
double
DEFAULT NULL,
`NULLIF(c_float, c_blob)`
float
DEFAULT NULL,
`NULLIF(c_float, c_enum)`
double
DEFAULT NULL,
`NULLIF(c_float, c_enum)`
float
DEFAULT NULL,
`NULLIF(c_float, c_datetime3)`
double
DEFAULT NULL,
`NULLIF(c_float, c_datetime3)`
float
DEFAULT NULL,
`NULLIF(c_float, c_timestamp3)`
double
DEFAULT NULL,
`NULLIF(c_float, c_timestamp3)`
float
DEFAULT NULL,
`NULLIF(c_float, c_date)`
double
DEFAULT NULL,
`NULLIF(c_float, c_date)`
float
DEFAULT NULL,
`NULLIF(c_float, c_time)`
double
DEFAULT NULL
`NULLIF(c_float, c_time)`
float
DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
CREATE TABLE t2 AS SELECT
...
...
mysql-test/t/func_hybrid_type.test
View file @
01b308c3
...
@@ -510,6 +510,29 @@ SHOW CREATE TABLE t2;
...
@@ -510,6 +510,29 @@ SHOW CREATE TABLE t2;
DROP
TABLE
t2
;
DROP
TABLE
t2
;
DROP
TABLE
t1
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# MDEV-12617 CASE and CASE-alike hybrid functions do not preserve exact data types
--
echo
#
CREATE
TABLE
t1
(
a
FLOAT
(
10
,
2
));
CREATE
TABLE
t2
AS
SELECT
COALESCE
(
a
)
FROM
t1
;
SHOW
CREATE
TABLE
t2
;
DROP
TABLE
t2
,
t1
;
CREATE
TABLE
t1
(
a
FLOAT
(
10
,
2
));
CREATE
TABLE
t2
AS
SELECT
LEAST
(
a
,
a
)
FROM
t1
;
SHOW
CREATE
TABLE
t2
;
DROP
TABLE
t2
,
t1
;
CREATE
TABLE
t1
(
a
TINYINT
(
1
));
CREATE
TABLE
t2
AS
SELECT
COALESCE
(
a
)
FROM
t1
;
SHOW
CREATE
TABLE
t2
;
DROP
TABLE
t2
,
t1
;
CREATE
TABLE
t1
(
a
TINYINT
(
1
));
CREATE
TABLE
t2
AS
SELECT
LEAST
(
a
,
a
)
FROM
t1
;
SHOW
CREATE
TABLE
t2
;
DROP
TABLE
t2
,
t1
;
--
echo
#
--
echo
#
--
echo
# End of 10.3 tests
--
echo
# End of 10.3 tests
...
...
sql/item_cmpfunc.cc
View file @
01b308c3
...
@@ -2786,7 +2786,7 @@ Item_func_nullif::is_null()
...
@@ -2786,7 +2786,7 @@ Item_func_nullif::is_null()
Item_func_case
::
Item_func_case
(
THD
*
thd
,
List
<
Item
>
&
list
,
Item_func_case
::
Item_func_case
(
THD
*
thd
,
List
<
Item
>
&
list
,
Item
*
first_expr_arg
,
Item
*
else_expr_arg
)
:
Item
*
first_expr_arg
,
Item
*
else_expr_arg
)
:
Item_func_
hybrid_field_type
(
thd
),
Item_func_
case_expression
(
thd
),
Predicant_to_list_comparator
(
thd
,
list
.
elements
/*QQ*/
),
Predicant_to_list_comparator
(
thd
,
list
.
elements
/*QQ*/
),
first_expr_num
(
-
1
),
else_expr_num
(
-
1
),
first_expr_num
(
-
1
),
else_expr_num
(
-
1
),
left_cmp_type
(
INT_RESULT
),
m_found_types
(
0
)
left_cmp_type
(
INT_RESULT
),
m_found_types
(
0
)
...
...
sql/item_cmpfunc.h
View file @
01b308c3
...
@@ -965,13 +965,13 @@ class Item_func_interval :public Item_int_func
...
@@ -965,13 +965,13 @@ class Item_func_interval :public Item_int_func
};
};
class
Item_func_coalesce
:
public
Item_func_
hybrid_field_type
class
Item_func_coalesce
:
public
Item_func_
case_expression
{
{
public:
public:
Item_func_coalesce
(
THD
*
thd
,
Item
*
a
,
Item
*
b
)
:
Item_func_coalesce
(
THD
*
thd
,
Item
*
a
,
Item
*
b
)
:
Item_func_
hybrid_field_type
(
thd
,
a
,
b
)
{}
Item_func_
case_expression
(
thd
,
a
,
b
)
{}
Item_func_coalesce
(
THD
*
thd
,
List
<
Item
>
&
list
)
:
Item_func_coalesce
(
THD
*
thd
,
List
<
Item
>
&
list
)
:
Item_func_
hybrid_field_type
(
thd
,
list
)
{}
Item_func_
case_expression
(
thd
,
list
)
{}
double
real_op
();
double
real_op
();
longlong
int_op
();
longlong
int_op
();
String
*
str_op
(
String
*
);
String
*
str_op
(
String
*
);
...
@@ -995,7 +995,7 @@ class Item_func_coalesce :public Item_func_hybrid_field_type
...
@@ -995,7 +995,7 @@ class Item_func_coalesce :public Item_func_hybrid_field_type
IF(switch, arg1, arg2)
IF(switch, arg1, arg2)
NVL2(switch, arg1, arg2)
NVL2(switch, arg1, arg2)
*/
*/
class
Item_func_case_abbreviation2
:
public
Item_func_
hybrid_field_type
class
Item_func_case_abbreviation2
:
public
Item_func_
case_expression
{
{
protected:
protected:
void
fix_length_and_dec2
(
Item
**
items
)
void
fix_length_and_dec2
(
Item
**
items
)
...
@@ -1034,9 +1034,9 @@ class Item_func_case_abbreviation2 :public Item_func_hybrid_field_type
...
@@ -1034,9 +1034,9 @@ class Item_func_case_abbreviation2 :public Item_func_hybrid_field_type
public:
public:
Item_func_case_abbreviation2
(
THD
*
thd
,
Item
*
a
,
Item
*
b
)
:
Item_func_case_abbreviation2
(
THD
*
thd
,
Item
*
a
,
Item
*
b
)
:
Item_func_
hybrid_field_type
(
thd
,
a
,
b
)
{
}
Item_func_
case_expression
(
thd
,
a
,
b
)
{
}
Item_func_case_abbreviation2
(
THD
*
thd
,
Item
*
a
,
Item
*
b
,
Item
*
c
)
:
Item_func_case_abbreviation2
(
THD
*
thd
,
Item
*
a
,
Item
*
b
,
Item
*
c
)
:
Item_func_
hybrid_field_type
(
thd
,
a
,
b
,
c
)
{
}
Item_func_
case_expression
(
thd
,
a
,
b
,
c
)
{
}
};
};
...
@@ -1056,8 +1056,6 @@ class Item_func_ifnull :public Item_func_case_abbreviation2
...
@@ -1056,8 +1056,6 @@ class Item_func_ifnull :public Item_func_case_abbreviation2
maybe_null
=
args
[
1
]
->
maybe_null
;
maybe_null
=
args
[
1
]
->
maybe_null
;
}
}
const
char
*
func_name
()
const
{
return
"ifnull"
;
}
const
char
*
func_name
()
const
{
return
"ifnull"
;
}
Field
*
create_field_for_create_select
(
TABLE
*
table
)
{
return
tmp_table_field_from_field_type
(
table
);
}
table_map
not_null_tables
()
const
{
return
0
;
}
table_map
not_null_tables
()
const
{
return
0
;
}
uint
decimal_precision
()
const
uint
decimal_precision
()
const
...
@@ -1161,7 +1159,7 @@ class Item_func_nvl2 :public Item_func_case_abbreviation2_switch
...
@@ -1161,7 +1159,7 @@ class Item_func_nvl2 :public Item_func_case_abbreviation2_switch
};
};
class
Item_func_nullif
:
public
Item_func_
hybrid_field_type
class
Item_func_nullif
:
public
Item_func_
case_expression
{
{
Arg_comparator
cmp
;
Arg_comparator
cmp
;
/*
/*
...
@@ -1199,7 +1197,7 @@ class Item_func_nullif :public Item_func_hybrid_field_type
...
@@ -1199,7 +1197,7 @@ class Item_func_nullif :public Item_func_hybrid_field_type
See also Item_func_nullif::fix_length_and_dec().
See also Item_func_nullif::fix_length_and_dec().
*/
*/
Item_func_nullif
(
THD
*
thd
,
Item
*
a
,
Item
*
b
)
:
Item_func_nullif
(
THD
*
thd
,
Item
*
a
,
Item
*
b
)
:
Item_func_
hybrid_field_type
(
thd
,
a
,
b
,
a
),
Item_func_
case_expression
(
thd
,
a
,
b
,
a
),
m_cache
(
NULL
),
m_cache
(
NULL
),
m_arg0
(
NULL
)
m_arg0
(
NULL
)
{
arg_count
--
;
}
{
arg_count
--
;
}
...
@@ -2031,7 +2029,7 @@ class Predicant_to_list_comparator
...
@@ -2031,7 +2029,7 @@ class Predicant_to_list_comparator
function and only comparators for there result types are used.
function and only comparators for there result types are used.
*/
*/
class
Item_func_case
:
public
Item_func_
hybrid_field_type
,
class
Item_func_case
:
public
Item_func_
case_expression
,
public
Predicant_to_list_comparator
public
Predicant_to_list_comparator
{
{
int
first_expr_num
,
else_expr_num
;
int
first_expr_num
,
else_expr_num
;
...
...
sql/item_func.h
View file @
01b308c3
...
@@ -599,6 +599,38 @@ class Item_func_hybrid_field_type: public Item_hybrid_func
...
@@ -599,6 +599,38 @@ class Item_func_hybrid_field_type: public Item_hybrid_func
};
};
/*
This class resembles SQL standard CASE-alike expressions:
CASE and its abbreviations COALESCE, NULLIF, IFNULL, IF.
<case expression> ::= <case abbreviation>
| <case specification>
*/
class
Item_func_case_expression
:
public
Item_func_hybrid_field_type
{
public:
Item_func_case_expression
(
THD
*
thd
)
:
Item_func_hybrid_field_type
(
thd
)
{
}
Item_func_case_expression
(
THD
*
thd
,
Item
*
a
)
:
Item_func_hybrid_field_type
(
thd
,
a
)
{
}
Item_func_case_expression
(
THD
*
thd
,
Item
*
a
,
Item
*
b
)
:
Item_func_hybrid_field_type
(
thd
,
a
,
b
)
{
}
Item_func_case_expression
(
THD
*
thd
,
Item
*
a
,
Item
*
b
,
Item
*
c
)
:
Item_func_hybrid_field_type
(
thd
,
a
,
b
,
c
)
{
}
Item_func_case_expression
(
THD
*
thd
,
List
<
Item
>
&
list
)
:
Item_func_hybrid_field_type
(
thd
,
list
)
{
}
Field
*
create_tmp_field
(
bool
group
,
TABLE
*
table
)
{
return
tmp_table_field_from_field_type
(
table
);
}
Field
*
create_field_for_create_select
(
TABLE
*
table
)
{
return
tmp_table_field_from_field_type
(
table
);
}
};
class
Item_func_numhybrid
:
public
Item_func_hybrid_field_type
class
Item_func_numhybrid
:
public
Item_func_hybrid_field_type
{
{
protected:
protected:
...
@@ -1404,6 +1436,10 @@ class Item_func_min_max :public Item_hybrid_func
...
@@ -1404,6 +1436,10 @@ class Item_func_min_max :public Item_hybrid_func
Item_func_min_max
(
THD
*
thd
,
List
<
Item
>
&
list
,
int
cmp_sign_arg
)
:
Item_func_min_max
(
THD
*
thd
,
List
<
Item
>
&
list
,
int
cmp_sign_arg
)
:
Item_hybrid_func
(
thd
,
list
),
cmp_sign
(
cmp_sign_arg
)
Item_hybrid_func
(
thd
,
list
),
cmp_sign
(
cmp_sign_arg
)
{}
{}
Field
*
create_tmp_field
(
bool
group
,
TABLE
*
table
)
{
return
tmp_table_field_from_field_type
(
table
);
}
Field
*
create_field_for_create_select
(
TABLE
*
table
)
{
return
tmp_table_field_from_field_type
(
table
);
}
String
*
val_str_native
(
String
*
str
);
String
*
val_str_native
(
String
*
str
);
double
val_real_native
();
double
val_real_native
();
longlong
val_int_native
();
longlong
val_int_native
();
...
...
sql/sql_type.cc
View file @
01b308c3
...
@@ -513,6 +513,21 @@ Type_handler_hybrid_field_type::aggregate_for_result(const Type_handler *other)
...
@@ -513,6 +513,21 @@ Type_handler_hybrid_field_type::aggregate_for_result(const Type_handler *other)
}
}
/*
This method is called for CASE (and its abbreviations) and LEAST/GREATEST
when data type aggregation returned LONGLONG and there were some BIT
expressions. This helps to adjust the data type from LONGLONG to LONG
if all expressions fit.
*/
const
Type_handler
*
Type_handler
::
bit_and_int_mixture_handler
(
uint
max_char_length
)
{
if
(
max_char_length
<=
MY_INT32_NUM_DECIMAL_DIGITS
)
return
&
type_handler_long
;
return
&
type_handler_longlong
;
}
/**
/**
@brief Aggregates field types from the array of items.
@brief Aggregates field types from the array of items.
...
@@ -552,6 +567,8 @@ Type_handler_hybrid_field_type::aggregate_for_result(const char *funcname,
...
@@ -552,6 +567,8 @@ Type_handler_hybrid_field_type::aggregate_for_result(const char *funcname,
Item
**
items
,
uint
nitems
,
Item
**
items
,
uint
nitems
,
bool
treat_bit_as_number
)
bool
treat_bit_as_number
)
{
{
bool
bit_and_non_bit_mixture_found
=
false
;
uint32
max_display_length
;
if
(
!
nitems
||
items
[
0
]
->
result_type
()
==
ROW_RESULT
)
if
(
!
nitems
||
items
[
0
]
->
result_type
()
==
ROW_RESULT
)
{
{
DBUG_ASSERT
(
0
);
DBUG_ASSERT
(
0
);
...
@@ -559,12 +576,15 @@ Type_handler_hybrid_field_type::aggregate_for_result(const char *funcname,
...
@@ -559,12 +576,15 @@ Type_handler_hybrid_field_type::aggregate_for_result(const char *funcname,
return
true
;
return
true
;
}
}
set_handler
(
items
[
0
]
->
type_handler
());
set_handler
(
items
[
0
]
->
type_handler
());
max_display_length
=
items
[
0
]
->
max_display_length
();
for
(
uint
i
=
1
;
i
<
nitems
;
i
++
)
for
(
uint
i
=
1
;
i
<
nitems
;
i
++
)
{
{
const
Type_handler
*
cur
=
items
[
i
]
->
type_handler
();
const
Type_handler
*
cur
=
items
[
i
]
->
type_handler
();
set_if_bigger
(
max_display_length
,
items
[
i
]
->
max_display_length
());
if
(
treat_bit_as_number
&&
if
(
treat_bit_as_number
&&
((
type_handler
()
==
&
type_handler_bit
)
^
(
cur
==
&
type_handler_bit
)))
((
type_handler
()
==
&
type_handler_bit
)
^
(
cur
==
&
type_handler_bit
)))
{
{
bit_and_non_bit_mixture_found
=
true
;
if
(
type_handler
()
==
&
type_handler_bit
)
if
(
type_handler
()
==
&
type_handler_bit
)
set_handler
(
&
type_handler_longlong
);
// BIT + non-BIT
set_handler
(
&
type_handler_longlong
);
// BIT + non-BIT
else
else
...
@@ -577,6 +597,8 @@ Type_handler_hybrid_field_type::aggregate_for_result(const char *funcname,
...
@@ -577,6 +597,8 @@ Type_handler_hybrid_field_type::aggregate_for_result(const char *funcname,
return
true
;
return
true
;
}
}
}
}
if
(
bit_and_non_bit_mixture_found
&&
type_handler
()
==
&
type_handler_longlong
)
set_handler
(
Type_handler
::
bit_and_int_mixture_handler
(
max_display_length
));
return
false
;
return
false
;
}
}
...
@@ -728,7 +750,9 @@ Type_handler_hybrid_field_type::aggregate_for_min_max(const Type_handler *h)
...
@@ -728,7 +750,9 @@ Type_handler_hybrid_field_type::aggregate_for_min_max(const Type_handler *h)
}
}
else
else
{
{
m_type_handler
=
&
type_handler_double
;
// Preserve FLOAT if two FLOATs, set to DOUBLE otherwise.
if
(
m_type_handler
!=
&
type_handler_float
||
h
!=
&
type_handler_float
)
m_type_handler
=
&
type_handler_double
;
}
}
return
false
;
return
false
;
}
}
...
@@ -738,12 +762,19 @@ bool
...
@@ -738,12 +762,19 @@ bool
Type_handler_hybrid_field_type
::
aggregate_for_min_max
(
const
char
*
funcname
,
Type_handler_hybrid_field_type
::
aggregate_for_min_max
(
const
char
*
funcname
,
Item
**
items
,
uint
nitems
)
Item
**
items
,
uint
nitems
)
{
{
bool
bit_and_non_bit_mixture_found
=
false
;
uint32
max_display_length
;
// LEAST/GREATEST require at least two arguments
// LEAST/GREATEST require at least two arguments
DBUG_ASSERT
(
nitems
>
1
);
DBUG_ASSERT
(
nitems
>
1
);
set_handler
(
items
[
0
]
->
type_handler
());
set_handler
(
items
[
0
]
->
type_handler
());
max_display_length
=
items
[
0
]
->
max_display_length
();
for
(
uint
i
=
1
;
i
<
nitems
;
i
++
)
for
(
uint
i
=
1
;
i
<
nitems
;
i
++
)
{
{
const
Type_handler
*
cur
=
items
[
i
]
->
type_handler
();
const
Type_handler
*
cur
=
items
[
i
]
->
type_handler
();
set_if_bigger
(
max_display_length
,
items
[
i
]
->
max_display_length
());
// Check if BIT + non-BIT, or non-BIT + BIT
bit_and_non_bit_mixture_found
|=
(
m_type_handler
==
&
type_handler_bit
)
!=
(
cur
==
&
type_handler_bit
);
if
(
aggregate_for_min_max
(
cur
))
if
(
aggregate_for_min_max
(
cur
))
{
{
my_error
(
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
,
MYF
(
0
),
my_error
(
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
,
MYF
(
0
),
...
@@ -751,6 +782,8 @@ Type_handler_hybrid_field_type::aggregate_for_min_max(const char *funcname,
...
@@ -751,6 +782,8 @@ Type_handler_hybrid_field_type::aggregate_for_min_max(const char *funcname,
return
true
;
return
true
;
}
}
}
}
if
(
bit_and_non_bit_mixture_found
&&
type_handler
()
==
&
type_handler_longlong
)
set_handler
(
Type_handler
::
bit_and_int_mixture_handler
(
max_display_length
));
return
false
;
return
false
;
}
}
...
...
sql/sql_type.h
View file @
01b308c3
...
@@ -535,6 +535,7 @@ class Type_handler
...
@@ -535,6 +535,7 @@ class Type_handler
public:
public:
static
const
Type_handler
*
blob_type_handler
(
uint
max_octet_length
);
static
const
Type_handler
*
blob_type_handler
(
uint
max_octet_length
);
static
const
Type_handler
*
string_type_handler
(
uint
max_octet_length
);
static
const
Type_handler
*
string_type_handler
(
uint
max_octet_length
);
static
const
Type_handler
*
bit_and_int_mixture_handler
(
uint
max_char_len
);
/**
/**
Return a string type handler for Item
Return a string type handler for Item
If too_big_for_varchar() returns a BLOB variant, according to length.
If too_big_for_varchar() returns a BLOB variant, according to length.
...
...
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