105
82
String &enclosed, ulong skip_lines,
106
83
bool ignore_check_option_errors);
108
static int read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
109
List<Item> &fields_vars, List<Item> &set_fields,
110
List<Item> &set_values, READ_INFO &read_info,
111
String &enclosed, ulong skip_lines,
112
bool ignore_check_option_errors);
114
85
static bool write_execute_load_query_log_event(THD *thd,
115
86
bool duplicates, bool ignore,
116
87
bool transactional_table,
383
354
(MODE_STRICT_TRANS_TABLES |
384
355
MODE_STRICT_ALL_TABLES)));
386
if (ex->filetype == FILETYPE_XML) /* load xml */
387
error= read_xml_field(thd, info, table_list, fields_vars,
388
set_fields, set_values, read_info,
389
*(ex->line_term), skip_lines, ignore);
390
else if (!field_term->length() && !enclosed->length())
357
if (!field_term->length() && !enclosed->length())
391
358
error= read_fixed_length(thd, info, table_list, fields_vars,
392
359
set_fields, set_values, read_info,
393
360
skip_lines, ignore);
834
/****************************************************************************
835
** Read rows in xml format
836
****************************************************************************/
838
read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
839
List<Item> &fields_vars, List<Item> &set_fields,
840
List<Item> &set_values, READ_INFO &read_info,
841
String &row_tag __attribute__((unused)),
843
bool ignore_check_option_errors)
845
List_iterator_fast<Item> it(fields_vars);
847
TABLE *table= table_list->table;
848
bool no_trans_update_stmt;
849
const CHARSET_INFO * const cs= read_info.read_charset;
851
no_trans_update_stmt= !table->file->has_transactions();
853
for ( ; ; it.rewind())
857
thd->send_kill_message();
861
// read row tag and save values into tag list
862
if (read_info.read_xml())
865
List_iterator_fast<XML_TAG> xmlit(read_info.taglist);
870
restore_record(table, s->default_values);
874
/* If this line is to be skipped we don't want to fill field or var */
878
/* find field in tag list */
882
while(tag && strcmp(tag->field.c_ptr(), item->name) != 0)
885
if (!tag) // found null
887
if (item->type() == Item::FIELD_ITEM)
889
Field *field= ((Item_field *) item)->field;
892
if (field == table->next_number_field)
893
table->auto_increment_field_not_null= true;
894
if (!field->maybe_null())
896
if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
897
((Field_timestamp *) field)->set_time();
898
else if (field != table->next_number_field)
899
field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
900
ER_WARN_NULL_TO_NOTNULL, 1);
904
((Item_user_var_as_out_param *) item)->set_null_value(cs);
908
if (item->type() == Item::FIELD_ITEM)
911
Field *field= ((Item_field *)item)->field;
912
field->set_notnull();
913
if (field == table->next_number_field)
914
table->auto_increment_field_not_null= true;
915
field->store((char *) tag->value.ptr(), tag->value.length(), cs);
918
((Item_user_var_as_out_param *) item)->set_value(
919
(char *) tag->value.ptr(),
920
tag->value.length(), cs);
934
/* Have not read any field, thus input file is simply ended */
935
if (item == fields_vars.head())
938
for ( ; item; item= it++)
940
if (item->type() == Item::FIELD_ITEM)
943
QQ: We probably should not throw warning for each field.
944
But how about intention to always have the same number
945
of warnings in THD::cuted_fields (and get rid of cuted_fields
949
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
950
ER_WARN_TOO_FEW_RECORDS,
951
ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
954
((Item_user_var_as_out_param *)item)->set_null_value(cs);
958
if (thd->killed || fill_record(thd, set_fields, set_values,
959
ignore_check_option_errors))
962
if (write_record(thd, table, &info))
966
We don't need to reset auto-increment field since we are restoring
967
its default value at the beginning of each loop iteration.
969
thd->transaction.stmt.modified_non_trans_table= no_trans_update_stmt;
972
return(test(read_info.error));
976
801
/* Unescape all escape characters, mark \N as null */
1426
Clear taglist from tags with a specified level
1428
int READ_INFO::clear_level(int level)
1430
List_iterator<XML_TAG> xmlit(taglist);
1434
while ((tag= xmlit++))
1436
if(tag->level >= level)
1447
Convert an XML entity to Unicode value.
1451
my_xml_entity_to_char(const char *name, uint length)
1455
if (!memcmp(name, "gt", length))
1457
if (!memcmp(name, "lt", length))
1460
else if (length == 3)
1462
if (!memcmp(name, "amp", length))
1465
else if (length == 4)
1467
if (!memcmp(name, "quot", length))
1469
if (!memcmp(name, "apos", length))
1477
@brief Convert newline, linefeed, tab to space
1479
@param chr character
1481
@details According to the "XML 1.0" standard,
1482
only space (#x20) characters, carriage returns,
1483
line feeds or tabs are considered as spaces.
1484
Convert all of them to space (#x20) for parsing simplicity.
1489
return (chr == '\t' || chr == '\r' || chr == '\n') ? ' ' : chr;
1494
Read an xml value: handle multibyte and xml escape
1496
int READ_INFO::read_value(int delim, String *val)
1501
for (chr= my_tospace(GET); chr != delim && chr != my_b_EOF; )
1504
if (my_mbcharlen(read_charset, chr) > 1)
1506
int i, ml= my_mbcharlen(read_charset, chr);
1507
for (i= 1; i < ml; i++)
1511
Don't use my_tospace() in the middle of a multi-byte character
1512
TODO: check that the multi-byte sequence is valid.
1515
if (chr == my_b_EOF)
1523
for (chr= my_tospace(GET) ; chr != ';' ; chr= my_tospace(GET))
1525
if (chr == my_b_EOF)
1529
if ((chr= my_xml_entity_to_char(tmp.ptr(), tmp.length())) >= 0)
1540
chr= my_tospace(GET);
1547
Read a record in xml format
1548
tags and attributes are stored in taglist
1549
when tag set in ROWS IDENTIFIED BY is closed, we are ready and return
1551
int READ_INFO::read_xml()
1553
int chr, chr2, chr3;
1555
String tag, attribute, value;
1559
attribute.length(0);
1562
for (chr= my_tospace(GET); chr != my_b_EOF ; )
1565
case '<': /* read tag */
1566
/* TODO: check if this is a comment <!-- comment --> */
1567
chr= my_tospace(GET);
1573
if(chr2 == '-' && chr3 == '-')
1577
chr= my_tospace(GET);
1579
while(chr != '>' || chr2 != '-' || chr3 != '-')
1586
else if (chr2 == '-')
1591
chr= my_tospace(GET);
1592
if (chr == my_b_EOF)
1600
while(chr != '>' && chr != ' ' && chr != '/' && chr != my_b_EOF)
1602
if(chr != delim) /* fix for the '<field name =' format */
1604
chr= my_tospace(GET);
1607
if(chr == ' ' || chr == '>')
1610
clear_level(level + 1);
1619
case ' ': /* read attribute */
1620
while(chr == ' ') /* skip blanks */
1621
chr= my_tospace(GET);
1626
while(chr != '=' && chr != '/' && chr != '>' && chr != my_b_EOF)
1628
attribute.append(chr);
1629
chr= my_tospace(GET);
1633
case '>': /* end tag - read tag value */
1635
chr= read_value('<', &value);
1639
/* save value to list */
1640
if(tag.length() > 0 && value.length() > 0)
1641
taglist.push_front( new XML_TAG(level, tag, value));
1645
attribute.length(0);
1648
case '/': /* close tag */
1650
chr= my_tospace(GET);
1651
if(chr != '>') /* if this is an empty tag <tag /> */
1652
tag.length(0); /* we should keep tag value */
1653
while(chr != '>' && chr != my_b_EOF)
1656
chr= my_tospace(GET);
1659
if((tag.length() == line_term_length -2) &&
1660
(strncmp(tag.c_ptr_safe(), line_term_ptr + 1, tag.length()) == 0))
1661
return(0); //normal return
1663
chr= my_tospace(GET);
1666
case '=': /* attribute name end - read the value */
1667
//check for tag field and attribute name
1668
if(!memcmp(tag.c_ptr_safe(), STRING_WITH_LEN("field")) &&
1669
!memcmp(attribute.c_ptr_safe(), STRING_WITH_LEN("name")))
1672
this is format <field name="xx">xx</field>
1673
where actual fieldname is in attribute
1675
delim= my_tospace(GET);
1677
attribute.length(0);
1678
chr= '<'; /* we pretend that it is a tag */
1685
if (chr == my_b_EOF)
1687
if(chr == '"' || chr == '\'')
1693
delim= ' '; /* no delimiter, use space */
1697
chr= read_value(delim, &value);
1698
if(attribute.length() > 0 && value.length() > 0)
1699
taglist.push_front(new XML_TAG(level + 1, attribute, value));
1701
attribute.length(0);
1704
chr= my_tospace(GET);
1708
chr= my_tospace(GET);