summaryrefslogtreecommitdiff
path: root/sql/sql_load.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_load.cc')
-rw-r--r--sql/sql_load.cc152
1 files changed, 105 insertions, 47 deletions
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index c4f5b1427af..174ccdfab5b 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -71,14 +71,16 @@ public:
void set_io_cache_arg(void* arg) { cache.arg = arg; }
};
-static int read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,
+static int read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields, READ_INFO &read_info,
- ulong skip_lines);
-static int read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
+ ulong skip_lines,
+ bool ignore_check_option_errors);
+static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields, READ_INFO &read_info,
- String &enclosed, ulong skip_lines);
+ String &enclosed, ulong skip_lines,
+ bool ignore_check_option_errors);
-int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
+bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
List<Item> &fields, enum enum_duplicates handle_duplicates,
bool ignore,
bool read_file_from_client,thr_lock_type lock_type)
@@ -89,6 +91,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
int error;
String *field_term=ex->field_term,*escaped=ex->escaped;
String *enclosed=ex->enclosed;
+ Item *unused_conds= 0;
bool is_fifo=0;
#ifndef EMBEDDED_LIBRARY
LOAD_FILE_INFO lf_info;
@@ -100,8 +103,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
loaded is located
*/
char *tdb= thd->db ? thd->db : db; // Result is never null
- bool transactional_table, log_delayed;
ulong skip_lines= ex->skip_lines;
+ bool transactional_table;
DBUG_ENTER("mysql_load");
#ifdef EMBEDDED_LIBRARY
@@ -112,12 +115,23 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
{
my_message(ER_WRONG_FIELD_TERMINATORS,ER(ER_WRONG_FIELD_TERMINATORS),
MYF(0));
- DBUG_RETURN(-1);
+ DBUG_RETURN(TRUE);
}
- if (!(table = open_ltable(thd,table_list,lock_type)))
- DBUG_RETURN(-1);
+ table_list->lock_type= lock_type;
+ if (open_and_lock_tables(thd, table_list))
+ DBUG_RETURN(TRUE);
+ if (setup_tables(thd, table_list, &unused_conds,
+ &thd->lex->select_lex.leaf_tables, FALSE, FALSE))
+ DBUG_RETURN(-1);
+ if (!table_list->table || // do not suport join view
+ !table_list->updatable || // and derived tables
+ check_key_in_view(thd, table_list))
+ {
+ my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD");
+ DBUG_RETURN(TRUE);
+ }
+ table= table_list->table;
transactional_table= table->file->has_transactions();
- log_delayed= (transactional_table || table->tmp_table);
if (!fields.elements)
{
@@ -128,14 +142,16 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
else
{ // Part field list
thd->dupp_field=0;
- if (setup_tables(table_list) ||
- setup_fields(thd, 0, table_list, fields, 1, 0, 0))
- DBUG_RETURN(-1);
+ /* TODO: use this conds for 'WITH CHECK OPTIONS' */
+ if (setup_fields(thd, 0, table_list, fields, 1, 0, 0))
+ DBUG_RETURN(TRUE);
if (thd->dupp_field)
{
my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), thd->dupp_field->field_name);
- DBUG_RETURN(-1);
+ DBUG_RETURN(TRUE);
}
+ if (check_that_all_fields_are_given_values(thd, table))
+ DBUG_RETURN(TRUE);
}
uint tot_length=0;
@@ -161,7 +177,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
{
my_message(ER_BLOBS_AND_NO_TERMINATED,ER(ER_BLOBS_AND_NO_TERMINATED),
MYF(0));
- DBUG_RETURN(-1);
+ DBUG_RETURN(TRUE);
}
/* We can't give an error in the middle when using LOCAL files */
@@ -193,7 +209,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
#if !defined(__WIN__) && !defined(OS2) && ! defined(__NETWARE__)
MY_STAT stat_info;
if (!my_stat(name,&stat_info,MYF(MY_WME)))
- DBUG_RETURN(-1);
+ DBUG_RETURN(TRUE);
// if we are not in slave thread, the file must be:
if (!thd->slave_thread &&
@@ -204,15 +220,15 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
((stat_info.st_mode & S_IFREG) == S_IFREG ||
(stat_info.st_mode & S_IFIFO) == S_IFIFO)))
{
- my_error(ER_TEXTFILE_NOT_READABLE,MYF(0),name);
- DBUG_RETURN(-1);
+ my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name);
+ DBUG_RETURN(TRUE);
}
if ((stat_info.st_mode & S_IFIFO) == S_IFIFO)
is_fifo = 1;
#endif
}
if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0)
- DBUG_RETURN(-1);
+ DBUG_RETURN(TRUE);
}
COPY_INFO info;
@@ -228,7 +244,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
{
if (file >= 0)
my_close(file,MYF(0)); // no files in net reading
- DBUG_RETURN(-1); // Can't allocate buffers
+ DBUG_RETURN(TRUE); // Can't allocate buffers
}
#ifndef EMBEDDED_LIBRARY
@@ -237,18 +253,18 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
lf_info.thd = thd;
lf_info.ex = ex;
lf_info.db = db;
- lf_info.table_name = table_list->real_name;
+ lf_info.table_name = table_list->table_name;
lf_info.fields = &fields;
lf_info.ignore= ignore;
lf_info.handle_dup = handle_duplicates;
lf_info.wrote_create_file = 0;
lf_info.last_pos_in_file = HA_POS_ERROR;
- lf_info.log_delayed= log_delayed;
+ lf_info.log_delayed= transactional_table;
read_info.set_io_cache_arg((void*) &lf_info);
}
#endif /*!EMBEDDED_LIBRARY*/
- restore_record(table,default_values);
+ restore_record(table, s->default_values);
thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */
thd->cuted_fields=0L;
@@ -276,12 +292,20 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
ha_enable_transaction(thd, FALSE);
table->file->start_bulk_insert((ha_rows) 0);
table->copy_blobs=1;
+
+ thd->no_trans_update= 0;
+ thd->abort_on_warning= (!ignore &&
+ (thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES |
+ MODE_STRICT_ALL_TABLES)));
+
if (!field_term->length() && !enclosed->length())
- error=read_fixed_length(thd,info,table,fields,read_info,
- skip_lines);
+ error= read_fixed_length(thd, info, table_list, fields,read_info,
+ skip_lines, ignore);
else
- error=read_sep_field(thd,info,table,fields,read_info,*enclosed,
- skip_lines);
+ error= read_sep_field(thd, info, table_list, fields, read_info,
+ *enclosed, skip_lines,
+ ignore);
if (table->file->end_bulk_insert())
error=1; /* purecov: inspected */
ha_enable_transaction(thd, TRUE);
@@ -337,7 +361,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
/* If the file was not empty, wrote_create_file is true */
if (lf_info.wrote_create_file)
{
- Delete_file_log_event d(thd, db, log_delayed);
+ Delete_file_log_event d(thd, db, transactional_table);
mysql_bin_log.write(&d);
}
}
@@ -348,11 +372,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
sprintf(name, ER(ER_LOAD_INFO), (ulong) info.records, (ulong) info.deleted,
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
send_ok(thd,info.copied+info.deleted,0L,name);
- // on the slave thd->query is never initialized
- if (!thd->slave_thread)
- mysql_update_log.write(thd,thd->query,thd->query_length);
- if (!log_delayed)
+ if (!transactional_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
#ifndef EMBEDDED_LIBRARY
if (mysql_bin_log.is_open())
@@ -362,22 +383,24 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
block will be logged only after Execute_load_log_event (which is wrong),
when read_info is destroyed.
*/
- read_info.end_io_cache();
+ read_info.end_io_cache();
if (lf_info.wrote_create_file)
{
- Execute_load_log_event e(thd, db, log_delayed);
+ Execute_load_log_event e(thd, db, transactional_table);
mysql_bin_log.write(&e);
}
}
#endif /*!EMBEDDED_LIBRARY*/
if (transactional_table)
- error=ha_autocommit_or_rollback(thd,error);
+ error=ha_autocommit_or_rollback(thd,error);
+
err:
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
thd->lock=0;
}
+ thd->abort_on_warning= 0;
DBUG_RETURN(error);
}
@@ -386,12 +409,15 @@ err:
****************************************************************************/
static int
-read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
- READ_INFO &read_info, ulong skip_lines)
+read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
+ List<Item> &fields, READ_INFO &read_info, ulong skip_lines,
+ bool ignore_check_option_errors)
{
List_iterator_fast<Item> it(fields);
Item_field *sql_field;
+ TABLE *table= table_list->table;
ulonglong id;
+ bool no_trans_update;
DBUG_ENTER("read_fixed_length");
id= 0;
@@ -404,7 +430,7 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
{
if (thd->killed)
{
- my_error(ER_SERVER_SHUTDOWN,MYF(0));
+ thd->send_kill_message();
DBUG_RETURN(1);
}
if (skip_lines)
@@ -423,6 +449,7 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
#ifdef HAVE_purify
read_info.row_end[0]=0;
#endif
+ no_trans_update= !table->file->has_transactions();
while ((sql_field= (Item_field*) it++))
{
Field *field= sql_field->field;
@@ -442,7 +469,7 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
field->field_length)
length=field->field_length;
save_chr=pos[length]; pos[length]='\0'; // Safeguard aganst malloc
- field->store((char*) pos,length,read_info.read_charset);
+ field->store((char*) pos,length,read_info.read_charset);
pos[length]=save_chr;
if ((pos+=length) > read_info.row_end)
pos= read_info.row_end; /* Fills rest with space */
@@ -455,8 +482,20 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
ER_WARN_TOO_MANY_RECORDS,
ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count);
}
- if (write_record(table,&info))
+
+ switch (table_list->view_check_option(thd,
+ ignore_check_option_errors)) {
+ case VIEW_CHECK_SKIP:
+ read_info.next_line();
+ goto continue_loop;
+ case VIEW_CHECK_ERROR:
+ DBUG_RETURN(-1);
+ }
+
+ if (thd->killed || write_record(thd,table,&info))
DBUG_RETURN(1);
+ thd->no_trans_update= no_trans_update;
+
/*
If auto_increment values are used, save the first one
for LAST_INSERT_ID() and for the binary/update log.
@@ -477,6 +516,7 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count);
}
thd->row_count++;
+continue_loop:;
}
if (id && !read_info.error)
thd->insert_id(id); // For binary/update log
@@ -486,24 +526,28 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List<Item> &fields,
static int
-read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
+read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields, READ_INFO &read_info,
- String &enclosed, ulong skip_lines)
+ String &enclosed, ulong skip_lines,
+ bool ignore_check_option_errors)
{
List_iterator_fast<Item> it(fields);
Item_field *sql_field;
+ TABLE *table= table_list->table;
uint enclosed_length;
ulonglong id;
+ bool no_trans_update;
DBUG_ENTER("read_sep_field");
enclosed_length=enclosed.length();
id= 0;
+ no_trans_update= !table->file->has_transactions();
for (;;it.rewind())
{
if (thd->killed)
{
- my_error(ER_SERVER_SHUTDOWN,MYF(0));
+ thd->send_kill_message();
DBUG_RETURN(1);
}
while ((sql_field=(Item_field*) it++))
@@ -559,7 +603,18 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
}
}
- if (write_record(table,&info))
+
+ switch (table_list->view_check_option(thd,
+ ignore_check_option_errors)) {
+ case VIEW_CHECK_SKIP:
+ read_info.next_line();
+ goto continue_loop;
+ case VIEW_CHECK_ERROR:
+ DBUG_RETURN(-1);
+ }
+
+
+ if (thd->killed || write_record(thd, table, &info))
DBUG_RETURN(1);
/*
If auto_increment values are used, save the first one
@@ -571,6 +626,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
id= thd->last_insert_id;
if (table->next_number_field)
table->next_number_field->reset(); // Clear for next record
+ thd->no_trans_update= no_trans_update;
if (read_info.next_line()) // Skip to next line
break;
if (read_info.line_cuted)
@@ -579,8 +635,11 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table,
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS),
thd->row_count);
+ if (thd->killed)
+ DBUG_RETURN(1);
}
thd->row_count++;
+continue_loop:;
}
if (id && !read_info.error)
thd->insert_id(id); // For binary/update log
@@ -669,12 +728,11 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
my_free((gptr) buffer,MYF(0)); /* purecov: inspected */
error=1;
}
- else
+ else
{
/*
init_io_cache() will not initialize read_function member
- if the cache is READ_NET. The reason is explained in
- mysys/mf_iocache.c. So we work around the problem with a
+ if the cache is READ_NET. So we work around the problem with a
manual assignment
*/
need_end_io_cache = 1;