~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2006 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1 by brian
clean slate
15
16
17
/* Copy data from a textfile to table */
18
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
19
#include <config.h>
2148.7.12 by Brian Aker
Merge in header fixes.
20
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
21
#include <drizzled/sql_load.h>
549 by Monty Taylor
Took gettext.h out of header files.
22
#include <drizzled/error.h>
520.6.7 by Monty Taylor
Moved a bunch of crap out of common_includes.
23
#include <drizzled/data_home.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
24
#include <drizzled/session.h>
25
#include <drizzled/sql_base.h>
1999.4.9 by Brian Aker
Created EPOCH
26
#include <drizzled/field/epoch.h>
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
27
#include <drizzled/internal/my_sys.h>
28
#include <drizzled/internal/iocache.h>
29
#include <drizzled/plugin/storage_engine.h>
2234.1.4 by Olaf van der Spek
Refactor includes
30
#include <drizzled/sql_lex.h>
2239.1.1 by Olaf van der Spek
Refactor includes
31
#include <drizzled/copy_info.h>
32
#include <drizzled/file_exchange.h>
2239.1.9 by Olaf van der Spek
Refactor includes
33
#include <drizzled/util/test.h>
2241.3.4 by Olaf van der Spek
Refactor Session::transaction
34
#include <drizzled/session/transactions.h>
1 by brian
clean slate
35
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
36
#include <sys/stat.h>
37
#include <fcntl.h>
1067.4.7 by Nathan Williams
The remaining files using cmax have been converted to std::max.
38
#include <algorithm>
1241.9.24 by Monty Taylor
Removed m_string.h from server_includes.h.
39
#include <climits>
1786.3.2 by Monty Taylor
Cleaned up the initial pass at this. It's not perfect, but it does work.
40
#include <boost/filesystem.hpp>
1067.4.7 by Nathan Williams
The remaining files using cmax have been converted to std::max.
41
1786.3.2 by Monty Taylor
Cleaned up the initial pass at this. It's not perfect, but it does work.
42
namespace fs=boost::filesystem;
1067.4.7 by Nathan Williams
The remaining files using cmax have been converted to std::max.
43
using namespace std;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
44
namespace drizzled
45
{
1067.4.7 by Nathan Williams
The remaining files using cmax have been converted to std::max.
46
1 by brian
clean slate
47
class READ_INFO {
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
48
  int	cursor;
1014.2.5 by Monty Taylor
Replaced a malloc with a calloc. Resisted the urge to rewrite/replace the entire class.
49
  unsigned char	*buffer;                /* Buffer for read text */
50
  unsigned char *end_of_buff;           /* Data in bufferts ends here */
51
  size_t buff_length;                   /* Length of buffert */
52
  size_t max_length;                    /* Max length of row */
1 by brian
clean slate
53
  char	*field_term_ptr,*line_term_ptr,*line_start_ptr,*line_start_end;
54
  uint	field_term_length,line_term_length,enclosed_length;
55
  int	field_term_char,line_term_char,enclosed_char,escape_char;
56
  int	*stack,*stack_pos;
57
  bool	found_end_of_line,start_of_line,eof;
58
  bool  need_end_io_cache;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
59
  internal::IO_CACHE cache;
1 by brian
clean slate
60
61
public:
62
  bool error,line_cuted,found_null,enclosed;
481 by Brian Aker
Remove all of uchar.
63
  unsigned char	*row_start,			/* Found row starts here */
1 by brian
clean slate
64
	*row_end;			/* Found row ends here */
2254 by Brian Aker
Shift CHARSET_INFO to charset_info_st
65
  const charset_info_st *read_charset;
1 by brian
clean slate
66
2254 by Brian Aker
Shift CHARSET_INFO to charset_info_st
67
  READ_INFO(int cursor, size_t tot_length, const charset_info_st * const cs,
1 by brian
clean slate
68
	    String &field_term,String &line_start,String &line_term,
919.1.2 by Brian Aker
Comitting the removal of server code for LOAD DATA "LOCAL" INFILE
69
	    String &enclosed,int escape, bool is_fifo);
1 by brian
clean slate
70
  ~READ_INFO();
71
  int read_field();
72
  int read_fixed_length(void);
73
  int next_line(void);
74
  char unescape(char chr);
482 by Brian Aker
Remove uint.
75
  int terminator(char *ptr,uint32_t length);
1 by brian
clean slate
76
  bool find_start_of_fields();
77
78
  /*
79
    We need to force cache close before destructor is invoked to log
80
    the last read block
81
  */
82
  void end_io_cache()
83
  {
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
84
    cache.end_io_cache();
1 by brian
clean slate
85
    need_end_io_cache = 0;
86
  }
87
88
  /*
89
    Either this method, or we need to make cache public
2026.2.1 by Monty Taylor
Renamed things prefixed mysql_ or mysqld_
90
    Arg must be set from load() since constructor does not see
520.1.21 by Brian Aker
THD -> Session rename
91
    either the table or Session value
1 by brian
clean slate
92
  */
93
  void set_io_cache_arg(void* arg) { cache.arg = arg; }
94
};
95
1711.6.1 by Brian Aker
Style on structure cleanup
96
static int read_fixed_length(Session *session, CopyInfo &info, TableList *table_list,
1 by brian
clean slate
97
                             List<Item> &fields_vars, List<Item> &set_fields,
98
                             List<Item> &set_values, READ_INFO &read_info,
307 by Brian Aker
Minor cleanups around ulong in kernel.
99
			     uint32_t skip_lines,
1 by brian
clean slate
100
			     bool ignore_check_option_errors);
1711.6.1 by Brian Aker
Style on structure cleanup
101
static int read_sep_field(Session *session, CopyInfo &info, TableList *table_list,
1 by brian
clean slate
102
                          List<Item> &fields_vars, List<Item> &set_fields,
103
                          List<Item> &set_values, READ_INFO &read_info,
307 by Brian Aker
Minor cleanups around ulong in kernel.
104
			  String &enclosed, uint32_t skip_lines,
1 by brian
clean slate
105
			  bool ignore_check_option_errors);
106
107
108
/*
109
  Execute LOAD DATA query
110
111
  SYNOPSYS
2026.2.1 by Monty Taylor
Renamed things prefixed mysql_ or mysqld_
112
    load()
520.1.22 by Brian Aker
Second pass of thd cleanup
113
      session - current thread
1208.3.2 by brian
Update for Cursor renaming.
114
      ex  - file_exchange object representing source cursor and its parsing rules
1 by brian
clean slate
115
      table_list  - list of tables to which we are loading data
116
      fields_vars - list of fields and variables to which we read
1208.3.2 by brian
Update for Cursor renaming.
117
                    data from cursor
1 by brian
clean slate
118
      set_fields  - list of fields mentioned in set clause
119
      set_values  - expressions to assign to fields in previous list
120
      handle_duplicates - indicates whenever we should emit error or
121
                          replace row if we will meet duplicates.
122
      ignore -          - indicates whenever we should ignore duplicates
123
124
  RETURN VALUES
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
125
    true - error / false - success
1 by brian
clean slate
126
*/
127
2026.2.1 by Monty Taylor
Renamed things prefixed mysql_ or mysqld_
128
int load(Session *session,file_exchange *ex,TableList *table_list,
1 by brian
clean slate
129
	        List<Item> &fields_vars, List<Item> &set_fields,
130
                List<Item> &set_values,
919.1.2 by Brian Aker
Comitting the removal of server code for LOAD DATA "LOCAL" INFILE
131
                enum enum_duplicates handle_duplicates, bool ignore)
1 by brian
clean slate
132
{
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
133
  int file;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
134
  Table *table= NULL;
1 by brian
clean slate
135
  int error;
136
  String *field_term=ex->field_term,*escaped=ex->escaped;
137
  String *enclosed=ex->enclosed;
138
  bool is_fifo=0;
1874.1.1 by Brian Aker
Encapsulate schema_name it table_list.
139
140
  assert(table_list->getSchemaName()); // This should never be null
141
1 by brian
clean slate
142
  /*
1208.3.2 by brian
Update for Cursor renaming.
143
    If path for cursor is not defined, we will use the current database.
1 by brian
clean slate
144
    If this is not set, we will use the directory where the table to be
145
    loaded is located
146
  */
1976.5.2 by Brian Aker
This resolves the issue where one thread may be looking at schema while
147
  util::string::const_shared_ptr schema(session->schema());
148
  const char *tdb= (schema and not schema->empty()) ? schema->c_str() : table_list->getSchemaName(); // Result should never be null
630 by Brian Aker
Removing old STMT logic from load data infile (still need to clean up the
149
  assert(tdb);
307 by Brian Aker
Minor cleanups around ulong in kernel.
150
  uint32_t skip_lines= ex->skip_lines;
1 by brian
clean slate
151
  bool transactional_table;
1910.2.8 by Brian Aker
Enapsulate Kill.
152
  Session::killed_state_t killed_status= Session::NOT_KILLED;
1 by brian
clean slate
153
685.4.6 by Jay Pipes
Fix for Bug#308457. Gave UTF8 enclosure and escape character on LOAD DATA INFILE and changed the error message to be more descriptive
154
  /* Escape and enclosed character may be a utf8 4-byte character */
155
  if (escaped->length() > 4 || enclosed->length() > 4)
1 by brian
clean slate
156
  {
685.4.6 by Jay Pipes
Fix for Bug#308457. Gave UTF8 enclosure and escape character on LOAD DATA INFILE and changed the error message to be more descriptive
157
    my_error(ER_WRONG_FIELD_TERMINATORS,MYF(0),enclosed->c_ptr(), enclosed->length());
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
158
    return(true);
1 by brian
clean slate
159
  }
1109.1.3 by Brian Aker
Move names around a bit (to align similar methods)
160
161
  if (session->openTablesLock(table_list))
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
162
    return(true);
1109.1.3 by Brian Aker
Move names around a bit (to align similar methods)
163
2227.4.8 by Olaf van der Spek
Session::lex()
164
  if (setup_tables_and_check_access(session, &session->lex().select_lex.context,
165
                                    &session->lex().select_lex.top_join_list,
1 by brian
clean slate
166
                                    table_list,
2227.4.8 by Olaf van der Spek
Session::lex()
167
                                    &session->lex().select_lex.leaf_tables, true))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
168
     return(-1);
1 by brian
clean slate
169
170
  /*
171
    Let us emit an error if we are loading data to table which is used
172
    in subselect in SET clause like we do it for INSERT.
173
174
    The main thing to fix to remove this restriction is to ensure that the
175
    table is marked to be 'used for insert' in which case we should never
176
    mark this table as 'const table' (ie, one that has only one row).
177
  */
1220.1.13 by Brian Aker
Remove mysql_lock_have_duplicate() (we don't have merge, and our partition
178
  if (unique_table(table_list, table_list->next_global))
1 by brian
clean slate
179
  {
1874.1.2 by Brian Aker
Encapsulate table_name from table_list.
180
    my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->getTableName());
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
181
    return(true);
1 by brian
clean slate
182
  }
183
184
  table= table_list->table;
1208.3.2 by brian
Update for Cursor renaming.
185
  transactional_table= table->cursor->has_transactions();
1 by brian
clean slate
186
2183.2.19 by Olaf van der Spek
Use List::size()
187
  if (!fields_vars.size())
1 by brian
clean slate
188
  {
189
    Field **field;
1578.2.16 by Brian Aker
Merge in change to getTable() to private the field objects.
190
    for (field= table->getFields(); *field ; field++)
1 by brian
clean slate
191
      fields_vars.push_back(new Item_field(*field));
1005.2.12 by Monty Taylor
Moved some things to the API.
192
    table->setWriteSet();
1 by brian
clean slate
193
    table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
194
    /*
195
      Let us also prepare SET clause, altough it is probably empty
196
      in this case.
197
    */
520.1.22 by Brian Aker
Second pass of thd cleanup
198
    if (setup_fields(session, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
199
        setup_fields(session, 0, set_values, MARK_COLUMNS_READ, 0, 0))
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
200
      return(true);
1 by brian
clean slate
201
  }
202
  else
203
  {						// Part field list
204
    /* TODO: use this conds for 'WITH CHECK OPTIONS' */
520.1.22 by Brian Aker
Second pass of thd cleanup
205
    if (setup_fields(session, 0, fields_vars, MARK_COLUMNS_WRITE, 0, 0) ||
206
        setup_fields(session, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
207
        check_that_all_fields_are_given_values(session, table, table_list))
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
208
      return(true);
1 by brian
clean slate
209
    /*
210
      Check whenever TIMESTAMP field with auto-set feature specified
211
      explicitly.
212
    */
213
    if (table->timestamp_field)
214
    {
1999.4.2 by Brian Aker
Encapsulate the field's position.
215
      if (table->isWriteSet(table->timestamp_field->position()))
216
      {
1 by brian
clean slate
217
        table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
1999.4.2 by Brian Aker
Encapsulate the field's position.
218
      }
1 by brian
clean slate
219
      else
220
      {
1999.4.2 by Brian Aker
Encapsulate the field's position.
221
        table->setWriteSet(table->timestamp_field->position());
1 by brian
clean slate
222
      }
223
    }
224
    /* Fix the expressions in SET clause */
520.1.22 by Brian Aker
Second pass of thd cleanup
225
    if (setup_fields(session, 0, set_values, MARK_COLUMNS_READ, 0, 0))
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
226
      return(true);
1 by brian
clean slate
227
  }
228
229
  table->mark_columns_needed_for_insert();
230
1014.2.5 by Monty Taylor
Replaced a malloc with a calloc. Resisted the urge to rewrite/replace the entire class.
231
  size_t tot_length=0;
1 by brian
clean slate
232
  bool use_blobs= 0, use_vars= 0;
2183.2.12 by Olaf van der Spek
Use List::begin()
233
  List<Item>::iterator it(fields_vars.begin());
1 by brian
clean slate
234
  Item *item;
235
236
  while ((item= it++))
237
  {
238
    Item *real_item= item->real_item();
239
240
    if (real_item->type() == Item::FIELD_ITEM)
241
    {
242
      Field *field= ((Item_field*)real_item)->field;
243
      if (field->flags & BLOB_FLAG)
244
      {
245
        use_blobs= 1;
246
        tot_length+= 256;			// Will be extended if needed
247
      }
248
      else
249
        tot_length+= field->field_length;
250
    }
251
    else if (item->type() == Item::STRING_ITEM)
252
      use_vars= 1;
253
  }
254
  if (use_blobs && !ex->line_term->length() && !field_term->length())
255
  {
256
    my_message(ER_BLOBS_AND_NO_TERMINATED,ER(ER_BLOBS_AND_NO_TERMINATED),
257
	       MYF(0));
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
258
    return(true);
1 by brian
clean slate
259
  }
260
  if (use_vars && !field_term->length() && !enclosed->length())
261
  {
262
    my_error(ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR, MYF(0));
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
263
    return(true);
1 by brian
clean slate
264
  }
265
1813.2.9 by Monty Taylor
Made data_home be fs::path natively.
266
  fs::path to_file(ex->file_name);
267
  fs::path target_path(fs::system_complete(getDataHomeCatalog()));
268
  if (not to_file.has_root_directory())
269
  {
270
    int count_elements= 0;
271
    for (fs::path::iterator iter= to_file.begin();
272
         iter != to_file.end();
273
         ++iter, ++count_elements)
274
    { }
275
276
    if (count_elements == 1)
277
    {
278
      target_path /= tdb;
279
    }
280
    target_path /= to_file;
281
  }
282
  else
283
  {
284
    target_path= to_file;
285
  }
286
287
  if (not secure_file_priv.string().empty())
288
  {
1813.2.10 by Monty Taylor
Expand secure-file-priv once at startup rather than on each path check.
289
    if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
1813.2.9 by Monty Taylor
Made data_home be fs::path natively.
290
    {
291
      /* Read only allowed from within dir specified by secure_file_priv */
292
      my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
293
      return(true);
673.3.8 by Stewart Smith
fix outfile_loaddata test for drizzle.
294
    }
1 by brian
clean slate
295
  }
296
1813.2.9 by Monty Taylor
Made data_home be fs::path natively.
297
  struct stat stat_info;
298
  if (stat(target_path.file_string().c_str(), &stat_info))
299
  {
300
    my_error(ER_FILE_NOT_FOUND, MYF(0), target_path.file_string().c_str(), errno);
301
    return(true);
302
  }
303
304
  // if we are not in slave thread, the cursor must be:
305
  if (!((stat_info.st_mode & S_IROTH) == S_IROTH &&  // readable by others
306
        (stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
307
        ((stat_info.st_mode & S_IFREG) == S_IFREG ||
308
         (stat_info.st_mode & S_IFIFO) == S_IFIFO)))
309
  {
310
    my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), target_path.file_string().c_str());
311
    return(true);
312
  }
313
  if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
314
    is_fifo = 1;
315
316
317
  if ((file=internal::my_open(target_path.file_string().c_str(), O_RDONLY,MYF(MY_WME))) < 0)
318
  {
319
    my_error(ER_CANT_OPEN_FILE, MYF(0), target_path.file_string().c_str(), errno);
320
    return(true);
321
  }
1711.6.1 by Brian Aker
Style on structure cleanup
322
  CopyInfo info;
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
323
  memset(&info, 0, sizeof(info));
1 by brian
clean slate
324
  info.ignore= ignore;
325
  info.handle_duplicates=handle_duplicates;
326
  info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX;
327
2087.4.1 by Brian Aker
Merge in schema identifier.
328
  identifier::Schema identifier(*schema);
1014.3.1 by Brian Aker
Simplify the calling stack for getting schema collation. We need to extend
329
  READ_INFO read_info(file, tot_length,
1415 by Brian Aker
Mass overhaul to use schema_identifier.
330
                      ex->cs ? ex->cs : plugin::StorageEngine::getSchemaCollation(identifier),
331
		      *field_term, *ex->line_start, *ex->line_term, *enclosed,
919.1.2 by Brian Aker
Comitting the removal of server code for LOAD DATA "LOCAL" INFILE
332
		      info.escape_char, is_fifo);
1 by brian
clean slate
333
  if (read_info.error)
334
  {
335
    if	(file >= 0)
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
336
      internal::my_close(file,MYF(0));			// no files in net reading
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
337
    return(true);				// Can't allocate buffers
1 by brian
clean slate
338
  }
339
685.4.1 by Jay Pipes
Enabled the null.test.
340
  /*
341
   * Per the SQL standard, inserting NULL into a NOT NULL
342
   * field requires an error to be thrown.
343
   *
344
   * @NOTE
345
   *
346
   * NULL check and handling occurs in field_conv.cc
347
   */
348
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
520.1.22 by Brian Aker
Second pass of thd cleanup
349
  session->cuted_fields=0L;
1 by brian
clean slate
350
  /* Skip lines if there is a line terminator */
266.1.23 by Monty Taylor
Removed load xml infile. Hope nobody liked it. Now the only thing we need xml.c
351
  if (ex->line_term->length())
1 by brian
clean slate
352
  {
353
    /* ex->skip_lines needs to be preserved for logging */
354
    while (skip_lines > 0)
355
    {
356
      skip_lines--;
357
      if (read_info.next_line())
358
	break;
359
    }
360
  }
361
362
  if (!(error=test(read_info.error)))
363
  {
364
365
    table->next_number_field=table->found_next_number_field;
366
    if (ignore ||
367
	handle_duplicates == DUP_REPLACE)
1208.3.2 by brian
Update for Cursor renaming.
368
      table->cursor->extra(HA_EXTRA_IGNORE_DUP_KEY);
1 by brian
clean slate
369
    if (handle_duplicates == DUP_REPLACE)
1208.3.2 by brian
Update for Cursor renaming.
370
        table->cursor->extra(HA_EXTRA_WRITE_CAN_REPLACE);
371
    table->cursor->ha_start_bulk_insert((ha_rows) 0);
1 by brian
clean slate
372
    table->copy_blobs=1;
373
2114.5.1 by Brian Aker
Additional abstract around time (this also makes the abort_on_warnings in
374
    session->setAbortOnWarning(true);
1 by brian
clean slate
375
266.1.23 by Monty Taylor
Removed load xml infile. Hope nobody liked it. Now the only thing we need xml.c
376
    if (!field_term->length() && !enclosed->length())
520.1.22 by Brian Aker
Second pass of thd cleanup
377
      error= read_fixed_length(session, info, table_list, fields_vars,
1 by brian
clean slate
378
                               set_fields, set_values, read_info,
379
			       skip_lines, ignore);
380
    else
520.1.22 by Brian Aker
Second pass of thd cleanup
381
      error= read_sep_field(session, info, table_list, fields_vars,
1 by brian
clean slate
382
                            set_fields, set_values, read_info,
383
			    *enclosed, skip_lines, ignore);
1208.3.2 by brian
Update for Cursor renaming.
384
    if (table->cursor->ha_end_bulk_insert() && !error)
1 by brian
clean slate
385
    {
1241.9.57 by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined.
386
      table->print_error(errno, MYF(0));
1 by brian
clean slate
387
      error= 1;
388
    }
1208.3.2 by brian
Update for Cursor renaming.
389
    table->cursor->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
390
    table->cursor->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
1 by brian
clean slate
391
    table->next_number_field=0;
392
  }
393
  if (file >= 0)
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
394
    internal::my_close(file,MYF(0));
1 by brian
clean slate
395
  free_blobs(table);				/* if pack_blob was used */
396
  table->copy_blobs=0;
1633.4.8 by Brian Aker
Update for count_cuted_fields.
397
  session->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
398
  /*
1 by brian
clean slate
399
     simulated killing in the middle of per-row loop
400
     must be effective for binlogging
401
  */
1910.2.8 by Brian Aker
Enapsulate Kill.
402
  killed_status= (error == 0)? Session::NOT_KILLED : session->getKilled();
1 by brian
clean slate
403
  if (error)
404
  {
405
    error= -1;				// Error on read
406
    goto err;
407
  }
1813.2.9 by Monty Taylor
Made data_home be fs::path natively.
408
409
  char msg[FN_REFLEN];
410
  snprintf(msg, sizeof(msg), ER(ER_LOAD_INFO), info.records, info.deleted,
1717.2.1 by David Shrewsbury
Remove incorrect casting of 8-byte numbers down to 4-bytes.
411
	   (info.records - info.copied), session->cuted_fields);
1 by brian
clean slate
412
1273.1.13 by Jay Pipes
Style cleanup around TransactionContext::modified_non_trans_table and dead code removal
413
  if (session->transaction.stmt.hasModifiedNonTransData())
414
    session->transaction.all.markModifiedNonTransData();
1 by brian
clean slate
415
416
  /* ok to client sent only after binlog write and engine commit */
1813.2.9 by Monty Taylor
Made data_home be fs::path natively.
417
  session->my_ok(info.copied + info.deleted, 0, 0L, msg);
1 by brian
clean slate
418
err:
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
419
  assert(transactional_table || !(info.copied || info.deleted) ||
1273.1.13 by Jay Pipes
Style cleanup around TransactionContext::modified_non_trans_table and dead code removal
420
              session->transaction.stmt.hasModifiedNonTransData());
1208.3.2 by brian
Update for Cursor renaming.
421
  table->cursor->ha_release_auto_increment();
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
422
  table->auto_increment_field_not_null= false;
2114.5.1 by Brian Aker
Additional abstract around time (this also makes the abort_on_warnings in
423
  session->setAbortOnWarning(false);
424
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
425
  return(error);
1 by brian
clean slate
426
}
427
428
429
/****************************************************************************
430
** Read of rows of fixed size + optional garage + optonal newline
431
****************************************************************************/
432
433
static int
1711.6.1 by Brian Aker
Style on structure cleanup
434
read_fixed_length(Session *session, CopyInfo &info, TableList *table_list,
1 by brian
clean slate
435
                  List<Item> &fields_vars, List<Item> &set_fields,
436
                  List<Item> &set_values, READ_INFO &read_info,
307 by Brian Aker
Minor cleanups around ulong in kernel.
437
                  uint32_t skip_lines, bool ignore_check_option_errors)
1 by brian
clean slate
438
{
2183.2.12 by Olaf van der Spek
Use List::begin()
439
  List<Item>::iterator it(fields_vars.begin());
1 by brian
clean slate
440
  Item_field *sql_field;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
441
  Table *table= table_list->table;
151 by Brian Aker
Ulonglong to uint64_t
442
  uint64_t id;
1 by brian
clean slate
443
  bool err;
444
445
  id= 0;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
446
1 by brian
clean slate
447
  while (!read_info.read_fixed_length())
448
  {
1910.2.8 by Brian Aker
Enapsulate Kill.
449
    if (session->getKilled())
1 by brian
clean slate
450
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
451
      session->send_kill_message();
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
452
      return(1);
1 by brian
clean slate
453
    }
454
    if (skip_lines)
455
    {
456
      /*
457
	We could implement this with a simple seek if:
458
	- We are not using DATA INFILE LOCAL
459
	- escape character is  ""
460
	- line starting prefix is ""
461
      */
462
      skip_lines--;
463
      continue;
464
    }
2183.2.7 by Olaf van der Spek
x
465
    it= fields_vars.begin();
481 by Brian Aker
Remove all of uchar.
466
    unsigned char *pos=read_info.row_start;
1859.2.14 by Brian Aker
Add support for --with-valgrind
467
#ifdef HAVE_VALGRIND
1 by brian
clean slate
468
    read_info.row_end[0]=0;
469
#endif
470
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
471
    table->restoreRecordAsDefault();
1 by brian
clean slate
472
    /*
473
      There is no variables in fields_vars list in this format so
474
      this conversion is safe.
475
    */
476
    while ((sql_field= (Item_field*) it++))
477
    {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
478
      Field *field= sql_field->field;
1 by brian
clean slate
479
      if (field == table->next_number_field)
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
480
        table->auto_increment_field_not_null= true;
1 by brian
clean slate
481
      /*
482
        No fields specified in fields_vars list can be null in this format.
483
        Mark field as not null, we should do this for each row because of
484
        restore_record...
485
      */
486
      field->set_notnull();
487
488
      if (pos == read_info.row_end)
489
      {
520.1.22 by Brian Aker
Second pass of thd cleanup
490
        session->cuted_fields++;			/* Not enough fields */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
491
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
492
                            ER_WARN_TOO_FEW_RECORDS,
520.1.22 by Brian Aker
Second pass of thd cleanup
493
                            ER(ER_WARN_TOO_FEW_RECORDS), session->row_count);
1999.4.9 by Brian Aker
Created EPOCH
494
2046.2.1 by Brian Aker
First pass on micro timestamp.
495
        if (not field->maybe_null() and field->is_timestamp())
1999.4.9 by Brian Aker
Created EPOCH
496
            ((field::Epoch::pointer) field)->set_time();
1 by brian
clean slate
497
      }
498
      else
499
      {
482 by Brian Aker
Remove uint.
500
	uint32_t length;
481 by Brian Aker
Remove all of uchar.
501
	unsigned char save_chr;
895 by Brian Aker
Completion (?) of uint conversion.
502
	if ((length=(uint32_t) (read_info.row_end-pos)) >
1 by brian
clean slate
503
	    field->field_length)
1014.2.6 by Monty Taylor
Style move.
504
        {
1 by brian
clean slate
505
	  length=field->field_length;
1014.2.6 by Monty Taylor
Style move.
506
        }
507
	save_chr=pos[length];
508
        pos[length]='\0'; // Add temp null terminator for store()
1 by brian
clean slate
509
        field->store((char*) pos,length,read_info.read_charset);
510
	pos[length]=save_chr;
511
	if ((pos+=length) > read_info.row_end)
512
	  pos= read_info.row_end;	/* Fills rest with space */
513
      }
514
    }
515
    if (pos != read_info.row_end)
516
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
517
      session->cuted_fields++;			/* To long row */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
518
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
519
                          ER_WARN_TOO_MANY_RECORDS,
520
                          ER(ER_WARN_TOO_MANY_RECORDS), session->row_count);
1 by brian
clean slate
521
    }
522
1910.2.8 by Brian Aker
Enapsulate Kill.
523
    if (session->getKilled() ||
520.1.22 by Brian Aker
Second pass of thd cleanup
524
        fill_record(session, set_fields, set_values,
1 by brian
clean slate
525
                    ignore_check_option_errors))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
526
      return(1);
1 by brian
clean slate
527
520.1.22 by Brian Aker
Second pass of thd cleanup
528
    err= write_record(session, table, &info);
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
529
    table->auto_increment_field_not_null= false;
1 by brian
clean slate
530
    if (err)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
531
      return(1);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
532
1 by brian
clean slate
533
    /*
534
      We don't need to reset auto-increment field since we are restoring
535
      its default value at the beginning of each loop iteration.
536
    */
537
    if (read_info.next_line())			// Skip to next line
538
      break;
539
    if (read_info.line_cuted)
540
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
541
      session->cuted_fields++;			/* To long row */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
542
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
543
                          ER_WARN_TOO_MANY_RECORDS,
544
                          ER(ER_WARN_TOO_MANY_RECORDS), session->row_count);
1 by brian
clean slate
545
    }
520.1.22 by Brian Aker
Second pass of thd cleanup
546
    session->row_count++;
1 by brian
clean slate
547
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
548
  return(test(read_info.error));
1 by brian
clean slate
549
}
550
551
552
553
static int
1711.6.1 by Brian Aker
Style on structure cleanup
554
read_sep_field(Session *session, CopyInfo &info, TableList *table_list,
1 by brian
clean slate
555
               List<Item> &fields_vars, List<Item> &set_fields,
556
               List<Item> &set_values, READ_INFO &read_info,
307 by Brian Aker
Minor cleanups around ulong in kernel.
557
	       String &enclosed, uint32_t skip_lines,
1 by brian
clean slate
558
	       bool ignore_check_option_errors)
559
{
2183.2.12 by Olaf van der Spek
Use List::begin()
560
  List<Item>::iterator it(fields_vars.begin());
1 by brian
clean slate
561
  Item *item;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
562
  Table *table= table_list->table;
482 by Brian Aker
Remove uint.
563
  uint32_t enclosed_length;
151 by Brian Aker
Ulonglong to uint64_t
564
  uint64_t id;
1 by brian
clean slate
565
  bool err;
566
567
  enclosed_length=enclosed.length();
568
  id= 0;
569
2183.2.7 by Olaf van der Spek
x
570
  for (;;it= fields_vars.begin())
1 by brian
clean slate
571
  {
1910.2.8 by Brian Aker
Enapsulate Kill.
572
    if (session->getKilled())
1 by brian
clean slate
573
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
574
      session->send_kill_message();
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
575
      return(1);
1 by brian
clean slate
576
    }
577
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
578
    table->restoreRecordAsDefault();
1 by brian
clean slate
579
580
    while ((item= it++))
581
    {
482 by Brian Aker
Remove uint.
582
      uint32_t length;
481 by Brian Aker
Remove all of uchar.
583
      unsigned char *pos;
1 by brian
clean slate
584
      Item *real_item;
585
586
      if (read_info.read_field())
587
	break;
588
589
      /* If this line is to be skipped we don't want to fill field or var */
590
      if (skip_lines)
591
        continue;
592
593
      pos=read_info.row_start;
895 by Brian Aker
Completion (?) of uint conversion.
594
      length=(uint32_t) (read_info.row_end-pos);
1 by brian
clean slate
595
596
      real_item= item->real_item();
597
598
      if ((!read_info.enclosed && (enclosed_length && length == 4 && !memcmp(pos, STRING_WITH_LEN("NULL")))) ||
599
	  (length == 1 && read_info.found_null))
600
      {
601
602
        if (real_item->type() == Item::FIELD_ITEM)
603
        {
604
          Field *field= ((Item_field *)real_item)->field;
605
          if (field->reset())
606
          {
607
            my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name,
520.1.22 by Brian Aker
Second pass of thd cleanup
608
                     session->row_count);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
609
            return(1);
1 by brian
clean slate
610
          }
611
          field->set_null();
2046.2.1 by Brian Aker
First pass on micro timestamp.
612
          if (not field->maybe_null())
1 by brian
clean slate
613
          {
2046.2.1 by Brian Aker
First pass on micro timestamp.
614
            if (field->is_timestamp())
1999.4.9 by Brian Aker
Created EPOCH
615
            {
616
              ((field::Epoch::pointer) field)->set_time();
617
            }
1 by brian
clean slate
618
            else if (field != table->next_number_field)
1999.4.9 by Brian Aker
Created EPOCH
619
            {
620
              field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_NULL_TO_NOTNULL, 1);
621
            }
1 by brian
clean slate
622
          }
623
	}
624
        else if (item->type() == Item::STRING_ITEM)
625
        {
626
          ((Item_user_var_as_out_param *)item)->set_null_value(
627
                                                  read_info.read_charset);
628
        }
629
        else
630
        {
631
          my_error(ER_LOAD_DATA_INVALID_COLUMN, MYF(0), item->full_name());
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
632
          return(1);
1 by brian
clean slate
633
        }
634
635
	continue;
636
      }
637
638
      if (real_item->type() == Item::FIELD_ITEM)
639
      {
640
        Field *field= ((Item_field *)real_item)->field;
641
        field->set_notnull();
642
        read_info.row_end[0]=0;			// Safe to change end marker
643
        if (field == table->next_number_field)
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
644
          table->auto_increment_field_not_null= true;
1 by brian
clean slate
645
        field->store((char*) pos, length, read_info.read_charset);
646
      }
647
      else if (item->type() == Item::STRING_ITEM)
648
      {
649
        ((Item_user_var_as_out_param *)item)->set_value((char*) pos, length,
650
                                                        read_info.read_charset);
651
      }
652
      else
653
      {
654
        my_error(ER_LOAD_DATA_INVALID_COLUMN, MYF(0), item->full_name());
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
655
        return(1);
1 by brian
clean slate
656
      }
657
    }
658
    if (read_info.error)
659
      break;
660
    if (skip_lines)
661
    {
662
      skip_lines--;
663
      continue;
664
    }
665
    if (item)
666
    {
1208.3.2 by brian
Update for Cursor renaming.
667
      /* Have not read any field, thus input cursor is simply ended */
2183.2.21 by Olaf van der Spek
Use List::front()
668
      if (item == &fields_vars.front())
1 by brian
clean slate
669
	break;
670
      for (; item ; item= it++)
671
      {
672
        Item *real_item= item->real_item();
673
        if (real_item->type() == Item::FIELD_ITEM)
674
        {
675
          Field *field= ((Item_field *)real_item)->field;
676
          if (field->reset())
677
          {
678
            my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),field->field_name,
520.1.22 by Brian Aker
Second pass of thd cleanup
679
                     session->row_count);
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
680
            return(1);
1 by brian
clean slate
681
          }
2046.2.1 by Brian Aker
First pass on micro timestamp.
682
          if (not field->maybe_null() and field->is_timestamp())
1999.4.9 by Brian Aker
Created EPOCH
683
              ((field::Epoch::pointer) field)->set_time();
1 by brian
clean slate
684
          /*
685
            QQ: We probably should not throw warning for each field.
686
            But how about intention to always have the same number
520.1.21 by Brian Aker
THD -> Session rename
687
            of warnings in Session::cuted_fields (and get rid of cuted_fields
1 by brian
clean slate
688
            in the end ?)
689
          */
520.1.22 by Brian Aker
Second pass of thd cleanup
690
          session->cuted_fields++;
691
          push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1 by brian
clean slate
692
                              ER_WARN_TOO_FEW_RECORDS,
520.1.22 by Brian Aker
Second pass of thd cleanup
693
                              ER(ER_WARN_TOO_FEW_RECORDS), session->row_count);
1 by brian
clean slate
694
        }
695
        else if (item->type() == Item::STRING_ITEM)
696
        {
697
          ((Item_user_var_as_out_param *)item)->set_null_value(
698
                                                  read_info.read_charset);
699
        }
700
        else
701
        {
702
          my_error(ER_LOAD_DATA_INVALID_COLUMN, MYF(0), item->full_name());
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
703
          return(1);
1 by brian
clean slate
704
        }
705
      }
706
    }
707
1910.2.8 by Brian Aker
Enapsulate Kill.
708
    if (session->getKilled() ||
520.1.22 by Brian Aker
Second pass of thd cleanup
709
        fill_record(session, set_fields, set_values,
1 by brian
clean slate
710
                    ignore_check_option_errors))
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
711
      return(1);
1 by brian
clean slate
712
520.1.22 by Brian Aker
Second pass of thd cleanup
713
    err= write_record(session, table, &info);
51.1.53 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
714
    table->auto_increment_field_not_null= false;
1 by brian
clean slate
715
    if (err)
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
716
      return(1);
1 by brian
clean slate
717
    /*
718
      We don't need to reset auto-increment field since we are restoring
719
      its default value at the beginning of each loop iteration.
720
    */
721
    if (read_info.next_line())			// Skip to next line
722
      break;
723
    if (read_info.line_cuted)
724
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
725
      session->cuted_fields++;			/* To long row */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
726
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
727
                          ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS),
728
                          session->row_count);
1910.2.8 by Brian Aker
Enapsulate Kill.
729
      if (session->getKilled())
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
730
        return(1);
1 by brian
clean slate
731
    }
520.1.22 by Brian Aker
Second pass of thd cleanup
732
    session->row_count++;
1 by brian
clean slate
733
  }
51.1.1 by Jay Pipes
Merged PatG's removal of various DBUG stuff with still keeping DBUG_ASSERT calls since they seem to be breaking test runs
734
  return(test(read_info.error));
1 by brian
clean slate
735
}
736
737
738
/* Unescape all escape characters, mark \N as null */
739
740
char
741
READ_INFO::unescape(char chr)
742
{
743
  /* keep this switch synchornous with the ESCAPE_CHARS macro */
744
  switch(chr) {
745
  case 'n': return '\n';
746
  case 't': return '\t';
747
  case 'r': return '\r';
748
  case 'b': return '\b';
749
  case '0': return 0;				// Ascii null
1208.3.2 by brian
Update for Cursor renaming.
750
  case 'Z': return '\032';			// Win32 end of cursor
1 by brian
clean slate
751
  case 'N': found_null=1;
752
753
    /* fall through */
754
  default:  return chr;
755
  }
756
}
757
758
759
/*
760
  Read a line using buffering
761
  If last line is empty (in line mode) then it isn't outputed
762
*/
763
764
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
765
READ_INFO::READ_INFO(int file_par, size_t tot_length,
2254 by Brian Aker
Shift CHARSET_INFO to charset_info_st
766
                     const charset_info_st * const cs,
1 by brian
clean slate
767
		     String &field_term, String &line_start, String &line_term,
919.1.2 by Brian Aker
Comitting the removal of server code for LOAD DATA "LOCAL" INFILE
768
		     String &enclosed_par, int escape, bool is_fifo)
1208.3.2 by brian
Update for Cursor renaming.
769
  :cursor(file_par),escape_char(escape)
1 by brian
clean slate
770
{
771
  read_charset= cs;
772
  field_term_ptr=(char*) field_term.ptr();
773
  field_term_length= field_term.length();
774
  line_term_ptr=(char*) line_term.ptr();
775
  line_term_length= line_term.length();
776
  if (line_start.length() == 0)
777
  {
778
    line_start_ptr=0;
779
    start_of_line= 0;
780
  }
781
  else
782
  {
783
    line_start_ptr=(char*) line_start.ptr();
784
    line_start_end=line_start_ptr+line_start.length();
785
    start_of_line= 1;
786
  }
787
  /* If field_terminator == line_terminator, don't use line_terminator */
788
  if (field_term_length == line_term_length &&
789
      !memcmp(field_term_ptr,line_term_ptr,field_term_length))
790
  {
791
    line_term_length=0;
792
    line_term_ptr=(char*) "";
793
  }
794
  enclosed_char= (enclosed_length=enclosed_par.length()) ?
481 by Brian Aker
Remove all of uchar.
795
    (unsigned char) enclosed_par[0] : INT_MAX;
796
  field_term_char= field_term_length ? (unsigned char) field_term_ptr[0] : INT_MAX;
797
  line_term_char= line_term_length ? (unsigned char) line_term_ptr[0] : INT_MAX;
1 by brian
clean slate
798
  error=eof=found_end_of_line=found_null=line_cuted=0;
799
  buff_length=tot_length;
800
801
802
  /* Set of a stack for unget if long terminators */
1816.3.1 by Brian Aker
Convert sql_string to use size_t (this should clean up ICC warnings).
803
  size_t length= max(field_term_length,line_term_length)+1;
804
  set_if_bigger(length, line_start.length());
1253.1.6 by Monty Taylor
Moved mem_root functions into drizzled::memory:: namespace.
805
  stack= stack_pos= (int*) memory::sql_alloc(sizeof(int)*length);
1 by brian
clean slate
806
1014.2.5 by Monty Taylor
Replaced a malloc with a calloc. Resisted the urge to rewrite/replace the entire class.
807
  if (!(buffer=(unsigned char*) calloc(1, buff_length+1)))
971.6.11 by Eric Day
Removed purecov messages.
808
    error=1;
1 by brian
clean slate
809
  else
810
  {
811
    end_of_buff=buffer+buff_length;
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
812
    if (cache.init_io_cache((false) ? -1 : cursor, 0,
813
                            (false) ? internal::READ_NET :
814
                            (is_fifo ? internal::READ_FIFO : internal::READ_CACHE),0L,1,
815
                            MYF(MY_WME)))
1 by brian
clean slate
816
    {
971.6.11 by Eric Day
Removed purecov messages.
817
      free((unsigned char*) buffer);
1 by brian
clean slate
818
      error=1;
819
    }
820
    else
821
    {
822
      /*
823
	init_io_cache() will not initialize read_function member
824
	if the cache is READ_NET. So we work around the problem with a
825
	manual assignment
826
      */
827
      need_end_io_cache = 1;
828
    }
829
  }
830
}
831
832
833
READ_INFO::~READ_INFO()
834
{
835
  if (!error)
836
  {
837
    if (need_end_io_cache)
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
838
      cache.end_io_cache();
1014.2.5 by Monty Taylor
Replaced a malloc with a calloc. Resisted the urge to rewrite/replace the entire class.
839
    free(buffer);
1 by brian
clean slate
840
    error=1;
841
  }
842
}
843
844
845
#define GET (stack_pos != stack ? *--stack_pos : my_b_get(&cache))
846
#define PUSH(A) *(stack_pos++)=(A)
847
848
482 by Brian Aker
Remove uint.
849
inline int READ_INFO::terminator(char *ptr,uint32_t length)
1 by brian
clean slate
850
{
851
  int chr=0;					// Keep gcc happy
482 by Brian Aker
Remove uint.
852
  uint32_t i;
1 by brian
clean slate
853
  for (i=1 ; i < length ; i++)
854
  {
855
    if ((chr=GET) != *++ptr)
856
    {
857
      break;
858
    }
859
  }
860
  if (i == length)
861
    return 1;
862
  PUSH(chr);
863
  while (i-- > 1)
481 by Brian Aker
Remove all of uchar.
864
    PUSH((unsigned char) *--ptr);
1 by brian
clean slate
865
  return 0;
866
}
867
868
869
int READ_INFO::read_field()
870
{
871
  int chr,found_enclosed_char;
481 by Brian Aker
Remove all of uchar.
872
  unsigned char *to,*new_buffer;
1 by brian
clean slate
873
874
  found_null=0;
875
  if (found_end_of_line)
876
    return 1;					// One have to call next_line
877
878
  /* Skip until we find 'line_start' */
879
880
  if (start_of_line)
881
  {						// Skip until line_start
882
    start_of_line=0;
883
    if (find_start_of_fields())
884
      return 1;
885
  }
886
  if ((chr=GET) == my_b_EOF)
887
  {
888
    found_end_of_line=eof=1;
889
    return 1;
890
  }
891
  to=buffer;
892
  if (chr == enclosed_char)
893
  {
894
    found_enclosed_char=enclosed_char;
481 by Brian Aker
Remove all of uchar.
895
    *to++=(unsigned char) chr;				// If error
1 by brian
clean slate
896
  }
897
  else
898
  {
899
    found_enclosed_char= INT_MAX;
900
    PUSH(chr);
901
  }
902
903
  for (;;)
904
  {
905
    while ( to < end_of_buff)
906
    {
907
      chr = GET;
908
      if ((my_mbcharlen(read_charset, chr) > 1) &&
909
          to+my_mbcharlen(read_charset, chr) <= end_of_buff)
910
      {
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
911
        unsigned char* p = (unsigned char*)to;
912
        *to++ = chr;
913
        int ml = my_mbcharlen(read_charset, chr);
914
        int i;
915
        for (i=1; i<ml; i++) {
916
          chr = GET;
917
          if (chr == my_b_EOF)
918
            goto found_eof;
919
          *to++ = chr;
920
        }
921
        if (my_ismbchar(read_charset,
922
              (const char *)p,
923
              (const char *)to))
924
          continue;
925
        for (i=0; i<ml; i++)
926
          PUSH((unsigned char) *--to);
927
        chr = GET;
1 by brian
clean slate
928
      }
929
      if (chr == my_b_EOF)
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
930
        goto found_eof;
1 by brian
clean slate
931
      if (chr == escape_char)
932
      {
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
933
        if ((chr=GET) == my_b_EOF)
934
        {
935
          *to++= (unsigned char) escape_char;
936
          goto found_eof;
937
        }
1 by brian
clean slate
938
        /*
939
          When escape_char == enclosed_char, we treat it like we do for
940
          handling quotes in SQL parsing -- you can double-up the
941
          escape_char to include it literally, but it doesn't do escapes
942
          like \n. This allows: LOAD DATA ... ENCLOSED BY '"' ESCAPED BY '"'
943
          with data like: "fie""ld1", "field2"
944
         */
945
        if (escape_char != enclosed_char || chr == escape_char)
946
        {
481 by Brian Aker
Remove all of uchar.
947
          *to++ = (unsigned char) unescape((char) chr);
1 by brian
clean slate
948
          continue;
949
        }
950
        PUSH(chr);
951
        chr= escape_char;
952
      }
953
#ifdef ALLOW_LINESEPARATOR_IN_STRINGS
954
      if (chr == line_term_char)
955
#else
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
956
        if (chr == line_term_char && found_enclosed_char == INT_MAX)
1 by brian
clean slate
957
#endif
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
958
        {
959
          if (terminator(line_term_ptr,line_term_length))
960
          {					// Maybe unexpected linefeed
961
            enclosed=0;
962
            found_end_of_line=1;
963
            row_start=buffer;
964
            row_end=  to;
965
            return 0;
966
          }
967
        }
1 by brian
clean slate
968
      if (chr == found_enclosed_char)
969
      {
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
970
        if ((chr=GET) == found_enclosed_char)
971
        {					// Remove dupplicated
972
          *to++ = (unsigned char) chr;
973
          continue;
974
        }
975
        // End of enclosed field if followed by field_term or line_term
976
        if (chr == my_b_EOF ||
977
            (chr == line_term_char && terminator(line_term_ptr, line_term_length)))
978
        {					// Maybe unexpected linefeed
979
          enclosed=1;
980
          found_end_of_line=1;
981
          row_start=buffer+1;
982
          row_end=  to;
983
          return 0;
984
        }
985
        if (chr == field_term_char &&
986
            terminator(field_term_ptr,field_term_length))
987
        {
988
          enclosed=1;
989
          row_start=buffer+1;
990
          row_end=  to;
991
          return 0;
992
        }
993
        /*
994
           The string didn't terminate yet.
995
           Store back next character for the loop
996
         */
997
        PUSH(chr);
998
        /* copy the found term character to 'to' */
999
        chr= found_enclosed_char;
1 by brian
clean slate
1000
      }
1001
      else if (chr == field_term_char && found_enclosed_char == INT_MAX)
1002
      {
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
1003
        if (terminator(field_term_ptr,field_term_length))
1004
        {
1005
          enclosed=0;
1006
          row_start=buffer;
1007
          row_end=  to;
1008
          return 0;
1009
        }
1 by brian
clean slate
1010
      }
481 by Brian Aker
Remove all of uchar.
1011
      *to++ = (unsigned char) chr;
1 by brian
clean slate
1012
    }
1013
    /*
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
1014
     ** We come here if buffer is too small. Enlarge it and continue
1015
     */
656.1.26 by Monty Taylor
Finally removed all of the my_malloc stuff.
1016
    if (!(new_buffer=(unsigned char*) realloc(buffer, buff_length+1+IO_SIZE)))
1 by brian
clean slate
1017
      return (error=1);
1018
    to=new_buffer + (to-buffer);
1019
    buffer=new_buffer;
1020
    buff_length+=IO_SIZE;
1021
    end_of_buff=buffer+buff_length;
1022
  }
1023
1024
found_eof:
1025
  enclosed=0;
1026
  found_end_of_line=eof=1;
1027
  row_start=buffer;
1028
  row_end=to;
1029
  return 0;
1030
}
1031
1032
/*
1033
  Read a row with fixed length.
1034
1035
  NOTES
1036
    The row may not be fixed size on disk if there are escape
1208.3.2 by brian
Update for Cursor renaming.
1037
    characters in the cursor.
1 by brian
clean slate
1038
1039
  IMPLEMENTATION NOTE
1040
    One can't use fixed length with multi-byte charset **
1041
1042
  RETURN
1043
    0  ok
1044
    1  error
1045
*/
1046
1047
int READ_INFO::read_fixed_length()
1048
{
1049
  int chr;
481 by Brian Aker
Remove all of uchar.
1050
  unsigned char *to;
1 by brian
clean slate
1051
  if (found_end_of_line)
1052
    return 1;					// One have to call next_line
1053
1054
  if (start_of_line)
1055
  {						// Skip until line_start
1056
    start_of_line=0;
1057
    if (find_start_of_fields())
1058
      return 1;
1059
  }
1060
1061
  to=row_start=buffer;
1062
  while (to < end_of_buff)
1063
  {
1064
    if ((chr=GET) == my_b_EOF)
1065
      goto found_eof;
1066
    if (chr == escape_char)
1067
    {
1068
      if ((chr=GET) == my_b_EOF)
1069
      {
481 by Brian Aker
Remove all of uchar.
1070
	*to++= (unsigned char) escape_char;
1 by brian
clean slate
1071
	goto found_eof;
1072
      }
481 by Brian Aker
Remove all of uchar.
1073
      *to++ =(unsigned char) unescape((char) chr);
1 by brian
clean slate
1074
      continue;
1075
    }
1076
    if (chr == line_term_char)
1077
    {
1078
      if (terminator(line_term_ptr,line_term_length))
1079
      {						// Maybe unexpected linefeed
1080
	found_end_of_line=1;
1081
	row_end=  to;
1082
	return 0;
1083
      }
1084
    }
481 by Brian Aker
Remove all of uchar.
1085
    *to++ = (unsigned char) chr;
1 by brian
clean slate
1086
  }
1087
  row_end=to;					// Found full line
1088
  return 0;
1089
1090
found_eof:
1091
  found_end_of_line=eof=1;
1092
  row_start=buffer;
1093
  row_end=to;
1094
  return to == buffer ? 1 : 0;
1095
}
1096
1097
1098
int READ_INFO::next_line()
1099
{
1100
  line_cuted=0;
1101
  start_of_line= line_start_ptr != 0;
1102
  if (found_end_of_line || eof)
1103
  {
1104
    found_end_of_line=0;
1105
    return eof;
1106
  }
1107
  found_end_of_line=0;
1108
  if (!line_term_length)
1109
    return 0;					// No lines
1110
  for (;;)
1111
  {
1112
    int chr = GET;
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
1113
    if (my_mbcharlen(read_charset, chr) > 1)
1114
    {
1115
      for (uint32_t i=1;
1116
          chr != my_b_EOF && i<my_mbcharlen(read_charset, chr);
1117
          i++)
1118
        chr = GET;
1119
      if (chr == escape_char)
1120
        continue;
1121
    }
1122
    if (chr == my_b_EOF)
1123
    {
1 by brian
clean slate
1124
      eof=1;
1125
      return 1;
1126
    }
1127
    if (chr == escape_char)
1128
    {
1129
      line_cuted=1;
1130
      if (GET == my_b_EOF)
1085.3.3 by Monty Taylor
Got rid of #ifdef have utf8 stuff.
1131
        return 1;
1 by brian
clean slate
1132
      continue;
1133
    }
1134
    if (chr == line_term_char && terminator(line_term_ptr,line_term_length))
1135
      return 0;
1136
    line_cuted=1;
1137
  }
1138
}
1139
1140
1141
bool READ_INFO::find_start_of_fields()
1142
{
1143
  int chr;
1144
 try_again:
1145
  do
1146
  {
1147
    if ((chr=GET) == my_b_EOF)
1148
    {
1149
      found_end_of_line=eof=1;
1150
      return 1;
1151
    }
1152
  } while ((char) chr != line_start_ptr[0]);
1153
  for (char *ptr=line_start_ptr+1 ; ptr != line_start_end ; ptr++)
1154
  {
1155
    chr=GET;					// Eof will be checked later
1156
    if ((char) chr != *ptr)
1157
    {						// Can't be line_start
1158
      PUSH(chr);
1159
      while (--ptr != line_start_ptr)
1160
      {						// Restart with next char
481 by Brian Aker
Remove all of uchar.
1161
	PUSH((unsigned char) *ptr);
1 by brian
clean slate
1162
      }
1163
      goto try_again;
1164
    }
1165
  }
1166
  return 0;
1167
}
1168
1169
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
1170
} /* namespace drizzled */