~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_load.cc

  • Committer: Padraig O'Sullivan
  • Date: 2009-09-17 00:08:20 UTC
  • mto: (1126.9.3 captain-20090915-01)
  • mto: This revision was merged to the branch mainline in revision 1133.
  • Revision ID: osullivan.padraig@gmail.com-20090917000820-urd6p46qngi1okjp
Updated calls to some dtrace probes to cast the parameter to const char *
appropriately. Also, removed the additional variable in places that I was
using.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/* Copy data from a textfile to table */
18
18
 
19
 
#include "config.h"
 
19
#include <drizzled/server_includes.h>
20
20
#include <drizzled/sql_load.h>
21
21
#include <drizzled/error.h>
22
22
#include <drizzled/data_home.h>
23
23
#include <drizzled/session.h>
24
24
#include <drizzled/sql_base.h>
25
25
#include <drizzled/field/timestamp.h>
26
 
#include "drizzled/internal/my_sys.h"
27
 
#include "drizzled/internal/iocache.h"
28
 
#include <drizzled/db.h>
29
26
 
30
 
#include <sys/stat.h>
31
 
#include <fcntl.h>
32
27
#include <algorithm>
33
 
#include <climits>
34
28
 
35
29
using namespace std;
36
 
namespace drizzled
37
 
{
38
30
 
39
31
class READ_INFO {
40
 
  int   cursor;
 
32
  File  file;
41
33
  unsigned char *buffer;                /* Buffer for read text */
42
34
  unsigned char *end_of_buff;           /* Data in bufferts ends here */
43
35
  size_t buff_length;                   /* Length of buffert */
48
40
  int   *stack,*stack_pos;
49
41
  bool  found_end_of_line,start_of_line,eof;
50
42
  bool  need_end_io_cache;
51
 
  internal::IO_CACHE cache;
 
43
  IO_CACHE cache;
52
44
 
53
45
public:
54
46
  bool error,line_cuted,found_null,enclosed;
56
48
        *row_end;                       /* Found row ends here */
57
49
  const CHARSET_INFO *read_charset;
58
50
 
59
 
  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,
60
52
            String &field_term,String &line_start,String &line_term,
61
53
            String &enclosed,int escape, bool is_fifo);
62
54
  ~READ_INFO();
73
65
  */
74
66
  void end_io_cache()
75
67
  {
76
 
    internal::end_io_cache(&cache);
 
68
    ::end_io_cache(&cache);
77
69
    need_end_io_cache = 0;
78
70
  }
79
71
 
103
95
  SYNOPSYS
104
96
    mysql_load()
105
97
      session - current thread
106
 
      ex  - file_exchange object representing source cursor and its parsing rules
 
98
      ex  - file_exchange object representing source file and its parsing rules
107
99
      table_list  - list of tables to which we are loading data
108
100
      fields_vars - list of fields and variables to which we read
109
 
                    data from cursor
 
101
                    data from file
110
102
      set_fields  - list of fields mentioned in set clause
111
103
      set_values  - expressions to assign to fields in previous list
112
104
      handle_duplicates - indicates whenever we should emit error or
123
115
                enum enum_duplicates handle_duplicates, bool ignore)
124
116
{
125
117
  char name[FN_REFLEN];
126
 
  int file;
 
118
  File file;
127
119
  Table *table= NULL;
128
120
  int error;
129
121
  String *field_term=ex->field_term,*escaped=ex->escaped;
132
124
  char *db= table_list->db;                     // This is never null
133
125
  assert(db);
134
126
  /*
135
 
    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.
136
128
    If this is not set, we will use the directory where the table to be
137
129
    loaded is located
138
130
  */
139
 
  const char *tdb= session->db.empty() ? db  : session->db.c_str();             // Result is never null
 
131
  char *tdb= session->db ? session->db : db;            // Result is never null
140
132
  assert(tdb);
141
133
  uint32_t skip_lines= ex->skip_lines;
142
134
  bool transactional_table;
166
158
    table is marked to be 'used for insert' in which case we should never
167
159
    mark this table as 'const table' (ie, one that has only one row).
168
160
  */
169
 
  if (unique_table(table_list, table_list->next_global))
 
161
  if (unique_table(session, table_list, table_list->next_global, 0))
170
162
  {
171
163
    my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->table_name);
172
164
    return(true);
173
165
  }
174
166
 
175
167
  table= table_list->table;
176
 
  transactional_table= table->cursor->has_transactions();
 
168
  transactional_table= table->file->has_transactions();
177
169
 
178
170
  if (!fields_vars.elements)
179
171
  {
256
248
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
257
249
    ex->file_name+=dirname_length(ex->file_name);
258
250
#endif
259
 
    if (!internal::dirname_length(ex->file_name))
 
251
    if (!dirname_length(ex->file_name))
260
252
    {
261
253
      strcpy(name, drizzle_real_data_home);
262
254
      strncat(name, tdb, FN_REFLEN-strlen(drizzle_real_data_home)-1);
263
 
      (void) internal::fn_format(name, ex->file_name, name, "",
 
255
      (void) fn_format(name, ex->file_name, name, "",
264
256
                       MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
265
257
    }
266
258
    else
267
259
    {
268
 
      (void) internal::fn_format(name, ex->file_name, drizzle_real_data_home, "",
 
260
      (void) fn_format(name, ex->file_name, drizzle_real_data_home, "",
269
261
                       MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
270
262
 
271
263
      if (opt_secure_file_priv &&
283
275
        return(true);
284
276
      }
285
277
 
286
 
      // if we are not in slave thread, the cursor must be:
 
278
      // if we are not in slave thread, the file must be:
287
279
      if (!((stat_info.st_mode & S_IROTH) == S_IROTH &&  // readable by others
288
280
            (stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
289
281
            ((stat_info.st_mode & S_IFREG) == S_IFREG ||
295
287
      if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
296
288
        is_fifo = 1;
297
289
    }
298
 
    if ((file=internal::my_open(name,O_RDONLY,MYF(MY_WME))) < 0)
 
290
    if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0)
299
291
    {
300
 
      my_error(ER_CANT_OPEN_FILE, MYF(0), name, errno);
 
292
      my_error(ER_CANT_OPEN_FILE, MYF(0), name, my_errno);
301
293
      return(true);
302
294
    }
303
295
  }
308
300
  info.handle_duplicates=handle_duplicates;
309
301
  info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX;
310
302
 
311
 
  SchemaIdentifier identifier(session->db);
312
303
  READ_INFO read_info(file, tot_length,
313
 
                      ex->cs ? ex->cs : plugin::StorageEngine::getSchemaCollation(identifier),
314
 
                      *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,
315
306
                      info.escape_char, is_fifo);
316
307
  if (read_info.error)
317
308
  {
318
309
    if  (file >= 0)
319
 
      internal::my_close(file,MYF(0));                  // no files in net reading
 
310
      my_close(file,MYF(0));                    // no files in net reading
320
311
    return(true);                               // Can't allocate buffers
321
312
  }
322
313
 
348
339
    table->next_number_field=table->found_next_number_field;
349
340
    if (ignore ||
350
341
        handle_duplicates == DUP_REPLACE)
351
 
      table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
342
      table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
352
343
    if (handle_duplicates == DUP_REPLACE)
353
 
        table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
354
 
    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);
355
346
    table->copy_blobs=1;
356
347
 
357
348
    session->abort_on_warning= true;
364
355
      error= read_sep_field(session, info, table_list, fields_vars,
365
356
                            set_fields, set_values, read_info,
366
357
                            *enclosed, skip_lines, ignore);
367
 
    if (table->cursor->ha_end_bulk_insert() && !error)
 
358
    if (table->file->ha_end_bulk_insert() && !error)
368
359
    {
369
 
      table->print_error(errno, MYF(0));
 
360
      table->file->print_error(my_errno, MYF(0));
370
361
      error= 1;
371
362
    }
372
 
    table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
373
 
    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);
374
365
    table->next_number_field=0;
375
366
  }
376
367
  if (file >= 0)
377
 
    internal::my_close(file,MYF(0));
 
368
    my_close(file,MYF(0));
378
369
  free_blobs(table);                            /* if pack_blob was used */
379
370
  table->copy_blobs=0;
380
371
  session->count_cuted_fields= CHECK_FIELD_IGNORE;
388
379
    error= -1;                          // Error on read
389
380
    goto err;
390
381
  }
391
 
  snprintf(name, sizeof(name), ER(ER_LOAD_INFO), (uint32_t) info.records, (uint32_t) info.deleted,
 
382
  sprintf(name, ER(ER_LOAD_INFO), (uint32_t) info.records, (uint32_t) info.deleted,
392
383
          (uint32_t) (info.records - info.copied), (uint32_t) session->cuted_fields);
393
384
 
394
 
  if (session->transaction.stmt.hasModifiedNonTransData())
395
 
    session->transaction.all.markModifiedNonTransData();
 
385
  if (session->transaction.stmt.modified_non_trans_table)
 
386
    session->transaction.all.modified_non_trans_table= true;
396
387
 
397
388
  /* ok to client sent only after binlog write and engine commit */
398
389
  session->my_ok(info.copied + info.deleted, 0, 0L, name);
399
390
err:
400
391
  assert(transactional_table || !(info.copied || info.deleted) ||
401
 
              session->transaction.stmt.hasModifiedNonTransData());
402
 
  table->cursor->ha_release_auto_increment();
 
392
              session->transaction.stmt.modified_non_trans_table);
 
393
  table->file->ha_release_auto_increment();
403
394
  table->auto_increment_field_not_null= false;
404
395
  session->abort_on_warning= 0;
405
396
  return(error);
640
631
    }
641
632
    if (item)
642
633
    {
643
 
      /* Have not read any field, thus input cursor is simply ended */
 
634
      /* Have not read any field, thus input file is simply ended */
644
635
      if (item == fields_vars.head())
645
636
        break;
646
637
      for (; item ; item= it++)
723
714
  case 'r': return '\r';
724
715
  case 'b': return '\b';
725
716
  case '0': return 0;                           // Ascii null
726
 
  case 'Z': return '\032';                      // Win32 end of cursor
 
717
  case 'Z': return '\032';                      // Win32 end of file
727
718
  case 'N': found_null=1;
728
719
 
729
720
    /* fall through */
738
729
*/
739
730
 
740
731
 
741
 
READ_INFO::READ_INFO(int file_par, size_t tot_length,
 
732
READ_INFO::READ_INFO(File file_par, size_t tot_length,
742
733
                     const CHARSET_INFO * const cs,
743
734
                     String &field_term, String &line_start, String &line_term,
744
735
                     String &enclosed_par, int escape, bool is_fifo)
745
 
  :cursor(file_par),escape_char(escape)
 
736
  :file(file_par),escape_char(escape)
746
737
{
747
738
  read_charset= cs;
748
739
  field_term_ptr=(char*) field_term.ptr();
778
769
  /* Set of a stack for unget if long terminators */
779
770
  uint32_t length= max(field_term_length,line_term_length)+1;
780
771
  set_if_bigger(length,line_start.length());
781
 
  stack= stack_pos= (int*) memory::sql_alloc(sizeof(int)*length);
 
772
  stack= stack_pos= (int*) sql_alloc(sizeof(int)*length);
782
773
 
783
774
  if (!(buffer=(unsigned char*) calloc(1, buff_length+1)))
784
 
    error=1;
 
775
    error=1; /* purecov: inspected */
785
776
  else
786
777
  {
787
778
    end_of_buff=buffer+buff_length;
788
 
    if (init_io_cache(&cache,(false) ? -1 : cursor, 0,
789
 
                      (false) ? internal::READ_NET :
790
 
                      (is_fifo ? internal::READ_FIFO : internal::READ_CACHE),0L,1,
 
779
    if (init_io_cache(&cache,(false) ? -1 : file, 0,
 
780
                      (false) ? READ_NET :
 
781
                      (is_fifo ? READ_FIFO : READ_CACHE),0L,1,
791
782
                      MYF(MY_WME)))
792
783
    {
793
 
      free((unsigned char*) buffer);
 
784
      free((unsigned char*) buffer); /* purecov: inspected */
794
785
      error=1;
795
786
    }
796
787
    else
811
802
  if (!error)
812
803
  {
813
804
    if (need_end_io_cache)
814
 
      internal::end_io_cache(&cache);
 
805
      ::end_io_cache(&cache);
815
806
    free(buffer);
816
807
    error=1;
817
808
  }
1010
1001
 
1011
1002
  NOTES
1012
1003
    The row may not be fixed size on disk if there are escape
1013
 
    characters in the cursor.
 
1004
    characters in the file.
1014
1005
 
1015
1006
  IMPLEMENTATION NOTE
1016
1007
    One can't use fixed length with multi-byte charset **
1143
1134
}
1144
1135
 
1145
1136
 
1146
 
} /* namespace drizzled */