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
45730fb1
Commit
45730fb1
authored
Apr 13, 2017
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-12238 Add Type_handler::Item_func_{plus|minus|mul|div|mod}_fix_length_and_dec()
parent
949faa2e
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
811 additions
and
103 deletions
+811
-103
mysql-test/r/gis-debug.result
mysql-test/r/gis-debug.result
+53
-0
mysql-test/r/gis.result
mysql-test/r/gis.result
+65
-0
mysql-test/t/gis-debug.test
mysql-test/t/gis-debug.test
+65
-0
mysql-test/t/gis.test
mysql-test/t/gis.test
+75
-0
sql/item_func.cc
sql/item_func.cc
+100
-89
sql/item_func.h
sql/item_func.h
+61
-1
sql/sql_type.cc
sql/sql_type.cc
+313
-0
sql/sql_type.h
sql/sql_type.h
+79
-13
No files found.
mysql-test/r/gis-debug.result
View file @
45730fb1
...
...
@@ -352,3 +352,56 @@ Note 1105 DBUG: types_compatible=yes bisect=yes
DROP TABLE t1;
SET SESSION debug_dbug="-d,Predicant_to_list_comparator";
SET SESSION debug_dbug="-d,Item_func_in";
#
# MDEV-12238 Add Type_handler::Item_func_{plus|minus|mul|div|mod}_fix_length_and_dec()
#
SET debug_dbug='+d,num_op';
CREATE TABLE t1 AS SELECT
POINT(0,0)+POINT(0,0),
POINT(0,0)-POINT(0,0),
POINT(0,0)*POINT(0,0),
POINT(0,0)/POINT(0,0),
POINT(0,0) MOD POINT(0,0) LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`POINT(0,0)+POINT(0,0)` geometry DEFAULT NULL,
`POINT(0,0)-POINT(0,0)` geometry DEFAULT NULL,
`POINT(0,0)*POINT(0,0)` geometry DEFAULT NULL,
`POINT(0,0)/POINT(0,0)` geometry DEFAULT NULL,
`POINT(0,0) MOD POINT(0,0)` geometry DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 AS SELECT
POINT(0,0)+'0',
POINT(0,0)-'0',
POINT(0,0)*'0',
POINT(0,0)/'0',
POINT(0,0) MOD '0' LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`POINT(0,0)+'0'` longtext DEFAULT NULL,
`POINT(0,0)-'0'` longtext DEFAULT NULL,
`POINT(0,0)*'0'` longtext DEFAULT NULL,
`POINT(0,0)/'0'` longtext DEFAULT NULL,
`POINT(0,0) MOD '0'` longtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 AS SELECT
'0'+POINT(0,0),
'0'*POINT(0,0) LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`'0'+POINT(0,0)` longtext DEFAULT NULL,
`'0'*POINT(0,0)` longtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 AS SELECT '0'-POINT(0,0) LIMIT 0;
ERROR HY000: Illegal parameter data types varchar and geometry for operation '-'
CREATE TABLE t1 AS SELECT '0'/POINT(0,0) LIMIT 0;
ERROR HY000: Illegal parameter data types varchar and geometry for operation '/'
CREATE TABLE t1 AS SELECT '0' MOD POINT(0,0) LIMIT 0;
ERROR HY000: Illegal parameter data types varchar and geometry for operation '%'
SET debug_dbug='-d,num_op';
mysql-test/r/gis.result
View file @
45730fb1
...
...
@@ -3837,5 +3837,70 @@ SELECT LENGTH(CAST(COALESCE(a) AS BINARY)) FROM t1;
LENGTH(CAST(COALESCE(a) AS BINARY))
DROP TABLE t1;
#
# MDEV-12238 Add Type_handler::Item_func_{plus|minus|mul|div|mod}_fix_length_and_dec()
#
CREATE TABLE t1 (a GEOMETRY);
SELECT POINT(1,1) + 1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '+'
SELECT POINT(1,1) - 1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '-'
SELECT POINT(1,1) * 1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '*'
SELECT POINT(1,1) / 1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '/'
SELECT POINT(1,1) MOD 1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '%'
SELECT 1 + POINT(1,1);
ERROR HY000: Illegal parameter data types bigint and geometry for operation '+'
SELECT 1 - POINT(1,1);
ERROR HY000: Illegal parameter data types bigint and geometry for operation '-'
SELECT 1 * POINT(1,1);
ERROR HY000: Illegal parameter data types bigint and geometry for operation '*'
SELECT 1 / POINT(1,1);
ERROR HY000: Illegal parameter data types bigint and geometry for operation '/'
SELECT 1 MOD POINT(1,1);
ERROR HY000: Illegal parameter data types bigint and geometry for operation '%'
SELECT a + 1 FROM t1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '+'
SELECT a - 1 FROM t1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '-'
SELECT a * 1 FROM t1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '*'
SELECT a / 1 FROM t1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '/'
SELECT a MOD 1 FROM t1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '%'
SELECT 1 + a FROM t1;
ERROR HY000: Illegal parameter data types bigint and geometry for operation '+'
SELECT 1 - a FROM t1;
ERROR HY000: Illegal parameter data types bigint and geometry for operation '-'
SELECT 1 * a FROM t1;
ERROR HY000: Illegal parameter data types bigint and geometry for operation '*'
SELECT 1 / a FROM t1;
ERROR HY000: Illegal parameter data types bigint and geometry for operation '/'
SELECT 1 MOD a FROM t1;
ERROR HY000: Illegal parameter data types bigint and geometry for operation '%'
SELECT COALESCE(a) + 1 FROM t1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '+'
SELECT COALESCE(a) - 1 FROM t1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '-'
SELECT COALESCE(a) * 1 FROM t1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '*'
SELECT COALESCE(a) / 1 FROM t1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '/'
SELECT COALESCE(a) MOD 1 FROM t1;
ERROR HY000: Illegal parameter data types geometry and bigint for operation '%'
SELECT 1 + COALESCE(a) FROM t1;
ERROR HY000: Illegal parameter data types bigint and geometry for operation '+'
SELECT 1 - COALESCE(a) FROM t1;
ERROR HY000: Illegal parameter data types bigint and geometry for operation '-'
SELECT 1 * COALESCE(a) FROM t1;
ERROR HY000: Illegal parameter data types bigint and geometry for operation '*'
SELECT 1 / COALESCE(a) FROM t1;
ERROR HY000: Illegal parameter data types bigint and geometry for operation '/'
SELECT 1 MOD COALESCE(a) FROM t1;
ERROR HY000: Illegal parameter data types bigint and geometry for operation '%'
DROP TABLE t1;
#
# End of 10.3 tests
#
mysql-test/t/gis-debug.test
View file @
45730fb1
...
...
@@ -46,3 +46,68 @@ DROP TABLE t1;
SET
SESSION
debug_dbug
=
"-d,Predicant_to_list_comparator"
;
SET
SESSION
debug_dbug
=
"-d,Item_func_in"
;
--
echo
#
--
echo
# MDEV-12238 Add Type_handler::Item_func_{plus|minus|mul|div|mod}_fix_length_and_dec()
--
echo
#
# This tests is to check that operators '+' and '*' are commutative,
# while operators '/', '-' and 'MOD' are not commutative.
#
# It forces substitution of type_aggregator_for_{plus|minus|mul|div|mod} to
# type_aggregator_for_result / type_aggregator_non_commutative_test,
# which have pairs:
# (GEOMETRY,GEOMETRY)->GEOMETRY
# (GEOMETRY,VARCHAR)->GEOMETRY
# Note, they don't not have a pair:
# (VARCHAR,GEOMETRY)->GEOMETRY
#
# Commutative operators should work for all these argument type combinations:
# (GEOMETRY,GEOMETRY), (GEOMETRY,VARCHAR), (VARCHAR,GEOMETRY).
# Non-commutative operators should work for:
# (GEOMETRY,GEOMETRY), (GEOMETRY,VARCHAR),
# but should fail for (VARCHAR,GEOMETRY).
#
# Note, LIMIT 0 is needed to avoid calling str_op(), which does DBUG_ASSERT(0).
SET
debug_dbug
=
'+d,num_op'
;
# (GEOMETRY,GEOMETRY) gives GEOMETRY for all operators
CREATE
TABLE
t1
AS
SELECT
POINT
(
0
,
0
)
+
POINT
(
0
,
0
),
POINT
(
0
,
0
)
-
POINT
(
0
,
0
),
POINT
(
0
,
0
)
*
POINT
(
0
,
0
),
POINT
(
0
,
0
)
/
POINT
(
0
,
0
),
POINT
(
0
,
0
)
MOD
POINT
(
0
,
0
)
LIMIT
0
;
SHOW
CREATE
TABLE
t1
;
DROP
TABLE
t1
;
# (GEOMETRY,VARCHAR) gives GEOMETRY for all operators
CREATE
TABLE
t1
AS
SELECT
POINT
(
0
,
0
)
+
'0'
,
POINT
(
0
,
0
)
-
'0'
,
POINT
(
0
,
0
)
*
'0'
,
POINT
(
0
,
0
)
/
'0'
,
POINT
(
0
,
0
)
MOD
'0'
LIMIT
0
;
SHOW
CREATE
TABLE
t1
;
DROP
TABLE
t1
;
# (VARCHAR,GEOMETRY) gives GEOMETRY for commutative operators
CREATE
TABLE
t1
AS
SELECT
'0'
+
POINT
(
0
,
0
),
'0'
*
POINT
(
0
,
0
)
LIMIT
0
;
SHOW
CREATE
TABLE
t1
;
DROP
TABLE
t1
;
# (VARCHAR,GEOMETRY) gives an error for non-commutative operators
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CREATE
TABLE
t1
AS
SELECT
'0'
-
POINT
(
0
,
0
)
LIMIT
0
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CREATE
TABLE
t1
AS
SELECT
'0'
/
POINT
(
0
,
0
)
LIMIT
0
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
CREATE
TABLE
t1
AS
SELECT
'0'
MOD
POINT
(
0
,
0
)
LIMIT
0
;
SET
debug_dbug
=
'-d,num_op'
;
mysql-test/t/gis.test
View file @
45730fb1
...
...
@@ -2016,6 +2016,81 @@ SELECT LENGTH(CAST(COALESCE(a) AS BINARY)) FROM t1;
DROP
TABLE
t1
;
--
echo
#
--
echo
# MDEV-12238 Add Type_handler::Item_func_{plus|minus|mul|div|mod}_fix_length_and_dec()
--
echo
#
CREATE
TABLE
t1
(
a
GEOMETRY
);
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
POINT
(
1
,
1
)
+
1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
POINT
(
1
,
1
)
-
1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
POINT
(
1
,
1
)
*
1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
POINT
(
1
,
1
)
/
1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
POINT
(
1
,
1
)
MOD
1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
+
POINT
(
1
,
1
);
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
-
POINT
(
1
,
1
);
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
*
POINT
(
1
,
1
);
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
/
POINT
(
1
,
1
);
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
MOD
POINT
(
1
,
1
);
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
a
+
1
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
a
-
1
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
a
*
1
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
a
/
1
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
a
MOD
1
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
+
a
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
-
a
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
*
a
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
/
a
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
MOD
a
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
COALESCE
(
a
)
+
1
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
COALESCE
(
a
)
-
1
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
COALESCE
(
a
)
*
1
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
COALESCE
(
a
)
/
1
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
COALESCE
(
a
)
MOD
1
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
+
COALESCE
(
a
)
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
-
COALESCE
(
a
)
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
*
COALESCE
(
a
)
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
/
COALESCE
(
a
)
FROM
t1
;
--
error
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
SELECT
1
MOD
COALESCE
(
a
)
FROM
t1
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# End of 10.3 tests
--
echo
#
sql/item_func.cc
View file @
45730fb1
...
...
@@ -729,47 +729,31 @@ bool Item_func_connection_id::fix_fields(THD *thd, Item **ref)
}
/**
Check arguments here to determine result's type for a numeric
function of two arguments.
*/
void
Item_num_op
::
fix_length_and_dec
(
void
)
bool
Item_num_op
::
fix_type_handler
(
const
Type_aggregator
*
aggregator
)
{
DBUG_ENTER
(
"Item_num_op::fix_length_and_dec"
);
DBUG_PRINT
(
"info"
,
(
"name %s"
,
func_name
()));
DBUG_ASSERT
(
arg_count
==
2
);
Item_result
r0
=
args
[
0
]
->
cast_to_int_type_handler
()
->
cmp_type
();
Item_result
r1
=
args
[
1
]
->
cast_to_int_type_handler
()
->
cmp_type
();
const
Type_handler
*
h0
=
args
[
0
]
->
cast_to_int_type_handler
();
const
Type_handler
*
h1
=
args
[
1
]
->
cast_to_int_type_handler
();
if
(
!
aggregate_for_num_op
(
aggregator
,
h0
,
h1
))
return
false
;
my_error
(
ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION
,
MYF
(
0
),
h0
->
name
().
ptr
(),
h1
->
name
().
ptr
(),
func_name
());
return
true
;
}
if
(
r0
==
REAL_RESULT
||
r1
==
REAL_RESULT
||
r0
==
STRING_RESULT
||
r1
==
STRING_RESULT
)
{
count_real_length
(
args
,
arg_count
);
max_length
=
float_length
(
decimals
);
set_handler_by_result_type
(
REAL_RESULT
);
}
else
if
(
r0
==
DECIMAL_RESULT
||
r1
==
DECIMAL_RESULT
||
r0
==
TIME_RESULT
||
r1
==
TIME_RESULT
)
{
set_handler_by_result_type
(
DECIMAL_RESULT
);
result_precision
();
fix_decimals
();
if
((
r0
==
TIME_RESULT
||
r1
==
TIME_RESULT
)
&&
decimals
==
0
)
set_handler_by_result_type
(
INT_RESULT
);
}
else
void
Item_func_plus
::
fix_length_and_dec
(
void
)
{
DBUG_ENTER
(
"Item_func_plus::fix_length_and_dec"
);
DBUG_PRINT
(
"info"
,
(
"name %s"
,
func_name
()));
const
Type_aggregator
*
aggregator
=
&
type_handler_data
->
m_type_aggregator_for_plus
;
DBUG_EXECUTE_IF
(
"num_op"
,
aggregator
=
&
type_handler_data
->
m_type_aggregator_for_result
;);
DBUG_ASSERT
(
aggregator
->
is_commutative
());
if
(
!
fix_type_handler
(
aggregator
))
{
DBUG_ASSERT
(
r0
==
INT_RESULT
&&
r1
==
INT_RESULT
);
set_handler_by_result_type
(
INT_RESULT
);
result_precision
();
decimals
=
0
;
Item_func_plus
::
type_handler
()
->
Item_func_plus_fix_length_and_dec
(
this
);
DBUG_PRINT
(
"info"
,
(
"Type: %s"
,
type_handler
()
->
name
().
ptr
()));
}
DBUG_PRINT
(
"info"
,
(
"Type: %s"
,
(
result_type
()
==
REAL_RESULT
?
"REAL_RESULT"
:
result_type
()
==
DECIMAL_RESULT
?
"DECIMAL_RESULT"
:
result_type
()
==
INT_RESULT
?
"INT_RESULT"
:
"--ILLEGAL!!!--"
)));
DBUG_VOID_RETURN
;
}
...
...
@@ -1299,11 +1283,6 @@ void Item_func_additive_op::result_precision()
DBUG_ASSERT
(
arg1_int
>=
0
);
DBUG_ASSERT
(
arg2_int
>=
0
);
/* Integer operations keep unsigned_flag if one of arguments is unsigned */
if
(
result_type
()
==
INT_RESULT
)
unsigned_flag
=
args
[
0
]
->
unsigned_flag
|
args
[
1
]
->
unsigned_flag
;
else
unsigned_flag
=
args
[
0
]
->
unsigned_flag
&
args
[
1
]
->
unsigned_flag
;
max_length
=
my_decimal_precision_to_length_no_truncation
(
precision
,
decimals
,
unsigned_flag
);
}
...
...
@@ -1313,16 +1292,30 @@ void Item_func_additive_op::result_precision()
The following function is here to allow the user to force
subtraction of UNSIGNED BIGINT to return negative values.
*/
void
Item_func_minus
::
fix_length_and_dec
()
void
Item_func_minus
::
fix_unsigned_flag
()
{
Item_num_op
::
fix_length_and_dec
();
if
(
unsigned_flag
&&
(
current_thd
->
variables
.
sql_mode
&
MODE_NO_UNSIGNED_SUBTRACTION
))
unsigned_flag
=
0
;
}
void
Item_func_minus
::
fix_length_and_dec
()
{
DBUG_ENTER
(
"Item_func_minus::fix_length_and_dec"
);
DBUG_PRINT
(
"info"
,
(
"name %s"
,
func_name
()));
const
Type_aggregator
*
aggregator
=
&
type_handler_data
->
m_type_aggregator_for_minus
;
DBUG_EXECUTE_IF
(
"num_op"
,
aggregator
=
&
type_handler_data
->
m_type_aggregator_non_commutative_test
;);
DBUG_ASSERT
(
!
aggregator
->
is_commutative
());
if
(
!
fix_type_handler
(
aggregator
))
{
Item_func_minus
::
type_handler
()
->
Item_func_minus_fix_length_and_dec
(
this
);
DBUG_PRINT
(
"info"
,
(
"Type: %s"
,
type_handler
()
->
name
().
ptr
()));
}
DBUG_VOID_RETURN
;
}
double
Item_func_minus
::
real_op
()
{
double
value
=
args
[
0
]
->
val_real
()
-
args
[
1
]
->
val_real
();
...
...
@@ -1530,13 +1523,8 @@ my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value)
void
Item_func_mul
::
result_precision
()
{
/* Integer operations keep unsigned_flag if one of arguments is unsigned */
if
(
result_type
()
==
INT_RESULT
)
unsigned_flag
=
args
[
0
]
->
unsigned_flag
|
args
[
1
]
->
unsigned_flag
;
else
unsigned_flag
=
args
[
0
]
->
unsigned_flag
&
args
[
1
]
->
unsigned_flag
;
decimals
=
MY_MIN
(
args
[
0
]
->
decimal_scale
()
+
args
[
1
]
->
decimal_scale
(),
DECIMAL_MAX_SCALE
);
DECIMAL_MAX_SCALE
);
uint
est_prec
=
args
[
0
]
->
decimal_precision
()
+
args
[
1
]
->
decimal_precision
();
uint
precision
=
MY_MIN
(
est_prec
,
DECIMAL_MAX_PRECISION
);
max_length
=
my_decimal_precision_to_length_no_truncation
(
precision
,
decimals
,
...
...
@@ -1544,6 +1532,22 @@ void Item_func_mul::result_precision()
}
void
Item_func_mul
::
fix_length_and_dec
(
void
)
{
DBUG_ENTER
(
"Item_func_mul::fix_length_and_dec"
);
DBUG_PRINT
(
"info"
,
(
"name %s"
,
func_name
()));
const
Type_aggregator
*
aggregator
=
&
type_handler_data
->
m_type_aggregator_for_mul
;
DBUG_EXECUTE_IF
(
"num_op"
,
aggregator
=
&
type_handler_data
->
m_type_aggregator_for_result
;);
DBUG_ASSERT
(
aggregator
->
is_commutative
());
if
(
!
fix_type_handler
(
aggregator
))
{
Item_func_mul
::
type_handler
()
->
Item_func_mul_fix_length_and_dec
(
this
);
DBUG_PRINT
(
"info"
,
(
"Type: %s"
,
type_handler
()
->
name
().
ptr
()));
}
DBUG_VOID_RETURN
;
}
double
Item_func_div
::
real_op
()
{
DBUG_ASSERT
(
fixed
==
1
);
...
...
@@ -1605,53 +1609,51 @@ void Item_func_div::result_precision()
uint
precision
=
MY_MIN
(
args
[
0
]
->
decimal_precision
()
+
args
[
1
]
->
divisor_precision_increment
()
+
prec_increment
,
DECIMAL_MAX_PRECISION
);
/* Integer operations keep unsigned_flag if one of arguments is unsigned */
if
(
result_type
()
==
INT_RESULT
)
unsigned_flag
=
args
[
0
]
->
unsigned_flag
|
args
[
1
]
->
unsigned_flag
;
else
unsigned_flag
=
args
[
0
]
->
unsigned_flag
&
args
[
1
]
->
unsigned_flag
;
decimals
=
MY_MIN
(
args
[
0
]
->
decimal_scale
()
+
prec_increment
,
DECIMAL_MAX_SCALE
);
max_length
=
my_decimal_precision_to_length_no_truncation
(
precision
,
decimals
,
unsigned_flag
);
}
void
Item_func_div
::
fix_length_and_dec
()
void
Item_func_div
::
fix_length_and_dec_double
(
void
)
{
Item_num_op
::
fix_length_and_dec_double
();
decimals
=
MY_MAX
(
args
[
0
]
->
decimals
,
args
[
1
]
->
decimals
)
+
prec_increment
;
set_if_smaller
(
decimals
,
NOT_FIXED_DEC
);
uint
tmp
=
float_length
(
decimals
);
if
(
decimals
==
NOT_FIXED_DEC
)
max_length
=
tmp
;
else
{
max_length
=
args
[
0
]
->
max_length
-
args
[
0
]
->
decimals
+
decimals
;
set_if_smaller
(
max_length
,
tmp
);
}
}
void
Item_func_div
::
fix_length_and_dec_int
(
void
)
{
set_handler
(
&
type_handler_newdecimal
);
DBUG_PRINT
(
"info"
,
(
"Type changed: %s"
,
type_handler
()
->
name
().
ptr
()));
Item_num_op
::
fix_length_and_dec_decimal
();
}
void
Item_func_div
::
fix_length_and_dec
(
void
)
{
DBUG_ENTER
(
"Item_func_div::fix_length_and_dec"
);
DBUG_PRINT
(
"info"
,
(
"name %s"
,
func_name
()));
prec_increment
=
current_thd
->
variables
.
div_precincrement
;
Item_num_op
::
fix_length_and_dec
();
switch
(
Item_func_div
::
result_type
())
{
case
REAL_RESULT
:
maybe_null
=
1
;
// devision by zero
const
Type_aggregator
*
aggregator
=
&
type_handler_data
->
m_type_aggregator_for_div
;
DBUG_EXECUTE_IF
(
"num_op"
,
aggregator
=
&
type_handler_data
->
m_type_aggregator_non_commutative_test
;);
DBUG_ASSERT
(
!
aggregator
->
is_commutative
());
if
(
!
fix_type_handler
(
aggregator
))
{
decimals
=
MY_MAX
(
args
[
0
]
->
decimals
,
args
[
1
]
->
decimals
)
+
prec_increment
;
set_if_smaller
(
decimals
,
NOT_FIXED_DEC
);
uint
tmp
=
float_length
(
decimals
);
if
(
decimals
==
NOT_FIXED_DEC
)
max_length
=
tmp
;
else
{
max_length
=
args
[
0
]
->
max_length
-
args
[
0
]
->
decimals
+
decimals
;
set_if_smaller
(
max_length
,
tmp
);
}
break
;
}
case
INT_RESULT
:
set_handler_by_result_type
(
DECIMAL_RESULT
);
DBUG_PRINT
(
"info"
,
(
"Type changed: DECIMAL_RESULT"
));
result_precision
();
break
;
case
DECIMAL_RESULT
:
result_precision
();
fix_decimals
();
break
;
case
STRING_RESULT
:
case
ROW_RESULT
:
case
TIME_RESULT
:
DBUG_ASSERT
(
0
);
Item_func_div
::
type_handler
()
->
Item_func_div_fix_length_and_dec
(
this
);
DBUG_PRINT
(
"info"
,
(
"Type: %s"
,
type_handler
()
->
name
().
ptr
()));
}
maybe_null
=
1
;
// devision by zero
DBUG_VOID_RETURN
;
}
...
...
@@ -1823,9 +1825,18 @@ void Item_func_mod::result_precision()
void
Item_func_mod
::
fix_length_and_dec
()
{
Item_num_op
::
fix_length_and_dec
();
maybe_null
=
1
;
unsigned_flag
=
args
[
0
]
->
unsigned_flag
;
DBUG_ENTER
(
"Item_func_mod::fix_length_and_dec"
);
DBUG_PRINT
(
"info"
,
(
"name %s"
,
func_name
()));
maybe_null
=
true
;
// division by zero
const
Type_aggregator
*
aggregator
=
&
type_handler_data
->
m_type_aggregator_for_mod
;
DBUG_EXECUTE_IF
(
"num_op"
,
aggregator
=
&
type_handler_data
->
m_type_aggregator_non_commutative_test
;);
DBUG_ASSERT
(
!
aggregator
->
is_commutative
());
if
(
!
fix_type_handler
(
aggregator
))
{
Item_func_mod
::
type_handler
()
->
Item_func_mod_fix_length_and_dec
(
this
);
DBUG_PRINT
(
"info"
,
(
"Type: %s"
,
type_handler
()
->
name
().
ptr
()));
}
DBUG_VOID_RETURN
;
}
...
...
sql/item_func.h
View file @
45730fb1
...
...
@@ -695,7 +695,31 @@ class Item_num_op :public Item_func_numhybrid
{
print_op
(
str
,
query_type
);
}
void
fix_length_and_dec
();
bool
fix_type_handler
(
const
Type_aggregator
*
aggregator
);
void
fix_length_and_dec_double
()
{
count_real_length
(
args
,
arg_count
);
max_length
=
float_length
(
decimals
);
}
void
fix_length_and_dec_decimal
()
{
unsigned_flag
=
args
[
0
]
->
unsigned_flag
&
args
[
1
]
->
unsigned_flag
;
result_precision
();
fix_decimals
();
}
void
fix_length_and_dec_int
()
{
unsigned_flag
=
args
[
0
]
->
unsigned_flag
|
args
[
1
]
->
unsigned_flag
;
result_precision
();
decimals
=
0
;
}
void
fix_length_and_dec_temporal
()
{
set_handler
(
&
type_handler_newdecimal
);
fix_length_and_dec_decimal
();
if
(
decimals
==
0
)
set_handler
(
&
type_handler_longlong
);
}
bool
need_parentheses_in_default
()
{
return
true
;
}
};
...
...
@@ -949,6 +973,7 @@ class Item_func_plus :public Item_func_additive_op
Item_func_additive_op
(
thd
,
a
,
b
)
{}
const
char
*
func_name
()
const
{
return
"+"
;
}
enum
precedence
precedence
()
const
{
return
ADD_PRECEDENCE
;
}
void
fix_length_and_dec
();
longlong
int_op
();
double
real_op
();
my_decimal
*
decimal_op
(
my_decimal
*
);
...
...
@@ -967,6 +992,22 @@ class Item_func_minus :public Item_func_additive_op
double
real_op
();
my_decimal
*
decimal_op
(
my_decimal
*
);
void
fix_length_and_dec
();
void
fix_unsigned_flag
();
void
fix_length_and_dec_double
()
{
Item_func_additive_op
::
fix_length_and_dec_double
();
fix_unsigned_flag
();
}
void
fix_length_and_dec_decimal
()
{
Item_func_additive_op
::
fix_length_and_dec_decimal
();
fix_unsigned_flag
();
}
void
fix_length_and_dec_int
()
{
Item_func_additive_op
::
fix_length_and_dec_int
();
fix_unsigned_flag
();
}
Item
*
get_copy
(
THD
*
thd
,
MEM_ROOT
*
mem_root
)
{
return
get_item_copy
<
Item_func_minus
>
(
thd
,
mem_root
,
this
);
}
};
...
...
@@ -983,6 +1024,7 @@ class Item_func_mul :public Item_num_op
double
real_op
();
my_decimal
*
decimal_op
(
my_decimal
*
);
void
result_precision
();
void
fix_length_and_dec
();
bool
check_partition_func_processor
(
void
*
int_arg
)
{
return
FALSE
;}
bool
check_vcol_func_processor
(
void
*
arg
)
{
return
FALSE
;}
Item
*
get_copy
(
THD
*
thd
,
MEM_ROOT
*
mem_root
)
...
...
@@ -1001,6 +1043,8 @@ class Item_func_div :public Item_num_op
const
char
*
func_name
()
const
{
return
"/"
;
}
enum
precedence
precedence
()
const
{
return
MUL_PRECEDENCE
;
}
void
fix_length_and_dec
();
void
fix_length_and_dec_double
();
void
fix_length_and_dec_int
();
void
result_precision
();
Item
*
get_copy
(
THD
*
thd
,
MEM_ROOT
*
mem_root
)
{
return
get_item_copy
<
Item_func_div
>
(
thd
,
mem_root
,
this
);
}
...
...
@@ -1040,6 +1084,22 @@ class Item_func_mod :public Item_num_op
enum
precedence
precedence
()
const
{
return
MUL_PRECEDENCE
;
}
void
result_precision
();
void
fix_length_and_dec
();
void
fix_length_and_dec_double
()
{
Item_num_op
::
fix_length_and_dec_double
();
unsigned_flag
=
args
[
0
]
->
unsigned_flag
;
}
void
fix_length_and_dec_decimal
()
{
Item_num_op
::
fix_length_and_dec_decimal
();
unsigned_flag
=
args
[
0
]
->
unsigned_flag
;
}
void
fix_length_and_dec_int
()
{
max_length
=
MY_MAX
(
args
[
0
]
->
max_length
,
args
[
1
]
->
max_length
);
decimals
=
0
;
unsigned_flag
=
args
[
0
]
->
unsigned_flag
;
}
bool
check_partition_func_processor
(
void
*
int_arg
)
{
return
FALSE
;}
bool
check_vcol_func_processor
(
void
*
arg
)
{
return
FALSE
;}
Item
*
get_copy
(
THD
*
thd
,
MEM_ROOT
*
mem_root
)
...
...
sql/sql_type.cc
View file @
45730fb1
...
...
@@ -60,6 +60,17 @@ Type_handler_geometry type_handler_geometry;
bool
Type_handler_data
::
init
()
{
#ifdef HAVE_SPATIAL
#ifndef DBUG_OFF
if
(
m_type_aggregator_non_commutative_test
.
add
(
&
type_handler_geometry
,
&
type_handler_geometry
,
&
type_handler_geometry
)
||
m_type_aggregator_non_commutative_test
.
add
(
&
type_handler_geometry
,
&
type_handler_varchar
,
&
type_handler_long_blob
))
return
true
;
#endif
return
m_type_aggregator_for_result
.
add
(
&
type_handler_geometry
,
&
type_handler_null
,
...
...
@@ -466,6 +477,63 @@ Type_handler_hybrid_field_type::aggregate_for_comparison(const Type_handler *h)
}
const
Type_handler
*
Type_handler
::
aggregate_for_num_op_traditional
(
const
Type_handler
*
h0
,
const
Type_handler
*
h1
)
{
Item_result
r0
=
h0
->
cmp_type
();
Item_result
r1
=
h1
->
cmp_type
();
if
(
r0
==
REAL_RESULT
||
r1
==
REAL_RESULT
||
r0
==
STRING_RESULT
||
r1
==
STRING_RESULT
)
return
&
type_handler_double
;
if
(
r0
==
TIME_RESULT
||
r1
==
TIME_RESULT
)
return
&
type_handler_datetime
;
if
(
r0
==
DECIMAL_RESULT
||
r1
==
DECIMAL_RESULT
)
return
&
type_handler_newdecimal
;
DBUG_ASSERT
(
r0
==
INT_RESULT
&&
r1
==
INT_RESULT
);
return
&
type_handler_longlong
;
}
const
Type_aggregator
::
Pair
*
Type_aggregator
::
find_pair
(
const
Type_handler
*
handler1
,
const
Type_handler
*
handler2
)
const
{
for
(
uint
i
=
0
;
i
<
m_array
.
elements
();
i
++
)
{
const
Pair
&
el
=
m_array
.
at
(
i
);
if
(
el
.
eq
(
handler1
,
handler2
)
||
(
m_is_commutative
&&
el
.
eq
(
handler2
,
handler1
)))
return
&
el
;
}
return
NULL
;
}
bool
Type_handler_hybrid_field_type
::
aggregate_for_num_op
(
const
Type_aggregator
*
agg
,
const
Type_handler
*
h0
,
const
Type_handler
*
h1
)
{
const
Type_handler
*
hres
;
if
(
h0
->
is_traditional_type
()
&&
h1
->
is_traditional_type
())
{
set_handler
(
Type_handler
::
aggregate_for_num_op_traditional
(
h0
,
h1
));
return
false
;
}
if
((
hres
=
agg
->
find_handler
(
h0
,
h1
)))
{
set_handler
(
hres
);
return
false
;
}
return
true
;
}
/***************************************************************************/
const
Type_handler
*
...
...
@@ -2709,3 +2777,248 @@ bool Type_handler_geometry::
#endif
/* HAVE_SPATIAL */
/***************************************************************************/
bool
Type_handler_row
::
Item_func_plus_fix_length_and_dec
(
Item_func_plus
*
item
)
const
{
DBUG_ASSERT
(
0
);
return
true
;
}
bool
Type_handler_int_result
::
Item_func_plus_fix_length_and_dec
(
Item_func_plus
*
item
)
const
{
item
->
fix_length_and_dec_int
();
return
false
;
}
bool
Type_handler_real_result
::
Item_func_plus_fix_length_and_dec
(
Item_func_plus
*
item
)
const
{
item
->
fix_length_and_dec_double
();
return
false
;
}
bool
Type_handler_decimal_result
::
Item_func_plus_fix_length_and_dec
(
Item_func_plus
*
item
)
const
{
item
->
fix_length_and_dec_decimal
();
return
false
;
}
bool
Type_handler_temporal_result
::
Item_func_plus_fix_length_and_dec
(
Item_func_plus
*
item
)
const
{
item
->
fix_length_and_dec_temporal
();
return
false
;
}
bool
Type_handler_string_result
::
Item_func_plus_fix_length_and_dec
(
Item_func_plus
*
item
)
const
{
item
->
fix_length_and_dec_double
();
return
false
;
}
/***************************************************************************/
bool
Type_handler_row
::
Item_func_minus_fix_length_and_dec
(
Item_func_minus
*
item
)
const
{
DBUG_ASSERT
(
0
);
return
true
;
}
bool
Type_handler_int_result
::
Item_func_minus_fix_length_and_dec
(
Item_func_minus
*
item
)
const
{
item
->
fix_length_and_dec_int
();
return
false
;
}
bool
Type_handler_real_result
::
Item_func_minus_fix_length_and_dec
(
Item_func_minus
*
item
)
const
{
item
->
fix_length_and_dec_double
();
return
false
;
}
bool
Type_handler_decimal_result
::
Item_func_minus_fix_length_and_dec
(
Item_func_minus
*
item
)
const
{
item
->
fix_length_and_dec_decimal
();
return
false
;
}
bool
Type_handler_temporal_result
::
Item_func_minus_fix_length_and_dec
(
Item_func_minus
*
item
)
const
{
item
->
fix_length_and_dec_temporal
();
return
false
;
}
bool
Type_handler_string_result
::
Item_func_minus_fix_length_and_dec
(
Item_func_minus
*
item
)
const
{
item
->
fix_length_and_dec_double
();
return
false
;
}
/***************************************************************************/
bool
Type_handler_row
::
Item_func_mul_fix_length_and_dec
(
Item_func_mul
*
item
)
const
{
DBUG_ASSERT
(
0
);
return
true
;
}
bool
Type_handler_int_result
::
Item_func_mul_fix_length_and_dec
(
Item_func_mul
*
item
)
const
{
item
->
fix_length_and_dec_int
();
return
false
;
}
bool
Type_handler_real_result
::
Item_func_mul_fix_length_and_dec
(
Item_func_mul
*
item
)
const
{
item
->
fix_length_and_dec_double
();
return
false
;
}
bool
Type_handler_decimal_result
::
Item_func_mul_fix_length_and_dec
(
Item_func_mul
*
item
)
const
{
item
->
fix_length_and_dec_decimal
();
return
false
;
}
bool
Type_handler_temporal_result
::
Item_func_mul_fix_length_and_dec
(
Item_func_mul
*
item
)
const
{
item
->
fix_length_and_dec_temporal
();
return
false
;
}
bool
Type_handler_string_result
::
Item_func_mul_fix_length_and_dec
(
Item_func_mul
*
item
)
const
{
item
->
fix_length_and_dec_double
();
return
false
;
}
/***************************************************************************/
bool
Type_handler_row
::
Item_func_div_fix_length_and_dec
(
Item_func_div
*
item
)
const
{
DBUG_ASSERT
(
0
);
return
true
;
}
bool
Type_handler_int_result
::
Item_func_div_fix_length_and_dec
(
Item_func_div
*
item
)
const
{
item
->
fix_length_and_dec_int
();
return
false
;
}
bool
Type_handler_real_result
::
Item_func_div_fix_length_and_dec
(
Item_func_div
*
item
)
const
{
item
->
fix_length_and_dec_double
();
return
false
;
}
bool
Type_handler_decimal_result
::
Item_func_div_fix_length_and_dec
(
Item_func_div
*
item
)
const
{
item
->
fix_length_and_dec_decimal
();
return
false
;
}
bool
Type_handler_temporal_result
::
Item_func_div_fix_length_and_dec
(
Item_func_div
*
item
)
const
{
item
->
fix_length_and_dec_temporal
();
return
false
;
}
bool
Type_handler_string_result
::
Item_func_div_fix_length_and_dec
(
Item_func_div
*
item
)
const
{
item
->
fix_length_and_dec_double
();
return
false
;
}
/***************************************************************************/
bool
Type_handler_row
::
Item_func_mod_fix_length_and_dec
(
Item_func_mod
*
item
)
const
{
DBUG_ASSERT
(
0
);
return
true
;
}
bool
Type_handler_int_result
::
Item_func_mod_fix_length_and_dec
(
Item_func_mod
*
item
)
const
{
item
->
fix_length_and_dec_int
();
return
false
;
}
bool
Type_handler_real_result
::
Item_func_mod_fix_length_and_dec
(
Item_func_mod
*
item
)
const
{
item
->
fix_length_and_dec_double
();
return
false
;
}
bool
Type_handler_decimal_result
::
Item_func_mod_fix_length_and_dec
(
Item_func_mod
*
item
)
const
{
item
->
fix_length_and_dec_decimal
();
return
false
;
}
bool
Type_handler_temporal_result
::
Item_func_mod_fix_length_and_dec
(
Item_func_mod
*
item
)
const
{
item
->
fix_length_and_dec_temporal
();
return
false
;
}
bool
Type_handler_string_result
::
Item_func_mod_fix_length_and_dec
(
Item_func_mod
*
item
)
const
{
item
->
fix_length_and_dec_double
();
return
false
;
}
/***************************************************************************/
sql/sql_type.h
View file @
45730fb1
...
...
@@ -51,6 +51,11 @@ class Item_char_typecast;
class
Item_time_typecast
;
class
Item_date_typecast
;
class
Item_datetime_typecast
;
class
Item_func_plus
;
class
Item_func_minus
;
class
Item_func_mul
;
class
Item_func_div
;
class
Item_func_mod
;
class
cmp_item
;
class
in_vector
;
class
Type_std_attributes
;
...
...
@@ -303,6 +308,9 @@ class Type_handler
static
const
Type_handler
*
aggregate_for_result_traditional
(
const
Type_handler
*
h1
,
const
Type_handler
*
h2
);
static
const
Type_handler
*
aggregate_for_num_op_traditional
(
const
Type_handler
*
h1
,
const
Type_handler
*
h2
);
virtual
const
Name
name
()
const
=
0
;
virtual
enum_field_types
field_type
()
const
=
0
;
...
...
@@ -497,6 +505,17 @@ class Type_handler
Item_date_typecast_fix_length_and_dec
(
Item_date_typecast
*
item
)
const
;
virtual
bool
Item_datetime_typecast_fix_length_and_dec
(
Item_datetime_typecast
*
item
)
const
;
virtual
bool
Item_func_plus_fix_length_and_dec
(
Item_func_plus
*
func
)
const
=
0
;
virtual
bool
Item_func_minus_fix_length_and_dec
(
Item_func_minus
*
func
)
const
=
0
;
virtual
bool
Item_func_mul_fix_length_and_dec
(
Item_func_mul
*
func
)
const
=
0
;
virtual
bool
Item_func_div_fix_length_and_dec
(
Item_func_div
*
func
)
const
=
0
;
virtual
bool
Item_func_mod_fix_length_and_dec
(
Item_func_mod
*
func
)
const
=
0
;
};
...
...
@@ -708,6 +727,12 @@ class Type_handler_row: public Type_handler
DBUG_ASSERT
(
0
);
return
true
;
}
bool
Item_func_plus_fix_length_and_dec
(
Item_func_plus
*
)
const
;
bool
Item_func_minus_fix_length_and_dec
(
Item_func_minus
*
)
const
;
bool
Item_func_mul_fix_length_and_dec
(
Item_func_mul
*
)
const
;
bool
Item_func_div_fix_length_and_dec
(
Item_func_div
*
)
const
;
bool
Item_func_mod_fix_length_and_dec
(
Item_func_mod
*
)
const
;
};
...
...
@@ -784,6 +809,11 @@ class Type_handler_real_result: public Type_handler_numeric
bool
Item_func_int_val_fix_length_and_dec
(
Item_func_int_val
*
)
const
;
bool
Item_func_abs_fix_length_and_dec
(
Item_func_abs
*
)
const
;
bool
Item_func_neg_fix_length_and_dec
(
Item_func_neg
*
)
const
;
bool
Item_func_plus_fix_length_and_dec
(
Item_func_plus
*
)
const
;
bool
Item_func_minus_fix_length_and_dec
(
Item_func_minus
*
)
const
;
bool
Item_func_mul_fix_length_and_dec
(
Item_func_mul
*
)
const
;
bool
Item_func_div_fix_length_and_dec
(
Item_func_div
*
)
const
;
bool
Item_func_mod_fix_length_and_dec
(
Item_func_mod
*
)
const
;
};
...
...
@@ -833,6 +863,11 @@ class Type_handler_decimal_result: public Type_handler_numeric
bool
Item_func_int_val_fix_length_and_dec
(
Item_func_int_val
*
)
const
;
bool
Item_func_abs_fix_length_and_dec
(
Item_func_abs
*
)
const
;
bool
Item_func_neg_fix_length_and_dec
(
Item_func_neg
*
)
const
;
bool
Item_func_plus_fix_length_and_dec
(
Item_func_plus
*
)
const
;
bool
Item_func_minus_fix_length_and_dec
(
Item_func_minus
*
)
const
;
bool
Item_func_mul_fix_length_and_dec
(
Item_func_mul
*
)
const
;
bool
Item_func_div_fix_length_and_dec
(
Item_func_div
*
)
const
;
bool
Item_func_mod_fix_length_and_dec
(
Item_func_mod
*
)
const
;
};
...
...
@@ -881,6 +916,11 @@ class Type_handler_int_result: public Type_handler_numeric
bool
Item_func_int_val_fix_length_and_dec
(
Item_func_int_val
*
)
const
;
bool
Item_func_abs_fix_length_and_dec
(
Item_func_abs
*
)
const
;
bool
Item_func_neg_fix_length_and_dec
(
Item_func_neg
*
)
const
;
bool
Item_func_plus_fix_length_and_dec
(
Item_func_plus
*
)
const
;
bool
Item_func_minus_fix_length_and_dec
(
Item_func_minus
*
)
const
;
bool
Item_func_mul_fix_length_and_dec
(
Item_func_mul
*
)
const
;
bool
Item_func_div_fix_length_and_dec
(
Item_func_div
*
)
const
;
bool
Item_func_mod_fix_length_and_dec
(
Item_func_mod
*
)
const
;
};
...
...
@@ -933,6 +973,11 @@ class Type_handler_temporal_result: public Type_handler
bool
Item_func_int_val_fix_length_and_dec
(
Item_func_int_val
*
)
const
;
bool
Item_func_abs_fix_length_and_dec
(
Item_func_abs
*
)
const
;
bool
Item_func_neg_fix_length_and_dec
(
Item_func_neg
*
)
const
;
bool
Item_func_plus_fix_length_and_dec
(
Item_func_plus
*
)
const
;
bool
Item_func_minus_fix_length_and_dec
(
Item_func_minus
*
)
const
;
bool
Item_func_mul_fix_length_and_dec
(
Item_func_mul
*
)
const
;
bool
Item_func_div_fix_length_and_dec
(
Item_func_div
*
)
const
;
bool
Item_func_mod_fix_length_and_dec
(
Item_func_mod
*
)
const
;
};
...
...
@@ -999,6 +1044,11 @@ class Type_handler_string_result: public Type_handler
bool
Item_func_int_val_fix_length_and_dec
(
Item_func_int_val
*
)
const
;
bool
Item_func_abs_fix_length_and_dec
(
Item_func_abs
*
)
const
;
bool
Item_func_neg_fix_length_and_dec
(
Item_func_neg
*
)
const
;
bool
Item_func_plus_fix_length_and_dec
(
Item_func_plus
*
)
const
;
bool
Item_func_minus_fix_length_and_dec
(
Item_func_minus
*
)
const
;
bool
Item_func_mul_fix_length_and_dec
(
Item_func_mul
*
)
const
;
bool
Item_func_div_fix_length_and_dec
(
Item_func_div
*
)
const
;
bool
Item_func_mod_fix_length_and_dec
(
Item_func_mod
*
)
const
;
};
...
...
@@ -1528,6 +1578,8 @@ class Type_handler_hybrid_field_type
bool
aggregate_for_result
(
const
Type_handler
*
other
);
bool
aggregate_for_result
(
const
char
*
funcname
,
Item
**
item
,
uint
nitems
,
bool
treat_bit_as_number
);
bool
aggregate_for_num_op
(
const
class
Type_aggregator
*
aggregator
,
const
Type_handler
*
h0
,
const
Type_handler
*
h1
);
};
...
...
@@ -1547,6 +1599,7 @@ extern Type_handler_set type_handler_set;
class
Type_aggregator
{
bool
m_is_commutative
;
class
Pair
{
public:
...
...
@@ -1566,18 +1619,10 @@ class Type_aggregator
};
Dynamic_array
<
Pair
>
m_array
;
const
Pair
*
find_pair
(
const
Type_handler
*
handler1
,
const
Type_handler
*
handler2
)
const
{
for
(
uint
i
=
0
;
i
<
m_array
.
elements
();
i
++
)
{
const
Pair
&
el
=
m_array
.
at
(
i
);
if
(
el
.
eq
(
handler1
,
handler2
)
||
el
.
eq
(
handler2
,
handler1
))
return
&
el
;
}
return
NULL
;
}
const
Type_handler
*
handler2
)
const
;
public:
Type_aggregator
()
Type_aggregator
(
bool
is_commutative
=
false
)
:
m_is_commutative
(
is_commutative
)
{
}
bool
add
(
const
Type_handler
*
handler1
,
const
Type_handler
*
handler2
,
...
...
@@ -1591,14 +1636,35 @@ class Type_aggregator
const
Pair
*
el
=
find_pair
(
handler1
,
handler2
);
return
el
?
el
->
m_result
:
NULL
;
}
bool
is_commutative
()
const
{
return
m_is_commutative
;
}
};
class
Type_aggregator_commutative
:
public
Type_aggregator
{
public:
Type_aggregator_commutative
()
:
Type_aggregator
(
true
)
{
}
};
class
Type_handler_data
{
public:
Type_aggregator
m_type_aggregator_for_result
;
Type_aggregator
m_type_aggregator_for_comparison
;
Type_aggregator_commutative
m_type_aggregator_for_result
;
Type_aggregator_commutative
m_type_aggregator_for_comparison
;
Type_aggregator_commutative
m_type_aggregator_for_plus
;
Type_aggregator_commutative
m_type_aggregator_for_mul
;
Type_aggregator
m_type_aggregator_for_minus
;
Type_aggregator
m_type_aggregator_for_div
;
Type_aggregator
m_type_aggregator_for_mod
;
#ifndef DBUG_OFF
// This is used for mtr purposes in debug builds
Type_aggregator
m_type_aggregator_non_commutative_test
;
#endif
bool
init
();
};
...
...
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