The world's most popular open source database
#include "mysql_priv.h"#include <my_dir.h>#include <m_ctype.h>#include "sql_repl.h"#include "sp_head.h"#include "sql_trigger.h"Include dependency graph for sql_load.cc:

Go to the source code of this file.
Classes | |
| class | READ_INFO |
Defines | |
| #define | GET (stack_pos != stack ? *--stack_pos : my_b_get(&cache)) |
| #define | PUSH(A) *(stack_pos++)=(A) |
Functions | |
| static int | read_fixed_length (THD *thd, COPY_INFO &info, TABLE_LIST *table_list, List< Item > &fields_vars, List< Item > &set_fields, List< Item > &set_values, READ_INFO &read_info, ulong skip_lines, bool ignore_check_option_errors) |
| static int | read_sep_field (THD *thd, COPY_INFO &info, TABLE_LIST *table_list, List< Item > &fields_vars, List< Item > &set_fields, List< Item > &set_values, READ_INFO &read_info, String &enclosed, ulong skip_lines, bool ignore_check_option_errors) |
| static bool | write_execute_load_query_log_event (THD *thd, bool duplicates, bool ignore, bool transactional_table) |
| bool | mysql_load (THD *thd, sql_exchange *ex, TABLE_LIST *table_list, List< Item > &fields_vars, List< Item > &set_fields, List< Item > &set_values, enum enum_duplicates handle_duplicates, bool ignore, bool read_file_from_client) |
| #define GET (stack_pos != stack ? *--stack_pos : my_b_get(&cache)) |
Definition at line 940 of file sql_load.cc.
Referenced by READ_INFO::find_start_of_fields(), READ_INFO::next_line(), READ_INFO::read_field(), READ_INFO::read_fixed_length(), and READ_INFO::terminator().
Definition at line 941 of file sql_load.cc.
| bool mysql_load | ( | THD * | thd, | |
| sql_exchange * | ex, | |||
| TABLE_LIST * | table_list, | |||
| List< Item > & | fields_vars, | |||
| List< Item > & | set_fields, | |||
| List< Item > & | set_values, | |||
| enum enum_duplicates | handle_duplicates, | |||
| bool | ignore, | |||
| bool | read_file_from_client | |||
| ) |
Definition at line 112 of file sql_load.cc.
References st_table_list::alias, bitmap_is_set(), bitmap_set_all, bitmap_set_bit(), BLOB_FLAG, bzero, CHECK_FIELD_IGNORE, check_key_in_view(), check_that_all_fields_are_given_values(), st_table::copy_blobs, st_table_list::db, db, DBUG_ENTER, DBUG_RETURN, dirname_length(), DUP_ERROR, DUP_REPLACE, base_list::elements, enclosed, READ_INFO::end_io_cache(), ER, ER_BLOBS_AND_NO_TERMINATED, ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR, ER_LOAD_INFO, ER_NON_UPDATABLE_TABLE, ER_TEXTFILE_NOT_READABLE, ER_UPDATE_TABLE_USED, ER_WRONG_FIELD_TERMINATORS, err, READ_INFO::error, error, escaped, handler::extra(), FALSE, st_table::field, Field::field_index, Item::FIELD_ITEM, st_table::file, Log_event::flags, fn_format(), FN_REFLEN, st_table::found_next_number_field, free_blobs(), ha_autocommit_or_rollback(), ha_enable_transaction(), handler::ha_end_bulk_insert(), HA_EXTRA_IGNORE_DUP_KEY, HA_EXTRA_NO_IGNORE_DUP_KEY, HA_EXTRA_WRITE_CAN_REPLACE, HA_EXTRA_WRITE_CANNOT_REPLACE, HA_POS_ERROR, handler::ha_release_auto_increment(), handler::ha_start_bulk_insert(), Table_triggers_list::has_delete_triggers(), handler::has_transactions(), HAVE_ROW_BASED_REPLICATION, info, INSERT_ACL, MYSQL_LOG::is_open(), String::length(), LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F, st_table::mark_columns_needed_for_insert(), MARK_COLUMNS_READ, MARK_COLUMNS_WRITE, MODE_STRICT_ALL_TABLES, MODE_STRICT_TRANS_TABLES, my_close(), my_errno, my_error(), my_message(), my_open(), MY_RELATIVE_PATH, my_stat(), MY_STAT, MY_UNPACK_FILENAME, MY_WME, MYF, mysql_bin_log, mysql_real_data_home, mysql_unlock_tables(), name, net_request_file(), st_table_list::next_global, READ_INFO::next_line(), st_table::next_number_field, NULL, NullS, open_and_lock_tables(), OPTION_STATUS_NO_TRANS_UPDATE, st_table_list::prepare_check_option(), st_table_list::prepare_where(), handler::print_error(), List< T >::push_back(), read_fixed_length(), read_sep_field(), S_IROTH, st_table_list::select_lex, send_ok(), READ_INFO::set_io_cache_arg(), setup_fields(), setup_tables_and_check_access(), strxnmov(), st_table_list::table, st_table_list::table_name, test, st_table::timestamp_field, st_table::timestamp_field_type, TIMESTAMP_NO_AUTO_SET, st_table::triggers, TRUE, Item::type(), unique_table(), st_table_list::updatable, UPDATE_ACL, MYSQL_BIN_LOG::write(), write_execute_load_query_log_event(), and st_table::write_set.
Referenced by mysql_execute_command().
00117 { 00118 char name[FN_REFLEN]; 00119 File file; 00120 TABLE *table= NULL; 00121 int error; 00122 String *field_term=ex->field_term,*escaped=ex->escaped; 00123 String *enclosed=ex->enclosed; 00124 bool is_fifo=0; 00125 #ifndef EMBEDDED_LIBRARY 00126 LOAD_FILE_INFO lf_info; 00127 #endif 00128 char *db = table_list->db; // This is never null 00129 /* 00130 If path for file is not defined, we will use the current database. 00131 If this is not set, we will use the directory where the table to be 00132 loaded is located 00133 */ 00134 char *tdb= thd->db ? thd->db : db; // Result is never null 00135 ulong skip_lines= ex->skip_lines; 00136 bool transactional_table; 00137 DBUG_ENTER("mysql_load"); 00138 00139 #ifdef EMBEDDED_LIBRARY 00140 read_file_from_client = 0; //server is always in the same process 00141 #endif 00142 00143 if (escaped->length() > 1 || enclosed->length() > 1) 00144 { 00145 my_message(ER_WRONG_FIELD_TERMINATORS,ER(ER_WRONG_FIELD_TERMINATORS), 00146 MYF(0)); 00147 DBUG_RETURN(TRUE); 00148 } 00149 /* 00150 This needs to be done before external_lock 00151 */ 00152 ha_enable_transaction(thd, FALSE); 00153 if (open_and_lock_tables(thd, table_list)) 00154 DBUG_RETURN(TRUE); 00155 if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context, 00156 &thd->lex->select_lex.top_join_list, 00157 table_list, 00158 &thd->lex->select_lex.leaf_tables, FALSE, 00159 INSERT_ACL | UPDATE_ACL)) 00160 DBUG_RETURN(-1); 00161 if (!table_list->table || // do not suport join view 00162 !table_list->updatable || // and derived tables 00163 check_key_in_view(thd, table_list)) 00164 { 00165 my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD"); 00166 DBUG_RETURN(TRUE); 00167 } 00168 if (table_list->prepare_where(thd, 0, TRUE) || 00169 table_list->prepare_check_option(thd)) 00170 { 00171 DBUG_RETURN(TRUE); 00172 } 00173 /* 00174 Let us emit an error if we are loading data to table which is used 00175 in subselect in SET clause like we do it for INSERT. 00176 00177 The main thing to fix to remove this restriction is to ensure that the 00178 table is marked to be 'used for insert' in which case we should never 00179 mark this table as 'const table' (ie, one that has only one row). 00180 */ 00181 if (unique_table(thd, table_list, table_list->next_global)) 00182 { 00183 my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name); 00184 DBUG_RETURN(TRUE); 00185 } 00186 00187 table= table_list->table; 00188 transactional_table= table->file->has_transactions(); 00189 00190 if (!fields_vars.elements) 00191 { 00192 Field **field; 00193 for (field=table->field; *field ; field++) 00194 fields_vars.push_back(new Item_field(*field)); 00195 bitmap_set_all(table->write_set); 00196 table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; 00197 /* 00198 Let us also prepare SET clause, altough it is probably empty 00199 in this case. 00200 */ 00201 if (setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) || 00202 setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0)) 00203 DBUG_RETURN(TRUE); 00204 } 00205 else 00206 { // Part field list 00207 /* TODO: use this conds for 'WITH CHECK OPTIONS' */ 00208 if (setup_fields(thd, 0, fields_vars, MARK_COLUMNS_WRITE, 0, 0) || 00209 setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) || 00210 check_that_all_fields_are_given_values(thd, table, table_list)) 00211 DBUG_RETURN(TRUE); 00212 /* 00213 Check whenever TIMESTAMP field with auto-set feature specified 00214 explicitly. 00215 */ 00216 if (table->timestamp_field) 00217 { 00218 if (bitmap_is_set(table->write_set, 00219 table->timestamp_field->field_index)) 00220 table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; 00221 else 00222 { 00223 bitmap_set_bit(table->write_set, 00224 table->timestamp_field->field_index); 00225 } 00226 } 00227 /* Fix the expressions in SET clause */ 00228 if (setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0)) 00229 DBUG_RETURN(TRUE); 00230 } 00231 00232 table->mark_columns_needed_for_insert(); 00233 00234 uint tot_length=0; 00235 bool use_blobs= 0, use_vars= 0; 00236 List_iterator_fast<Item> it(fields_vars); 00237 Item *item; 00238 00239 while ((item= it++)) 00240 { 00241 if (item->type() == Item::FIELD_ITEM) 00242 { 00243 Field *field= ((Item_field*)item)->field; 00244 if (field->flags & BLOB_FLAG) 00245 { 00246 use_blobs= 1; 00247 tot_length+= 256; // Will be extended if needed 00248 } 00249 else 00250 tot_length+= field->field_length; 00251 } 00252 else 00253 use_vars= 1; 00254 } 00255 if (use_blobs && !ex->line_term->length() && !field_term->length()) 00256 { 00257 my_message(ER_BLOBS_AND_NO_TERMINATED,ER(ER_BLOBS_AND_NO_TERMINATED), 00258 MYF(0)); 00259 DBUG_RETURN(TRUE); 00260 } 00261 if (use_vars && !field_term->length() && !enclosed->length()) 00262 { 00263 my_error(ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR, MYF(0)); 00264 DBUG_RETURN(TRUE); 00265 } 00266 00267 /* We can't give an error in the middle when using LOCAL files */ 00268 if (read_file_from_client && handle_duplicates == DUP_ERROR) 00269 ignore= 1; 00270 00271 #ifndef EMBEDDED_LIBRARY 00272 if (read_file_from_client) 00273 { 00274 (void)net_request_file(&thd->net,ex->file_name); 00275 file = -1; 00276 } 00277 else 00278 #endif 00279 { 00280 #ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS 00281 ex->file_name+=dirname_length(ex->file_name); 00282 #endif 00283 if (!dirname_length(ex->file_name)) 00284 { 00285 strxnmov(name, FN_REFLEN-1, mysql_real_data_home, tdb, NullS); 00286 (void) fn_format(name, ex->file_name, name, "", 00287 MY_RELATIVE_PATH | MY_UNPACK_FILENAME); 00288 } 00289 else 00290 { 00291 (void) fn_format(name, ex->file_name, mysql_real_data_home, "", 00292 MY_RELATIVE_PATH | MY_UNPACK_FILENAME); 00293 #if !defined(__WIN__) && ! defined(__NETWARE__) 00294 MY_STAT stat_info; 00295 if (!my_stat(name,&stat_info,MYF(MY_WME))) 00296 DBUG_RETURN(TRUE); 00297 00298 // if we are not in slave thread, the file must be: 00299 if (!thd->slave_thread && 00300 !((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others 00301 (stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink 00302 ((stat_info.st_mode & S_IFREG) == S_IFREG || 00303 (stat_info.st_mode & S_IFIFO) == S_IFIFO))) 00304 { 00305 my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name); 00306 DBUG_RETURN(TRUE); 00307 } 00308 if ((stat_info.st_mode & S_IFIFO) == S_IFIFO) 00309 is_fifo = 1; 00310 #endif 00311 } 00312 if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0) 00313 DBUG_RETURN(TRUE); 00314 } 00315 00316 COPY_INFO info; 00317 bzero((char*) &info,sizeof(info)); 00318 info.ignore= ignore; 00319 info.handle_duplicates=handle_duplicates; 00320 info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX; 00321 00322 READ_INFO read_info(file,tot_length,thd->variables.collation_database, 00323 *field_term,*ex->line_start, *ex->line_term, *enclosed, 00324 info.escape_char, read_file_from_client, is_fifo); 00325 if (read_info.error) 00326 { 00327 if (file >= 0) 00328 my_close(file,MYF(0)); // no files in net reading 00329 DBUG_RETURN(TRUE); // Can't allocate buffers 00330 } 00331 00332 #ifndef EMBEDDED_LIBRARY 00333 if (mysql_bin_log.is_open()) 00334 { 00335 lf_info.thd = thd; 00336 lf_info.wrote_create_file = 0; 00337 lf_info.last_pos_in_file = HA_POS_ERROR; 00338 lf_info.log_delayed= transactional_table; 00339 read_info.set_io_cache_arg((void*) &lf_info); 00340 } 00341 #endif 00343 thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */ 00344 thd->cuted_fields=0L; 00345 /* Skip lines if there is a line terminator */ 00346 if (ex->line_term->length()) 00347 { 00348 /* ex->skip_lines needs to be preserved for logging */ 00349 while (skip_lines > 0) 00350 { 00351 skip_lines--; 00352 if (read_info.next_line()) 00353 break; 00354 } 00355 } 00356 00357 if (!(error=test(read_info.error))) 00358 { 00359 00360 table->next_number_field=table->found_next_number_field; 00361 if (ignore || 00362 handle_duplicates == DUP_REPLACE) 00363 table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); 00364 if (handle_duplicates == DUP_REPLACE && 00365 (!table->triggers || 00366 !table->triggers->has_delete_triggers())) 00367 table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE); 00368 if (!thd->prelocked_mode) 00369 table->file->ha_start_bulk_insert((ha_rows) 0); 00370 table->copy_blobs=1; 00371 00372 thd->no_trans_update= 0; 00373 thd->abort_on_warning= (!ignore && 00374 (thd->variables.sql_mode & 00375 (MODE_STRICT_TRANS_TABLES | 00376 MODE_STRICT_ALL_TABLES))); 00377 00378 if (!field_term->length() && !enclosed->length()) 00379 error= read_fixed_length(thd, info, table_list, fields_vars, 00380 set_fields, set_values, read_info, 00381 skip_lines, ignore); 00382 else 00383 error= read_sep_field(thd, info, table_list, fields_vars, 00384 set_fields, set_values, read_info, 00385 *enclosed, skip_lines, ignore); 00386 if (!thd->prelocked_mode && table->file->ha_end_bulk_insert() && !error) 00387 { 00388 table->file->print_error(my_errno, MYF(0)); 00389 error= 1; 00390 } 00391 table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); 00392 table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); 00393 table->next_number_field=0; 00394 } 00395 ha_enable_transaction(thd, TRUE); 00396 if (file >= 0) 00397 my_close(file,MYF(0)); 00398 free_blobs(table); /* if pack_blob was used */ 00399 table->copy_blobs=0; 00400 thd->count_cuted_fields= CHECK_FIELD_IGNORE; 00401 00402 /* 00403 We must invalidate the table in query cache before binlog writing and 00404 ha_autocommit_... 00405 */ 00406 query_cache_invalidate3(thd, table_list, 0); 00407 00408 if (error) 00409 { 00410 if (transactional_table) 00411 ha_autocommit_or_rollback(thd,error); 00412 00413 if (read_file_from_client) 00414 while (!read_info.next_line()) 00415 ; 00416 00417 #ifndef EMBEDDED_LIBRARY 00418 if (mysql_bin_log.is_open()) 00419 { 00420 { 00421 /* 00422 Make sure last block (the one which caused the error) gets 00423 logged. This is needed because otherwise after write of (to 00424 the binlog, not to read_info (which is a cache)) 00425 Delete_file_log_event the bad block will remain in read_info 00426 (because pre_read is not called at the end of the last 00427 block; remember pre_read is called whenever a new block is 00428 read from disk). At the end of mysql_load(), the destructor 00429 of read_info will call end_io_cache() which will flush 00430 read_info, so we will finally have this in the binlog: 00431 00432 Append_block # The last successfull block 00433 Delete_file 00434 Append_block # The failing block 00435 which is nonsense. 00436 Or could also be (for a small file) 00437 Create_file # The failing block 00438 which is nonsense (Delete_file is not written in this case, because: 00439 Create_file has not been written, so Delete_file is not written, then 00440 when read_info is destroyed end_io_cache() is called which writes 00441 Create_file. 00442 */ 00443 read_info.end_io_cache(); 00444 /* If the file was not empty, wrote_create_file is true */ 00445 if (lf_info.wrote_create_file) 00446 { 00447 if ((info.copied || info.deleted) && !transactional_table) 00448 write_execute_load_query_log_event(thd, handle_duplicates, 00449 ignore, transactional_table); 00450 else 00451 { 00452 Delete_file_log_event d(thd, db, transactional_table); 00453 d.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F; 00454 mysql_bin_log.write(&d); 00455 } 00456 } 00457 } 00458 } 00459 #endif 00460 error= -1; // Error on read 00461 goto err; 00462 } 00463 sprintf(name, ER(ER_LOAD_INFO), (ulong) info.records, (ulong) info.deleted, 00464 (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); 00465 send_ok(thd,info.copied+info.deleted,0L,name); 00466 00467 if (!transactional_table) 00468 thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; 00469 #ifndef EMBEDDED_LIBRARY 00470 if (mysql_bin_log.is_open()) 00471 { 00472 #ifdef HAVE_ROW_BASED_REPLICATION 00473 /* 00474 We need to do the job that is normally done inside 00475 binlog_query() here, which is to ensure that the pending event 00476 is written before tables are unlocked and before any other 00477 events are written. We also need to update the table map 00478 version for the binary log to mark that table maps are invalid 00479 after this point. 00480 */ 00481 if (thd->current_stmt_binlog_row_based) 00482 thd->binlog_flush_pending_rows_event(true); 00483 else 00484 #endif 00485 { 00486 /* 00487 As already explained above, we need to call end_io_cache() or the last 00488 block will be logged only after Execute_load_query_log_event (which is 00489 wrong), when read_info is destroyed. 00490 */ 00491 read_info.end_io_cache(); 00492 if (lf_info.wrote_create_file) 00493 { 00494 write_execute_load_query_log_event(thd, handle_duplicates, 00495 ignore, transactional_table); 00496 } 00497 } 00498 } 00499 #endif 00500 if (transactional_table) 00501 error=ha_autocommit_or_rollback(thd,error); 00502 00503 err: 00504 table->file->ha_release_auto_increment(); 00505 if (thd->lock) 00506 { 00507 mysql_unlock_tables(thd, thd->lock); 00508 thd->lock=0; 00509 } 00510 thd->abort_on_warning= 0; 00511 DBUG_RETURN(error); 00512 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int read_fixed_length | ( | THD * | thd, | |
| COPY_INFO & | info, | |||
| TABLE_LIST * | table_list, | |||
| List< Item > & | fields_vars, | |||
| List< Item > & | set_fields, | |||
| List< Item > & | set_values, | |||
| READ_INFO & | read_info, | |||
| ulong | skip_lines, | |||
| bool | ignore_check_option_errors | |||
| ) | [static] |
Definition at line 537 of file sql_load.cc.
References st_table::auto_increment_field_not_null, DBUG_ENTER, DBUG_RETURN, ER, ER_WARN_TOO_FEW_RECORDS, ER_WARN_TOO_MANY_RECORDS, READ_INFO::error, Item_field::field, Field::field_length, st_table::file, fill_record_n_invoke_before_triggers(), handler::has_transactions(), id, READ_INFO::line_cuted, READ_INFO::next_line(), st_table::next_number_field, pos(), push_warning_printf(), READ_INFO::read_charset, READ_INFO::read_fixed_length(), restore_record, List_iterator_fast< T >::rewind(), READ_INFO::row_end, READ_INFO::row_start, Field::set_notnull(), Field::store(), st_table_list::table, test, TRG_EVENT_INSERT, st_table::triggers, TRUE, VIEW_CHECK_ERROR, st_table_list::view_check_option(), VIEW_CHECK_SKIP, MYSQL_ERROR::WARN_LEVEL_WARN, and write_record().
Referenced by mysql_load().
00541 { 00542 List_iterator_fast<Item> it(fields_vars); 00543 Item_field *sql_field; 00544 TABLE *table= table_list->table; 00545 ulonglong id; 00546 bool no_trans_update; 00547 DBUG_ENTER("read_fixed_length"); 00548 00549 id= 0; 00550 00551 while (!read_info.read_fixed_length()) 00552 { 00553 if (thd->killed) 00554 { 00555 thd->send_kill_message(); 00556 DBUG_RETURN(1); 00557 } 00558 if (skip_lines) 00559 { 00560 /* 00561 We could implement this with a simple seek if: 00562 - We are not using DATA INFILE LOCAL 00563 - escape character is "" 00564 - line starting prefix is "" 00565 */ 00566 skip_lines--; 00567 continue; 00568 } 00569 it.rewind(); 00570 byte *pos=read_info.row_start; 00571 #ifdef HAVE_purify 00572 read_info.row_end[0]=0; 00573 #endif 00574 no_trans_update= !table->file->has_transactions(); 00575 00576 restore_record(table, s->default_values); 00577 /* 00578 There is no variables in fields_vars list in this format so 00579 this conversion is safe. 00580 */ 00581 while ((sql_field= (Item_field*) it++)) 00582 { 00583 Field *field= sql_field->field; 00584 if (field == table->next_number_field) 00585 table->auto_increment_field_not_null= TRUE; 00586 /* 00587 No fields specified in fields_vars list can be null in this format. 00588 Mark field as not null, we should do this for each row because of 00589 restore_record... 00590 */ 00591 field->set_notnull(); 00592 00593 if (pos == read_info.row_end) 00594 { 00595 thd->cuted_fields++; /* Not enough fields */ 00596 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 00597 ER_WARN_TOO_FEW_RECORDS, 00598 ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count); 00599 } 00600 else 00601 { 00602 uint length; 00603 byte save_chr; 00604 if (field == table->next_number_field) 00605 table->auto_increment_field_not_null= TRUE; 00606 if ((length=(uint) (read_info.row_end-pos)) > 00607 field->field_length) 00608 length=field->field_length; 00609 save_chr=pos[length]; pos[length]='\0'; // Safeguard aganst malloc 00610 field->store((char*) pos,length,read_info.read_charset); 00611 pos[length]=save_chr; 00612 if ((pos+=length) > read_info.row_end) 00613 pos= read_info.row_end; /* Fills rest with space */ 00614 } 00615 } 00616 if (pos != read_info.row_end) 00617 { 00618 thd->cuted_fields++; /* To long row */ 00619 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 00620 ER_WARN_TOO_MANY_RECORDS, 00621 ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count); 00622 } 00623 00624 if (thd->killed || 00625 fill_record_n_invoke_before_triggers(thd, set_fields, set_values, 00626 ignore_check_option_errors, 00627 table->triggers, 00628 TRG_EVENT_INSERT)) 00629 DBUG_RETURN(1); 00630 00631 switch (table_list->view_check_option(thd, 00632 ignore_check_option_errors)) { 00633 case VIEW_CHECK_SKIP: 00634 read_info.next_line(); 00635 goto continue_loop; 00636 case VIEW_CHECK_ERROR: 00637 DBUG_RETURN(-1); 00638 } 00639 00640 if (write_record(thd, table, &info)) 00641 DBUG_RETURN(1); 00642 thd->no_trans_update= no_trans_update; 00643 00644 /* 00645 We don't need to reset auto-increment field since we are restoring 00646 its default value at the beginning of each loop iteration. 00647 */ 00648 if (read_info.next_line()) // Skip to next line 00649 break; 00650 if (read_info.line_cuted) 00651 { 00652 thd->cuted_fields++; /* To long row */ 00653 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 00654 ER_WARN_TOO_MANY_RECORDS, 00655 ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count); 00656 } 00657 thd->row_count++; 00658 continue_loop:; 00659 } 00660 DBUG_RETURN(test(read_info.error)); 00661 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int read_sep_field | ( | THD * | thd, | |
| COPY_INFO & | info, | |||
| TABLE_LIST * | table_list, | |||
| List< Item > & | fields_vars, | |||
| List< Item > & | set_fields, | |||
| List< Item > & | set_values, | |||
| READ_INFO & | read_info, | |||
| String & | enclosed, | |||
| ulong | skip_lines, | |||
| bool | ignore_check_option_errors | |||
| ) | [static] |
Definition at line 666 of file sql_load.cc.
References st_table::auto_increment_field_not_null, DBUG_ENTER, DBUG_RETURN, READ_INFO::enclosed, enclosed, ER, ER_WARN_NULL_TO_NOTNULL, ER_WARN_TOO_FEW_RECORDS, ER_WARN_TOO_MANY_RECORDS, READ_INFO::error, Item::FIELD_ITEM, FIELD_TYPE_TIMESTAMP, st_table::file, fill_record_n_invoke_before_triggers(), READ_INFO::found_null, handler::has_transactions(), List< T >::head(), id, READ_INFO::line_cuted, memcmp(), READ_INFO::next_line(), st_table::next_number_field, pos(), push_warning_printf(), READ_INFO::read_charset, READ_INFO::read_field(), restore_record, List_iterator_fast< T >::rewind(), READ_INFO::row_end, READ_INFO::row_start, Field::set_warning(), STRING_WITH_LEN, st_table_list::table, test, TRG_EVENT_INSERT, st_table::triggers, TRUE, Item::type(), VIEW_CHECK_ERROR, st_table_list::view_check_option(), VIEW_CHECK_SKIP, MYSQL_ERROR::WARN_LEVEL_WARN, and write_record().
Referenced by mysql_load().
00671 { 00672 List_iterator_fast<Item> it(fields_vars); 00673 Item *item; 00674 TABLE *table= table_list->table; 00675 uint enclosed_length; 00676 ulonglong id; 00677 bool no_trans_update; 00678 DBUG_ENTER("read_sep_field"); 00679 00680 enclosed_length=enclosed.length(); 00681 id= 0; 00682 no_trans_update= !table->file->has_transactions(); 00683 00684 for (;;it.rewind()) 00685 { 00686 if (thd->killed) 00687 { 00688 thd->send_kill_message(); 00689 DBUG_RETURN(1); 00690 } 00691 00692 restore_record(table, s->default_values); 00693 00694 while ((item= it++)) 00695 { 00696 uint length; 00697 byte *pos; 00698 00699 if (read_info.read_field()) 00700 break; 00701 00702 /* If this line is to be skipped we don't want to fill field or var */ 00703 if (skip_lines) 00704 continue; 00705 00706 pos=read_info.row_start; 00707 length=(uint) (read_info.row_end-pos); 00708 00709 if (!read_info.enclosed && 00710 (enclosed_length && length == 4 && 00711 !memcmp(pos, STRING_WITH_LEN("NULL"))) || 00712 (length == 1 && read_info.found_null)) 00713 { 00714 if (item->type() == Item::FIELD_ITEM) 00715 { 00716 Field *field= ((Item_field *)item)->field; 00717 field->reset(); 00718 field->set_null(); 00719 if (field == table->next_number_field) 00720 table->auto_increment_field_not_null= TRUE; 00721 if (!field->maybe_null()) 00722 { 00723 if (field->type() == FIELD_TYPE_TIMESTAMP) 00724 ((Field_timestamp*) field)->set_time(); 00725 else if (field != table->next_number_field) 00726 field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, 00727 ER_WARN_NULL_TO_NOTNULL, 1); 00728 } 00729 } 00730 else 00731 ((Item_user_var_as_out_param *)item)->set_null_value( 00732 read_info.read_charset); 00733 continue; 00734 } 00735 00736 if (item->type() == Item::FIELD_ITEM) 00737 { 00738 00739 Field *field= ((Item_field *)item)->field; 00740 field->set_notnull(); 00741 read_info.row_end[0]=0; // Safe to change end marker 00742 if (field == table->next_number_field) 00743 table->auto_increment_field_not_null= TRUE; 00744 field->store((char*) pos, length, read_info.read_charset); 00745 } 00746 else 00747 ((Item_user_var_as_out_param *)item)->set_value((char*) pos, length, 00748 read_info.read_charset); 00749 } 00750 if (read_info.error) 00751 break; 00752 if (skip_lines) 00753 { 00754 skip_lines--; 00755 continue; 00756 } 00757 if (item) 00758 { 00759 /* Have not read any field, thus input file is simply ended */ 00760 if (item == fields_vars.head()) 00761 break; 00762 for (; item ; item= it++) 00763 { 00764 if (item->type() == Item::FIELD_ITEM) 00765 { 00766 /* 00767 QQ: We probably should not throw warning for each field. 00768 But how about intention to always have the same number 00769 of warnings in THD::cuted_fields (and get rid of cuted_fields 00770 in the end ?) 00771 */ 00772 thd->cuted_fields++; 00773 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 00774 ER_WARN_TOO_FEW_RECORDS, 00775 ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count); 00776 } 00777 else 00778 ((Item_user_var_as_out_param *)item)->set_null_value( 00779 read_info.read_charset); 00780 } 00781 } 00782 00783 if (thd->killed || 00784 fill_record_n_invoke_before_triggers(thd, set_fields, set_values, 00785 ignore_check_option_errors, 00786 table->triggers, 00787 TRG_EVENT_INSERT)) 00788 DBUG_RETURN(1); 00789 00790 switch (table_list->view_check_option(thd, 00791 ignore_check_option_errors)) { 00792 case VIEW_CHECK_SKIP: 00793 read_info.next_line(); 00794 goto continue_loop; 00795 case VIEW_CHECK_ERROR: 00796 DBUG_RETUR

