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
db0917f6
Commit
db0917f6
authored
May 05, 2017
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-12696 Crash with LOAD XML and non-updatable VIEW column
parent
96247be1
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
89 additions
and
45 deletions
+89
-45
mysql-test/r/loadxml.result
mysql-test/r/loadxml.result
+11
-0
mysql-test/std_data/loaddata/mdev12696.xml
mysql-test/std_data/loaddata/mdev12696.xml
+9
-0
mysql-test/t/loadxml.test
mysql-test/t/loadxml.test
+13
-0
sql/item.h
sql/item.h
+21
-0
sql/item_func.cc
sql/item_func.cc
+5
-4
sql/item_func.h
sql/item_func.h
+6
-4
sql/sql_load.cc
sql/sql_load.cc
+24
-37
No files found.
mysql-test/r/loadxml.result
View file @
db0917f6
...
...
@@ -123,3 +123,14 @@ col1 col2 col3
ABC DEF NULL
GHI NULL 123
DROP TABLE t1;
#
# MDEV-12696 Crash with LOAD XML and non-updatable VIEW column
#
CREATE TABLE t1 (c1 TEXT);
CREATE VIEW v1 AS SELECT CONCAT(c1,'') AS c1, NULL AS c2 FROM t1;
LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c1);
ERROR HY000: Invalid column reference (v1.c1) in LOAD DATA
LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c2);
ERROR HY000: Invalid column reference (v1.c2) in LOAD DATA
DROP VIEW v1;
DROP TABLE t1;
mysql-test/std_data/loaddata/mdev12696.xml
0 → 100644
View file @
db0917f6
<?xml version="1.0"?>
<resultset
statement=
"SELECT 'test' AS c1, NULL AS c2
"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
>
<row>
<field
name=
"c1"
>
test
</field>
<field
name=
"c2"
xsi:nil=
"true"
/>
</row>
</resultset>
mysql-test/t/loadxml.test
View file @
db0917f6
...
...
@@ -130,3 +130,16 @@ CREATE TABLE t1 (col1 VARCHAR(3), col2 VARCHAR(3), col3 INTEGER);
LOAD
XML
INFILE
'../../std_data/bug16171518_2.dat'
INTO
TABLE
t1
;
SELECT
*
FROM
t1
ORDER
BY
col1
,
col2
,
col3
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# MDEV-12696 Crash with LOAD XML and non-updatable VIEW column
--
echo
#
CREATE
TABLE
t1
(
c1
TEXT
);
CREATE
VIEW
v1
AS
SELECT
CONCAT
(
c1
,
''
)
AS
c1
,
NULL
AS
c2
FROM
t1
;
--
error
ER_LOAD_DATA_INVALID_COLUMN
LOAD
XML
INFILE
'../../std_data/loaddata/mdev12696.xml'
INTO
TABLE
v1
(
c1
);
--
error
ER_LOAD_DATA_INVALID_COLUMN
,
LOAD
XML
INFILE
'../../std_data/loaddata/mdev12696.xml'
INTO
TABLE
v1
(
c2
);
DROP
VIEW
v1
;
DROP
TABLE
t1
;
sql/item.h
View file @
db0917f6
...
...
@@ -439,6 +439,19 @@ typedef struct replace_equal_field_arg
struct
st_join_table
*
context_tab
;
}
REPLACE_EQUAL_FIELD_ARG
;
class
Load_data_out_param
{
public:
Load_data_out_param
()
{
}
virtual
~
Load_data_out_param
()
{
}
virtual
void
load_data_set_null_value
(
CHARSET_INFO
*
cs
)
=
0
;
virtual
void
load_data_set_value
(
const
char
*
str
,
uint
length
,
CHARSET_INFO
*
cs
)
=
0
;
virtual
void
load_data_print
(
THD
*
thd
,
String
*
str
)
=
0
;
};
class
Settable_routine_parameter
{
public:
...
...
@@ -1789,6 +1802,14 @@ class Item: public Value_source,
delete
this
;
}
virtual
Load_data_out_param
*
get_load_data_out_param
()
{
return
0
;
}
Load_data_out_param
*
get_load_data_out_param_or_error
()
{
Load_data_out_param
*
res
=
get_load_data_out_param
();
if
(
!
res
)
my_error
(
ER_LOAD_DATA_INVALID_COLUMN
,
MYF
(
0
),
full_name
());
return
res
;
}
virtual
Item_splocal
*
get_item_splocal
()
{
return
0
;
}
virtual
Rewritable_query_parameter
*
get_rewritable_query_parameter
()
{
return
0
;
}
...
...
sql/item_func.cc
View file @
db0917f6
...
...
@@ -5675,13 +5675,14 @@ bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref)
}
void
Item_user_var_as_out_param
::
set_null_value
(
CHARSET_INFO
*
cs
)
void
Item_user_var_as_out_param
::
load_data_
set_null_value
(
CHARSET_INFO
*
cs
)
{
::
update_hash
(
entry
,
TRUE
,
0
,
0
,
STRING_RESULT
,
cs
,
0
/* unsigned_arg */
);
}
void
Item_user_var_as_out_param
::
set_value
(
const
char
*
str
,
uint
length
,
void
Item_user_var_as_out_param
::
load_data_set_value
(
const
char
*
str
,
uint
length
,
CHARSET_INFO
*
cs
)
{
::
update_hash
(
entry
,
FALSE
,
(
void
*
)
str
,
length
,
STRING_RESULT
,
cs
,
...
...
@@ -5717,7 +5718,7 @@ my_decimal* Item_user_var_as_out_param::val_decimal(my_decimal *decimal_buffer)
}
void
Item_user_var_as_out_param
::
print_for_load
(
THD
*
thd
,
String
*
str
)
void
Item_user_var_as_out_param
::
load_data_print
(
THD
*
thd
,
String
*
str
)
{
str
->
append
(
'@'
);
append_identifier
(
thd
,
str
,
name
.
str
,
name
.
length
);
...
...
sql/item_func.h
View file @
db0917f6
...
...
@@ -2006,7 +2006,8 @@ class Item_func_get_user_var :public Item_func_user_var,
in List<Item> and desire to place this code somewhere near other functions
working with user variables.
*/
class
Item_user_var_as_out_param
:
public
Item
class
Item_user_var_as_out_param
:
public
Item
,
public
Load_data_out_param
{
LEX_STRING
name
;
user_var_entry
*
entry
;
...
...
@@ -2021,9 +2022,10 @@ class Item_user_var_as_out_param :public Item
my_decimal
*
val_decimal
(
my_decimal
*
decimal_buffer
);
/* fix_fields() binds variable name with its entry structure */
bool
fix_fields
(
THD
*
thd
,
Item
**
ref
);
void
print_for_load
(
THD
*
thd
,
String
*
str
);
void
set_null_value
(
CHARSET_INFO
*
cs
);
void
set_value
(
const
char
*
str
,
uint
length
,
CHARSET_INFO
*
cs
);
Load_data_out_param
*
get_load_data_out_param
()
{
return
this
;
}
void
load_data_print
(
THD
*
thd
,
String
*
str
);
void
load_data_set_null_value
(
CHARSET_INFO
*
cs
);
void
load_data_set_value
(
const
char
*
str
,
uint
length
,
CHARSET_INFO
*
cs
);
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_DOUBLE
;
}
Item
*
get_copy
(
THD
*
thd
,
MEM_ROOT
*
mem_root
)
{
return
get_item_copy
<
Item_user_var_as_out_param
>
(
thd
,
mem_root
,
this
);
}
...
...
sql/sql_load.cc
View file @
db0917f6
...
...
@@ -431,7 +431,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
else
tot_length
+=
field
->
field_length
;
}
else
if
(
item
->
type
()
==
Item
::
STRING_ITEM
)
else
if
(
item
->
get_load_data_out_param
()
)
use_vars
=
1
;
}
if
(
use_blobs
&&
!
ex
->
line_term
->
length
()
&&
!
field_term
->
length
())
...
...
@@ -814,11 +814,7 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex,
if
(
item
->
real_type
()
==
Item
::
FIELD_ITEM
)
append_identifier
(
thd
,
&
query_str
,
item
->
name
,
strlen
(
item
->
name
));
else
{
/* Actually Item_user_var_as_out_param despite claiming STRING_ITEM. */
DBUG_ASSERT
(
item
->
type
()
==
Item
::
STRING_ITEM
);
((
Item_user_var_as_out_param
*
)
item
)
->
print_for_load
(
thd
,
&
query_str
);
}
item
->
get_load_data_out_param
()
->
load_data_print
(
thd
,
&
query_str
);
}
query_str
.
append
(
")"
);
}
...
...
@@ -1062,6 +1058,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
uint
length
;
uchar
*
pos
;
Item
*
real_item
;
Load_data_out_param
*
out_param
;
if
(
read_info
.
read_field
())
break
;
...
...
@@ -1105,17 +1102,10 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
/* Do not auto-update this field. */
field
->
set_has_explicit_value
();
}
else
if
(
item
->
type
()
==
Item
::
STRING_ITEM
)
{
((
Item_user_var_as_out_param
*
)
item
)
->
set_null_value
(
read_info
.
read_charset
);
}
else
if
((
out_param
=
item
->
get_load_data_out_param_or_error
()))
out_param
->
load_data_set_null_value
(
read_info
.
read_charset
);
else
{
my_error
(
ER_LOAD_DATA_INVALID_COLUMN
,
MYF
(
0
),
item
->
full_name
());
DBUG_RETURN
(
1
);
}
continue
;
}
...
...
@@ -1129,17 +1119,12 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
field
->
store
((
char
*
)
pos
,
length
,
read_info
.
read_charset
);
field
->
set_has_explicit_value
();
}
else
if
(
item
->
type
()
==
Item
::
STRING_ITEM
)
{
((
Item_user_var_as_out_param
*
)
item
)
->
set_value
((
char
*
)
pos
,
length
,
else
if
((
out_param
=
item
->
get_load_data_out_param_or_error
()))
out_param
->
load_data_set_value
((
const
char
*
)
pos
,
length
,
read_info
.
read_charset
);
}
else
{
my_error
(
ER_LOAD_DATA_INVALID_COLUMN
,
MYF
(
0
),
item
->
full_name
());
DBUG_RETURN
(
1
);
}
}
if
(
thd
->
is_error
())
read_info
.
error
=
1
;
...
...
@@ -1158,6 +1143,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
break
;
for
(;
item
;
item
=
it
++
)
{
Load_data_out_param
*
out_param
;
Item
*
real_item
=
item
->
real_item
();
if
(
real_item
->
type
()
==
Item
::
FIELD_ITEM
)
{
...
...
@@ -1183,18 +1169,12 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
ER_THD
(
thd
,
ER_WARN_TOO_FEW_RECORDS
),
thd
->
get_stmt_da
()
->
current_row_for_warning
());
}
else
if
(
item
->
type
()
==
Item
::
STRING_ITEM
)
{
((
Item_user_var_as_out_param
*
)
item
)
->
set_null_value
(
read_info
.
read_charset
);
}
else
if
((
out_param
=
item
->
get_load_data_out_param_or_error
()))
out_param
->
load_data_set_null_value
(
read_info
.
read_charset
);
else
{
my_error
(
ER_LOAD_DATA_INVALID_COLUMN
,
MYF
(
0
),
item
->
full_name
());
DBUG_RETURN
(
1
);
}
}
}
if
(
thd
->
killed
||
fill_record_n_invoke_before_triggers
(
thd
,
table
,
set_fields
,
...
...
@@ -1288,6 +1268,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
while
((
item
=
it
++
))
{
Load_data_out_param
*
out_param
;
/* If this line is to be skipped we don't want to fill field or var */
if
(
skip_lines
)
continue
;
...
...
@@ -1319,14 +1300,15 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
/* Do not auto-update this field. */
field
->
set_has_explicit_value
();
}
else
if
((
out_param
=
item
->
get_load_data_out_param_or_error
()))
out_param
->
load_data_set_null_value
(
cs
);
else
((
Item_user_var_as_out_param
*
)
item
)
->
set_null_value
(
cs
);
DBUG_RETURN
(
1
);
continue
;
}
if
(
item
->
type
()
==
Item
::
FIELD_ITEM
)
{
Field
*
field
=
((
Item_field
*
)
item
)
->
field
;
field
->
set_notnull
();
if
(
field
==
table
->
next_number_field
)
...
...
@@ -1334,10 +1316,12 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
field
->
store
((
char
*
)
tag
->
value
.
ptr
(),
tag
->
value
.
length
(),
cs
);
field
->
set_has_explicit_value
();
}
else
((
Item_user_var_as_out_param
*
)
item
)
->
set_value
(
(
char
*
)
tag
->
value
.
ptr
(),
else
if
((
out_param
=
item
->
get_load_data_out_param_or_error
()))
out_param
->
load_data_set_value
((
const
char
*
)
tag
->
value
.
ptr
(),
tag
->
value
.
length
(),
cs
);
else
DBUG_RETURN
(
1
);
}
if
(
read_info
.
error
)
...
...
@@ -1357,6 +1341,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
for
(
;
item
;
item
=
it
++
)
{
Load_data_out_param
*
out_param
;
if
(
item
->
type
()
==
Item
::
FIELD_ITEM
)
{
/*
...
...
@@ -1371,8 +1356,10 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
ER_THD
(
thd
,
ER_WARN_TOO_FEW_RECORDS
),
thd
->
get_stmt_da
()
->
current_row_for_warning
());
}
else
if
((
out_param
=
item
->
get_load_data_out_param_or_error
()))
out_param
->
load_data_set_null_value
(
cs
);
else
((
Item_user_var_as_out_param
*
)
item
)
->
set_null_value
(
cs
);
DBUG_RETURN
(
1
);
}
}
...
...
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