35
53
bool need_end_io_cache;
56
int level; /* for load xml */
40
59
bool error,line_cuted,found_null,enclosed;
41
unsigned char *row_start, /* Found row starts here */
60
uchar *row_start, /* Found row starts here */
42
61
*row_end; /* Found row ends here */
43
const CHARSET_INFO *read_charset;
62
CHARSET_INFO *read_charset;
45
READ_INFO(File file,uint32_t tot_length, const CHARSET_INFO * const cs,
64
READ_INFO(File file,uint tot_length,CHARSET_INFO *cs,
46
65
String &field_term,String &line_start,String &line_term,
47
66
String &enclosed,int escape,bool get_it_from_net, bool is_fifo);
71
95
void set_io_cache_arg(void* arg) { cache.arg = arg; }
74
static int read_fixed_length(THD *thd, COPY_INFO &info, TableList *table_list,
98
static int read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
75
99
List<Item> &fields_vars, List<Item> &set_fields,
76
100
List<Item> &set_values, READ_INFO &read_info,
78
102
bool ignore_check_option_errors);
79
static int read_sep_field(THD *thd, COPY_INFO &info, TableList *table_list,
103
static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
80
104
List<Item> &fields_vars, List<Item> &set_fields,
81
105
List<Item> &set_values, READ_INFO &read_info,
82
String &enclosed, uint32_t skip_lines,
106
String &enclosed, ulong skip_lines,
83
107
bool ignore_check_option_errors);
109
static int read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
110
List<Item> &fields_vars, List<Item> &set_fields,
111
List<Item> &set_values, READ_INFO &read_info,
112
String &enclosed, ulong skip_lines,
113
bool ignore_check_option_errors);
85
115
static bool write_execute_load_query_log_event(THD *thd,
86
116
bool duplicates, bool ignore,
87
117
bool transactional_table,
349
380
table->file->ha_start_bulk_insert((ha_rows) 0);
350
381
table->copy_blobs=1;
352
thd->abort_on_warning= true;
383
thd->abort_on_warning= (!ignore &&
384
(thd->variables.sql_mode &
385
(MODE_STRICT_TRANS_TABLES |
386
MODE_STRICT_ALL_TABLES)));
354
if (!field_term->length() && !enclosed->length())
388
if (ex->filetype == FILETYPE_XML) /* load xml */
389
error= read_xml_field(thd, info, table_list, fields_vars,
390
set_fields, set_values, read_info,
391
*(ex->line_term), skip_lines, ignore);
392
else if (!field_term->length() && !enclosed->length())
355
393
error= read_fixed_length(thd, info, table_list, fields_vars,
356
394
set_fields, set_values, read_info,
357
395
skip_lines, ignore);
602
646
if (read_info.line_cuted)
604
648
thd->cuted_fields++; /* To long row */
605
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
649
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
606
650
ER_WARN_TOO_MANY_RECORDS,
607
651
ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count);
609
653
thd->row_count++;
611
return(test(read_info.error));
655
DBUG_RETURN(test(read_info.error));
617
read_sep_field(THD *thd, COPY_INFO &info, TableList *table_list,
661
read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
618
662
List<Item> &fields_vars, List<Item> &set_fields,
619
663
List<Item> &set_values, READ_INFO &read_info,
620
String &enclosed, uint32_t skip_lines,
664
String &enclosed, ulong skip_lines,
621
665
bool ignore_check_option_errors)
623
667
List_iterator_fast<Item> it(fields_vars);
625
Table *table= table_list->table;
626
uint32_t enclosed_length;
669
TABLE *table= table_list->table;
670
uint enclosed_length;
673
DBUG_ENTER("read_sep_field");
630
675
enclosed_length=enclosed.length();
783
828
if (read_info.line_cuted)
785
830
thd->cuted_fields++; /* To long row */
786
push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
831
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
787
832
ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS),
792
837
thd->row_count++;
794
return(test(read_info.error));
839
DBUG_RETURN(test(read_info.error));
843
/****************************************************************************
844
** Read rows in xml format
845
****************************************************************************/
847
read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
848
List<Item> &fields_vars, List<Item> &set_fields,
849
List<Item> &set_values, READ_INFO &read_info,
850
String &row_tag, ulong skip_lines,
851
bool ignore_check_option_errors)
853
List_iterator_fast<Item> it(fields_vars);
855
TABLE *table= table_list->table;
856
bool no_trans_update_stmt;
857
CHARSET_INFO *cs= read_info.read_charset;
858
DBUG_ENTER("read_xml_field");
860
no_trans_update_stmt= !table->file->has_transactions();
862
for ( ; ; it.rewind())
866
thd->send_kill_message();
870
// read row tag and save values into tag list
871
if (read_info.read_xml())
874
List_iterator_fast<XML_TAG> xmlit(read_info.taglist);
879
DBUG_PRINT("read_xml_field", ("skip_lines=%d", (int) skip_lines));
880
while ((tag= xmlit++))
882
DBUG_PRINT("read_xml_field", ("got tag:%i '%s' '%s'",
883
tag->level, tag->field.c_ptr(),
884
tag->value.c_ptr()));
888
restore_record(table, s->default_values);
892
/* If this line is to be skipped we don't want to fill field or var */
896
/* find field in tag list */
900
while(tag && strcmp(tag->field.c_ptr(), item->name) != 0)
903
if (!tag) // found null
905
if (item->type() == Item::FIELD_ITEM)
907
Field *field= ((Item_field *) item)->field;
910
if (field == table->next_number_field)
911
table->auto_increment_field_not_null= TRUE;
912
if (!field->maybe_null())
914
if (field->type() == FIELD_TYPE_TIMESTAMP)
915
((Field_timestamp *) field)->set_time();
916
else if (field != table->next_number_field)
917
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
918
ER_WARN_NULL_TO_NOTNULL, 1);
922
((Item_user_var_as_out_param *) item)->set_null_value(cs);
926
if (item->type() == Item::FIELD_ITEM)
929
Field *field= ((Item_field *)item)->field;
930
field->set_notnull();
931
if (field == table->next_number_field)
932
table->auto_increment_field_not_null= TRUE;
933
field->store((char *) tag->value.ptr(), tag->value.length(), cs);
936
((Item_user_var_as_out_param *) item)->set_value(
937
(char *) tag->value.ptr(),
938
tag->value.length(), cs);
952
/* Have not read any field, thus input file is simply ended */
953
if (item == fields_vars.head())
956
for ( ; item; item= it++)
958
if (item->type() == Item::FIELD_ITEM)
961
QQ: We probably should not throw warning for each field.
962
But how about intention to always have the same number
963
of warnings in THD::cuted_fields (and get rid of cuted_fields
967
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
968
ER_WARN_TOO_FEW_RECORDS,
969
ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
972
((Item_user_var_as_out_param *)item)->set_null_value(cs);
976
if (thd->killed || fill_record(thd, set_fields, set_values,
977
ignore_check_option_errors))
980
if (write_record(thd, table, &info))
984
We don't need to reset auto-increment field since we are restoring
985
its default value at the beginning of each loop iteration.
987
thd->transaction.stmt.modified_non_trans_table= no_trans_update_stmt;
990
DBUG_RETURN(test(read_info.error));
798
994
/* Unescape all escape characters, mark \N as null */
852
1049
line_term_ptr=(char*) "";
854
1051
enclosed_char= (enclosed_length=enclosed_par.length()) ?
855
(unsigned char) enclosed_par[0] : INT_MAX;
856
field_term_char= field_term_length ? (unsigned char) field_term_ptr[0] : INT_MAX;
857
line_term_char= line_term_length ? (unsigned char) line_term_ptr[0] : INT_MAX;
1052
(uchar) enclosed_par[0] : INT_MAX;
1053
field_term_char= field_term_length ? (uchar) field_term_ptr[0] : INT_MAX;
1054
line_term_char= line_term_length ? (uchar) line_term_ptr[0] : INT_MAX;
858
1055
error=eof=found_end_of_line=found_null=line_cuted=0;
859
1056
buff_length=tot_length;
862
1059
/* Set of a stack for unget if long terminators */
863
uint32_t length=cmax(field_term_length,line_term_length)+1;
1060
uint length=max(field_term_length,line_term_length)+1;
864
1061
set_if_bigger(length,line_start.length());
865
1062
stack=stack_pos=(int*) sql_alloc(sizeof(int)*length);
867
if (!(buffer=(unsigned char*) my_malloc(buff_length+1,MYF(0))))
1064
if (!(buffer=(uchar*) my_malloc(buff_length+1,MYF(0))))
868
1065
error=1; /* purecov: inspected */
1444
Clear taglist from tags with a specified level
1446
int READ_INFO::clear_level(int level)
1448
DBUG_ENTER("READ_INFO::read_xml clear_level");
1449
List_iterator<XML_TAG> xmlit(taglist);
1453
while ((tag= xmlit++))
1455
if(tag->level >= level)
1466
Convert an XML entity to Unicode value.
1470
my_xml_entity_to_char(const char *name, uint length)
1474
if (!memcmp(name, "gt", length))
1476
if (!memcmp(name, "lt", length))
1479
else if (length == 3)
1481
if (!memcmp(name, "amp", length))
1484
else if (length == 4)
1486
if (!memcmp(name, "quot", length))
1488
if (!memcmp(name, "apos", length))
1496
@brief Convert newline, linefeed, tab to space
1498
@param chr character
1500
@details According to the "XML 1.0" standard,
1501
only space (#x20) characters, carriage returns,
1502
line feeds or tabs are considered as spaces.
1503
Convert all of them to space (#x20) for parsing simplicity.
1508
return (chr == '\t' || chr == '\r' || chr == '\n') ? ' ' : chr;
1513
Read an xml value: handle multibyte and xml escape
1515
int READ_INFO::read_value(int delim, String *val)
1520
for (chr= my_tospace(GET); chr != delim && chr != my_b_EOF; )
1523
if (my_mbcharlen(read_charset, chr) > 1)
1525
DBUG_PRINT("read_xml",("multi byte"));
1526
int i, ml= my_mbcharlen(read_charset, chr);
1527
for (i= 1; i < ml; i++)
1531
Don't use my_tospace() in the middle of a multi-byte character
1532
TODO: check that the multi-byte sequence is valid.
1535
if (chr == my_b_EOF)
1543
for (chr= my_tospace(GET) ; chr != ';' ; chr= my_tospace(GET))
1545
if (chr == my_b_EOF)
1549
if ((chr= my_xml_entity_to_char(tmp.ptr(), tmp.length())) >= 0)
1560
chr= my_tospace(GET);
1567
Read a record in xml format
1568
tags and attributes are stored in taglist
1569
when tag set in ROWS IDENTIFIED BY is closed, we are ready and return
1571
int READ_INFO::read_xml()
1573
DBUG_ENTER("READ_INFO::read_xml");
1574
int chr, chr2, chr3;
1576
String tag, attribute, value;
1580
attribute.length(0);
1583
for (chr= my_tospace(GET); chr != my_b_EOF ; )
1586
case '<': /* read tag */
1587
/* TODO: check if this is a comment <!-- comment --> */
1588
chr= my_tospace(GET);
1594
if(chr2 == '-' && chr3 == '-')
1598
chr= my_tospace(GET);
1600
while(chr != '>' || chr2 != '-' || chr3 != '-')
1607
else if (chr2 == '-')
1612
chr= my_tospace(GET);
1613
if (chr == my_b_EOF)
1621
while(chr != '>' && chr != ' ' && chr != '/' && chr != my_b_EOF)
1623
if(chr != delim) /* fix for the '<field name =' format */
1625
chr= my_tospace(GET);
1628
// row tag should be in ROWS IDENTIFIED BY '<row>' - stored in line_term
1629
if((tag.length() == line_term_length -2) &&
1630
(strncmp(tag.c_ptr_safe(), line_term_ptr + 1, tag.length()) == 0))
1632
DBUG_PRINT("read_xml", ("start-of-row: %i %s %s",
1633
level,tag.c_ptr_safe(), line_term_ptr));
1636
if(chr == ' ' || chr == '>')
1639
clear_level(level + 1);
1648
case ' ': /* read attribute */
1649
while(chr == ' ') /* skip blanks */
1650
chr= my_tospace(GET);
1655
while(chr != '=' && chr != '/' && chr != '>' && chr != my_b_EOF)
1657
attribute.append(chr);
1658
chr= my_tospace(GET);
1662
case '>': /* end tag - read tag value */
1664
chr= read_value('<', &value);
1668
/* save value to list */
1669
if(tag.length() > 0 && value.length() > 0)
1671
DBUG_PRINT("read_xml", ("lev:%i tag:%s val:%s",
1672
level,tag.c_ptr_safe(), value.c_ptr_safe()));
1673
taglist.push_front( new XML_TAG(level, tag, value));
1677
attribute.length(0);
1680
case '/': /* close tag */
1682
chr= my_tospace(GET);
1683
if(chr != '>') /* if this is an empty tag <tag /> */
1684
tag.length(0); /* we should keep tag value */
1685
while(chr != '>' && chr != my_b_EOF)
1688
chr= my_tospace(GET);
1691
if((tag.length() == line_term_length -2) &&
1692
(strncmp(tag.c_ptr_safe(), line_term_ptr + 1, tag.length()) == 0))
1694
DBUG_PRINT("read_xml", ("found end-of-row %i %s",
1695
level, tag.c_ptr_safe()));
1696
DBUG_RETURN(0); //normal return
1698
chr= my_tospace(GET);
1701
case '=': /* attribute name end - read the value */
1702
//check for tag field and attribute name
1703
if(!memcmp(tag.c_ptr_safe(), STRING_WITH_LEN("field")) &&
1704
!memcmp(attribute.c_ptr_safe(), STRING_WITH_LEN("name")))
1707
this is format <field name="xx">xx</field>
1708
where actual fieldname is in attribute
1710
delim= my_tospace(GET);
1712
attribute.length(0);
1713
chr= '<'; /* we pretend that it is a tag */
1720
if (chr == my_b_EOF)
1722
if(chr == '"' || chr == '\'')
1728
delim= ' '; /* no delimiter, use space */
1732
chr= read_value(delim, &value);
1733
if(attribute.length() > 0 && value.length() > 0)
1735
DBUG_PRINT("read_xml", ("lev:%i att:%s val:%s\n",
1737
attribute.c_ptr_safe(),
1738
value.c_ptr_safe()));
1739
taglist.push_front(new XML_TAG(level + 1, attribute, value));
1741
attribute.length(0);
1744
chr= my_tospace(GET);
1748
chr= my_tospace(GET);
1753
DBUG_PRINT("read_xml",("Found eof"));