Skip to content

Commit ee02650

Browse files
author
Shishir Jaiswal
committed
Bug #16171518 - LOAD XML DOES NOT HANDLE EMPTY ELEMENTS
DESCRIPTION =========== Inability of mysql LOAD XML command to handle empty XML tags i.e. <row><tag/></row>. Also the behaviour is wrong and (different than above) when there is a space in empty tag i.e. <row><tag /></row> ANALYSIS ======== In read_xml() the case where we encounter a close tag ('/') we're decreasing the 'level' blindly which is wrong. Actually when its an without-space-empty-tag (succeeding char is '>'), we need to skip the decrement. In other words whenever we hit a close tag ('/'), decrease the 'level' only when (i) It's not an (without space) empty tag i.e. <tag/> or, (ii) It is of format <row col="val" .../> FIX === The switch case for '/' is modified. We've removed the blind decrement of 'level'. We do it only when its not an without-space-empty-tag. Also we are setting 'in_tag' to false to let program know that we're done reading current tag (required in the case of format <row col="val" .../>)
1 parent 93ac0eb commit ee02650

File tree

5 files changed

+121
-2
lines changed

5 files changed

+121
-2
lines changed

mysql-test/r/loadxml.result

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,30 @@ a b
9393
216 !&bb b;
9494
3 !b3
9595
DROP TABLE t1;
96+
#
97+
# Bug#16171518 LOAD XML DOES NOT HANDLE EMPTY ELEMENTS
98+
#
99+
CREATE TABLE t1 (col1 VARCHAR(3), col2 VARCHAR(3), col3 VARCHAR(3), col4 VARCHAR(4));
100+
LOAD XML INFILE '../../std_data/bug16171518_1.dat' INTO TABLE t1;
101+
SELECT * FROM t1 ORDER BY col1, col2, col3, col4;
102+
col1 col2 col3 col4
103+
0bc def ghi jkl
104+
1no NULL pqr stu
105+
2BC DEF GHI JKL
106+
3NO NULL PQR STU
107+
4bc def ghi jkl
108+
5no pqr stu vwx
109+
6BC DEF NULL JKL
110+
7NO PQR STU VWX
111+
8bc def ghi NULL
112+
9kl NULL mno pqr
113+
ABC DEF NULL JKL
114+
MNO NULL STU VWX
115+
DROP TABLE t1;
116+
CREATE TABLE t1 (col1 VARCHAR(3), col2 VARCHAR(3), col3 INTEGER);
117+
LOAD XML INFILE '../../std_data/bug16171518_2.dat' INTO TABLE t1;
118+
SELECT * FROM t1 ORDER BY col1, col2, col3;
119+
col1 col2 col3
120+
ABC DEF NULL
121+
GHI NULL 123
122+
DROP TABLE t1;

mysql-test/std_data/bug16171518_1.dat

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<test_rows>
2+
<row>
3+
<col1>0bc</col1>
4+
<col2>def</col2>
5+
<col3>ghi</col3>
6+
<col4>jkl</col4>
7+
</row>
8+
<row>
9+
<col1>1no</col1>
10+
<col2/>
11+
<col3>pqr</col3>
12+
<col4>stu</col4>
13+
</row>
14+
15+
<row>
16+
<col1>2BC</col1>
17+
<col2>DEF</col2>
18+
<col3>GHI</col3>
19+
<col4>JKL</col4>
20+
</row>
21+
<row>
22+
<col1>3NO</col1>
23+
<col2 />
24+
<col3>PQR</col3>
25+
<col4>STU</col4>
26+
</row>
27+
28+
<row col1="4bc" col2="def" col3="ghi" col4="jkl"/>
29+
<row col1="5no" col2="pqr" col3="stu" col4="vwx" />
30+
31+
<row>
32+
<field name='col1'>6BC</field>
33+
<field name='col2'>DEF</field>
34+
<field name='col3'></field>
35+
<field name='col4'>JKL</field>
36+
</row>
37+
<row>
38+
<field name='col1'>7NO</field>
39+
<field name='col2'>PQR</field>
40+
<field name='col3'>STU</field>
41+
<field name='col4'>VWX</field>
42+
</row>
43+
44+
<row>
45+
<col1>8bc</col1>
46+
<col2>def</col2>
47+
<col3>ghi</col3>
48+
<col4 />
49+
</row>
50+
<row>
51+
<col1>9kl</col1>
52+
<col2/>
53+
<col3>mno</col3>
54+
<col4>pqr</col4>
55+
</row>
56+
57+
<row col1="ABC" col2="DEF" col3="" col4="JKL"/>
58+
<row col1="MNO" col2="" col3="STU" col4="VWX"/>
59+
</test_rows>

mysql-test/std_data/bug16171518_2.dat

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<test_rows>
2+
<row>
3+
<col1>ABC</col1>
4+
<col2>DEF</col2>
5+
<col3 />
6+
</row>
7+
<row>
8+
<col1>GHI</col1>
9+
<col2 />
10+
<col3>123</col3>
11+
</row>
12+
</test_rows>

mysql-test/t/loadxml.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,17 @@ LOAD XML INFILE '../../std_data/loadxml.dat' INTO TABLE t1
116116
ROWS IDENTIFIED BY '<row>' (a,@b) SET b=concat('!',@b);
117117
SELECT * FROM t1 ORDER BY a;
118118
DROP TABLE t1;
119+
120+
121+
--echo #
122+
--echo # Bug#16171518 LOAD XML DOES NOT HANDLE EMPTY ELEMENTS
123+
--echo #
124+
CREATE TABLE t1 (col1 VARCHAR(3), col2 VARCHAR(3), col3 VARCHAR(3), col4 VARCHAR(4));
125+
LOAD XML INFILE '../../std_data/bug16171518_1.dat' INTO TABLE t1;
126+
SELECT * FROM t1 ORDER BY col1, col2, col3, col4;
127+
DROP TABLE t1;
128+
129+
CREATE TABLE t1 (col1 VARCHAR(3), col2 VARCHAR(3), col3 INTEGER);
130+
LOAD XML INFILE '../../std_data/bug16171518_2.dat' INTO TABLE t1;
131+
SELECT * FROM t1 ORDER BY col1, col2, col3;
132+
DROP TABLE t1;

sql/sql_load.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -1987,8 +1987,15 @@ int READ_INFO::read_xml()
19871987
break;
19881988

19891989
case '/': /* close tag */
1990-
level--;
19911990
chr= my_tospace(GET);
1991+
/* Decrease the 'level' only when (i) It's not an */
1992+
/* (without space) empty tag i.e. <tag/> or, (ii) */
1993+
/* It is of format <row col="val" .../> */
1994+
if(chr != '>' || in_tag)
1995+
{
1996+
level--;
1997+
in_tag= false;
1998+
}
19921999
if(chr != '>') /* if this is an empty tag <tag /> */
19932000
tag.length(0); /* we should keep tag value */
19942001
while(chr != '>' && chr != my_b_EOF)

0 commit comments

Comments
 (0)