~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_load.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-03-21 01:02:23 UTC
  • mto: (960.2.5 mordred)
  • mto: This revision was merged to the branch mainline in revision 961.
  • Revision ID: osullivan.padraig@gmail.com-20090321010223-j8cph7eeyt1u3xol
Fixed function object to ensure it correctly returns a boolean type since
memcmp returns an integer. Added some more comments.

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;
44
47
 
45
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
 
            String &enclosed,int escape,bool get_it_from_net, bool is_fifo);
 
50
            String &enclosed,int escape, bool is_fifo);
48
51
  ~READ_INFO();
49
52
  int read_field();
50
53
  int read_fixed_length(void);
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, TableList *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, TableList *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
102
101
      handle_duplicates - indicates whenever we should emit error or
103
102
                          replace row if we will meet duplicates.
104
103
      ignore -          - indicates whenever we should ignore duplicates
105
 
      read_file_from_client - is this LOAD DATA LOCAL ?
106
104
 
107
105
  RETURN VALUES
108
106
    true - error / false - success
109
107
*/
110
108
 
111
 
int mysql_load(THD *thd,sql_exchange *ex,TableList *table_list,
 
109
int mysql_load(Session *session,file_exchange *ex,TableList *table_list,
112
110
                List<Item> &fields_vars, List<Item> &set_fields,
113
111
                List<Item> &set_values,
114
 
                enum enum_duplicates handle_duplicates, bool ignore,
115
 
                bool read_file_from_client)
 
112
                enum enum_duplicates handle_duplicates, bool ignore)
116
113
{
117
114
  char name[FN_REFLEN];
118
115
  File file;
121
118
  String *field_term=ex->field_term,*escaped=ex->escaped;
122
119
  String *enclosed=ex->enclosed;
123
120
  bool is_fifo=0;
124
 
  LOAD_FILE_INFO lf_info;
125
 
  char *db = table_list->db;                    // This is never null
 
121
  char *db= table_list->db;                     // This is never null
 
122
  assert(db);
126
123
  /*
127
124
    If path for file is not defined, we will use the current database.
128
125
    If this is not set, we will use the directory where the table to be
129
126
    loaded is located
130
127
  */
131
 
  char *tdb= thd->db ? thd->db : db;            // Result is never null
 
128
  char *tdb= session->db ? session->db : db;            // Result is never null
 
129
  assert(tdb);
132
130
  uint32_t skip_lines= ex->skip_lines;
133
131
  bool transactional_table;
134
 
  THD::killed_state killed_status= THD::NOT_KILLED;
 
132
  Session::killed_state killed_status= Session::NOT_KILLED;
135
133
 
136
 
  if (escaped->length() > 1 || enclosed->length() > 1)
 
134
  /* Escape and enclosed character may be a utf8 4-byte character */
 
135
  if (escaped->length() > 4 || enclosed->length() > 4)
137
136
  {
138
 
    my_message(ER_WRONG_FIELD_TERMINATORS,ER(ER_WRONG_FIELD_TERMINATORS),
139
 
               MYF(0));
 
137
    my_error(ER_WRONG_FIELD_TERMINATORS,MYF(0),enclosed->c_ptr(), enclosed->length());
140
138
    return(true);
141
139
  }
142
 
  if (open_and_lock_tables(thd, table_list))
 
140
  if (open_and_lock_tables(session, table_list))
143
141
    return(true);
144
 
  if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
145
 
                                    &thd->lex->select_lex.top_join_list,
 
142
  if (setup_tables_and_check_access(session, &session->lex->select_lex.context,
 
143
                                    &session->lex->select_lex.top_join_list,
146
144
                                    table_list,
147
 
                                    &thd->lex->select_lex.leaf_tables, true))
 
145
                                    &session->lex->select_lex.leaf_tables, true))
148
146
     return(-1);
149
147
 
150
148
  /*
155
153
    table is marked to be 'used for insert' in which case we should never
156
154
    mark this table as 'const table' (ie, one that has only one row).
157
155
  */
158
 
  if (unique_table(thd, table_list, table_list->next_global, 0))
 
156
  if (unique_table(session, table_list, table_list->next_global, 0))
159
157
  {
160
158
    my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
161
159
    return(true);
175
173
      Let us also prepare SET clause, altough it is probably empty
176
174
      in this case.
177
175
    */
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))
 
176
    if (setup_fields(session, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
 
177
        setup_fields(session, 0, set_values, MARK_COLUMNS_READ, 0, 0))
180
178
      return(true);
181
179
  }
182
180
  else
183
181
  {                                             // Part field list
184
182
    /* 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))
 
183
    if (setup_fields(session, 0, fields_vars, MARK_COLUMNS_WRITE, 0, 0) ||
 
184
        setup_fields(session, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
 
185
        check_that_all_fields_are_given_values(session, table, table_list))
188
186
      return(true);
189
187
    /*
190
188
      Check whenever TIMESTAMP field with auto-set feature specified
202
200
      }
203
201
    }
204
202
    /* Fix the expressions in SET clause */
205
 
    if (setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0))
 
203
    if (setup_fields(session, 0, set_values, MARK_COLUMNS_READ, 0, 0))
206
204
      return(true);
207
205
  }
208
206
 
243
241
    return(true);
244
242
  }
245
243
 
246
 
  /* We can't give an error in the middle when using LOCAL files */
247
 
  if (read_file_from_client && handle_duplicates == DUP_ERROR)
248
 
    ignore= 1;
249
 
 
250
 
  if (read_file_from_client)
251
 
  {
252
 
    (void)net_request_file(&thd->net,ex->file_name);
253
 
    file = -1;
254
 
  }
255
 
  else
256
244
  {
257
245
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
258
246
    ex->file_name+=dirname_length(ex->file_name);
259
247
#endif
260
248
    if (!dirname_length(ex->file_name))
261
249
    {
262
 
      strxnmov(name, FN_REFLEN-1, mysql_real_data_home, tdb, NULL);
 
250
      strcpy(name, drizzle_real_data_home);
 
251
      strncat(name, tdb, FN_REFLEN-strlen(drizzle_real_data_home)-1);
263
252
      (void) fn_format(name, ex->file_name, name, "",
264
253
                       MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
265
254
    }
266
255
    else
267
256
    {
268
 
      (void) fn_format(name, ex->file_name, mysql_real_data_home, "",
 
257
      (void) fn_format(name, ex->file_name, drizzle_real_data_home, "",
269
258
                       MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
270
259
 
271
260
      if (opt_secure_file_priv &&
278
267
 
279
268
      struct stat stat_info;
280
269
      if (stat(name,&stat_info))
 
270
      {
 
271
        my_error(ER_FILE_NOT_FOUND, MYF(0), name, errno);
281
272
        return(true);
 
273
      }
282
274
 
283
275
      // 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)))
 
276
      if (!((stat_info.st_mode & S_IROTH) == S_IROTH &&  // readable by others
 
277
            (stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
 
278
            ((stat_info.st_mode & S_IFREG) == S_IFREG ||
 
279
             (stat_info.st_mode & S_IFIFO) == S_IFIFO)))
289
280
      {
290
281
        my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name);
291
282
        return(true);
294
285
        is_fifo = 1;
295
286
    }
296
287
    if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0)
 
288
    {
 
289
      my_error(ER_CANT_OPEN_FILE, MYF(0), name, my_errno);
297
290
      return(true);
 
291
    }
298
292
  }
299
293
 
300
294
  COPY_INFO info;
304
298
  info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX;
305
299
 
306
300
  READ_INFO read_info(file,tot_length,
307
 
                      ex->cs ? ex->cs : thd->variables.collation_database,
 
301
                      ex->cs ? ex->cs : session->variables.collation_database,
308
302
                      *field_term,*ex->line_start, *ex->line_term, *enclosed,
309
 
                      info.escape_char, read_file_from_client, is_fifo);
 
303
                      info.escape_char, is_fifo);
310
304
  if (read_info.error)
311
305
  {
312
306
    if  (file >= 0)
314
308
    return(true);                               // Can't allocate buffers
315
309
  }
316
310
 
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;
 
311
  /*
 
312
   * Per the SQL standard, inserting NULL into a NOT NULL
 
313
   * field requires an error to be thrown.
 
314
   *
 
315
   * @NOTE
 
316
   *
 
317
   * NULL check and handling occurs in field_conv.cc
 
318
   */
 
319
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
 
320
  session->cuted_fields=0L;
328
321
  /* Skip lines if there is a line terminator */
329
322
  if (ex->line_term->length())
330
323
  {
349
342
    table->file->ha_start_bulk_insert((ha_rows) 0);
350
343
    table->copy_blobs=1;
351
344
 
352
 
    thd->abort_on_warning= true;
 
345
    session->abort_on_warning= true;
353
346
 
354
347
    if (!field_term->length() && !enclosed->length())
355
 
      error= read_fixed_length(thd, info, table_list, fields_vars,
 
348
      error= read_fixed_length(session, info, table_list, fields_vars,
356
349
                               set_fields, set_values, read_info,
357
350
                               skip_lines, ignore);
358
351
    else
359
 
      error= read_sep_field(thd, info, table_list, fields_vars,
 
352
      error= read_sep_field(session, info, table_list, fields_vars,
360
353
                            set_fields, set_values, read_info,
361
354
                            *enclosed, skip_lines, ignore);
362
355
    if (table->file->ha_end_bulk_insert() && !error)
372
365
    my_close(file,MYF(0));
373
366
  free_blobs(table);                            /* if pack_blob was used */
374
367
  table->copy_blobs=0;
375
 
  thd->count_cuted_fields= CHECK_FIELD_IGNORE;
376
 
  /* 
 
368
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
 
369
  /*
377
370
     simulated killing in the middle of per-row loop
378
371
     must be effective for binlogging
379
372
  */
380
 
  killed_status= (error == 0)? THD::NOT_KILLED : thd->killed;
 
373
  killed_status= (error == 0)? Session::NOT_KILLED : session->killed;
381
374
  if (error)
382
375
  {
383
 
    if (read_file_from_client)
384
 
      while (!read_info.next_line())
385
 
        ;
386
 
 
387
 
    if (mysql_bin_log.is_open())
388
 
    {
389
 
      {
390
 
        /*
391
 
          Make sure last block (the one which caused the error) gets
392
 
          logged.  This is needed because otherwise after write of (to
393
 
          the binlog, not to read_info (which is a cache))
394
 
          Delete_file_log_event the bad block will remain in read_info
395
 
          (because pre_read is not called at the end of the last
396
 
          block; remember pre_read is called whenever a new block is
397
 
          read from disk).  At the end of mysql_load(), the destructor
398
 
          of read_info will call end_io_cache() which will flush
399
 
          read_info, so we will finally have this in the binlog:
400
 
 
401
 
          Append_block # The last successfull block
402
 
          Delete_file
403
 
          Append_block # The failing block
404
 
          which is nonsense.
405
 
          Or could also be (for a small file)
406
 
          Create_file  # The failing block
407
 
          which is nonsense (Delete_file is not written in this case, because:
408
 
          Create_file has not been written, so Delete_file is not written, then
409
 
          when read_info is destroyed end_io_cache() is called which writes
410
 
          Create_file.
411
 
        */
412
 
        read_info.end_io_cache();
413
 
        /* If the file was not empty, wrote_create_file is true */
414
 
        if (lf_info.wrote_create_file)
415
 
        {
416
 
          if (thd->transaction.stmt.modified_non_trans_table)
417
 
            write_execute_load_query_log_event(thd, handle_duplicates,
418
 
                                               ignore, transactional_table,
419
 
                                               killed_status);
420
 
          else
421
 
          {
422
 
            Delete_file_log_event d(thd, db, transactional_table);
423
 
            d.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
424
 
            mysql_bin_log.write(&d);
425
 
          }
426
 
        }
427
 
      }
428
 
    }
429
376
    error= -1;                          // Error on read
430
377
    goto err;
431
378
  }
432
379
  sprintf(name, ER(ER_LOAD_INFO), (uint32_t) info.records, (uint32_t) info.deleted,
433
 
          (uint32_t) (info.records - info.copied), (uint32_t) thd->cuted_fields);
434
 
 
435
 
  if (thd->transaction.stmt.modified_non_trans_table)
436
 
    thd->transaction.all.modified_non_trans_table= true;
437
 
 
438
 
  if (mysql_bin_log.is_open())
439
 
  {
440
 
    /*
441
 
      We need to do the job that is normally done inside
442
 
      binlog_query() here, which is to ensure that the pending event
443
 
      is written before tables are unlocked and before any other
444
 
      events are written.  We also need to update the table map
445
 
      version for the binary log to mark that table maps are invalid
446
 
      after this point.
447
 
     */
448
 
    if (thd->current_stmt_binlog_row_based)
449
 
      thd->binlog_flush_pending_rows_event(true);
450
 
    else
451
 
    {
452
 
      /*
453
 
        As already explained above, we need to call end_io_cache() or the last
454
 
        block will be logged only after Execute_load_query_log_event (which is
455
 
        wrong), when read_info is destroyed.
456
 
      */
457
 
      read_info.end_io_cache();
458
 
      if (lf_info.wrote_create_file)
459
 
      {
460
 
        write_execute_load_query_log_event(thd, handle_duplicates, ignore,
461
 
                                           transactional_table,killed_status);
462
 
      }
463
 
    }
464
 
  }
 
380
          (uint32_t) (info.records - info.copied), (uint32_t) session->cuted_fields);
 
381
 
 
382
  if (session->transaction.stmt.modified_non_trans_table)
 
383
    session->transaction.all.modified_non_trans_table= true;
465
384
 
466
385
  /* ok to client sent only after binlog write and engine commit */
467
 
  my_ok(thd, info.copied + info.deleted, 0L, name);
 
386
  session->my_ok(info.copied + info.deleted, 0L, name);
468
387
err:
469
388
  assert(transactional_table || !(info.copied || info.deleted) ||
470
 
              thd->transaction.stmt.modified_non_trans_table);
 
389
              session->transaction.stmt.modified_non_trans_table);
471
390
  table->file->ha_release_auto_increment();
472
391
  table->auto_increment_field_not_null= false;
473
 
  thd->abort_on_warning= 0;
 
392
  session->abort_on_warning= 0;
474
393
  return(error);
475
394
}
476
395
 
477
396
 
478
 
/* Not a very useful function; just to avoid duplication of code */
479
 
static bool write_execute_load_query_log_event(THD *thd,
480
 
                                               bool duplicates, bool ignore,
481
 
                                               bool transactional_table,
482
 
                                               THD::killed_state killed_err_arg)
483
 
{
484
 
  Execute_load_query_log_event
485
 
    e(thd, thd->query, thd->query_length,
486
 
      (char*)thd->lex->fname_start - (char*)thd->query,
487
 
      (char*)thd->lex->fname_end - (char*)thd->query,
488
 
      (duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
489
 
      (ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
490
 
      transactional_table, false, killed_err_arg);
491
 
  e.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
492
 
  return mysql_bin_log.write(&e);
493
 
}
494
 
 
495
 
 
496
397
/****************************************************************************
497
398
** Read of rows of fixed size + optional garage + optonal newline
498
399
****************************************************************************/
499
400
 
500
401
static int
501
 
read_fixed_length(THD *thd, COPY_INFO &info, TableList *table_list,
 
402
read_fixed_length(Session *session, COPY_INFO &info, TableList *table_list,
502
403
                  List<Item> &fields_vars, List<Item> &set_fields,
503
404
                  List<Item> &set_values, READ_INFO &read_info,
504
405
                  uint32_t skip_lines, bool ignore_check_option_errors)
510
411
  bool err;
511
412
 
512
413
  id= 0;
513
 
 
 
414
 
514
415
  while (!read_info.read_fixed_length())
515
416
  {
516
 
    if (thd->killed)
 
417
    if (session->killed)
517
418
    {
518
 
      thd->send_kill_message();
 
419
      session->send_kill_message();
519
420
      return(1);
520
421
    }
521
422
    if (skip_lines)
542
443
    */
543
444
    while ((sql_field= (Item_field*) it++))
544
445
    {
545
 
      Field *field= sql_field->field;                  
 
446
      Field *field= sql_field->field;
546
447
      if (field == table->next_number_field)
547
448
        table->auto_increment_field_not_null= true;
548
449
      /*
554
455
 
555
456
      if (pos == read_info.row_end)
556
457
      {
557
 
        thd->cuted_fields++;                    /* Not enough fields */
558
 
        push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 
559
 
                            ER_WARN_TOO_FEW_RECORDS, 
560
 
                            ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
 
458
        session->cuted_fields++;                        /* Not enough fields */
 
459
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
460
                            ER_WARN_TOO_FEW_RECORDS,
 
461
                            ER(ER_WARN_TOO_FEW_RECORDS), session->row_count);
561
462
        if (!field->maybe_null() && field->type() == DRIZZLE_TYPE_TIMESTAMP)
562
463
            ((Field_timestamp*) field)->set_time();
563
464
      }
565
466
      {
566
467
        uint32_t length;
567
468
        unsigned char save_chr;
568
 
        if ((length=(uint) (read_info.row_end-pos)) >
 
469
        if ((length=(uint32_t) (read_info.row_end-pos)) >
569
470
            field->field_length)
570
471
          length=field->field_length;
571
472
        save_chr=pos[length]; pos[length]='\0'; // Safeguard aganst malloc
577
478
    }
578
479
    if (pos != read_info.row_end)
579
480
    {
580
 
      thd->cuted_fields++;                      /* To long row */
581
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 
582
 
                          ER_WARN_TOO_MANY_RECORDS, 
583
 
                          ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count); 
 
481
      session->cuted_fields++;                  /* To long row */
 
482
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
483
                          ER_WARN_TOO_MANY_RECORDS,
 
484
                          ER(ER_WARN_TOO_MANY_RECORDS), session->row_count);
584
485
    }
585
486
 
586
 
    if (thd->killed ||
587
 
        fill_record(thd, set_fields, set_values,
 
487
    if (session->killed ||
 
488
        fill_record(session, set_fields, set_values,
588
489
                    ignore_check_option_errors))
589
490
      return(1);
590
491
 
591
 
    err= write_record(thd, table, &info);
 
492
    err= write_record(session, table, &info);
592
493
    table->auto_increment_field_not_null= false;
593
494
    if (err)
594
495
      return(1);
595
 
   
 
496
 
596
497
    /*
597
498
      We don't need to reset auto-increment field since we are restoring
598
499
      its default value at the beginning of each loop iteration.
601
502
      break;
602
503
    if (read_info.line_cuted)
603
504
    {
604
 
      thd->cuted_fields++;                      /* To long row */
605
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 
606
 
                          ER_WARN_TOO_MANY_RECORDS, 
607
 
                          ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count); 
 
505
      session->cuted_fields++;                  /* To long row */
 
506
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
507
                          ER_WARN_TOO_MANY_RECORDS,
 
508
                          ER(ER_WARN_TOO_MANY_RECORDS), session->row_count);
608
509
    }
609
 
    thd->row_count++;
 
510
    session->row_count++;
610
511
  }
611
512
  return(test(read_info.error));
612
513
}
614
515
 
615
516
 
616
517
static int
617
 
read_sep_field(THD *thd, COPY_INFO &info, TableList *table_list,
 
518
read_sep_field(Session *session, COPY_INFO &info, TableList *table_list,
618
519
               List<Item> &fields_vars, List<Item> &set_fields,
619
520
               List<Item> &set_values, READ_INFO &read_info,
620
521
               String &enclosed, uint32_t skip_lines,
632
533
 
633
534
  for (;;it.rewind())
634
535
  {
635
 
    if (thd->killed)
 
536
    if (session->killed)
636
537
    {
637
 
      thd->send_kill_message();
 
538
      session->send_kill_message();
638
539
      return(1);
639
540
    }
640
541
 
654
555
        continue;
655
556
 
656
557
      pos=read_info.row_start;
657
 
      length=(uint) (read_info.row_end-pos);
 
558
      length=(uint32_t) (read_info.row_end-pos);
658
559
 
659
560
      real_item= item->real_item();
660
561
 
668
569
          if (field->reset())
669
570
          {
670
571
            my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name,
671
 
                     thd->row_count);
 
572
                     session->row_count);
672
573
            return(1);
673
574
          }
674
575
          field->set_null();
736
637
          if (field->reset())
737
638
          {
738
639
            my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),field->field_name,
739
 
                     thd->row_count);
 
640
                     session->row_count);
740
641
            return(1);
741
642
          }
742
643
          if (!field->maybe_null() && field->type() == DRIZZLE_TYPE_TIMESTAMP)
744
645
          /*
745
646
            QQ: We probably should not throw warning for each field.
746
647
            But how about intention to always have the same number
747
 
            of warnings in THD::cuted_fields (and get rid of cuted_fields
 
648
            of warnings in Session::cuted_fields (and get rid of cuted_fields
748
649
            in the end ?)
749
650
          */
750
 
          thd->cuted_fields++;
751
 
          push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
651
          session->cuted_fields++;
 
652
          push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
752
653
                              ER_WARN_TOO_FEW_RECORDS,
753
 
                              ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
 
654
                              ER(ER_WARN_TOO_FEW_RECORDS), session->row_count);
754
655
        }
755
656
        else if (item->type() == Item::STRING_ITEM)
756
657
        {
765
666
      }
766
667
    }
767
668
 
768
 
    if (thd->killed ||
769
 
        fill_record(thd, set_fields, set_values,
 
669
    if (session->killed ||
 
670
        fill_record(session, set_fields, set_values,
770
671
                    ignore_check_option_errors))
771
672
      return(1);
772
673
 
773
 
    err= write_record(thd, table, &info);
 
674
    err= write_record(session, table, &info);
774
675
    table->auto_increment_field_not_null= false;
775
676
    if (err)
776
677
      return(1);
782
683
      break;
783
684
    if (read_info.line_cuted)
784
685
    {
785
 
      thd->cuted_fields++;                      /* To long row */
786
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN, 
787
 
                          ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS), 
788
 
                          thd->row_count);   
789
 
      if (thd->killed)
 
686
      session->cuted_fields++;                  /* To long row */
 
687
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
688
                          ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS),
 
689
                          session->row_count);
 
690
      if (session->killed)
790
691
        return(1);
791
692
    }
792
 
    thd->row_count++;
 
693
    session->row_count++;
793
694
  }
794
695
  return(test(read_info.error));
795
696
}
824
725
 
825
726
READ_INFO::READ_INFO(File file_par, uint32_t tot_length, const CHARSET_INFO * const cs,
826
727
                     String &field_term, String &line_start, String &line_term,
827
 
                     String &enclosed_par, int escape, bool get_it_from_net,
828
 
                     bool is_fifo)
 
728
                     String &enclosed_par, int escape, bool is_fifo)
829
729
  :file(file_par),escape_char(escape)
830
730
{
831
731
  read_charset= cs;
864
764
  set_if_bigger(length,line_start.length());
865
765
  stack=stack_pos=(int*) sql_alloc(sizeof(int)*length);
866
766
 
867
 
  if (!(buffer=(unsigned char*) my_malloc(buff_length+1,MYF(0))))
 
767
  if (!(buffer=(unsigned char*) malloc(buff_length+1)))
868
768
    error=1; /* purecov: inspected */
869
769
  else
870
770
  {
871
771
    end_of_buff=buffer+buff_length;
872
 
    if (init_io_cache(&cache,(get_it_from_net) ? -1 : file, 0,
873
 
                      (get_it_from_net) ? READ_NET :
 
772
    if (init_io_cache(&cache,(false) ? -1 : file, 0,
 
773
                      (false) ? READ_NET :
874
774
                      (is_fifo ? READ_FIFO : READ_CACHE),0L,1,
875
775
                      MYF(MY_WME)))
876
776
    {
885
785
        manual assignment
886
786
      */
887
787
      need_end_io_cache = 1;
888
 
 
889
 
      if (get_it_from_net)
890
 
        cache.read_function = _my_b_net_read;
891
 
 
892
 
      if (mysql_bin_log.is_open())
893
 
        cache.pre_read = cache.pre_close =
894
 
          (IO_CACHE_CALLBACK) log_loaded_block;
895
788
    }
896
789
  }
897
790
}
1082
975
    /*
1083
976
    ** We come here if buffer is too small. Enlarge it and continue
1084
977
    */
1085
 
    if (!(new_buffer=(unsigned char*) my_realloc((char*) buffer,buff_length+1+IO_SIZE,
1086
 
                                        MYF(MY_WME))))
 
978
    if (!(new_buffer=(unsigned char*) realloc(buffer, buff_length+1+IO_SIZE)))
1087
979
      return (error=1);
1088
980
    to=new_buffer + (to-buffer);
1089
981
    buffer=new_buffer;