~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_load.cc

  • Committer: Brian Aker
  • Date: 2009-01-21 05:53:36 UTC
  • mto: This revision was merged to the branch mainline in revision 801.
  • Revision ID: brian@tangent.org-20090121055336-fxoz6wfzreo8gi9x
Removed purge

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