12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
17
/* Copy data from a textfile to table */
19
19
#include "config.h"
21
20
#include <drizzled/sql_load.h>
22
21
#include <drizzled/error.h>
23
22
#include <drizzled/data_home.h>
24
23
#include <drizzled/session.h>
25
24
#include <drizzled/sql_base.h>
26
#include <drizzled/field/epoch.h>
25
#include <drizzled/field/timestamp.h>
27
26
#include "drizzled/internal/my_sys.h"
28
27
#include "drizzled/internal/iocache.h"
29
28
#include <drizzled/db.h>
30
#include "drizzled/plugin/storage_engine.h"
32
30
#include <sys/stat.h>
34
32
#include <algorithm>
36
#include <boost/filesystem.hpp>
38
namespace fs=boost::filesystem;
39
35
using namespace std;
121
117
true - error / false - success
124
int load(Session *session,file_exchange *ex,TableList *table_list,
120
int mysql_load(Session *session,file_exchange *ex,TableList *table_list,
125
121
List<Item> &fields_vars, List<Item> &set_fields,
126
122
List<Item> &set_values,
127
123
enum enum_duplicates handle_duplicates, bool ignore)
125
char name[FN_REFLEN];
130
127
Table *table= NULL;
132
129
String *field_term=ex->field_term,*escaped=ex->escaped;
133
130
String *enclosed=ex->enclosed;
136
assert(table_list->getSchemaName()); // This should never be null
132
char *db= table_list->db; // This is never null
139
135
If path for cursor is not defined, we will use the current database.
140
136
If this is not set, we will use the directory where the table to be
141
137
loaded is located
143
util::string::const_shared_ptr schema(session->schema());
144
const char *tdb= (schema and not schema->empty()) ? schema->c_str() : table_list->getSchemaName(); // Result should never be null
139
const char *tdb= session->db.empty() ? db : session->db.c_str(); // Result is never null
146
141
uint32_t skip_lines= ex->skip_lines;
147
142
bool transactional_table;
148
Session::killed_state_t killed_status= Session::NOT_KILLED;
143
Session::killed_state killed_status= Session::NOT_KILLED;
150
145
/* Escape and enclosed character may be a utf8 4-byte character */
151
146
if (escaped->length() > 4 || enclosed->length() > 4)
262
fs::path to_file(ex->file_name);
263
fs::path target_path(fs::system_complete(getDataHomeCatalog()));
264
if (not to_file.has_root_directory())
266
int count_elements= 0;
267
for (fs::path::iterator iter= to_file.begin();
268
iter != to_file.end();
269
++iter, ++count_elements)
272
if (count_elements == 1)
276
target_path /= to_file;
280
target_path= to_file;
283
if (not secure_file_priv.string().empty())
285
if (target_path.file_string().substr(0, secure_file_priv.file_string().size()) != secure_file_priv.file_string())
287
/* Read only allowed from within dir specified by secure_file_priv */
288
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
256
#ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS
257
ex->file_name+=dirname_length(ex->file_name);
259
if (!internal::dirname_length(ex->file_name))
261
strcpy(name, data_home_real);
262
strncat(name, tdb, FN_REFLEN-strlen(data_home_real)-1);
263
(void) internal::fn_format(name, ex->file_name, name, "",
264
MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
268
(void) internal::fn_format(name, ex->file_name, data_home_real, "",
269
MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
271
if (opt_secure_file_priv &&
272
strncmp(opt_secure_file_priv, name, strlen(opt_secure_file_priv)))
274
/* Read only allowed from within dir specified by secure_file_priv */
275
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv");
279
struct stat stat_info;
280
if (stat(name,&stat_info))
282
my_error(ER_FILE_NOT_FOUND, MYF(0), name, errno);
286
// if we are not in slave thread, the cursor must be:
287
if (!((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others
288
(stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
289
((stat_info.st_mode & S_IFREG) == S_IFREG ||
290
(stat_info.st_mode & S_IFIFO) == S_IFIFO)))
292
my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name);
295
if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
298
if ((file=internal::my_open(name,O_RDONLY,MYF(MY_WME))) < 0)
300
my_error(ER_CANT_OPEN_FILE, MYF(0), name, errno);
293
struct stat stat_info;
294
if (stat(target_path.file_string().c_str(), &stat_info))
296
my_error(ER_FILE_NOT_FOUND, MYF(0), target_path.file_string().c_str(), errno);
300
// if we are not in slave thread, the cursor must be:
301
if (!((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others
302
(stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink
303
((stat_info.st_mode & S_IFREG) == S_IFREG ||
304
(stat_info.st_mode & S_IFIFO) == S_IFIFO)))
306
my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), target_path.file_string().c_str());
309
if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
313
if ((file=internal::my_open(target_path.file_string().c_str(), O_RDONLY,MYF(MY_WME))) < 0)
315
my_error(ER_CANT_OPEN_FILE, MYF(0), target_path.file_string().c_str(), errno);
319
306
memset(&info, 0, sizeof(info));
320
307
info.ignore= ignore;
321
308
info.handle_duplicates=handle_duplicates;
322
309
info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX;
324
identifier::Schema identifier(*schema);
311
SchemaIdentifier identifier(session->db);
325
312
READ_INFO read_info(file, tot_length,
326
313
ex->cs ? ex->cs : plugin::StorageEngine::getSchemaCollation(identifier),
327
314
*field_term, *ex->line_start, *ex->line_term, *enclosed,
395
382
simulated killing in the middle of per-row loop
396
383
must be effective for binlogging
398
killed_status= (error == 0)? Session::NOT_KILLED : session->getKilled();
385
killed_status= (error == 0)? Session::NOT_KILLED : session->killed;
401
388
error= -1; // Error on read
406
snprintf(msg, sizeof(msg), ER(ER_LOAD_INFO), info.records, info.deleted,
391
snprintf(name, sizeof(name), ER(ER_LOAD_INFO), info.records, info.deleted,
407
392
(info.records - info.copied), session->cuted_fields);
409
394
if (session->transaction.stmt.hasModifiedNonTransData())
410
395
session->transaction.all.markModifiedNonTransData();
412
397
/* ok to client sent only after binlog write and engine commit */
413
session->my_ok(info.copied + info.deleted, 0, 0L, msg);
398
session->my_ok(info.copied + info.deleted, 0, 0L, name);
415
400
assert(transactional_table || !(info.copied || info.deleted) ||
416
401
session->transaction.stmt.hasModifiedNonTransData());
417
402
table->cursor->ha_release_auto_increment();
418
403
table->auto_increment_field_not_null= false;
419
session->setAbortOnWarning(false);
404
session->abort_on_warning= 0;
607
590
field->set_null();
608
if (not field->maybe_null())
591
if (!field->maybe_null())
610
if (field->is_timestamp())
612
((field::Epoch::pointer) field)->set_time();
593
if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
594
((Field_timestamp*) field)->set_time();
614
595
else if (field != table->next_number_field)
616
field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_NULL_TO_NOTNULL, 1);
596
field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
597
ER_WARN_NULL_TO_NOTNULL, 1);
620
600
else if (item->type() == Item::STRING_ITEM)
807
787
end_of_buff=buffer+buff_length;
808
if (cache.init_io_cache((false) ? -1 : cursor, 0,
809
(false) ? internal::READ_NET :
810
(is_fifo ? internal::READ_FIFO : internal::READ_CACHE),0L,1,
788
if (init_io_cache(&cache,(false) ? -1 : cursor, 0,
789
(false) ? internal::READ_NET :
790
(is_fifo ? internal::READ_FIFO : internal::READ_CACHE),0L,1,
813
793
free((unsigned char*) buffer);