12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
17
/* Copy data from a textfile to table */
20
#include <drizzled/sql_load.h>
21
#include <drizzled/error.h>
22
#include <drizzled/data_home.h>
23
#include <drizzled/session.h>
24
#include <drizzled/sql_base.h>
25
#include <drizzled/field/timestamp.h>
26
#include "drizzled/internal/my_sys.h"
27
#include "drizzled/internal/iocache.h"
28
#include <drizzled/db.h>
34
#include <boost/filesystem.hpp>
36
namespace fs=boost::filesystem;
18
/* 2006-12 Erik Wetterberg : LOAD XML added */
20
#include "mysql_priv.h"
30
XML_TAG(int l, String f, String v);
34
XML_TAG::XML_TAG(int l, String f, String v)
43
unsigned char *buffer; /* Buffer for read text */
44
unsigned char *end_of_buff; /* Data in bufferts ends here */
45
size_t buff_length; /* Length of buffert */
46
size_t max_length; /* Max length of row */
44
uchar *buffer, /* Buffer for read text */
45
*end_of_buff; /* Data in bufferts ends here */
46
uint buff_length, /* Length of buffert */
47
max_length; /* Max length of row */
47
48
char *field_term_ptr,*line_term_ptr,*line_start_ptr,*line_start_end;
48
49
uint field_term_length,line_term_length,enclosed_length;
49
50
int field_term_char,line_term_char,enclosed_char,escape_char;
50
51
int *stack,*stack_pos;
51
52
bool found_end_of_line,start_of_line,eof;
52
53
bool need_end_io_cache;
53
internal::IO_CACHE cache;
56
int level; /* for load xml */
56
59
bool error,line_cuted,found_null,enclosed;
57
unsigned char *row_start, /* Found row starts here */
60
uchar *row_start, /* Found row starts here */
58
61
*row_end; /* Found row ends here */
59
const CHARSET_INFO *read_charset;
62
CHARSET_INFO *read_charset;
61
READ_INFO(int cursor, size_t tot_length, const CHARSET_INFO * const cs,
64
READ_INFO(File file,uint tot_length,CHARSET_INFO *cs,
62
65
String &field_term,String &line_start,String &line_term,
63
String &enclosed,int escape, bool is_fifo);
66
String &enclosed,int escape,bool get_it_from_net, bool is_fifo);
66
69
int read_fixed_length(void);
67
70
int next_line(void);
68
71
char unescape(char chr);
69
int terminator(char *ptr,uint32_t length);
72
int terminator(char *ptr,uint length);
70
73
bool find_start_of_fields();
75
List<XML_TAG> taglist;
76
int read_value(int delim, String *val);
78
int clear_level(int level);
73
81
We need to force cache close before destructor is invoked to log
76
84
void end_io_cache()
86
::end_io_cache(&cache);
79
87
need_end_io_cache = 0;
83
91
Either this method, or we need to make cache public
84
92
Arg must be set from mysql_load() since constructor does not see
85
either the table or Session value
93
either the table or THD value
87
95
void set_io_cache_arg(void* arg) { cache.arg = arg; }
90
static int read_fixed_length(Session *session, CopyInfo &info, TableList *table_list,
98
static int read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
91
99
List<Item> &fields_vars, List<Item> &set_fields,
92
100
List<Item> &set_values, READ_INFO &read_info,
94
102
bool ignore_check_option_errors);
95
static int read_sep_field(Session *session, CopyInfo &info, TableList *table_list,
103
static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
96
104
List<Item> &fields_vars, List<Item> &set_fields,
97
105
List<Item> &set_values, READ_INFO &read_info,
98
String &enclosed, uint32_t skip_lines,
106
String &enclosed, ulong skip_lines,
99
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);
115
static bool write_execute_load_query_log_event(THD *thd,
116
bool duplicates, bool ignore,
117
bool transactional_table,
118
THD::killed_state killed_status);
103
121
Execute LOAD DATA query
107
session - current thread
108
ex - file_exchange object representing source cursor and its parsing rules
126
ex - sql_exchange object representing source file and its parsing rules
109
127
table_list - list of tables to which we are loading data
110
128
fields_vars - list of fields and variables to which we read
112
130
set_fields - list of fields mentioned in set clause
113
131
set_values - expressions to assign to fields in previous list
114
132
handle_duplicates - indicates whenever we should emit error or
115
133
replace row if we will meet duplicates.
116
134
ignore - - indicates whenever we should ignore duplicates
135
read_file_from_client - is this LOAD DATA LOCAL ?
119
138
true - error / false - success
122
int mysql_load(Session *session,file_exchange *ex,TableList *table_list,
141
int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
123
142
List<Item> &fields_vars, List<Item> &set_fields,
124
143
List<Item> &set_values,
125
enum enum_duplicates handle_duplicates, bool ignore)
144
enum enum_duplicates handle_duplicates, bool ignore,
145
bool read_file_from_client)
147
char name[FN_REFLEN];
130
151
String *field_term=ex->field_term,*escaped=ex->escaped;
131
152
String *enclosed=ex->enclosed;
134
assert(table_list->getSchemaName()); // This should never be null
154
LOAD_FILE_INFO lf_info;
155
char *db = table_list->db; // This is never null
137
If path for cursor is not defined, we will use the current database.
157
If path for file is not defined, we will use the current database.
138
158
If this is not set, we will use the directory where the table to be
139
159
loaded is located
141
util::string::const_shared_ptr schema(session->schema());
142
const char *tdb= (schema and not schema->empty()) ? schema->c_str() : table_list->getSchemaName(); // Result should never be null
144
uint32_t skip_lines= ex->skip_lines;
161
char *tdb= thd->db ? thd->db : db; // Result is never null
162
ulong skip_lines= ex->skip_lines;
145
163
bool transactional_table;
146
Session::killed_state_t killed_status= Session::NOT_KILLED;
164
THD::killed_state killed_status= THD::NOT_KILLED;
148
/* Escape and enclosed character may be a utf8 4-byte character */
149
if (escaped->length() > 4 || enclosed->length() > 4)
166
if (escaped->length() > 1 || enclosed->length() > 1)
151
my_error(ER_WRONG_FIELD_TERMINATORS,MYF(0),enclosed->c_ptr(), enclosed->length());
168
my_message(ER_WRONG_FIELD_TERMINATORS,ER(ER_WRONG_FIELD_TERMINATORS),
155
if (session->openTablesLock(table_list))
172
if (open_and_lock_tables(thd, table_list))
158
if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
159
&session->lex->select_lex.top_join_list,
174
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
175
&thd->lex->select_lex.top_join_list,
161
&session->lex->select_lex.leaf_tables, true))
177
&thd->lex->select_lex.leaf_tables, true))
169
185
table is marked to be 'used for insert' in which case we should never
170
186
mark this table as 'const table' (ie, one that has only one row).
172
if (unique_table(table_list, table_list->next_global))
188
if (unique_table(thd, table_list, table_list->next_global, 0))
174
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->getTableName());
190
my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
178
194
table= table_list->table;
179
transactional_table= table->cursor->has_transactions();
195
transactional_table= table->file->has_transactions();
181
197
if (!fields_vars.elements)
184
for (field= table->getFields(); *field ; field++)
200
for (field=table->field; *field ; field++)
185
201
fields_vars.push_back(new Item_field(*field));
186
table->setWriteSet();
202
bitmap_set_all(table->write_set);
187
203
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
189
205
Let us also prepare SET clause, altough it is probably empty
192
if (setup_fields(session, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
193
setup_fields(session, 0, set_values, MARK_COLUMNS_READ, 0, 0))
208
if (setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
209
setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0))
197
213
{ // Part field list
198
214
/* TODO: use this conds for 'WITH CHECK OPTIONS' */
199
if (setup_fields(session, 0, fields_vars, MARK_COLUMNS_WRITE, 0, 0) ||
200
setup_fields(session, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
201
check_that_all_fields_are_given_values(session, table, table_list))
215
if (setup_fields(thd, 0, fields_vars, MARK_COLUMNS_WRITE, 0, 0) ||
216
setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
217
check_that_all_fields_are_given_values(thd, table, table_list))
204
220
Check whenever TIMESTAMP field with auto-set feature specified
260
fs::path to_file(ex->file_name);
261
fs::path target_path(fs::system_complete(getDataHomeCatalog()));
262
if (not to_file.has_root_directory())
276
/* We can't give an error in the middle when using LOCAL files */
277
if (read_file_from_client && handle_duplicates == DUP_ERROR)
280
if (read_file_from_client)
264
int count_elements= 0;
265
for (fs::path::iterator iter= to_file.begin();
266
iter != to_file.end();
267
++iter, ++count_elements)
270
if (count_elements == 1)
274
target_path /= to_file;
282
(void)net_request_file(&thd->net,ex->file_name);
278
target_path= to_file;
281
if (not secure_file_priv.string().empty())
283
if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
285
/* Read only allowed from within dir specified by secure_file_priv */
286
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
287
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
288
ex->file_name+=dirname_length(ex->file_name);
290
if (!dirname_length(ex->file_name))
292
strxnmov(name, FN_REFLEN-1, mysql_real_data_home, tdb, NullS);
293
(void) fn_format(name, ex->file_name, name, "",
294
MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
298
(void) fn_format(name, ex->file_name, mysql_real_data_home, "",
299
MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
301
if (opt_secure_file_priv &&
302
strncmp(opt_secure_file_priv, name, strlen(opt_secure_file_priv)))
304
/* Read only allowed from within dir specified by secure_file_priv */
305
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
309
struct stat stat_info;
310
if (stat(name,&stat_info))
313
// if we are not in slave thread, the file must be:
314
if (!thd->slave_thread &&
315
!((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others
316
(stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
317
((stat_info.st_mode & S_IFREG) == S_IFREG ||
318
(stat_info.st_mode & S_IFIFO) == S_IFIFO)))
320
my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name);
323
if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
326
if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0)
291
struct stat stat_info;
292
if (stat(target_path.file_string().c_str(), &stat_info))
294
my_error(ER_FILE_NOT_FOUND, MYF(0), target_path.file_string().c_str(), errno);
298
// if we are not in slave thread, the cursor must be:
299
if (!((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others
300
(stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
301
((stat_info.st_mode & S_IFREG) == S_IFREG ||
302
(stat_info.st_mode & S_IFIFO) == S_IFIFO)))
304
my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), target_path.file_string().c_str());
307
if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
311
if ((file=internal::my_open(target_path.file_string().c_str(), O_RDONLY,MYF(MY_WME))) < 0)
313
my_error(ER_CANT_OPEN_FILE, MYF(0), target_path.file_string().c_str(), errno);
317
memset(&info, 0, sizeof(info));
331
bzero((char*) &info,sizeof(info));
318
332
info.ignore= ignore;
319
333
info.handle_duplicates=handle_duplicates;
320
334
info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX;
322
SchemaIdentifier identifier(*schema);
323
READ_INFO read_info(file, tot_length,
324
ex->cs ? ex->cs : plugin::StorageEngine::getSchemaCollation(identifier),
325
*field_term, *ex->line_start, *ex->line_term, *enclosed,
326
info.escape_char, is_fifo);
336
READ_INFO read_info(file,tot_length,
337
ex->cs ? ex->cs : thd->variables.collation_database,
338
*field_term,*ex->line_start, *ex->line_term, *enclosed,
339
info.escape_char, read_file_from_client, is_fifo);
327
340
if (read_info.error)
330
internal::my_close(file,MYF(0)); // no files in net reading
343
my_close(file,MYF(0)); // no files in net reading
331
344
return(true); // Can't allocate buffers
335
* Per the SQL standard, inserting NULL into a NOT NULL
336
* field requires an error to be thrown.
340
* NULL check and handling occurs in field_conv.cc
342
session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
343
session->cuted_fields=0L;
347
if (mysql_bin_log.is_open())
350
lf_info.wrote_create_file = 0;
351
lf_info.last_pos_in_file = HA_POS_ERROR;
352
lf_info.log_delayed= transactional_table;
353
read_info.set_io_cache_arg((void*) &lf_info);
356
thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */
357
thd->cuted_fields=0L;
344
358
/* Skip lines if there is a line terminator */
345
if (ex->line_term->length())
359
if (ex->line_term->length() && ex->filetype != FILETYPE_XML)
347
361
/* ex->skip_lines needs to be preserved for logging */
348
362
while (skip_lines > 0)
359
373
table->next_number_field=table->found_next_number_field;
361
375
handle_duplicates == DUP_REPLACE)
362
table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
376
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
363
377
if (handle_duplicates == DUP_REPLACE)
364
table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
365
table->cursor->ha_start_bulk_insert((ha_rows) 0);
378
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
379
table->file->ha_start_bulk_insert((ha_rows) 0);
366
380
table->copy_blobs=1;
368
session->abort_on_warning= true;
382
thd->abort_on_warning= (!ignore &&
383
(thd->variables.sql_mode &
384
(MODE_STRICT_TRANS_TABLES |
385
MODE_STRICT_ALL_TABLES)));
370
if (!field_term->length() && !enclosed->length())
371
error= read_fixed_length(session, info, table_list, fields_vars,
387
if (ex->filetype == FILETYPE_XML) /* load xml */
388
error= read_xml_field(thd, info, table_list, fields_vars,
389
set_fields, set_values, read_info,
390
*(ex->line_term), skip_lines, ignore);
391
else if (!field_term->length() && !enclosed->length())
392
error= read_fixed_length(thd, info, table_list, fields_vars,
372
393
set_fields, set_values, read_info,
373
394
skip_lines, ignore);
375
error= read_sep_field(session, info, table_list, fields_vars,
396
error= read_sep_field(thd, info, table_list, fields_vars,
376
397
set_fields, set_values, read_info,
377
398
*enclosed, skip_lines, ignore);
378
if (table->cursor->ha_end_bulk_insert() && !error)
399
if (table->file->ha_end_bulk_insert() && !error)
380
table->print_error(errno, MYF(0));
401
table->file->print_error(my_errno, MYF(0));
383
table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
384
table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
404
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
405
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
385
406
table->next_number_field=0;
388
internal::my_close(file,MYF(0));
409
my_close(file,MYF(0));
389
410
free_blobs(table); /* if pack_blob was used */
390
411
table->copy_blobs=0;
391
session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
412
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
393
414
simulated killing in the middle of per-row loop
394
415
must be effective for binlogging
396
killed_status= (error == 0)? Session::NOT_KILLED : session->getKilled();
417
killed_status= (error == 0)? THD::NOT_KILLED : thd->killed;
420
if (read_file_from_client)
421
while (!read_info.next_line())
424
if (mysql_bin_log.is_open())
428
Make sure last block (the one which caused the error) gets
429
logged. This is needed because otherwise after write of (to
430
the binlog, not to read_info (which is a cache))
431
Delete_file_log_event the bad block will remain in read_info
432
(because pre_read is not called at the end of the last
433
block; remember pre_read is called whenever a new block is
434
read from disk). At the end of mysql_load(), the destructor
435
of read_info will call end_io_cache() which will flush
436
read_info, so we will finally have this in the binlog:
438
Append_block # The last successfull block
440
Append_block # The failing block
442
Or could also be (for a small file)
443
Create_file # The failing block
444
which is nonsense (Delete_file is not written in this case, because:
445
Create_file has not been written, so Delete_file is not written, then
446
when read_info is destroyed end_io_cache() is called which writes
449
read_info.end_io_cache();
450
/* If the file was not empty, wrote_create_file is true */
451
if (lf_info.wrote_create_file)
453
if (thd->transaction.stmt.modified_non_trans_table)
454
write_execute_load_query_log_event(thd, handle_duplicates,
455
ignore, transactional_table,
459
Delete_file_log_event d(thd, db, transactional_table);
460
d.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
461
mysql_bin_log.write(&d);
399
466
error= -1; // Error on read
404
snprintf(msg, sizeof(msg), ER(ER_LOAD_INFO), info.records, info.deleted,
405
(info.records - info.copied), session->cuted_fields);
407
if (session->transaction.stmt.hasModifiedNonTransData())
408
session->transaction.all.markModifiedNonTransData();
469
sprintf(name, ER(ER_LOAD_INFO), (ulong) info.records, (ulong) info.deleted,
470
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
472
if (thd->transaction.stmt.modified_non_trans_table)
473
thd->transaction.all.modified_non_trans_table= true;
475
if (mysql_bin_log.is_open())
478
We need to do the job that is normally done inside
479
binlog_query() here, which is to ensure that the pending event
480
is written before tables are unlocked and before any other
481
events are written. We also need to update the table map
482
version for the binary log to mark that table maps are invalid
485
if (thd->current_stmt_binlog_row_based)
486
thd->binlog_flush_pending_rows_event(true);
490
As already explained above, we need to call end_io_cache() or the last
491
block will be logged only after Execute_load_query_log_event (which is
492
wrong), when read_info is destroyed.
494
read_info.end_io_cache();
495
if (lf_info.wrote_create_file)
497
write_execute_load_query_log_event(thd, handle_duplicates, ignore,
498
transactional_table,killed_status);
410
503
/* ok to client sent only after binlog write and engine commit */
411
session->my_ok(info.copied + info.deleted, 0, 0L, msg);
504
my_ok(thd, info.copied + info.deleted, 0L, name);
413
506
assert(transactional_table || !(info.copied || info.deleted) ||
414
session->transaction.stmt.hasModifiedNonTransData());
415
table->cursor->ha_release_auto_increment();
507
thd->transaction.stmt.modified_non_trans_table);
508
table->file->ha_release_auto_increment();
416
509
table->auto_increment_field_not_null= false;
417
session->abort_on_warning= 0;
510
thd->abort_on_warning= 0;
515
/* Not a very useful function; just to avoid duplication of code */
516
static bool write_execute_load_query_log_event(THD *thd,
517
bool duplicates, bool ignore,
518
bool transactional_table,
519
THD::killed_state killed_err_arg)
521
Execute_load_query_log_event
522
e(thd, thd->query, thd->query_length,
523
(char*)thd->lex->fname_start - (char*)thd->query,
524
(char*)thd->lex->fname_end - (char*)thd->query,
525
(duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
526
(ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
527
transactional_table, false, killed_err_arg);
528
e.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
529
return mysql_bin_log.write(&e);
422
533
/****************************************************************************
423
534
** Read of rows of fixed size + optional garage + optonal newline
424
535
****************************************************************************/
427
read_fixed_length(Session *session, CopyInfo &info, TableList *table_list,
538
read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
428
539
List<Item> &fields_vars, List<Item> &set_fields,
429
540
List<Item> &set_values, READ_INFO &read_info,
430
uint32_t skip_lines, bool ignore_check_option_errors)
541
ulong skip_lines, bool ignore_check_option_errors)
432
543
List_iterator_fast<Item> it(fields_vars);
433
544
Item_field *sql_field;
434
Table *table= table_list->table;
545
TABLE *table= table_list->table;
440
551
while (!read_info.read_fixed_length())
442
if (session->getKilled())
444
session->send_kill_message();
555
thd->send_kill_message();
712
820
if (read_info.line_cuted)
714
session->cuted_fields++; /* To long row */
715
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
716
ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS),
718
if (session->getKilled())
822
thd->cuted_fields++; /* To long row */
823
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
824
ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS),
721
session->row_count++;
723
831
return(test(read_info.error));
835
/****************************************************************************
836
** Read rows in xml format
837
****************************************************************************/
839
read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
840
List<Item> &fields_vars, List<Item> &set_fields,
841
List<Item> &set_values, READ_INFO &read_info,
842
String &row_tag __attribute__((__unused__)),
844
bool ignore_check_option_errors)
846
List_iterator_fast<Item> it(fields_vars);
848
TABLE *table= table_list->table;
849
bool no_trans_update_stmt;
850
CHARSET_INFO *cs= read_info.read_charset;
852
no_trans_update_stmt= !table->file->has_transactions();
854
for ( ; ; it.rewind())
858
thd->send_kill_message();
862
// read row tag and save values into tag list
863
if (read_info.read_xml())
866
List_iterator_fast<XML_TAG> xmlit(read_info.taglist);
871
restore_record(table, s->default_values);
875
/* If this line is to be skipped we don't want to fill field or var */
879
/* find field in tag list */
883
while(tag && strcmp(tag->field.c_ptr(), item->name) != 0)
886
if (!tag) // found null
888
if (item->type() == Item::FIELD_ITEM)
890
Field *field= ((Item_field *) item)->field;
893
if (field == table->next_number_field)
894
table->auto_increment_field_not_null= true;
895
if (!field->maybe_null())
897
if (field->type() == FIELD_TYPE_TIMESTAMP)
898
((Field_timestamp *) field)->set_time();
899
else if (field != table->next_number_field)
900
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
901
ER_WARN_NULL_TO_NOTNULL, 1);
905
((Item_user_var_as_out_param *) item)->set_null_value(cs);
909
if (item->type() == Item::FIELD_ITEM)
912
Field *field= ((Item_field *)item)->field;
913
field->set_notnull();
914
if (field == table->next_number_field)
915
table->auto_increment_field_not_null= true;
916
field->store((char *) tag->value.ptr(), tag->value.length(), cs);
919
((Item_user_var_as_out_param *) item)->set_value(
920
(char *) tag->value.ptr(),
921
tag->value.length(), cs);
935
/* Have not read any field, thus input file is simply ended */
936
if (item == fields_vars.head())
939
for ( ; item; item= it++)
941
if (item->type() == Item::FIELD_ITEM)
944
QQ: We probably should not throw warning for each field.
945
But how about intention to always have the same number
946
of warnings in THD::cuted_fields (and get rid of cuted_fields
950
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
951
ER_WARN_TOO_FEW_RECORDS,
952
ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
955
((Item_user_var_as_out_param *)item)->set_null_value(cs);
959
if (thd->killed || fill_record(thd, set_fields, set_values,
960
ignore_check_option_errors))
963
if (write_record(thd, table, &info))
967
We don't need to reset auto-increment field since we are restoring
968
its default value at the beginning of each loop iteration.
970
thd->transaction.stmt.modified_non_trans_table= no_trans_update_stmt;
973
return(test(read_info.error));
727
977
/* Unescape all escape characters, mark \N as null */
781
1032
line_term_ptr=(char*) "";
783
1034
enclosed_char= (enclosed_length=enclosed_par.length()) ?
784
(unsigned char) enclosed_par[0] : INT_MAX;
785
field_term_char= field_term_length ? (unsigned char) field_term_ptr[0] : INT_MAX;
786
line_term_char= line_term_length ? (unsigned char) line_term_ptr[0] : INT_MAX;
1035
(uchar) enclosed_par[0] : INT_MAX;
1036
field_term_char= field_term_length ? (uchar) field_term_ptr[0] : INT_MAX;
1037
line_term_char= line_term_length ? (uchar) line_term_ptr[0] : INT_MAX;
787
1038
error=eof=found_end_of_line=found_null=line_cuted=0;
788
1039
buff_length=tot_length;
791
1042
/* Set of a stack for unget if long terminators */
792
size_t length= max(field_term_length,line_term_length)+1;
793
set_if_bigger(length, line_start.length());
794
stack= stack_pos= (int*) memory::sql_alloc(sizeof(int)*length);
1043
uint length=max(field_term_length,line_term_length)+1;
1044
set_if_bigger(length,line_start.length());
1045
stack=stack_pos=(int*) sql_alloc(sizeof(int)*length);
796
if (!(buffer=(unsigned char*) calloc(1, buff_length+1)))
1047
if (!(buffer=(uchar*) my_malloc(buff_length+1,MYF(0))))
1048
error=1; /* purecov: inspected */
800
1051
end_of_buff=buffer+buff_length;
801
if (cache.init_io_cache((false) ? -1 : cursor, 0,
802
(false) ? internal::READ_NET :
803
(is_fifo ? internal::READ_FIFO : internal::READ_CACHE),0L,1,
1052
if (init_io_cache(&cache,(get_it_from_net) ? -1 : file, 0,
1053
(get_it_from_net) ? READ_NET :
1054
(is_fifo ? READ_FIFO : READ_CACHE),0L,1,
806
free((unsigned char*) buffer);
1057
my_free((uchar*) buffer,MYF(0)); /* purecov: inspected */
942
1206
#ifdef ALLOW_LINESEPARATOR_IN_STRINGS
943
1207
if (chr == line_term_char)
945
if (chr == line_term_char && found_enclosed_char == INT_MAX)
1209
if (chr == line_term_char && found_enclosed_char == INT_MAX)
948
if (terminator(line_term_ptr,line_term_length))
949
{ // Maybe unexpected linefeed
1212
if (terminator(line_term_ptr,line_term_length))
1213
{ // Maybe unexpected linefeed
1215
found_end_of_line=1;
957
1221
if (chr == found_enclosed_char)
959
if ((chr=GET) == found_enclosed_char)
960
{ // Remove dupplicated
961
*to++ = (unsigned char) chr;
964
// End of enclosed field if followed by field_term or line_term
965
if (chr == my_b_EOF ||
966
(chr == line_term_char && terminator(line_term_ptr, line_term_length)))
967
{ // Maybe unexpected linefeed
974
if (chr == field_term_char &&
975
terminator(field_term_ptr,field_term_length))
983
The string didn't terminate yet.
984
Store back next character for the loop
987
/* copy the found term character to 'to' */
988
chr= found_enclosed_char;
1223
if ((chr=GET) == found_enclosed_char)
1224
{ // Remove dupplicated
1225
*to++ = (uchar) chr;
1228
// End of enclosed field if followed by field_term or line_term
1229
if (chr == my_b_EOF ||
1230
(chr == line_term_char && terminator(line_term_ptr, line_term_length)))
1231
{ // Maybe unexpected linefeed
1233
found_end_of_line=1;
1238
if (chr == field_term_char &&
1239
terminator(field_term_ptr,field_term_length))
1247
The string didn't terminate yet.
1248
Store back next character for the loop
1251
/* copy the found term character to 'to' */
1252
chr= found_enclosed_char;
990
1254
else if (chr == field_term_char && found_enclosed_char == INT_MAX)
992
if (terminator(field_term_ptr,field_term_length))
1256
if (terminator(field_term_ptr,field_term_length))
1000
*to++ = (unsigned char) chr;
1264
*to++ = (uchar) chr;
1003
** We come here if buffer is too small. Enlarge it and continue
1005
if (!(new_buffer=(unsigned char*) realloc(buffer, buff_length+1+IO_SIZE)))
1267
** We come here if buffer is too small. Enlarge it and continue
1269
if (!(new_buffer=(uchar*) my_realloc((char*) buffer,buff_length+1+IO_SIZE,
1006
1271
return (error=1);
1007
1272
to=new_buffer + (to-buffer);
1008
1273
buffer=new_buffer;
1159
} /* namespace drizzled */
1427
Clear taglist from tags with a specified level
1429
int READ_INFO::clear_level(int level)
1431
List_iterator<XML_TAG> xmlit(taglist);
1435
while ((tag= xmlit++))
1437
if(tag->level >= level)
1448
Convert an XML entity to Unicode value.
1452
my_xml_entity_to_char(const char *name, uint length)
1456
if (!memcmp(name, "gt", length))
1458
if (!memcmp(name, "lt", length))
1461
else if (length == 3)
1463
if (!memcmp(name, "amp", length))
1466
else if (length == 4)
1468
if (!memcmp(name, "quot", length))
1470
if (!memcmp(name, "apos", length))
1478
@brief Convert newline, linefeed, tab to space
1480
@param chr character
1482
@details According to the "XML 1.0" standard,
1483
only space (#x20) characters, carriage returns,
1484
line feeds or tabs are considered as spaces.
1485
Convert all of them to space (#x20) for parsing simplicity.
1490
return (chr == '\t' || chr == '\r' || chr == '\n') ? ' ' : chr;
1495
Read an xml value: handle multibyte and xml escape
1497
int READ_INFO::read_value(int delim, String *val)
1502
for (chr= my_tospace(GET); chr != delim && chr != my_b_EOF; )
1505
if (my_mbcharlen(read_charset, chr) > 1)
1507
int i, ml= my_mbcharlen(read_charset, chr);
1508
for (i= 1; i < ml; i++)
1512
Don't use my_tospace() in the middle of a multi-byte character
1513
TODO: check that the multi-byte sequence is valid.
1516
if (chr == my_b_EOF)
1524
for (chr= my_tospace(GET) ; chr != ';' ; chr= my_tospace(GET))
1526
if (chr == my_b_EOF)
1530
if ((chr= my_xml_entity_to_char(tmp.ptr(), tmp.length())) >= 0)
1541
chr= my_tospace(GET);
1548
Read a record in xml format
1549
tags and attributes are stored in taglist
1550
when tag set in ROWS IDENTIFIED BY is closed, we are ready and return
1552
int READ_INFO::read_xml()
1554
int chr, chr2, chr3;
1556
String tag, attribute, value;
1560
attribute.length(0);
1563
for (chr= my_tospace(GET); chr != my_b_EOF ; )
1566
case '<': /* read tag */
1567
/* TODO: check if this is a comment <!-- comment --> */
1568
chr= my_tospace(GET);
1574
if(chr2 == '-' && chr3 == '-')
1578
chr= my_tospace(GET);
1580
while(chr != '>' || chr2 != '-' || chr3 != '-')
1587
else if (chr2 == '-')
1592
chr= my_tospace(GET);
1593
if (chr == my_b_EOF)
1601
while(chr != '>' && chr != ' ' && chr != '/' && chr != my_b_EOF)
1603
if(chr != delim) /* fix for the '<field name =' format */
1605
chr= my_tospace(GET);
1608
if(chr == ' ' || chr == '>')
1611
clear_level(level + 1);
1620
case ' ': /* read attribute */
1621
while(chr == ' ') /* skip blanks */
1622
chr= my_tospace(GET);
1627
while(chr != '=' && chr != '/' && chr != '>' && chr != my_b_EOF)
1629
attribute.append(chr);
1630
chr= my_tospace(GET);
1634
case '>': /* end tag - read tag value */
1636
chr= read_value('<', &value);
1640
/* save value to list */
1641
if(tag.length() > 0 && value.length() > 0)
1642
taglist.push_front( new XML_TAG(level, tag, value));
1646
attribute.length(0);
1649
case '/': /* close tag */
1651
chr= my_tospace(GET);
1652
if(chr != '>') /* if this is an empty tag <tag /> */
1653
tag.length(0); /* we should keep tag value */
1654
while(chr != '>' && chr != my_b_EOF)
1657
chr= my_tospace(GET);
1660
if((tag.length() == line_term_length -2) &&
1661
(strncmp(tag.c_ptr_safe(), line_term_ptr + 1, tag.length()) == 0))
1662
return(0); //normal return
1664
chr= my_tospace(GET);
1667
case '=': /* attribute name end - read the value */
1668
//check for tag field and attribute name
1669
if(!memcmp(tag.c_ptr_safe(), STRING_WITH_LEN("field")) &&
1670
!memcmp(attribute.c_ptr_safe(), STRING_WITH_LEN("name")))
1673
this is format <field name="xx">xx</field>
1674
where actual fieldname is in attribute
1676
delim= my_tospace(GET);
1678
attribute.length(0);
1679
chr= '<'; /* we pretend that it is a tag */
1686
if (chr == my_b_EOF)
1688
if(chr == '"' || chr == '\'')
1694
delim= ' '; /* no delimiter, use space */
1698
chr= read_value(delim, &value);
1699
if(attribute.length() > 0 && value.length() > 0)
1700
taglist.push_front(new XML_TAG(level + 1, attribute, value));
1702
attribute.length(0);
1705
chr= my_tospace(GET);
1709
chr= my_tospace(GET);