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
b5fae7f7
Commit
b5fae7f7
authored
Oct 11, 2019
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-20795 CAST(inet6 AS BINARY) returns wrong result
parent
d04f2de8
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
362 additions
and
14 deletions
+362
-14
plugin/type_inet/mysql-test/type_inet/type_inet6.result
plugin/type_inet/mysql-test/type_inet/type_inet6.result
+105
-0
plugin/type_inet/mysql-test/type_inet/type_inet6.test
plugin/type_inet/mysql-test/type_inet/type_inet6.test
+65
-0
plugin/type_inet/sql_type_inet.cc
plugin/type_inet/sql_type_inet.cc
+48
-0
plugin/type_inet/sql_type_inet.h
plugin/type_inet/sql_type_inet.h
+1
-5
sql/item_func.h
sql/item_func.h
+50
-0
sql/item_timefunc.cc
sql/item_timefunc.cc
+85
-1
sql/item_timefunc.h
sql/item_timefunc.h
+8
-8
No files found.
plugin/type_inet/mysql-test/type_inet/type_inet6.result
View file @
b5fae7f7
...
...
@@ -720,6 +720,99 @@ t1 CREATE TABLE `t1` (
`a` varchar(39) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('ffff::ffff');
CREATE TABLE t2 AS SELECT
CAST(a AS CHAR),
CAST(a AS CHAR(39)),
CAST(a AS CHAR(530)),
CAST(a AS CHAR(65535)),
CAST(a AS CHAR(66000)),
CAST(a AS CHAR(16777215)),
CAST(a AS CHAR(16777216))
FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`CAST(a AS CHAR)` varchar(39) DEFAULT NULL,
`CAST(a AS CHAR(39))` varchar(39) DEFAULT NULL,
`CAST(a AS CHAR(530))` text DEFAULT NULL,
`CAST(a AS CHAR(65535))` text DEFAULT NULL,
`CAST(a AS CHAR(66000))` mediumtext DEFAULT NULL,
`CAST(a AS CHAR(16777215))` mediumtext DEFAULT NULL,
`CAST(a AS CHAR(16777216))` longtext DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT * FROM t2;
CAST(a AS CHAR) ffff::ffff
CAST(a AS CHAR(39)) ffff::ffff
CAST(a AS CHAR(530)) ffff::ffff
CAST(a AS CHAR(65535)) ffff::ffff
CAST(a AS CHAR(66000)) ffff::ffff
CAST(a AS CHAR(16777215)) ffff::ffff
CAST(a AS CHAR(16777216)) ffff::ffff
DROP TABLE t2;
DROP TABLE t1;
CREATE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('ffff::ffff');
CREATE TABLE t2 AS SELECT
CAST(a AS BINARY(4)) AS cb4,
CAST(a AS BINARY) AS cb,
CAST(a AS BINARY(16)) AS cb16,
CAST(a AS BINARY(32)) AS cb32,
CAST(a AS BINARY(530)) AS cb530,
CAST(a AS BINARY(65535)) AS cb65535,
CAST(a AS BINARY(66000)) AS cb66000,
CAST(a AS BINARY(16777215)) AS cb16777215,
CAST(a AS BINARY(16777216)) AS cb16777216
FROM t1 LIMIT 0;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`cb4` binary(4) DEFAULT NULL,
`cb` binary(16) DEFAULT NULL,
`cb16` binary(16) DEFAULT NULL,
`cb32` binary(32) DEFAULT NULL,
`cb530` varbinary(530) DEFAULT NULL,
`cb65535` blob DEFAULT NULL,
`cb66000` mediumblob DEFAULT NULL,
`cb16777215` mediumblob DEFAULT NULL,
`cb16777216` longblob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2;
CREATE TABLE t2 AS SELECT
CAST(a AS BINARY(4)) AS cb4,
CAST(a AS BINARY) AS cb,
CAST(a AS BINARY(16)) AS cb16,
CAST(a AS BINARY(32)) AS cb32,
CAST(a AS BINARY(530)) AS cb530,
CAST(a AS BINARY(65535)) AS cb65535
FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`cb4` binary(4) DEFAULT NULL,
`cb` binary(16) DEFAULT NULL,
`cb16` binary(16) DEFAULT NULL,
`cb32` binary(32) DEFAULT NULL,
`cb530` varbinary(530) DEFAULT NULL,
`cb65535` blob DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT
HEX(cb4),
HEX(cb),
HEX(cb16),
HEX(cb32),
LENGTH(cb530),
LENGTH(cb65535)
FROM t2;
HEX(cb4) FFFF0000
HEX(cb) FFFF000000000000000000000000FFFF
HEX(cb16) FFFF000000000000000000000000FFFF
HEX(cb32) FFFF000000000000000000000000FFFF00000000000000000000000000000000
LENGTH(cb530) 530
LENGTH(cb65535) 65535
DROP TABLE t2;
DROP TABLE t1;
#
# Implicit conversion to other types in INSERT
#
...
...
@@ -1516,3 +1609,15 @@ SELECT HEX(a) FROM t1;
HEX(a)
20010DB8000000000000FF0000428329
DROP TABLE t1;
#
# MDEV-20795 CAST(inet6 AS BINARY) returns wrong result
#
CREATE OR REPLACE TABLE t1 (a INET6);
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
SELECT HEX(CAST(a AS BINARY)) FROM t1;
HEX(CAST(a AS BINARY))
20010DB8000000000000FF0000428329
SELECT HEX(CAST(a AS BINARY(16))) FROM t1;
HEX(CAST(a AS BINARY(16)))
20010DB8000000000000FF0000428329
DROP TABLE t1;
plugin/type_inet/mysql-test/type_inet/type_inet6.test
View file @
b5fae7f7
...
...
@@ -383,6 +383,61 @@ CREATE TABLE t1 AS SELECT CAST(CAST('::' AS INET6) AS CHAR) AS a;
SHOW
CREATE
TABLE
t1
;
DROP
TABLE
t1
;
CREATE
TABLE
t1
(
a
INET6
);
INSERT
INTO
t1
VALUES
(
'ffff::ffff'
);
CREATE
TABLE
t2
AS
SELECT
CAST
(
a
AS
CHAR
),
CAST
(
a
AS
CHAR
(
39
)),
CAST
(
a
AS
CHAR
(
530
)),
CAST
(
a
AS
CHAR
(
65535
)),
CAST
(
a
AS
CHAR
(
66000
)),
CAST
(
a
AS
CHAR
(
16777215
)),
CAST
(
a
AS
CHAR
(
16777216
))
FROM
t1
;
SHOW
CREATE
TABLE
t2
;
--
vertical_results
SELECT
*
FROM
t2
;
--
horizontal_results
DROP
TABLE
t2
;
DROP
TABLE
t1
;
CREATE
TABLE
t1
(
a
INET6
);
INSERT
INTO
t1
VALUES
(
'ffff::ffff'
);
CREATE
TABLE
t2
AS
SELECT
CAST
(
a
AS
BINARY
(
4
))
AS
cb4
,
CAST
(
a
AS
BINARY
)
AS
cb
,
CAST
(
a
AS
BINARY
(
16
))
AS
cb16
,
CAST
(
a
AS
BINARY
(
32
))
AS
cb32
,
CAST
(
a
AS
BINARY
(
530
))
AS
cb530
,
CAST
(
a
AS
BINARY
(
65535
))
AS
cb65535
,
CAST
(
a
AS
BINARY
(
66000
))
AS
cb66000
,
CAST
(
a
AS
BINARY
(
16777215
))
AS
cb16777215
,
CAST
(
a
AS
BINARY
(
16777216
))
AS
cb16777216
FROM
t1
LIMIT
0
;
SHOW
CREATE
TABLE
t2
;
DROP
TABLE
t2
;
CREATE
TABLE
t2
AS
SELECT
CAST
(
a
AS
BINARY
(
4
))
AS
cb4
,
CAST
(
a
AS
BINARY
)
AS
cb
,
CAST
(
a
AS
BINARY
(
16
))
AS
cb16
,
CAST
(
a
AS
BINARY
(
32
))
AS
cb32
,
CAST
(
a
AS
BINARY
(
530
))
AS
cb530
,
CAST
(
a
AS
BINARY
(
65535
))
AS
cb65535
FROM
t1
;
SHOW
CREATE
TABLE
t2
;
--
vertical_results
SELECT
HEX
(
cb4
),
HEX
(
cb
),
HEX
(
cb16
),
HEX
(
cb32
),
LENGTH
(
cb530
),
LENGTH
(
cb65535
)
FROM
t2
;
--
horizontal_results
DROP
TABLE
t2
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# Implicit conversion to other types in INSERT
...
...
@@ -1049,3 +1104,13 @@ INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
ALTER
TABLE
t1
MODIFY
a
BINARY
(
16
);
SELECT
HEX
(
a
)
FROM
t1
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# MDEV-20795 CAST(inet6 AS BINARY) returns wrong result
--
echo
#
CREATE
OR
REPLACE
TABLE
t1
(
a
INET6
);
INSERT
INTO
t1
VALUES
(
'2001:db8::ff00:42:8329'
);
SELECT
HEX
(
CAST
(
a
AS
BINARY
))
FROM
t1
;
SELECT
HEX
(
CAST
(
a
AS
BINARY
(
16
)))
FROM
t1
;
DROP
TABLE
t1
;
plugin/type_inet/sql_type_inet.cc
View file @
b5fae7f7
...
...
@@ -1216,6 +1216,54 @@ class in_inet6 :public in_vector
};
class
Item_char_typecast_func_handler_inet6_to_binary
:
public
Item_handled_func
::
Handler_str
{
public:
const
Type_handler
*
return_type_handler
()
const
override
{
return
&
type_handler_string
;
}
const
Type_handler
*
type_handler_for_create_select
(
const
Item_handled_func
*
item
)
const
{
if
(
item
->
max_length
>
MAX_FIELD_VARCHARLENGTH
)
return
Type_handler
::
blob_type_handler
(
item
->
max_length
);
if
(
item
->
max_length
>
255
)
return
&
type_handler_varchar
;
return
&
type_handler_string
;
}
bool
fix_length_and_dec
(
Item_handled_func
*
xitem
)
const
override
{
return
false
;
}
String
*
val_str
(
Item_handled_func
*
item
,
String
*
to
)
const
override
{
DBUG_ASSERT
(
dynamic_cast
<
const
Item_char_typecast
*>
(
item
));
return
static_cast
<
Item_char_typecast
*>
(
item
)
->
val_str_binary_from_native
(
to
);
}
};
static
const
Item_char_typecast_func_handler_inet6_to_binary
item_char_typecast_func_handler_inet6_to_binary
;
bool
Type_handler_inet6
::
Item_char_typecast_fix_length_and_dec
(
Item_char_typecast
*
item
)
const
{
if
(
item
->
cast_charset
()
==
&
my_charset_bin
)
{
item
->
fix_length_and_dec_native_to_binary
(
Inet6
::
binary_length
());
item
->
set_func_handler
(
&
item_char_typecast_func_handler_inet6_to_binary
);
return
false
;
}
item
->
fix_length_and_dec_str
();
return
false
;
}
bool
Type_handler_inet6
::
character_or_binary_string_to_native
(
THD
*
thd
,
const
String
*
str
,
...
...
plugin/type_inet/sql_type_inet.h
View file @
b5fae7f7
...
...
@@ -930,11 +930,7 @@ class Type_handler_inet6: public Type_handler
}
bool
Item_char_typecast_fix_length_and_dec
(
Item_char_typecast
*
item
)
const
override
{
item
->
fix_length_and_dec_str
();
return
false
;
}
const
override
;
bool
Item_time_typecast_fix_length_and_dec
(
Item_time_typecast
*
item
)
const
override
{
...
...
sql/item_func.h
View file @
b5fae7f7
...
...
@@ -467,9 +467,46 @@ class Item_handled_func: public Item_func
virtual
my_decimal
*
val_decimal
(
Item_handled_func
*
,
my_decimal
*
)
const
=
0
;
virtual
bool
get_date
(
THD
*
thd
,
Item_handled_func
*
,
MYSQL_TIME
*
,
date_mode_t
fuzzydate
)
const
=
0
;
virtual
const
Type_handler
*
return_type_handler
()
const
=
0
;
virtual
const
Type_handler
*
type_handler_for_create_select
(
const
Item_handled_func
*
item
)
const
{
return
return_type_handler
();
}
virtual
bool
fix_length_and_dec
(
Item_handled_func
*
)
const
=
0
;
};
class
Handler_str
:
public
Handler
{
public:
String
*
val_str_ascii
(
Item_handled_func
*
item
,
String
*
str
)
const
{
return
item
->
Item
::
val_str_ascii
(
str
);
}
double
val_real
(
Item_handled_func
*
item
)
const
{
DBUG_ASSERT
(
item
->
is_fixed
());
StringBuffer
<
64
>
tmp
;
String
*
res
=
item
->
val_str
(
&
tmp
);
return
res
?
item
->
double_from_string_with_check
(
res
)
:
0.0
;
}
longlong
val_int
(
Item_handled_func
*
item
)
const
{
DBUG_ASSERT
(
item
->
is_fixed
());
StringBuffer
<
22
>
tmp
;
String
*
res
=
item
->
val_str
(
&
tmp
);
return
res
?
item
->
longlong_from_string_with_check
(
res
)
:
0
;
}
my_decimal
*
val_decimal
(
Item_handled_func
*
item
,
my_decimal
*
to
)
const
{
return
item
->
val_decimal_from_string
(
to
);
}
bool
get_date
(
THD
*
thd
,
Item_handled_func
*
item
,
MYSQL_TIME
*
to
,
date_mode_t
fuzzydate
)
const
{
return
item
->
get_date_from_string
(
thd
,
to
,
fuzzydate
);
}
};
/**
Abstract class for functions returning TIME, DATE, DATETIME or string values,
whose data type depends on parameters and is set at fix_fields time.
...
...
@@ -496,6 +533,11 @@ class Item_handled_func: public Item_func
{
return
&
type_handler_string
;
}
const
Type_handler
*
type_handler_for_create_select
(
const
Item_handled_func
*
item
)
const
{
return
return_type_handler
()
->
type_handler_for_tmp_table
(
item
);
}
double
val_real
(
Item_handled_func
*
item
)
const
{
return
Temporal_hybrid
(
item
).
to_double
();
...
...
@@ -613,6 +655,14 @@ class Item_handled_func: public Item_func
{
return
m_func_handler
->
return_type_handler
();
}
Field
*
create_field_for_create_select
(
MEM_ROOT
*
root
,
TABLE
*
table
)
{
DBUG_ASSERT
(
fixed
);
const
Type_handler
*
h
=
m_func_handler
->
type_handler_for_create_select
(
this
);
return
h
->
make_and_init_table_field
(
root
,
&
name
,
Record_addr
(
maybe_null
),
*
this
,
table
);
}
String
*
val_str
(
String
*
to
)
{
return
m_func_handler
->
val_str
(
this
,
to
);
...
...
sql/item_timefunc.cc
View file @
b5fae7f7
...
...
@@ -2326,7 +2326,7 @@ uint Item_char_typecast::adjusted_length_with_warn(uint length)
}
String
*
Item_char_typecast
::
val_str
(
String
*
str
)
String
*
Item_char_typecast
::
val_str
_generic
(
String
*
str
)
{
DBUG_ASSERT
(
fixed
==
1
);
String
*
res
;
...
...
@@ -2382,11 +2382,75 @@ String *Item_char_typecast::val_str(String *str)
}
String
*
Item_char_typecast
::
val_str_binary_from_native
(
String
*
str
)
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
cast_cs
==
&
my_charset_bin
);
NativeBuffer
<
STRING_BUFFER_USUAL_SIZE
>
native
;
if
(
args
[
0
]
->
val_native
(
current_thd
,
&
native
))
{
null_value
=
1
;
return
0
;
}
if
(
has_explicit_length
())
{
cast_length
=
adjusted_length_with_warn
(
cast_length
);
if
(
cast_length
>
native
.
length
())
{
// add trailing 0x00s
DBUG_ASSERT
(
cast_length
<=
current_thd
->
variables
.
max_allowed_packet
);
str
->
alloc
(
cast_length
);
str
->
copy
(
native
.
ptr
(),
native
.
length
(),
&
my_charset_bin
);
bzero
((
char
*
)
str
->
end
(),
cast_length
-
str
->
length
());
str
->
length
(
cast_length
);
}
else
str
->
copy
(
native
.
ptr
(),
cast_length
,
&
my_charset_bin
);
}
else
str
->
copy
(
native
.
ptr
(),
native
.
length
(),
&
my_charset_bin
);
return
((
null_value
=
(
str
->
length
()
>
adjusted_length_with_warn
(
str
->
length
()))))
?
0
:
str
;
}
class
Item_char_typecast_func_handler
:
public
Item_handled_func
::
Handler_str
{
public:
const
Type_handler
*
return_type_handler
()
const
{
return
&
type_handler_varchar
;
}
const
Type_handler
*
type_handler_for_create_select
(
const
Item_handled_func
*
item
)
const
{
return
return_type_handler
()
->
type_handler_for_tmp_table
(
item
);
}
bool
fix_length_and_dec
(
Item_handled_func
*
item
)
const
{
return
false
;
}
String
*
val_str
(
Item_handled_func
*
item
,
String
*
to
)
const
{
DBUG_ASSERT
(
dynamic_cast
<
const
Item_char_typecast
*>
(
item
));
return
static_cast
<
Item_char_typecast
*>
(
item
)
->
val_str_generic
(
to
);
}
};
static
const
Item_char_typecast_func_handler
item_char_typecast_func_handler
;
void
Item_char_typecast
::
fix_length_and_dec_numeric
()
{
fix_length_and_dec_internal
(
from_cs
=
cast_cs
->
mbminlen
==
1
?
cast_cs
:
&
my_charset_latin1
);
set_func_handler
(
&
item_char_typecast_func_handler
);
}
...
...
@@ -2395,6 +2459,24 @@ void Item_char_typecast::fix_length_and_dec_generic()
fix_length_and_dec_internal
(
from_cs
=
args
[
0
]
->
dynamic_result
()
?
0
:
args
[
0
]
->
collation
.
collation
);
set_func_handler
(
&
item_char_typecast_func_handler
);
}
void
Item_char_typecast
::
fix_length_and_dec_str
()
{
fix_length_and_dec_generic
();
m_suppress_warning_to_error_escalation
=
true
;
set_func_handler
(
&
item_char_typecast_func_handler
);
}
void
Item_char_typecast
::
fix_length_and_dec_native_to_binary
(
uint32
octet_length
)
{
collation
.
set
(
&
my_charset_bin
,
DERIVATION_IMPLICIT
);
max_length
=
has_explicit_length
()
?
(
uint32
)
cast_length
:
octet_length
;
maybe_null
|=
current_thd
->
is_strict_mode
();
}
...
...
@@ -2438,6 +2520,8 @@ void Item_char_typecast::fix_length_and_dec_internal(CHARSET_INFO *from_cs)
(
cast_cs
==
&
my_charset_bin
?
1
:
args
[
0
]
->
collation
.
collation
->
mbmaxlen
));
max_length
=
char_length
*
cast_cs
->
mbmaxlen
;
// Add NULL-ability in strict mode. See Item_str_func::fix_fields()
maybe_null
=
maybe_null
||
current_thd
->
is_strict_mode
();
}
...
...
sql/item_timefunc.h
View file @
b5fae7f7
...
...
@@ -1074,14 +1074,16 @@ class Item_extract :public Item_int_func,
};
class
Item_char_typecast
:
public
Item_
str
_func
class
Item_char_typecast
:
public
Item_
handled
_func
{
uint
cast_length
;
CHARSET_INFO
*
cast_cs
,
*
from_cs
;
bool
charset_conversion
;
String
tmp_value
;
bool
m_suppress_warning_to_error_escalation
;
public:
bool
has_explicit_length
()
const
{
return
cast_length
!=
~
0U
;
}
private:
String
*
reuse
(
String
*
src
,
size_t
length
);
String
*
copy
(
String
*
src
,
CHARSET_INFO
*
cs
);
uint
adjusted_length_with_warn
(
uint
length
);
...
...
@@ -1092,20 +1094,18 @@ class Item_char_typecast :public Item_str_func
uint
get_cast_length
()
const
{
return
cast_length
;
}
public:
Item_char_typecast
(
THD
*
thd
,
Item
*
a
,
uint
length_arg
,
CHARSET_INFO
*
cs_arg
)
:
Item_
str
_func
(
thd
,
a
),
cast_length
(
length_arg
),
cast_cs
(
cs_arg
),
Item_
handled
_func
(
thd
,
a
),
cast_length
(
length_arg
),
cast_cs
(
cs_arg
),
m_suppress_warning_to_error_escalation
(
false
)
{}
enum
Functype
functype
()
const
{
return
CHAR_TYPECAST_FUNC
;
}
bool
eq
(
const
Item
*
item
,
bool
binary_cmp
)
const
;
const
char
*
func_name
()
const
{
return
"cast_as_char"
;
}
CHARSET_INFO
*
cast_charset
()
const
{
return
cast_cs
;
}
String
*
val_str
(
String
*
a
);
String
*
val_str_generic
(
String
*
a
);
String
*
val_str_binary_from_native
(
String
*
a
);
void
fix_length_and_dec_generic
();
void
fix_length_and_dec_numeric
();
void
fix_length_and_dec_str
()
{
fix_length_and_dec_generic
();
m_suppress_warning_to_error_escalation
=
true
;
}
void
fix_length_and_dec_str
();
void
fix_length_and_dec_native_to_binary
(
uint32
octet_length
);
bool
fix_length_and_dec
()
{
return
args
[
0
]
->
type_handler
()
->
Item_char_typecast_fix_length_and_dec
(
this
);
...
...
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