~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_load.cc

  • Committer: Brian Aker
  • Date: 2009-08-17 01:44:23 UTC
  • mto: This revision was merged to the branch mainline in revision 1118.
  • Revision ID: brian@gaz-20090817014423-jxi2qonsumm8mndf
Remove SQL level reference for DELAY (just now done correctly by default in
engine).

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/* Copy data from a textfile to table */
18
18
 
19
 
#include "config.h"
20
 
 
 
19
#include <drizzled/server_includes.h>
21
20
#include <drizzled/sql_load.h>
22
21
#include <drizzled/error.h>
23
22
#include <drizzled/data_home.h>
24
23
#include <drizzled/session.h>
25
24
#include <drizzled/sql_base.h>
26
 
#include <drizzled/field/epoch.h>
27
 
#include "drizzled/internal/my_sys.h"
28
 
#include "drizzled/internal/iocache.h"
29
 
#include <drizzled/db.h>
30
 
#include "drizzled/plugin/storage_engine.h"
 
25
#include <drizzled/field/timestamp.h>
31
26
 
32
 
#include <sys/stat.h>
33
 
#include <fcntl.h>
34
27
#include <algorithm>
35
 
#include <climits>
36
 
#include <boost/filesystem.hpp>
37
28
 
38
 
namespace fs=boost::filesystem;
39
29
using namespace std;
40
 
namespace drizzled
41
 
{
42
30
 
43
31
class READ_INFO {
44
 
  int   cursor;
 
32
  File  file;
45
33
  unsigned char *buffer;                /* Buffer for read text */
46
34
  unsigned char *end_of_buff;           /* Data in bufferts ends here */
47
35
  size_t buff_length;                   /* Length of buffert */
52
40
  int   *stack,*stack_pos;
53
41
  bool  found_end_of_line,start_of_line,eof;
54
42
  bool  need_end_io_cache;
55
 
  internal::IO_CACHE cache;
 
43
  IO_CACHE cache;
56
44
 
57
45
public:
58
46
  bool error,line_cuted,found_null,enclosed;
60
48
        *row_end;                       /* Found row ends here */
61
49
  const CHARSET_INFO *read_charset;
62
50
 
63
 
  READ_INFO(int cursor, size_t tot_length, const CHARSET_INFO * const cs,
 
51
  READ_INFO(File file, size_t tot_length, const CHARSET_INFO * const cs,
64
52
            String &field_term,String &line_start,String &line_term,
65
53
            String &enclosed,int escape, bool is_fifo);
66
54
  ~READ_INFO();
77
65
  */
78
66
  void end_io_cache()
79
67
  {
80
 
    cache.end_io_cache();
 
68
    ::end_io_cache(&cache);
81
69
    need_end_io_cache = 0;
82
70
  }
83
71
 
84
72
  /*
85
73
    Either this method, or we need to make cache public
86
 
    Arg must be set from load() since constructor does not see
 
74
    Arg must be set from mysql_load() since constructor does not see
87
75
    either the table or Session value
88
76
  */
89
77
  void set_io_cache_arg(void* arg) { cache.arg = arg; }
90
78
};
91
79
 
92
 
static int read_fixed_length(Session *session, CopyInfo &info, TableList *table_list,
 
80
static int read_fixed_length(Session *session, COPY_INFO &info, TableList *table_list,
93
81
                             List<Item> &fields_vars, List<Item> &set_fields,
94
82
                             List<Item> &set_values, READ_INFO &read_info,
95
83
                             uint32_t skip_lines,
96
84
                             bool ignore_check_option_errors);
97
 
static int read_sep_field(Session *session, CopyInfo &info, TableList *table_list,
 
85
static int read_sep_field(Session *session, COPY_INFO &info, TableList *table_list,
98
86
                          List<Item> &fields_vars, List<Item> &set_fields,
99
87
                          List<Item> &set_values, READ_INFO &read_info,
100
88
                          String &enclosed, uint32_t skip_lines,
105
93
  Execute LOAD DATA query
106
94
 
107
95
  SYNOPSYS
108
 
    load()
 
96
    mysql_load()
109
97
      session - current thread
110
 
      ex  - file_exchange object representing source cursor and its parsing rules
 
98
      ex  - file_exchange object representing source file and its parsing rules
111
99
      table_list  - list of tables to which we are loading data
112
100
      fields_vars - list of fields and variables to which we read
113
 
                    data from cursor
 
101
                    data from file
114
102
      set_fields  - list of fields mentioned in set clause
115
103
      set_values  - expressions to assign to fields in previous list
116
104
      handle_duplicates - indicates whenever we should emit error or
121
109
    true - error / false - success
122
110
*/
123
111
 
124
 
int load(Session *session,file_exchange *ex,TableList *table_list,
 
112
int mysql_load(Session *session,file_exchange *ex,TableList *table_list,
125
113
                List<Item> &fields_vars, List<Item> &set_fields,
126
114
                List<Item> &set_values,
127
115
                enum enum_duplicates handle_duplicates, bool ignore)
128
116
{
129
 
  int file;
 
117
  char name[FN_REFLEN];
 
118
  File file;
130
119
  Table *table= NULL;
131
120
  int error;
132
121
  String *field_term=ex->field_term,*escaped=ex->escaped;
133
122
  String *enclosed=ex->enclosed;
134
123
  bool is_fifo=0;
135
 
 
136
 
  assert(table_list->getSchemaName()); // This should never be null
137
 
 
 
124
  char *db= table_list->db;                     // This is never null
 
125
  assert(db);
138
126
  /*
139
 
    If path for cursor is not defined, we will use the current database.
 
127
    If path for file is not defined, we will use the current database.
140
128
    If this is not set, we will use the directory where the table to be
141
129
    loaded is located
142
130
  */
143
 
  util::string::const_shared_ptr schema(session->schema());
144
 
  const char *tdb= (schema and not schema->empty()) ? schema->c_str() : table_list->getSchemaName(); // Result should never be null
 
131
  char *tdb= session->db ? session->db : db;            // Result is never null
145
132
  assert(tdb);
146
133
  uint32_t skip_lines= ex->skip_lines;
147
134
  bool transactional_table;
148
 
  Session::killed_state_t killed_status= Session::NOT_KILLED;
 
135
  Session::killed_state killed_status= Session::NOT_KILLED;
149
136
 
150
137
  /* Escape and enclosed character may be a utf8 4-byte character */
151
138
  if (escaped->length() > 4 || enclosed->length() > 4)
171
158
    table is marked to be 'used for insert' in which case we should never
172
159
    mark this table as 'const table' (ie, one that has only one row).
173
160
  */
174
 
  if (unique_table(table_list, table_list->next_global))
 
161
  if (unique_table(session, table_list, table_list->next_global, 0))
175
162
  {
176
 
    my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->getTableName());
 
163
    my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
177
164
    return(true);
178
165
  }
179
166
 
180
167
  table= table_list->table;
181
 
  transactional_table= table->cursor->has_transactions();
 
168
  transactional_table= table->file->has_transactions();
182
169
 
183
170
  if (!fields_vars.elements)
184
171
  {
185
172
    Field **field;
186
 
    for (field= table->getFields(); *field ; field++)
 
173
    for (field=table->field; *field ; field++)
187
174
      fields_vars.push_back(new Item_field(*field));
188
175
    table->setWriteSet();
189
176
    table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
208
195
    */
209
196
    if (table->timestamp_field)
210
197
    {
211
 
      if (table->isWriteSet(table->timestamp_field->position()))
212
 
      {
 
198
      if (table->isWriteSet(table->timestamp_field->field_index))
213
199
        table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
214
 
      }
215
200
      else
216
201
      {
217
 
        table->setWriteSet(table->timestamp_field->position());
 
202
        table->setWriteSet(table->timestamp_field->field_index);
218
203
      }
219
204
    }
220
205
    /* Fix the expressions in SET clause */
259
244
    return(true);
260
245
  }
261
246
 
262
 
  fs::path to_file(ex->file_name);
263
 
  fs::path target_path(fs::system_complete(getDataHomeCatalog()));
264
 
  if (not to_file.has_root_directory())
265
 
  {
266
 
    int count_elements= 0;
267
 
    for (fs::path::iterator iter= to_file.begin();
268
 
         iter != to_file.end();
269
 
         ++iter, ++count_elements)
270
 
    { }
271
 
 
272
 
    if (count_elements == 1)
273
 
    {
274
 
      target_path /= tdb;
275
 
    }
276
 
    target_path /= to_file;
277
 
  }
278
 
  else
279
 
  {
280
 
    target_path= to_file;
281
 
  }
282
 
 
283
 
  if (not secure_file_priv.string().empty())
284
 
  {
285
 
    if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
286
 
    {
287
 
      /* Read only allowed from within dir specified by secure_file_priv */
288
 
      my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
 
247
  {
 
248
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
 
249
    ex->file_name+=dirname_length(ex->file_name);
 
250
#endif
 
251
    if (!dirname_length(ex->file_name))
 
252
    {
 
253
      strcpy(name, drizzle_real_data_home);
 
254
      strncat(name, tdb, FN_REFLEN-strlen(drizzle_real_data_home)-1);
 
255
      (void) fn_format(name, ex->file_name, name, "",
 
256
                       MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
 
257
    }
 
258
    else
 
259
    {
 
260
      (void) fn_format(name, ex->file_name, drizzle_real_data_home, "",
 
261
                       MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
 
262
 
 
263
      if (opt_secure_file_priv &&
 
264
          strncmp(opt_secure_file_priv, name, strlen(opt_secure_file_priv)))
 
265
      {
 
266
        /* Read only allowed from within dir specified by secure_file_priv */
 
267
        my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
 
268
        return(true);
 
269
      }
 
270
 
 
271
      struct stat stat_info;
 
272
      if (stat(name,&stat_info))
 
273
      {
 
274
        my_error(ER_FILE_NOT_FOUND, MYF(0), name, errno);
 
275
        return(true);
 
276
      }
 
277
 
 
278
      // if we are not in slave thread, the file must be:
 
279
      if (!((stat_info.st_mode & S_IROTH) == S_IROTH &&  // readable by others
 
280
            (stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
 
281
            ((stat_info.st_mode & S_IFREG) == S_IFREG ||
 
282
             (stat_info.st_mode & S_IFIFO) == S_IFIFO)))
 
283
      {
 
284
        my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name);
 
285
        return(true);
 
286
      }
 
287
      if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
 
288
        is_fifo = 1;
 
289
    }
 
290
    if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0)
 
291
    {
 
292
      my_error(ER_CANT_OPEN_FILE, MYF(0), name, my_errno);
289
293
      return(true);
290
294
    }
291
295
  }
292
296
 
293
 
  struct stat stat_info;
294
 
  if (stat(target_path.file_string().c_str(), &stat_info))
295
 
  {
296
 
    my_error(ER_FILE_NOT_FOUND, MYF(0), target_path.file_string().c_str(), errno);
297
 
    return(true);
298
 
  }
299
 
 
300
 
  // if we are not in slave thread, the cursor must be:
301
 
  if (!((stat_info.st_mode & S_IROTH) == S_IROTH &&  // readable by others
302
 
        (stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
303
 
        ((stat_info.st_mode & S_IFREG) == S_IFREG ||
304
 
         (stat_info.st_mode & S_IFIFO) == S_IFIFO)))
305
 
  {
306
 
    my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), target_path.file_string().c_str());
307
 
    return(true);
308
 
  }
309
 
  if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
310
 
    is_fifo = 1;
311
 
 
312
 
 
313
 
  if ((file=internal::my_open(target_path.file_string().c_str(), O_RDONLY,MYF(MY_WME))) < 0)
314
 
  {
315
 
    my_error(ER_CANT_OPEN_FILE, MYF(0), target_path.file_string().c_str(), errno);
316
 
    return(true);
317
 
  }
318
 
  CopyInfo info;
 
297
  COPY_INFO info;
319
298
  memset(&info, 0, sizeof(info));
320
299
  info.ignore= ignore;
321
300
  info.handle_duplicates=handle_duplicates;
322
301
  info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX;
323
302
 
324
 
  identifier::Schema identifier(*schema);
325
303
  READ_INFO read_info(file, tot_length,
326
 
                      ex->cs ? ex->cs : plugin::StorageEngine::getSchemaCollation(identifier),
327
 
                      *field_term, *ex->line_start, *ex->line_term, *enclosed,
 
304
                      ex->cs ? ex->cs : get_default_db_collation(session->db),
 
305
                      *field_term,*ex->line_start, *ex->line_term, *enclosed,
328
306
                      info.escape_char, is_fifo);
329
307
  if (read_info.error)
330
308
  {
331
309
    if  (file >= 0)
332
 
      internal::my_close(file,MYF(0));                  // no files in net reading
 
310
      my_close(file,MYF(0));                    // no files in net reading
333
311
    return(true);                               // Can't allocate buffers
334
312
  }
335
313
 
361
339
    table->next_number_field=table->found_next_number_field;
362
340
    if (ignore ||
363
341
        handle_duplicates == DUP_REPLACE)
364
 
      table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
342
      table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
365
343
    if (handle_duplicates == DUP_REPLACE)
366
 
        table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
367
 
    table->cursor->ha_start_bulk_insert((ha_rows) 0);
 
344
        table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
 
345
    table->file->ha_start_bulk_insert((ha_rows) 0);
368
346
    table->copy_blobs=1;
369
347
 
370
 
    session->setAbortOnWarning(true);
 
348
    session->abort_on_warning= true;
371
349
 
372
350
    if (!field_term->length() && !enclosed->length())
373
351
      error= read_fixed_length(session, info, table_list, fields_vars,
377
355
      error= read_sep_field(session, info, table_list, fields_vars,
378
356
                            set_fields, set_values, read_info,
379
357
                            *enclosed, skip_lines, ignore);
380
 
    if (table->cursor->ha_end_bulk_insert() && !error)
 
358
    if (table->file->ha_end_bulk_insert() && !error)
381
359
    {
382
 
      table->print_error(errno, MYF(0));
 
360
      table->file->print_error(my_errno, MYF(0));
383
361
      error= 1;
384
362
    }
385
 
    table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
386
 
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
 
363
    table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
364
    table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
387
365
    table->next_number_field=0;
388
366
  }
389
367
  if (file >= 0)
390
 
    internal::my_close(file,MYF(0));
 
368
    my_close(file,MYF(0));
391
369
  free_blobs(table);                            /* if pack_blob was used */
392
370
  table->copy_blobs=0;
393
 
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
 
371
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
394
372
  /*
395
373
     simulated killing in the middle of per-row loop
396
374
     must be effective for binlogging
397
375
  */
398
 
  killed_status= (error == 0)? Session::NOT_KILLED : session->getKilled();
 
376
  killed_status= (error == 0)? Session::NOT_KILLED : session->killed;
399
377
  if (error)
400
378
  {
401
379
    error= -1;                          // Error on read
402
380
    goto err;
403
381
  }
404
 
 
405
 
  char msg[FN_REFLEN];
406
 
  snprintf(msg, sizeof(msg), ER(ER_LOAD_INFO), info.records, info.deleted,
407
 
           (info.records - info.copied), session->cuted_fields);
408
 
 
409
 
  if (session->transaction.stmt.hasModifiedNonTransData())
410
 
    session->transaction.all.markModifiedNonTransData();
 
382
  sprintf(name, ER(ER_LOAD_INFO), (uint32_t) info.records, (uint32_t) info.deleted,
 
383
          (uint32_t) (info.records - info.copied), (uint32_t) session->cuted_fields);
 
384
 
 
385
  if (session->transaction.stmt.modified_non_trans_table)
 
386
    session->transaction.all.modified_non_trans_table= true;
411
387
 
412
388
  /* ok to client sent only after binlog write and engine commit */
413
 
  session->my_ok(info.copied + info.deleted, 0, 0L, msg);
 
389
  session->my_ok(info.copied + info.deleted, 0, 0L, name);
414
390
err:
415
391
  assert(transactional_table || !(info.copied || info.deleted) ||
416
 
              session->transaction.stmt.hasModifiedNonTransData());
417
 
  table->cursor->ha_release_auto_increment();
 
392
              session->transaction.stmt.modified_non_trans_table);
 
393
  table->file->ha_release_auto_increment();
418
394
  table->auto_increment_field_not_null= false;
419
 
  session->setAbortOnWarning(false);
420
 
 
 
395
  session->abort_on_warning= 0;
421
396
  return(error);
422
397
}
423
398
 
427
402
****************************************************************************/
428
403
 
429
404
static int
430
 
read_fixed_length(Session *session, CopyInfo &info, TableList *table_list,
 
405
read_fixed_length(Session *session, COPY_INFO &info, TableList *table_list,
431
406
                  List<Item> &fields_vars, List<Item> &set_fields,
432
407
                  List<Item> &set_values, READ_INFO &read_info,
433
408
                  uint32_t skip_lines, bool ignore_check_option_errors)
442
417
 
443
418
  while (!read_info.read_fixed_length())
444
419
  {
445
 
    if (session->getKilled())
 
420
    if (session->killed)
446
421
    {
447
422
      session->send_kill_message();
448
423
      return(1);
460
435
    }
461
436
    it.rewind();
462
437
    unsigned char *pos=read_info.row_start;
463
 
#ifdef HAVE_VALGRIND
 
438
#ifdef HAVE_purify
464
439
    read_info.row_end[0]=0;
465
440
#endif
466
441
 
487
462
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
488
463
                            ER_WARN_TOO_FEW_RECORDS,
489
464
                            ER(ER_WARN_TOO_FEW_RECORDS), session->row_count);
490
 
 
491
 
        if (not field->maybe_null() and field->is_timestamp())
492
 
            ((field::Epoch::pointer) field)->set_time();
 
465
        if (!field->maybe_null() && field->type() == DRIZZLE_TYPE_TIMESTAMP)
 
466
            ((Field_timestamp*) field)->set_time();
493
467
      }
494
468
      else
495
469
      {
516
490
                          ER(ER_WARN_TOO_MANY_RECORDS), session->row_count);
517
491
    }
518
492
 
519
 
    if (session->getKilled() ||
 
493
    if (session->killed ||
520
494
        fill_record(session, set_fields, set_values,
521
495
                    ignore_check_option_errors))
522
496
      return(1);
547
521
 
548
522
 
549
523
static int
550
 
read_sep_field(Session *session, CopyInfo &info, TableList *table_list,
 
524
read_sep_field(Session *session, COPY_INFO &info, TableList *table_list,
551
525
               List<Item> &fields_vars, List<Item> &set_fields,
552
526
               List<Item> &set_values, READ_INFO &read_info,
553
527
               String &enclosed, uint32_t skip_lines,
565
539
 
566
540
  for (;;it.rewind())
567
541
  {
568
 
    if (session->getKilled())
 
542
    if (session->killed)
569
543
    {
570
544
      session->send_kill_message();
571
545
      return(1);
605
579
            return(1);
606
580
          }
607
581
          field->set_null();
608
 
          if (not field->maybe_null())
 
582
          if (!field->maybe_null())
609
583
          {
610
 
            if (field->is_timestamp())
611
 
            {
612
 
              ((field::Epoch::pointer) field)->set_time();
613
 
            }
 
584
            if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
 
585
              ((Field_timestamp*) field)->set_time();
614
586
            else if (field != table->next_number_field)
615
 
            {
616
 
              field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_NULL_TO_NOTNULL, 1);
617
 
            }
 
587
              field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
588
                                 ER_WARN_NULL_TO_NOTNULL, 1);
618
589
          }
619
590
        }
620
591
        else if (item->type() == Item::STRING_ITEM)
660
631
    }
661
632
    if (item)
662
633
    {
663
 
      /* Have not read any field, thus input cursor is simply ended */
 
634
      /* Have not read any field, thus input file is simply ended */
664
635
      if (item == fields_vars.head())
665
636
        break;
666
637
      for (; item ; item= it++)
675
646
                     session->row_count);
676
647
            return(1);
677
648
          }
678
 
          if (not field->maybe_null() and field->is_timestamp())
679
 
              ((field::Epoch::pointer) field)->set_time();
 
649
          if (!field->maybe_null() && field->type() == DRIZZLE_TYPE_TIMESTAMP)
 
650
              ((Field_timestamp*) field)->set_time();
680
651
          /*
681
652
            QQ: We probably should not throw warning for each field.
682
653
            But how about intention to always have the same number
701
672
      }
702
673
    }
703
674
 
704
 
    if (session->getKilled() ||
 
675
    if (session->killed ||
705
676
        fill_record(session, set_fields, set_values,
706
677
                    ignore_check_option_errors))
707
678
      return(1);
722
693
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
723
694
                          ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS),
724
695
                          session->row_count);
725
 
      if (session->getKilled())
 
696
      if (session->killed)
726
697
        return(1);
727
698
    }
728
699
    session->row_count++;
743
714
  case 'r': return '\r';
744
715
  case 'b': return '\b';
745
716
  case '0': return 0;                           // Ascii null
746
 
  case 'Z': return '\032';                      // Win32 end of cursor
 
717
  case 'Z': return '\032';                      // Win32 end of file
747
718
  case 'N': found_null=1;
748
719
 
749
720
    /* fall through */
758
729
*/
759
730
 
760
731
 
761
 
READ_INFO::READ_INFO(int file_par, size_t tot_length,
 
732
READ_INFO::READ_INFO(File file_par, size_t tot_length,
762
733
                     const CHARSET_INFO * const cs,
763
734
                     String &field_term, String &line_start, String &line_term,
764
735
                     String &enclosed_par, int escape, bool is_fifo)
765
 
  :cursor(file_par),escape_char(escape)
 
736
  :file(file_par),escape_char(escape)
766
737
{
767
738
  read_charset= cs;
768
739
  field_term_ptr=(char*) field_term.ptr();
796
767
 
797
768
 
798
769
  /* Set of a stack for unget if long terminators */
799
 
  size_t length= max(field_term_length,line_term_length)+1;
800
 
  set_if_bigger(length, line_start.length());
801
 
  stack= stack_pos= (int*) memory::sql_alloc(sizeof(int)*length);
 
770
  uint32_t length= max(field_term_length,line_term_length)+1;
 
771
  set_if_bigger(length,line_start.length());
 
772
  stack= stack_pos= (int*) sql_alloc(sizeof(int)*length);
802
773
 
803
774
  if (!(buffer=(unsigned char*) calloc(1, buff_length+1)))
804
 
    error=1;
 
775
    error=1; /* purecov: inspected */
805
776
  else
806
777
  {
807
778
    end_of_buff=buffer+buff_length;
808
 
    if (cache.init_io_cache((false) ? -1 : cursor, 0,
809
 
                            (false) ? internal::READ_NET :
810
 
                            (is_fifo ? internal::READ_FIFO : internal::READ_CACHE),0L,1,
811
 
                            MYF(MY_WME)))
 
779
    if (init_io_cache(&cache,(false) ? -1 : file, 0,
 
780
                      (false) ? READ_NET :
 
781
                      (is_fifo ? READ_FIFO : READ_CACHE),0L,1,
 
782
                      MYF(MY_WME)))
812
783
    {
813
 
      free((unsigned char*) buffer);
 
784
      free((unsigned char*) buffer); /* purecov: inspected */
814
785
      error=1;
815
786
    }
816
787
    else
831
802
  if (!error)
832
803
  {
833
804
    if (need_end_io_cache)
834
 
      cache.end_io_cache();
 
805
      ::end_io_cache(&cache);
835
806
    free(buffer);
836
807
    error=1;
837
808
  }
1030
1001
 
1031
1002
  NOTES
1032
1003
    The row may not be fixed size on disk if there are escape
1033
 
    characters in the cursor.
 
1004
    characters in the file.
1034
1005
 
1035
1006
  IMPLEMENTATION NOTE
1036
1007
    One can't use fixed length with multi-byte charset **
1163
1134
}
1164
1135
 
1165
1136
 
1166
 
} /* namespace drizzled */