YoushouldhavereceivedacopyoftheGNUGeneralPublicLicense alongwiththisprogram;ifnot,writetotheFreeSoftware
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
/* Copy data from a textfile to table */ /* 2006-12 Erik Wetterberg : LOAD XML added */
class READ_INFO: public Load_data_param
{
File file;
String data; /* Read buffer */
Term_string m_field_term; /* FIELDS TERMINATED BY 'string' */
Term_string m_line_term; /* LINES TERMINATED BY 'string' */
Term_string m_line_start; /* LINES STARTING BY 'string' */ int enclosed_char,escape_char; int *stack,*stack_pos; bool found_end_of_line,start_of_line,eof; int level; /* for load xml */
bool getbyte(char *to)
{ int chr= GET; if (chr == my_b_EOF) return (eof= true);
*to= chr; returnfalse;
}
Inthisexampleitworksasfollows: -0x8Fisreadfromthefileandputinto"data"beforethecall forread_mbtail() -0xA1isreadfromthefileandputinto"data"byread_mbtail() -0x0Aiskeptinthereadqueue,sothenextreaditerationafter thecurrentread_mbtail()callwillnormallyfinditandrecognizeas alinedelimiter -thecurrentcallforread_mbtail()returns"false", becausenoEOFhappened
*/ bool read_mbtail(String *str)
{ int chlen; if ((chlen= charset()->charlen(str->end() - 1, str->end())) == 1) returnfalse; // Single byte character found for (uint32 length0= str->length() - 1 ; MY_CS_IS_TOOSMALL(chlen); )
{ int chr= GET; if (chr == my_b_EOF)
{
DBUG_PRINT("info", ("read_mbtail: chlen=%d; unexpected EOF", chlen)); returntrue; // EOF
}
str->append(chr);
chlen= charset()->charlen(str->ptr() + length0, str->end()); if (chlen == MY_CS_ILSEQ)
{ /** Ithasbeenanincomplete(butavalid)sequencesofar, butthelastbyteturneditintoabadbytesequence. Ungettheverylastbyte.
*/
str->length(str->length() - 1);
PUSH(chr);
DBUG_PRINT("info", ("read_mbtail: ILSEQ")); returnfalse; // Bad byte sequence
}
}
DBUG_PRINT("info", ("read_mbtail: chlen=%d", chlen)); returnfalse; // Good multi-byte character
}
public: bool error,line_cuted,found_null,enclosed;
uchar *row_start, /* Found row starts here */
*row_end; /* Found row ends here */
LOAD_FILE_IO_CACHE cache;
if (open_and_lock_tables(thd, table_list, TRUE, 0))
DBUG_RETURN(TRUE); if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
DBUG_RETURN(TRUE); if (thd->lex->handle_list_of_derived(table_list, DT_PREPARE))
DBUG_RETURN(TRUE);
if (setup_tables_and_check_access(thd,
&thd->lex->first_select_lex()->context,
&thd->lex->first_select_lex()->
top_join_list,
table_list,
thd->lex->first_select_lex()->leaf_tables, FALSE,
INSERT_ACL | UPDATE_ACL,
INSERT_ACL | UPDATE_ACL, false))
DBUG_RETURN(-1); if (!table_list->table || // do not support join view
!table_list->single_table_updatable() || // and derived tables
check_key_in_view(thd, table_list))
{
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias.str, "LOAD");
DBUG_RETURN(TRUE);
} if (table_list->is_multitable())
{
my_error(ER_WRONG_USAGE, MYF(0), "Multi-table VIEW", "LOAD");
DBUG_RETURN(TRUE);
} if (table_list->prepare_where(thd, 0, TRUE) ||
table_list->prepare_check_option(thd))
{
DBUG_RETURN(TRUE);
}
if (thd->rgi_slave)
{ #ifdefined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) if (strncmp(thd->rgi_slave->rli->slave_patternload_file, name,
thd->rgi_slave->rli->slave_patternload_file_size))
{ /* LOADDATAINFILEintheslaveSQLThreadcanonlyreadfrom --slave-load-tmpdir".Thisshouldneverhappen.Please,reportabug.
*/
sql_print_error("LOAD DATA INFILE in the slave SQL Thread can only read from --slave-load-tmpdir. " \ "Please, report a bug.");
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--slave-load-tmpdir");
DBUG_RETURN(TRUE);
} #else /* Thisisimpossibleandshouldneverhappen.
*/
DBUG_ASSERT(FALSE); #endif
} elseif (!is_secure_file_path(name))
{ /* Read only allowed from within dir specified by secure_file_priv */
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
DBUG_RETURN(TRUE);
}
#if !defined(_WIN32)
MY_STAT stat_info; if (!my_stat(name, &stat_info, MYF(MY_WME)))
DBUG_RETURN(TRUE);
// if we are not in slave thread, the file must be: if (!thd->slave_thread &&
!((stat_info.st_mode & S_IFLNK) != S_IFLNK && // symlink
((stat_info.st_mode & S_IFREG) == S_IFREG || // regular file
(stat_info.st_mode & S_IFIFO) == S_IFIFO))) // named pipe
{
my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name);
DBUG_RETURN(TRUE);
} if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
is_fifo= 1; #endif if ((file= mysql_file_open(key_file_load,
name, O_RDONLY, MYF(MY_WME))) < 0)
thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */
thd->cuted_fields=0L; /* Skip lines if there is a line terminator */ if (ex->line_term->length() && ex->filetype != FILETYPE_XML)
{ /* ex->skip_lines needs to be preserved for logging */ while (skip_lines > 0)
{
skip_lines--; if (read_info.next_line()) break;
}
}
thd_proc_info(thd, "Reading file"); if (likely(!(error= MY_TEST(read_info.error))))
{
table->reset_default_fields();
table->next_number_field=table->found_next_number_field; if (ignore ||
handle_duplicates == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); if (handle_duplicates == DUP_REPLACE &&
(!table->triggers ||
!table->triggers->has_delete_triggers()))
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE); if (thd->locked_tables_mode <= LTM_LOCK_TABLES &&
!table->s->long_unique_table)
table->file->ha_start_bulk_insert((ha_rows) 0);
table->copy_blobs=1;
/* Wemustinvalidatethetableinquerycachebeforebinlogwritingand ha_autocommit_...
*/
query_cache_invalidate3(thd, table_list, 0); if (error)
{ if (read_file_from_client)
read_info.skip_data_till_eof();
#ifndef EMBEDDED_LIBRARY if (mysql_bin_log.is_open())
{
{ /* Makesurelastblock(theonewhichcausedtheerror)gets logged.
*/
log_loaded_block(&read_info.cache, 0, 0); /* If the file was not empty, wrote_create_file is true */ if (read_info.cache.wrote_create_file)
{ int errcode= query_error_code(thd, killed_status == NOT_KILLED);
/* since there is already an error, the possible error of
writing binary log will be ignored */ if (thd->transaction->stmt.modified_non_trans_table)
(void) write_execute_load_query_log_event(thd, ex,
table_list->db.str,
table_list->table_name.str,
is_concurrent,
handle_duplicates, ignore,
transactional_table,
errcode); else
{
Delete_file_log_event d(thd, db, transactional_table);
(void) mysql_bin_log.write(&d);
}
}
}
} #endif/*!EMBEDDED_LIBRARY*/
error= -1; // Error on read goto err;
}
snprintf(name, sizeof(name), ER_THD(thd, ER_LOAD_INFO),
(ulong) info.records, (ulong) info.deleted,
(ulong) (info.records - info.copied),
(long) thd->get_stmt_da()->current_statement_warn_count());
/* ok to client sent only after binlog write and engine commit */
my_ok(thd, info.copied + info.deleted, 0L, name);
err:
DBUG_ASSERT(transactional_table || !(info.copied || info.deleted) ||
thd->transaction->stmt.modified_non_trans_table);
table->file->ha_release_auto_increment();
table->auto_increment_field_not_null= FALSE; if (thd->tmp_table_binlog_handled)
table->mark_as_not_binlogged(); // tmp table changes are not in binlog
thd->abort_on_warning= 0;
DBUG_RETURN(error);
}
if (ex->cs)
{
query_str.append(STRING_WITH_LEN(" CHARACTER SET "));
query_str.append(ex->cs->cs_name);
}
/* We have to create all optional fields as the default is not empty */
query_str.append(STRING_WITH_LEN(" FIELDS TERMINATED BY '"));
query_str.append_for_single_quote(ex->field_term);
query_str.append(STRING_WITH_LEN("'")); if (ex->opt_enclosed)
query_str.append(STRING_WITH_LEN(" OPTIONALLY"));
query_str.append(STRING_WITH_LEN(" ENCLOSED BY '"));
query_str.append_for_single_quote(ex->enclosed);
query_str.append(STRING_WITH_LEN("'"));
query_str.append(STRING_WITH_LEN(" ESCAPED BY '"));
query_str.append_for_single_quote(ex->escaped);
query_str.append(STRING_WITH_LEN("'"));
query_str.append(STRING_WITH_LEN(" LINES TERMINATED BY '"));
query_str.append_for_single_quote(ex->line_term);
query_str.append(STRING_WITH_LEN("'")); if (ex->line_start->length())
{
query_str.append(STRING_WITH_LEN(" STARTING BY '"));
query_str.append_for_single_quote(ex->line_start);
query_str.append(STRING_WITH_LEN("'"));
}
switch (table_list->view_check_option(thd, ignore_check_option_errors)) { case VIEW_CHECK_SKIP:
read_info.next_line(); goto continue_loop; case VIEW_CHECK_ERROR:
DBUG_RETURN(-1);
}
if (!trg_skip_row)
err= write.write_record();
table->auto_increment_field_not_null= FALSE; if (err)
DBUG_RETURN(1);
/* Wedon'tneedtoresetauto-incrementfieldsincewearerestoring itsdefaultvalueatthebeginningofeachloopiteration.
*/ if (read_info.next_line()) // Skip to next line break; if (read_info.line_cuted)
{
thd->cuted_fields++; /* To long row */
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARN_TOO_MANY_RECORDS,
ER_THD(thd, ER_WARN_TOO_MANY_RECORDS),
thd->get_stmt_da()->current_row_for_warning());
}
thd->get_stmt_da()->inc_current_row_for_warning();
continue_loop:;
}
DBUG_RETURN(MY_TEST(read_info.error));
}
if ((!read_info.enclosed &&
(enclosed_length && length == 4 &&
!memcmp(pos, STRING_WITH_LEN("NULL")))) ||
(length == 1 && read_info.found_null))
{ if (dst->load_data_set_null(thd, &read_info))
DBUG_RETURN(1);
} else
{
read_info.row_end[0]= 0; // Safe to change end marker if (dst->load_data_set_value(thd, (constchar *) pos, length, &read_info))
DBUG_RETURN(1);
}
}
if (unlikely(thd->is_error()))
read_info.error= 1; if (unlikely(read_info.error)) break;
if (skip_lines)
{
skip_lines--; continue;
} if (item)
{ /* Have not read any field, thus input file is simply ended */ if (item == fields_vars.head()) break; for (; item ; item= it++)
{
Load_data_outvar *dst= item->get_load_data_outvar_or_error();
DBUG_ASSERT(dst); if (unlikely(dst->load_data_set_no_data(thd, &read_info)))
DBUG_RETURN(1);
}
}
if (trg_skip_row)
{
read_info.next_line(); continue;
}
switch (table_list->view_check_option(thd,
ignore_check_option_errors)) { case VIEW_CHECK_SKIP:
read_info.next_line(); goto continue_loop; case VIEW_CHECK_ERROR:
DBUG_RETURN(-1);
}
err= write.write_record();
table->auto_increment_field_not_null= FALSE; if (err)
DBUG_RETURN(1); /* Wedon'tneedtoresetauto-incrementfieldsincewearerestoring itsdefaultvalueatthebeginningofeachloopiteration.
*/ if (read_info.next_line()) // Skip to next line break; if (read_info.line_cuted)
{
thd->cuted_fields++; /* To long row */
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARN_TOO_MANY_RECORDS,
ER_THD(thd, ER_WARN_TOO_MANY_RECORDS),
thd->get_stmt_da()->current_row_for_warning()); if (thd->killed)
DBUG_RETURN(1);
}
thd->get_stmt_da()->inc_current_row_for_warning();
continue_loop:;
}
DBUG_RETURN(MY_TEST(read_info.error));
}
restore_default_record_for_insert(table); while ((item= it++))
{ /* If this line is to be skipped we don't want to fill field or var */ if (skip_lines) continue;
/* find field in tag list */
xmlit.rewind();
tag= xmlit++;
level= 0; /* for load xml */
start_of_line= line_start.length() != 0; /* If field_terminator == line_terminator, don't use line_terminator */ if (m_field_term.eq(m_line_term))
m_line_term.reset();
enclosed_char= enclosed_par.length() ? (uchar) enclosed_par[0] : INT_MAX;
/* Set of a stack for unget if long terminators */
uint length= MY_MAX(charset()->mbmaxlen, MY_MAX(m_field_term.length(),
m_line_term.length())) + 1;
set_if_bigger(length,line_start.length());
stack= stack_pos= thd->alloc<int>(length);
case'>': /* end tag - read tag value */
in_tag= false;
chr= read_value('<', &value); if(chr == my_b_EOF) goto found_eof;
/* save value to list */ if (tag.length() > 0 && value.length() > 0)
{
DBUG_PRINT("read_xml", ("lev:%i tag:%s val:%s",
level,tag.c_ptr_safe(), value.c_ptr_safe()));
XML_TAG *tmp= new XML_TAG(level, tag, value); if (!tmp || taglist.push_front(tmp, thd->mem_root))
DBUG_RETURN(1); // End of memory
}
tag.length(0);
value.length(0);
attribute.length(0); break;
case'/': /* close tag */
chr= my_tospace(GET); /* 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" .../> */ if(chr != '>' || in_tag)
{
level--;
in_tag= false;
} if(chr != '>') /* if this is an empty tag <tag /> */
tag.length(0); /* we should keep tag value */ while(chr != '>' && chr != my_b_EOF)
{
tag.append(chr);
chr= my_tospace(GET);
}
case'=': /* attribute name end - read the value */ //check for tag field and attribute name if(!strcmp(tag.c_ptr_safe(), "field") &&
!strcmp(attribute.c_ptr_safe(), "name"))
{ /* thisisformat<fieldname="xx">xx</field> whereactualfieldnameisinattribute
*/
delim= my_tospace(GET);
tag.length(0);
attribute.length(0);
chr= '<'; /* we pretend that it is a tag */
level--; break;
}
//check for " or '
chr= GET; if (chr == my_b_EOF) goto found_eof; if(chr == '"' || chr == '\'')
{
delim= chr;
} else
{
delim= ' '; /* no delimiter, use space */
PUSH(chr);
}
chr= read_value(delim, &value); if (attribute.length() > 0 && value.length() > 0)
{
DBUG_PRINT("read_xml", ("lev:%i att:%s val:%s",
level + 1,
attribute.c_ptr_safe(),
value.c_ptr_safe()));
XML_TAG *tmp= new XML_TAG(level + 1, attribute, value); if (!tmp || taglist.push_front(tmp, thd->mem_root))
DBUG_RETURN(1); // End of memory
}
attribute.length(0);
value.length(0); if (chr != ' ')
chr= my_tospace(GET); break;
default:
chr= my_tospace(GET);
} /* end switch */
} /* end while */
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.71Bemerkung:
(vorverarbeitet am 2026-10-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.