~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_load.cc

  • Committer: Monty Taylor
  • Date: 2009-02-05 21:07:57 UTC
  • mto: This revision was merged to the branch mainline in revision 840.
  • Revision ID: mordred@inaugust.com-20090205210757-6487lf69y3mndcds
Fixed warnings badness in csv_alter_table test.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
/* Copy data from a textfile to table */
18
18
 
19
19
#include <drizzled/server_includes.h>
20
 
#include "sql_repl.h"
21
 
#include <drizzled/drizzled_error_messages.h>
22
 
 
 
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>
23
26
 
24
27
class READ_INFO {
25
28
  File  file;
26
 
  uchar *buffer,                        /* Buffer for read text */
 
29
  unsigned char *buffer,                        /* Buffer for read text */
27
30
        *end_of_buff;                   /* Data in bufferts ends here */
28
31
  uint  buff_length,                    /* Length of buffert */
29
32
        max_length;                     /* Max length of row */
38
41
 
39
42
public:
40
43
  bool error,line_cuted,found_null,enclosed;
41
 
  uchar *row_start,                     /* Found row starts here */
 
44
  unsigned char *row_start,                     /* Found row starts here */
42
45
        *row_end;                       /* Found row ends here */
43
46
  const CHARSET_INFO *read_charset;
44
47
 
45
 
  READ_INFO(File file,uint tot_length, const CHARSET_INFO * const cs,
 
48
  READ_INFO(File file,uint32_t tot_length, const CHARSET_INFO * const cs,
46
49
            String &field_term,String &line_start,String &line_term,
47
50
            String &enclosed,int escape,bool get_it_from_net, bool is_fifo);
48
51
  ~READ_INFO();
50
53
  int read_fixed_length(void);
51
54
  int next_line(void);
52
55
  char unescape(char chr);
53
 
  int terminator(char *ptr,uint length);
 
56
  int terminator(char *ptr,uint32_t length);
54
57
  bool find_start_of_fields();
55
58
 
56
59
  /*
66
69
  /*
67
70
    Either this method, or we need to make cache public
68
71
    Arg must be set from mysql_load() since constructor does not see
69
 
    either the table or THD value
 
72
    either the table or Session value
70
73
  */
71
74
  void set_io_cache_arg(void* arg) { cache.arg = arg; }
72
75
};
73
76
 
74
 
static int read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
 
77
static int read_fixed_length(Session *session, COPY_INFO &info, TableList *table_list,
75
78
                             List<Item> &fields_vars, List<Item> &set_fields,
76
79
                             List<Item> &set_values, READ_INFO &read_info,
77
80
                             uint32_t skip_lines,
78
81
                             bool ignore_check_option_errors);
79
 
static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
 
82
static int read_sep_field(Session *session, COPY_INFO &info, TableList *table_list,
80
83
                          List<Item> &fields_vars, List<Item> &set_fields,
81
84
                          List<Item> &set_values, READ_INFO &read_info,
82
85
                          String &enclosed, uint32_t skip_lines,
83
86
                          bool ignore_check_option_errors);
84
87
 
85
 
static bool write_execute_load_query_log_event(THD *thd,
86
 
                                               bool duplicates, bool ignore,
87
 
                                               bool transactional_table,
88
 
                                               THD::killed_state killed_status);
89
88
 
90
89
/*
91
90
  Execute LOAD DATA query
92
91
 
93
92
  SYNOPSYS
94
93
    mysql_load()
95
 
      thd - current thread
96
 
      ex  - sql_exchange object representing source file and its parsing rules
 
94
      session - current thread
 
95
      ex  - file_exchange object representing source file and its parsing rules
97
96
      table_list  - list of tables to which we are loading data
98
97
      fields_vars - list of fields and variables to which we read
99
98
                    data from file
108
107
    true - error / false - success
109
108
*/
110
109
 
111
 
int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
 
110
int mysql_load(Session *session,file_exchange *ex,TableList *table_list,
112
111
                List<Item> &fields_vars, List<Item> &set_fields,
113
112
                List<Item> &set_values,
114
113
                enum enum_duplicates handle_duplicates, bool ignore,
116
115
{
117
116
  char name[FN_REFLEN];
118
117
  File file;
119
 
  TABLE *table= NULL;
 
118
  Table *table= NULL;
120
119
  int error;
121
120
  String *field_term=ex->field_term,*escaped=ex->escaped;
122
121
  String *enclosed=ex->enclosed;
123
122
  bool is_fifo=0;
124
 
  LOAD_FILE_INFO lf_info;
125
 
  char *db = table_list->db;                    // This is never null
 
123
  char *db= table_list->db;                     // This is never null
 
124
  assert(db);
126
125
  /*
127
126
    If path for file is not defined, we will use the current database.
128
127
    If this is not set, we will use the directory where the table to be
129
128
    loaded is located
130
129
  */
131
 
  char *tdb= thd->db ? thd->db : db;            // Result is never null
 
130
  char *tdb= session->db ? session->db : db;            // Result is never null
 
131
  assert(tdb);
132
132
  uint32_t skip_lines= ex->skip_lines;
133
133
  bool transactional_table;
134
 
  THD::killed_state killed_status= THD::NOT_KILLED;
 
134
  Session::killed_state killed_status= Session::NOT_KILLED;
135
135
 
136
 
  if (escaped->length() > 1 || enclosed->length() > 1)
 
136
  /* Escape and enclosed character may be a utf8 4-byte character */
 
137
  if (escaped->length() > 4 || enclosed->length() > 4)
137
138
  {
138
 
    my_message(ER_WRONG_FIELD_TERMINATORS,ER(ER_WRONG_FIELD_TERMINATORS),
139
 
               MYF(0));
 
139
    my_error(ER_WRONG_FIELD_TERMINATORS,MYF(0),enclosed->c_ptr(), enclosed->length());
140
140
    return(true);
141
141
  }
142
 
  if (open_and_lock_tables(thd, table_list))
 
142
  if (open_and_lock_tables(session, table_list))
143
143
    return(true);
144
 
  if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
145
 
                                    &thd->lex->select_lex.top_join_list,
 
144
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
 
145
                                    &session->lex->select_lex.top_join_list,
146
146
                                    table_list,
147
 
                                    &thd->lex->select_lex.leaf_tables, true))
 
147
                                    &session->lex->select_lex.leaf_tables, true))
148
148
     return(-1);
149
149
 
150
150
  /*
155
155
    table is marked to be 'used for insert' in which case we should never
156
156
    mark this table as 'const table' (ie, one that has only one row).
157
157
  */
158
 
  if (unique_table(thd, table_list, table_list->next_global, 0))
 
158
  if (unique_table(session, table_list, table_list->next_global, 0))
159
159
  {
160
160
    my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
161
161
    return(true);
175
175
      Let us also prepare SET clause, altough it is probably empty
176
176
      in this case.
177
177
    */
178
 
    if (setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
179
 
        setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0))
 
178
    if (setup_fields(session, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
 
179
        setup_fields(session, 0, set_values, MARK_COLUMNS_READ, 0, 0))
180
180
      return(true);
181
181
  }
182
182
  else
183
183
  {                                             // Part field list
184
184
    /* TODO: use this conds for 'WITH CHECK OPTIONS' */
185
 
    if (setup_fields(thd, 0, fields_vars, MARK_COLUMNS_WRITE, 0, 0) ||
186
 
        setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
187
 
        check_that_all_fields_are_given_values(thd, table, table_list))
 
185
    if (setup_fields(session, 0, fields_vars, MARK_COLUMNS_WRITE, 0, 0) ||
 
186
        setup_fields(session, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
 
187
        check_that_all_fields_are_given_values(session, table, table_list))
188
188
      return(true);
189
189
    /*
190
190
      Check whenever TIMESTAMP field with auto-set feature specified
202
202
      }
203
203
    }
204
204
    /* Fix the expressions in SET clause */
205
 
    if (setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0))
 
205
    if (setup_fields(session, 0, set_values, MARK_COLUMNS_READ, 0, 0))
206
206
      return(true);
207
207
  }
208
208
 
209
209
  table->mark_columns_needed_for_insert();
210
210
 
211
 
  uint tot_length=0;
 
211
  uint32_t tot_length=0;
212
212
  bool use_blobs= 0, use_vars= 0;
213
213
  List_iterator_fast<Item> it(fields_vars);
214
214
  Item *item;
249
249
 
250
250
  if (read_file_from_client)
251
251
  {
252
 
    (void)net_request_file(&thd->net,ex->file_name);
 
252
    assert(0);
253
253
    file = -1;
254
254
  }
255
255
  else
259
259
#endif
260
260
    if (!dirname_length(ex->file_name))
261
261
    {
262
 
      strxnmov(name, FN_REFLEN-1, mysql_real_data_home, tdb, NullS);
 
262
      strcpy(name, drizzle_real_data_home);
 
263
      strncat(name, tdb, FN_REFLEN-strlen(drizzle_real_data_home)-1);
263
264
      (void) fn_format(name, ex->file_name, name, "",
264
265
                       MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
265
266
    }
266
267
    else
267
268
    {
268
 
      (void) fn_format(name, ex->file_name, mysql_real_data_home, "",
 
269
      (void) fn_format(name, ex->file_name, drizzle_real_data_home, "",
269
270
                       MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
270
271
 
271
272
      if (opt_secure_file_priv &&
278
279
 
279
280
      struct stat stat_info;
280
281
      if (stat(name,&stat_info))
 
282
      {
 
283
        my_error(ER_FILE_NOT_FOUND, MYF(0), name, errno);
281
284
        return(true);
 
285
      }
282
286
 
283
287
      // if we are not in slave thread, the file must be:
284
 
      if (!thd->slave_thread &&
285
 
          !((stat_info.st_mode & S_IROTH) == S_IROTH &&  // readable by others
286
 
            (stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
287
 
            ((stat_info.st_mode & S_IFREG) == S_IFREG ||
288
 
             (stat_info.st_mode & S_IFIFO) == S_IFIFO)))
 
288
      if (!((stat_info.st_mode & S_IROTH) == S_IROTH &&  // readable by others
 
289
            (stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
 
290
            ((stat_info.st_mode & S_IFREG) == S_IFREG ||
 
291
             (stat_info.st_mode & S_IFIFO) == S_IFIFO)))
289
292
      {
290
293
        my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name);
291
294
        return(true);
294
297
        is_fifo = 1;
295
298
    }
296
299
    if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0)
 
300
    {
 
301
      my_error(ER_CANT_OPEN_FILE, MYF(0), my_errno);
297
302
      return(true);
 
303
    }
298
304
  }
299
305
 
300
306
  COPY_INFO info;
304
310
  info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX;
305
311
 
306
312
  READ_INFO read_info(file,tot_length,
307
 
                      ex->cs ? ex->cs : thd->variables.collation_database,
 
313
                      ex->cs ? ex->cs : session->variables.collation_database,
308
314
                      *field_term,*ex->line_start, *ex->line_term, *enclosed,
309
315
                      info.escape_char, read_file_from_client, is_fifo);
310
316
  if (read_info.error)
314
320
    return(true);                               // Can't allocate buffers
315
321
  }
316
322
 
317
 
  if (mysql_bin_log.is_open())
318
 
  {
319
 
    lf_info.thd = thd;
320
 
    lf_info.wrote_create_file = 0;
321
 
    lf_info.last_pos_in_file = HA_POS_ERROR;
322
 
    lf_info.log_delayed= transactional_table;
323
 
    read_info.set_io_cache_arg((void*) &lf_info);
324
 
  }
325
 
 
326
 
  thd->count_cuted_fields= CHECK_FIELD_WARN;            /* calc cuted fields */
327
 
  thd->cuted_fields=0L;
 
323
  /*
 
324
   * Per the SQL standard, inserting NULL into a NOT NULL
 
325
   * field requires an error to be thrown.
 
326
   *
 
327
   * @NOTE
 
328
   *
 
329
   * NULL check and handling occurs in field_conv.cc
 
330
   */
 
331
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
 
332
  session->cuted_fields=0L;
328
333
  /* Skip lines if there is a line terminator */
329
334
  if (ex->line_term->length())
330
335
  {
349
354
    table->file->ha_start_bulk_insert((ha_rows) 0);
350
355
    table->copy_blobs=1;
351
356
 
352
 
    thd->abort_on_warning= (!ignore &&
353
 
                            (thd->variables.sql_mode &
354
 
                             (MODE_STRICT_TRANS_TABLES |
355
 
                              MODE_STRICT_ALL_TABLES)));
 
357
    session->abort_on_warning= true;
356
358
 
357
359
    if (!field_term->length() && !enclosed->length())
358
 
      error= read_fixed_length(thd, info, table_list, fields_vars,
 
360
      error= read_fixed_length(session, info, table_list, fields_vars,
359
361
                               set_fields, set_values, read_info,
360
362
                               skip_lines, ignore);
361
363
    else
362
 
      error= read_sep_field(thd, info, table_list, fields_vars,
 
364
      error= read_sep_field(session, info, table_list, fields_vars,
363
365
                            set_fields, set_values, read_info,
364
366
                            *enclosed, skip_lines, ignore);
365
367
    if (table->file->ha_end_bulk_insert() && !error)
375
377
    my_close(file,MYF(0));
376
378
  free_blobs(table);                            /* if pack_blob was used */
377
379
  table->copy_blobs=0;
378
 
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
379
 
  /* 
 
380
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
 
381
  /*
380
382
     simulated killing in the middle of per-row loop
381
383
     must be effective for binlogging
382
384
  */
383
 
  killed_status= (error == 0)? THD::NOT_KILLED : thd->killed;
 
385
  killed_status= (error == 0)? Session::NOT_KILLED : session->killed;
384
386
  if (error)
385
387
  {
386
388
    if (read_file_from_client)
387
389
      while (!read_info.next_line())
388
390
        ;
389
391
 
390
 
    if (mysql_bin_log.is_open())
391
 
    {
392
 
      {
393
 
        /*
394
 
          Make sure last block (the one which caused the error) gets
395
 
          logged.  This is needed because otherwise after write of (to
396
 
          the binlog, not to read_info (which is a cache))
397
 
          Delete_file_log_event the bad block will remain in read_info
398
 
          (because pre_read is not called at the end of the last
399
 
          block; remember pre_read is called whenever a new block is
400
 
          read from disk).  At the end of mysql_load(), the destructor
401
 
          of read_info will call end_io_cache() which will flush
402
 
          read_info, so we will finally have this in the binlog:
403
 
 
404
 
          Append_block # The last successfull block
405
 
          Delete_file
406
 
          Append_block # The failing block
407
 
          which is nonsense.
408
 
          Or could also be (for a small file)
409
 
          Create_file  # The failing block
410
 
          which is nonsense (Delete_file is not written in this case, because:
411
 
          Create_file has not been written, so Delete_file is not written, then
412
 
          when read_info is destroyed end_io_cache() is called which writes
413
 
          Create_file.
414
 
        */
415
 
        read_info.end_io_cache();
416
 
        /* If the file was not empty, wrote_create_file is true */
417
 
        if (lf_info.wrote_create_file)
418
 
        {
419
 
          if (thd->transaction.stmt.modified_non_trans_table)
420
 
            write_execute_load_query_log_event(thd, handle_duplicates,
421
 
                                               ignore, transactional_table,
422
 
                                               killed_status);
423
 
          else
424
 
          {
425
 
            Delete_file_log_event d(thd, db, transactional_table);
426
 
            d.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
427
 
            mysql_bin_log.write(&d);
428
 
          }
429
 
        }
430
 
      }
431
 
    }
432
392
    error= -1;                          // Error on read
433
393
    goto err;
434
394
  }
435
395
  sprintf(name, ER(ER_LOAD_INFO), (uint32_t) info.records, (uint32_t) info.deleted,
436
 
          (uint32_t) (info.records - info.copied), (uint32_t) thd->cuted_fields);
437
 
 
438
 
  if (thd->transaction.stmt.modified_non_trans_table)
439
 
    thd->transaction.all.modified_non_trans_table= true;
440
 
 
441
 
  if (mysql_bin_log.is_open())
442
 
  {
443
 
    /*
444
 
      We need to do the job that is normally done inside
445
 
      binlog_query() here, which is to ensure that the pending event
446
 
      is written before tables are unlocked and before any other
447
 
      events are written.  We also need to update the table map
448
 
      version for the binary log to mark that table maps are invalid
449
 
      after this point.
450
 
     */
451
 
    if (thd->current_stmt_binlog_row_based)
452
 
      thd->binlog_flush_pending_rows_event(true);
453
 
    else
454
 
    {
455
 
      /*
456
 
        As already explained above, we need to call end_io_cache() or the last
457
 
        block will be logged only after Execute_load_query_log_event (which is
458
 
        wrong), when read_info is destroyed.
459
 
      */
460
 
      read_info.end_io_cache();
461
 
      if (lf_info.wrote_create_file)
462
 
      {
463
 
        write_execute_load_query_log_event(thd, handle_duplicates, ignore,
464
 
                                           transactional_table,killed_status);
465
 
      }
466
 
    }
467
 
  }
 
396
          (uint32_t) (info.records - info.copied), (uint32_t) session->cuted_fields);
 
397
 
 
398
  if (session->transaction.stmt.modified_non_trans_table)
 
399
    session->transaction.all.modified_non_trans_table= true;
468
400
 
469
401
  /* ok to client sent only after binlog write and engine commit */
470
 
  my_ok(thd, info.copied + info.deleted, 0L, name);
 
402
  session->my_ok(info.copied + info.deleted, 0L, name);
471
403
err:
472
404
  assert(transactional_table || !(info.copied || info.deleted) ||
473
 
              thd->transaction.stmt.modified_non_trans_table);
 
405
              session->transaction.stmt.modified_non_trans_table);
474
406
  table->file->ha_release_auto_increment();
475
407
  table->auto_increment_field_not_null= false;
476
 
  thd->abort_on_warning= 0;
 
408
  session->abort_on_warning= 0;
477
409
  return(error);
478
410
}
479
411
 
480
412
 
481
 
/* Not a very useful function; just to avoid duplication of code */
482
 
static bool write_execute_load_query_log_event(THD *thd,
483
 
                                               bool duplicates, bool ignore,
484
 
                                               bool transactional_table,
485
 
                                               THD::killed_state killed_err_arg)
486
 
{
487
 
  Execute_load_query_log_event
488
 
    e(thd, thd->query, thd->query_length,
489
 
      (char*)thd->lex->fname_start - (char*)thd->query,
490
 
      (char*)thd->lex->fname_end - (char*)thd->query,
491
 
      (duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
492
 
      (ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
493
 
      transactional_table, false, killed_err_arg);
494
 
  e.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
495
 
  return mysql_bin_log.write(&e);
496
 
}
497
 
 
498
 
 
499
413
/****************************************************************************
500
414
** Read of rows of fixed size + optional garage + optonal newline
501
415
****************************************************************************/
502
416
 
503
417
static int
504
 
read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
 
418
read_fixed_length(Session *session, COPY_INFO &info, TableList *table_list,
505
419
                  List<Item> &fields_vars, List<Item> &set_fields,
506
420
                  List<Item> &set_values, READ_INFO &read_info,
507
421
                  uint32_t skip_lines, bool ignore_check_option_errors)
508
422
{
509
423
  List_iterator_fast<Item> it(fields_vars);
510
424
  Item_field *sql_field;
511
 
  TABLE *table= table_list->table;
 
425
  Table *table= table_list->table;
512
426
  uint64_t id;
513
427
  bool err;
514
428
 
515
429
  id= 0;
516
 
 
 
430
 
517
431
  while (!read_info.read_fixed_length())
518
432
  {
519
 
    if (thd->killed)
 
433
    if (session->killed)
520
434
    {
521
 
      thd->send_kill_message();
 
435
      session->send_kill_message();
522
436
      return(1);
523
437
    }
524
438
    if (skip_lines)
533
447
      continue;
534
448
    }
535
449
    it.rewind();
536
 
    uchar *pos=read_info.row_start;
 
450
    unsigned char *pos=read_info.row_start;
537
451
#ifdef HAVE_purify
538
452
    read_info.row_end[0]=0;
539
453
#endif
545
459
    */
546
460
    while ((sql_field= (Item_field*) it++))
547
461
    {
548
 
      Field *field= sql_field->field;                  
 
462
      Field *field= sql_field->field;
549
463
      if (field == table->next_number_field)
550
464
        table->auto_increment_field_not_null= true;
551
465
      /*
557
471
 
558
472
      if (pos == read_info.row_end)
559
473
      {
560
 
        thd->cuted_fields++;                    /* Not enough fields */
561
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 
562
 
                            ER_WARN_TOO_FEW_RECORDS, 
563
 
                            ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
 
474
        session->cuted_fields++;                        /* Not enough fields */
 
475
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
476
                            ER_WARN_TOO_FEW_RECORDS,
 
477
                            ER(ER_WARN_TOO_FEW_RECORDS), session->row_count);
564
478
        if (!field->maybe_null() && field->type() == DRIZZLE_TYPE_TIMESTAMP)
565
479
            ((Field_timestamp*) field)->set_time();
566
480
      }
567
481
      else
568
482
      {
569
 
        uint length;
570
 
        uchar save_chr;
 
483
        uint32_t length;
 
484
        unsigned char save_chr;
571
485
        if ((length=(uint) (read_info.row_end-pos)) >
572
486
            field->field_length)
573
487
          length=field->field_length;
580
494
    }
581
495
    if (pos != read_info.row_end)
582
496
    {
583
 
      thd->cuted_fields++;                      /* To long row */
584
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 
585
 
                          ER_WARN_TOO_MANY_RECORDS, 
586
 
                          ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count); 
 
497
      session->cuted_fields++;                  /* To long row */
 
498
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
499
                          ER_WARN_TOO_MANY_RECORDS,
 
500
                          ER(ER_WARN_TOO_MANY_RECORDS), session->row_count);
587
501
    }
588
502
 
589
 
    if (thd->killed ||
590
 
        fill_record(thd, set_fields, set_values,
 
503
    if (session->killed ||
 
504
        fill_record(session, set_fields, set_values,
591
505
                    ignore_check_option_errors))
592
506
      return(1);
593
507
 
594
 
    err= write_record(thd, table, &info);
 
508
    err= write_record(session, table, &info);
595
509
    table->auto_increment_field_not_null= false;
596
510
    if (err)
597
511
      return(1);
598
 
   
 
512
 
599
513
    /*
600
514
      We don't need to reset auto-increment field since we are restoring
601
515
      its default value at the beginning of each loop iteration.
604
518
      break;
605
519
    if (read_info.line_cuted)
606
520
    {
607
 
      thd->cuted_fields++;                      /* To long row */
608
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 
609
 
                          ER_WARN_TOO_MANY_RECORDS, 
610
 
                          ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count); 
 
521
      session->cuted_fields++;                  /* To long row */
 
522
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
523
                          ER_WARN_TOO_MANY_RECORDS,
 
524
                          ER(ER_WARN_TOO_MANY_RECORDS), session->row_count);
611
525
    }
612
 
    thd->row_count++;
 
526
    session->row_count++;
613
527
  }
614
528
  return(test(read_info.error));
615
529
}
617
531
 
618
532
 
619
533
static int
620
 
read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
 
534
read_sep_field(Session *session, COPY_INFO &info, TableList *table_list,
621
535
               List<Item> &fields_vars, List<Item> &set_fields,
622
536
               List<Item> &set_values, READ_INFO &read_info,
623
537
               String &enclosed, uint32_t skip_lines,
625
539
{
626
540
  List_iterator_fast<Item> it(fields_vars);
627
541
  Item *item;
628
 
  TABLE *table= table_list->table;
629
 
  uint enclosed_length;
 
542
  Table *table= table_list->table;
 
543
  uint32_t enclosed_length;
630
544
  uint64_t id;
631
545
  bool err;
632
546
 
635
549
 
636
550
  for (;;it.rewind())
637
551
  {
638
 
    if (thd->killed)
 
552
    if (session->killed)
639
553
    {
640
 
      thd->send_kill_message();
 
554
      session->send_kill_message();
641
555
      return(1);
642
556
    }
643
557
 
645
559
 
646
560
    while ((item= it++))
647
561
    {
648
 
      uint length;
649
 
      uchar *pos;
 
562
      uint32_t length;
 
563
      unsigned char *pos;
650
564
      Item *real_item;
651
565
 
652
566
      if (read_info.read_field())
671
585
          if (field->reset())
672
586
          {
673
587
            my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name,
674
 
                     thd->row_count);
 
588
                     session->row_count);
675
589
            return(1);
676
590
          }
677
591
          field->set_null();
739
653
          if (field->reset())
740
654
          {
741
655
            my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),field->field_name,
742
 
                     thd->row_count);
 
656
                     session->row_count);
743
657
            return(1);
744
658
          }
745
659
          if (!field->maybe_null() && field->type() == DRIZZLE_TYPE_TIMESTAMP)
747
661
          /*
748
662
            QQ: We probably should not throw warning for each field.
749
663
            But how about intention to always have the same number
750
 
            of warnings in THD::cuted_fields (and get rid of cuted_fields
 
664
            of warnings in Session::cuted_fields (and get rid of cuted_fields
751
665
            in the end ?)
752
666
          */
753
 
          thd->cuted_fields++;
754
 
          push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
667
          session->cuted_fields++;
 
668
          push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
755
669
                              ER_WARN_TOO_FEW_RECORDS,
756
 
                              ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
 
670
                              ER(ER_WARN_TOO_FEW_RECORDS), session->row_count);
757
671
        }
758
672
        else if (item->type() == Item::STRING_ITEM)
759
673
        {
768
682
      }
769
683
    }
770
684
 
771
 
    if (thd->killed ||
772
 
        fill_record(thd, set_fields, set_values,
 
685
    if (session->killed ||
 
686
        fill_record(session, set_fields, set_values,
773
687
                    ignore_check_option_errors))
774
688
      return(1);
775
689
 
776
 
    err= write_record(thd, table, &info);
 
690
    err= write_record(session, table, &info);
777
691
    table->auto_increment_field_not_null= false;
778
692
    if (err)
779
693
      return(1);
785
699
      break;
786
700
    if (read_info.line_cuted)
787
701
    {
788
 
      thd->cuted_fields++;                      /* To long row */
789
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 
790
 
                          ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS), 
791
 
                          thd->row_count);   
792
 
      if (thd->killed)
 
702
      session->cuted_fields++;                  /* To long row */
 
703
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
704
                          ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS),
 
705
                          session->row_count);
 
706
      if (session->killed)
793
707
        return(1);
794
708
    }
795
 
    thd->row_count++;
 
709
    session->row_count++;
796
710
  }
797
711
  return(test(read_info.error));
798
712
}
825
739
*/
826
740
 
827
741
 
828
 
READ_INFO::READ_INFO(File file_par, uint tot_length, const CHARSET_INFO * const cs,
 
742
READ_INFO::READ_INFO(File file_par, uint32_t tot_length, const CHARSET_INFO * const cs,
829
743
                     String &field_term, String &line_start, String &line_term,
830
744
                     String &enclosed_par, int escape, bool get_it_from_net,
831
745
                     bool is_fifo)
855
769
    line_term_ptr=(char*) "";
856
770
  }
857
771
  enclosed_char= (enclosed_length=enclosed_par.length()) ?
858
 
    (uchar) enclosed_par[0] : INT_MAX;
859
 
  field_term_char= field_term_length ? (uchar) field_term_ptr[0] : INT_MAX;
860
 
  line_term_char= line_term_length ? (uchar) line_term_ptr[0] : INT_MAX;
 
772
    (unsigned char) enclosed_par[0] : INT_MAX;
 
773
  field_term_char= field_term_length ? (unsigned char) field_term_ptr[0] : INT_MAX;
 
774
  line_term_char= line_term_length ? (unsigned char) line_term_ptr[0] : INT_MAX;
861
775
  error=eof=found_end_of_line=found_null=line_cuted=0;
862
776
  buff_length=tot_length;
863
777
 
864
778
 
865
779
  /* Set of a stack for unget if long terminators */
866
 
  uint length=max(field_term_length,line_term_length)+1;
 
780
  uint32_t length=cmax(field_term_length,line_term_length)+1;
867
781
  set_if_bigger(length,line_start.length());
868
782
  stack=stack_pos=(int*) sql_alloc(sizeof(int)*length);
869
783
 
870
 
  if (!(buffer=(uchar*) my_malloc(buff_length+1,MYF(0))))
 
784
  if (!(buffer=(unsigned char*) malloc(buff_length+1)))
871
785
    error=1; /* purecov: inspected */
872
786
  else
873
787
  {
877
791
                      (is_fifo ? READ_FIFO : READ_CACHE),0L,1,
878
792
                      MYF(MY_WME)))
879
793
    {
880
 
      my_free((uchar*) buffer,MYF(0)); /* purecov: inspected */
 
794
      free((unsigned char*) buffer); /* purecov: inspected */
881
795
      error=1;
882
796
    }
883
797
    else
891
805
 
892
806
      if (get_it_from_net)
893
807
        cache.read_function = _my_b_net_read;
894
 
 
895
 
      if (mysql_bin_log.is_open())
896
 
        cache.pre_read = cache.pre_close =
897
 
          (IO_CACHE_CALLBACK) log_loaded_block;
898
808
    }
899
809
  }
900
810
}
906
816
  {
907
817
    if (need_end_io_cache)
908
818
      ::end_io_cache(&cache);
909
 
    my_free((uchar*) buffer,MYF(0));
 
819
    free((unsigned char*) buffer);
910
820
    error=1;
911
821
  }
912
822
}
916
826
#define PUSH(A) *(stack_pos++)=(A)
917
827
 
918
828
 
919
 
inline int READ_INFO::terminator(char *ptr,uint length)
 
829
inline int READ_INFO::terminator(char *ptr,uint32_t length)
920
830
{
921
831
  int chr=0;                                    // Keep gcc happy
922
 
  uint i;
 
832
  uint32_t i;
923
833
  for (i=1 ; i < length ; i++)
924
834
  {
925
835
    if ((chr=GET) != *++ptr)
931
841
    return 1;
932
842
  PUSH(chr);
933
843
  while (i-- > 1)
934
 
    PUSH((uchar) *--ptr);
 
844
    PUSH((unsigned char) *--ptr);
935
845
  return 0;
936
846
}
937
847
 
939
849
int READ_INFO::read_field()
940
850
{
941
851
  int chr,found_enclosed_char;
942
 
  uchar *to,*new_buffer;
 
852
  unsigned char *to,*new_buffer;
943
853
 
944
854
  found_null=0;
945
855
  if (found_end_of_line)
962
872
  if (chr == enclosed_char)
963
873
  {
964
874
    found_enclosed_char=enclosed_char;
965
 
    *to++=(uchar) chr;                          // If error
 
875
    *to++=(unsigned char) chr;                          // If error
966
876
  }
967
877
  else
968
878
  {
979
889
      if ((my_mbcharlen(read_charset, chr) > 1) &&
980
890
          to+my_mbcharlen(read_charset, chr) <= end_of_buff)
981
891
      {
982
 
          uchar* p = (uchar*)to;
 
892
          unsigned char* p = (unsigned char*)to;
983
893
          *to++ = chr;
984
894
          int ml = my_mbcharlen(read_charset, chr);
985
895
          int i;
994
904
                          (const char *)to))
995
905
            continue;
996
906
          for (i=0; i<ml; i++)
997
 
            PUSH((uchar) *--to);
 
907
            PUSH((unsigned char) *--to);
998
908
          chr = GET;
999
909
      }
1000
910
#endif
1004
914
      {
1005
915
        if ((chr=GET) == my_b_EOF)
1006
916
        {
1007
 
          *to++= (uchar) escape_char;
 
917
          *to++= (unsigned char) escape_char;
1008
918
          goto found_eof;
1009
919
        }
1010
920
        /*
1016
926
         */
1017
927
        if (escape_char != enclosed_char || chr == escape_char)
1018
928
        {
1019
 
          *to++ = (uchar) unescape((char) chr);
 
929
          *to++ = (unsigned char) unescape((char) chr);
1020
930
          continue;
1021
931
        }
1022
932
        PUSH(chr);
1041
951
      {
1042
952
        if ((chr=GET) == found_enclosed_char)
1043
953
        {                                       // Remove dupplicated
1044
 
          *to++ = (uchar) chr;
 
954
          *to++ = (unsigned char) chr;
1045
955
          continue;
1046
956
        }
1047
957
        // End of enclosed field if followed by field_term or line_term
1080
990
          return 0;
1081
991
        }
1082
992
      }
1083
 
      *to++ = (uchar) chr;
 
993
      *to++ = (unsigned char) chr;
1084
994
    }
1085
995
    /*
1086
996
    ** We come here if buffer is too small. Enlarge it and continue
1087
997
    */
1088
 
    if (!(new_buffer=(uchar*) my_realloc((char*) buffer,buff_length+1+IO_SIZE,
1089
 
                                        MYF(MY_WME))))
 
998
    if (!(new_buffer=(unsigned char*) realloc(buffer, buff_length+1+IO_SIZE)))
1090
999
      return (error=1);
1091
1000
    to=new_buffer + (to-buffer);
1092
1001
    buffer=new_buffer;
1120
1029
int READ_INFO::read_fixed_length()
1121
1030
{
1122
1031
  int chr;
1123
 
  uchar *to;
 
1032
  unsigned char *to;
1124
1033
  if (found_end_of_line)
1125
1034
    return 1;                                   // One have to call next_line
1126
1035
 
1140
1049
    {
1141
1050
      if ((chr=GET) == my_b_EOF)
1142
1051
      {
1143
 
        *to++= (uchar) escape_char;
 
1052
        *to++= (unsigned char) escape_char;
1144
1053
        goto found_eof;
1145
1054
      }
1146
 
      *to++ =(uchar) unescape((char) chr);
 
1055
      *to++ =(unsigned char) unescape((char) chr);
1147
1056
      continue;
1148
1057
    }
1149
1058
    if (chr == line_term_char)
1155
1064
        return 0;
1156
1065
      }
1157
1066
    }
1158
 
    *to++ = (uchar) chr;
 
1067
    *to++ = (unsigned char) chr;
1159
1068
  }
1160
1069
  row_end=to;                                   // Found full line
1161
1070
  return 0;
1186
1095
#ifdef USE_MB
1187
1096
   if (my_mbcharlen(read_charset, chr) > 1)
1188
1097
   {
1189
 
       for (uint i=1;
 
1098
       for (uint32_t i=1;
1190
1099
            chr != my_b_EOF && i<my_mbcharlen(read_charset, chr);
1191
1100
            i++)
1192
1101
           chr = GET;
1233
1142
      PUSH(chr);
1234
1143
      while (--ptr != line_start_ptr)
1235
1144
      {                                         // Restart with next char
1236
 
        PUSH((uchar) *ptr);
 
1145
        PUSH((unsigned char) *ptr);
1237
1146
      }
1238
1147
      goto try_again;
1239
1148
    }