diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_strfunc.h | 2 | ||||
-rw-r--r-- | sql/log_event.cc | 2 | ||||
-rw-r--r-- | sql/mysql_priv.h | 5 | ||||
-rw-r--r-- | sql/sql_base.cc | 4 | ||||
-rw-r--r-- | sql/sql_insert.cc | 19 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 | ||||
-rw-r--r-- | sql/sql_load.cc | 65 | ||||
-rw-r--r-- | sql/sql_parse.cc | 3 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 | ||||
-rw-r--r-- | sql/table.cc | 29 | ||||
-rw-r--r-- | sql/table.h | 2 |
11 files changed, 93 insertions, 41 deletions
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 357ce0af45a..49429a55cac 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -218,7 +218,7 @@ public: Item_func_substr_index(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {} String *val_str(String *); void fix_length_and_dec(); - const char *func_name() const { return "substr_index"; } + const char *func_name() const { return "substring_index"; } }; diff --git a/sql/log_event.cc b/sql/log_event.cc index 01dcb2af21c..c2a684ffe03 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2548,7 +2548,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, thd->net.pkt_nr = net->pkt_nr; } if (mysql_load(thd, &ex, &tables, field_list, handle_dup, net != 0, - TL_WRITE)) + TL_WRITE, 0)) thd->query_error = 1; if (thd->cuted_fields) { diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index a10722cd726..d8916149b77 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -838,9 +838,10 @@ inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table, bool eval_const_cond(COND *cond); /* sql_load.cc */ -int mysql_load(THD *thd,sql_exchange *ex, TABLE_LIST *table_list, +int mysql_load(THD *thd, sql_exchange *ex, TABLE_LIST *table_list, List<Item> &fields, enum enum_duplicates handle_duplicates, - bool local_file,thr_lock_type lock_type); + bool local_file, thr_lock_type lock_type, + bool ignore_check_option_errors); int write_record(THD *thd, TABLE *table, COPY_INFO *info); /* sql_manager.cc */ diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8199c6fcdce..4f273fbd0c4 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2697,7 +2697,9 @@ bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds) table->keys_in_use_for_query.subtract(map); } table->used_keys.intersect(table->keys_in_use_for_query); - if (table_list->ancestor && table_list->setup_ancestor(thd, conds)) + if (table_list->ancestor && + table_list->setup_ancestor(thd, conds, + table_list->effective_with_check)) DBUG_RETURN(1); } if (tablenr > MAX_TABLES) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 36ac56799de..d9002c2da29 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -319,14 +319,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, break; } } - if ((res= table_list->view_check_option(thd, ignore_err)) == - VIEW_CHECK_SKIP) - continue; - else if (res == VIEW_CHECK_ERROR) - { - error= 1; - break; - } /* FIXME: Actually we should do this before @@ -336,6 +328,17 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, table->triggers->process_triggers(thd, TRG_EVENT_INSERT, TRG_ACTION_BEFORE); + if ((res= table_list->view_check_option(thd, + (values_list.elements == 1 ? + 0 : + ignore_err))) == + VIEW_CHECK_SKIP) + continue; + else if (res == VIEW_CHECK_ERROR) + { + error= 1; + break; + } #ifndef EMBEDDED_LIBRARY if (lock_type == TL_WRITE_DELAYED) { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 59dc1a7ee8b..73f99d0dd68 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1616,6 +1616,7 @@ bool st_lex::can_use_merged() case SQLCOM_INSERT_SELECT: case SQLCOM_REPLACE: case SQLCOM_REPLACE_SELECT: + case SQLCOM_LOAD: return TRUE; default: return FALSE; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 28de2b9d116..95025a8fd77 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -71,16 +71,19 @@ 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, List<Item> &fields, enum enum_duplicates handle_duplicates, - bool read_file_from_client,thr_lock_type lock_type) + bool read_file_from_client,thr_lock_type lock_type, + bool ignore_check_option_errors) { char name[FN_REFLEN]; File file; @@ -88,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; bool is_fifo=0; #ifndef EMBEDDED_LIBRARY LOAD_FILE_INFO lf_info; @@ -117,8 +121,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, table_list->lock_type= lock_type; if ((res= open_and_lock_tables(thd, table_list))) DBUG_RETURN(res); - /* TODO: add key check when we will support VIEWs in LOAD */ - if (!table_list->updatable) + if (setup_tables(thd, table_list, &unused_conds)) + DBUG_RETURN(-1); + if (!table_list->updatable || check_key_in_view(thd, table_list)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD"); DBUG_RETURN(-1); @@ -294,11 +299,12 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, 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_check_option_errors); 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_check_option_errors); if (table->file->end_bulk_insert()) error=1; /* purecov: inspected */ table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); @@ -401,11 +407,13 @@ 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"); @@ -472,6 +480,17 @@ 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); } + + 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; @@ -496,6 +515,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 @@ -505,12 +525,14 @@ 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; @@ -580,6 +602,18 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count); } } + + 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); /* @@ -605,6 +639,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, DBUG_RETURN(1); } thd->row_count++; +continue_loop:; } if (id && !read_info.error) thd->insert_id(id); // For binary/update log diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f93aaf09933..54a1240c0ab 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3135,7 +3135,8 @@ unsent_create_error: goto error; } res= mysql_load(thd, lex->exchange, first_table, lex->field_list, - lex->duplicates, (bool) lex->local_file, lex->lock_option); + lex->duplicates, (bool) lex->local_file, + lex->lock_option, lex->duplicates == DUP_IGNORE); break; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d2964df008b..6fb13684098 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7921,7 +7921,7 @@ check_option: /* empty */ { Lex->create_view_check= VIEW_CHECK_NONE; } | WITH CHECK_SYM OPTION - { Lex->create_view_check= VIEW_CHECK_LOCAL; } + { Lex->create_view_check= VIEW_CHECK_CASCADED; } | WITH CASCADED CHECK_SYM OPTION { Lex->create_view_check= VIEW_CHECK_CASCADED; } | WITH LOCAL_SYM CHECK_SYM OPTION diff --git a/sql/table.cc b/sql/table.cc index bfe5395c3db..e372de57177 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1497,8 +1497,10 @@ void st_table_list::set_ancestor() SYNOPSIS st_table_list::setup_ancestor() - thd - thread handler - conds - condition of this JOIN + thd - thread handler + conds - condition of this JOIN + check_opt_type - WHITH CHECK OPTION type (VIEW_CHECK_NONE, + VIEW_CHECK_LOCAL, VIEW_CHECK_CASCADED) DESCRIPTION It is: @@ -1513,7 +1515,8 @@ void st_table_list::set_ancestor() 1 - error */ -bool st_table_list::setup_ancestor(THD *thd, Item **conds) +bool st_table_list::setup_ancestor(THD *thd, Item **conds, + uint8 check_opt_type) { Item **transl; SELECT_LEX *select= &view->select_lex; @@ -1527,7 +1530,10 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) DBUG_ENTER("st_table_list::setup_ancestor"); if (ancestor->ancestor && - ancestor->setup_ancestor(thd, conds)) + ancestor->setup_ancestor(thd, conds, + (check_opt_type == VIEW_CHECK_CASCADED ? + VIEW_CHECK_CASCADED : + VIEW_CHECK_NONE))) DBUG_RETURN(1); if (field_translation) @@ -1586,23 +1592,26 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) field_translation= transl; /* TODO: sort this list? Use hash for big number of fields */ - if (where) + if (where || + (check_opt_type == VIEW_CHECK_CASCADED && + ancestor->check_option)) { Item_arena *arena= thd->current_arena, backup; TABLE_LIST *tbl= this; if (arena->is_conventional()) arena= 0; // For easier test - if (!where->fixed && where->fix_fields(thd, ancestor, &where)) + if (where && !where->fixed && where->fix_fields(thd, ancestor, &where)) goto err; if (arena) thd->set_n_backup_item_arena(arena, &backup); - if (effective_with_check) + if (check_opt_type) { - check_option= where->copy_andor_structure(thd); - if (effective_with_check == VIEW_CHECK_CASCADED) + if (where) + check_option= where->copy_andor_structure(thd); + if (check_opt_type == VIEW_CHECK_CASCADED) { check_option= and_conds(check_option, ancestor->check_option); } @@ -1612,7 +1621,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) check that it is not VIEW in which we insert with INSERT SELECT (in this case we can't add view WHERE condition to main SELECT_LEX) */ - if (!no_where_clause) + if (where && !no_where_clause) { /* Go up to join tree and try to find left join */ for (; tbl; tbl= tbl->embedding) diff --git a/sql/table.h b/sql/table.h index 605cd516d9c..3e2a61d5a21 100644 --- a/sql/table.h +++ b/sql/table.h @@ -283,7 +283,7 @@ typedef struct st_table_list void calc_md5(char *buffer); void set_ancestor(); int view_check_option(THD *thd, bool ignore_failure); - bool setup_ancestor(THD *thd, Item **conds); + bool setup_ancestor(THD *thd, Item **conds, uint8 check_option); bool placeholder() {return derived || view; } void print(THD *thd, String *str); inline st_table_list *next_independent() |