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