diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/lex.h | 1 | ||||
-rw-r--r-- | sql/sp_rcontext.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.cc | 6 | ||||
-rw-r--r-- | sql/sql_class.h | 23 | ||||
-rw-r--r-- | sql/sql_error.cc | 3 | ||||
-rw-r--r-- | sql/sql_error.h | 11 | ||||
-rw-r--r-- | sql/sql_get_diagnostics.cc | 2 | ||||
-rw-r--r-- | sql/sql_get_diagnostics.h | 3 | ||||
-rw-r--r-- | sql/sql_insert.cc | 9 | ||||
-rw-r--r-- | sql/sql_parse.cc | 1 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 4 | ||||
-rw-r--r-- | sql/sql_signal.cc | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 10 |
13 files changed, 69 insertions, 8 deletions
diff --git a/sql/lex.h b/sql/lex.h index 8643197e862..57d8d807909 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -222,6 +222,7 @@ SYMBOL symbols[] = { { "ENUM", SYM(ENUM)}, { "ERROR", SYM(ERROR_SYM)}, { "ERRORS", SYM(ERRORS)}, + { "ERROR_INDEX", SYM(ERROR_INDEX_SYM)}, { "ESCAPE", SYM(ESCAPE_SYM)}, { "ESCAPED", SYM(ESCAPED)}, { "EVENT", SYM(EVENT_SYM)}, diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index c4c19dd39f6..7170018c995 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -518,7 +518,7 @@ bool sp_rcontext::handle_sql_condition(THD *thd, found_condition= new (callers_arena->mem_root) Sql_condition(callers_arena->mem_root, da->get_error_condition_identity(), - da->message()); + da->message(), 0); } } else if (da->current_statement_warn_count()) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c88bfc4c484..34d220aa27e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -908,6 +908,7 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) org_charset= 0; /* Restore THR_THD */ set_current_thd(old_THR_THD); + current_insert_index= 0; } @@ -1055,6 +1056,8 @@ Sql_condition* THD::raise_condition(uint sql_errno, { Diagnostics_area *da= get_stmt_da(); Sql_condition *cond= NULL; + ulonglong saved_error_index; + DBUG_ENTER("THD::raise_condition"); DBUG_ASSERT(level < Sql_condition::WARN_LEVEL_END); @@ -1149,7 +1152,10 @@ Sql_condition* THD::raise_condition(uint sql_errno, if (likely(!(is_fatal_error && (sql_errno == EE_OUTOFMEMORY || sql_errno == ER_OUTOFMEMORY)))) { + saved_error_index= this->current_insert_index; + this->current_insert_index= this->correct_error_index(sql_errno); cond= da->push_warning(this, sql_errno, sqlstate, level, ucid, msg); + this->current_insert_index= saved_error_index; } DBUG_RETURN(cond); } diff --git a/sql/sql_class.h b/sql/sql_class.h index e569fcd32d6..791e67b4f59 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -5502,6 +5502,29 @@ public: { lex= backup_lex; } + + /* + Stores the the processed record during INSERT/REPLACE. Used for assigning + value of error_index in case of warning or error. + */ + ulonglong current_insert_index; + + /* + Error may take place in prepare phase and it might not be because of + rows/values we are inserting into the table, it could be because of say + something like wrong field name. In such case we want to return 0 + for error index. + */ + ulonglong correct_error_index(uint error_no) + { + if (error_no == ER_FIELD_SPECIFIED_TWICE || + error_no == ER_BAD_FIELD_ERROR || + error_no == ER_VIEW_NO_INSERT_FIELD_LIST || + error_no == ER_VIEW_MULTIUPDATE) + return 0; + + return current_insert_index; + } }; diff --git a/sql/sql_error.cc b/sql/sql_error.cc index cef9e6cec00..6961f1b258e 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -672,7 +672,8 @@ Sql_condition *Warning_info::push_warning(THD *thd, if (m_allow_unlimited_warnings || m_warn_list.elements() < thd->variables.max_error_count) { - cond= new (& m_warn_root) Sql_condition(& m_warn_root, *value, msg); + cond= new (& m_warn_root) Sql_condition(& m_warn_root, *value, msg, + thd->current_insert_index); if (cond) m_warn_list.push_back(cond); } diff --git a/sql/sql_error.h b/sql/sql_error.h index 6b0d4d7749c..113b51454c6 100644 --- a/sql/sql_error.h +++ b/sql/sql_error.h @@ -396,7 +396,7 @@ private: */ Sql_condition() :m_mem_root(NULL) - { } + { error_index= 0; } /** Complete the Sql_condition initialisation. @@ -419,6 +419,7 @@ private: :m_mem_root(mem_root) { DBUG_ASSERT(mem_root != NULL); + error_index= 0; } Sql_condition(MEM_ROOT *mem_root, const Sql_user_condition_identity &ucid) @@ -426,6 +427,7 @@ private: m_mem_root(mem_root) { DBUG_ASSERT(mem_root != NULL); + error_index= 0; } /** Constructor for a fixed message text. @@ -436,7 +438,8 @@ private: */ Sql_condition(MEM_ROOT *mem_root, const Sql_condition_identity &value, - const char *msg) + const char *msg, + ulonglong current_error_index) :Sql_condition_identity(value), m_mem_root(mem_root) { @@ -444,6 +447,7 @@ private: DBUG_ASSERT(value.get_sql_errno() != 0); DBUG_ASSERT(msg != NULL); set_builtin_message_text(msg); + error_index= current_error_index; } /** Destructor. */ @@ -497,6 +501,9 @@ private: /** Memory root to use to hold condition item values. */ MEM_ROOT *m_mem_root; + + /* Index of error for INSERT/REPLACE statement. */ + ulonglong error_index; }; /////////////////////////////////////////////////////////////////////////// diff --git a/sql/sql_get_diagnostics.cc b/sql/sql_get_diagnostics.cc index 197bf5e7a00..0de1cde3c49 100644 --- a/sql/sql_get_diagnostics.cc +++ b/sql/sql_get_diagnostics.cc @@ -338,6 +338,8 @@ Condition_information_item::get_value(THD *thd, const Sql_condition *cond) str.set_ascii(cond->get_sqlstate(), strlen(cond->get_sqlstate())); value= make_utf8_string_item(thd, &str); break; + case ERROR_INDEX: + value= new (thd->mem_root) Item_uint(thd, cond->error_index); } DBUG_RETURN(value); diff --git a/sql/sql_get_diagnostics.h b/sql/sql_get_diagnostics.h index f283aa5b2c6..69432f9cf86 100644 --- a/sql/sql_get_diagnostics.h +++ b/sql/sql_get_diagnostics.h @@ -254,7 +254,8 @@ public: CURSOR_NAME, MESSAGE_TEXT, MYSQL_ERRNO, - RETURNED_SQLSTATE + RETURNED_SQLSTATE, + ERROR_INDEX }; /** diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index eaafb8d7742..7b2b820752c 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -711,6 +711,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, Name_resolution_context_state ctx_state; SELECT_LEX *returning= thd->lex->has_returning() ? thd->lex->returning() : 0; unsigned char *readbuff= NULL; + thd->current_insert_index= 0; #ifndef EMBEDDED_LIBRARY char *query= thd->query(); @@ -830,7 +831,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, while ((values= its++)) { - counter++; + thd->current_insert_index= ++counter; if (values->elements != value_count) { my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); @@ -842,6 +843,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, switch_to_nullable_trigger_fields(*values, table); } its.rewind (); + thd->current_insert_index= 0; /* Restore the current context. */ ctx_state.restore_state(context, table_list); @@ -1008,6 +1010,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, while ((values= its++)) { + thd->current_insert_index++; if (fields.elements || !value_count) { /* @@ -1131,6 +1134,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, } while (bulk_parameters_iterations(thd)); values_loop_end: + thd->current_insert_index= 0; free_underlaid_joins(thd, thd->lex->first_select_lex()); joins_freed= TRUE; @@ -1606,6 +1610,8 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, bool res= 0; table_map map= 0; TABLE *table; + thd->current_insert_index= 1; + DBUG_ENTER("mysql_prepare_insert"); DBUG_PRINT("enter", ("table_list: %p view: %d", table_list, (int) insert_into_view)); @@ -1659,6 +1665,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, if (!res) res= setup_fields(thd, Ref_ptr_array(), update_values, MARK_COLUMNS_READ, 0, NULL, 0); + thd->current_insert_index= 0; if (!res && duplic == DUP_UPDATE) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b9d3eec5a60..d853b09b354 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7978,6 +7978,7 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, LEX *lex= thd->lex; bool err= parse_sql(thd, parser_state, NULL, true); + thd->current_insert_index= 0; if (likely(!err)) { diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 09ad632dd98..4d92d46f9c2 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1338,9 +1338,10 @@ static bool mysql_test_insert_common(Prepared_statement *stmt, table_list->table_name.str)); goto error; } + thd->current_insert_index= 0; while ((values= its++)) { - counter++; + thd->current_insert_index= ++counter; if (values->elements != value_count) { my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); @@ -1350,6 +1351,7 @@ static bool mysql_test_insert_common(Prepared_statement *stmt, *values, COLUMNS_READ, 0, NULL, 0)) goto error; } + thd->current_insert_index= 0; } DBUG_RETURN(FALSE); diff --git a/sql/sql_signal.cc b/sql/sql_signal.cc index 8e973f9b0b3..5a085c99de7 100644 --- a/sql/sql_signal.cc +++ b/sql/sql_signal.cc @@ -419,7 +419,7 @@ bool Sql_cmd_resignal::execute(THD *thd) DBUG_RETURN(result); } - Sql_condition signaled_err(thd->mem_root, *signaled, signaled->message); + Sql_condition signaled_err(thd->mem_root, *signaled, signaled->message, 0); if (m_cond) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 89e20165984..57201b22802 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -971,6 +971,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token <kwd> MUTEX_SYM %token <kwd> MYSQL_SYM %token <kwd> MYSQL_ERRNO_SYM +%token <kwd> ERROR_INDEX_SYM %token <kwd> NAMES_SYM /* SQL-2003-N */ %token <kwd> NAME_SYM /* SQL-2003-N */ %token <kwd> NATIONAL_SYM /* SQL-2003-R */ @@ -3627,6 +3628,8 @@ condition_information_item_name: { $$= Condition_information_item::MYSQL_ERRNO; } | RETURNED_SQLSTATE_SYM { $$= Condition_information_item::RETURNED_SQLSTATE; } + | ERROR_INDEX_SYM + { $$= Condition_information_item::ERROR_INDEX; } ; sp_decl_ident: @@ -12915,6 +12918,7 @@ insert_table: //lex->field_list.empty(); lex->many_values.empty(); lex->insert_list=0; + thd->current_insert_index= lex->many_values.elements+1; } ; @@ -12924,11 +12928,14 @@ insert_field_spec: | SET { LEX *lex=Lex; + ulonglong saved_current_insert_index= thd->current_insert_index; if (unlikely(!(lex->insert_list= new (thd->mem_root) List_item)) || unlikely(lex->many_values.push_back(lex->insert_list, thd->mem_root))) MYSQL_YYABORT; lex->current_select->parsing_place= NO_MATTER; + if (saved_current_insert_index < lex->many_values.elements) + thd->current_insert_index++; } ident_eq_list ; @@ -13009,6 +13016,7 @@ no_braces: if (unlikely(lex->many_values.push_back(lex->insert_list, thd->mem_root))) MYSQL_YYABORT; + thd->current_insert_index++; } ; @@ -13024,6 +13032,7 @@ no_braces_with_names: if (unlikely(lex->many_values.push_back(lex->insert_list, thd->mem_root))) MYSQL_YYABORT; + thd->current_insert_index++; } ; @@ -15652,6 +15661,7 @@ keyword_sp_var_and_label: | INVOKER_SYM | IMPORT | INDEXES + | ERROR_INDEX_SYM | INITIAL_SIZE_SYM | IO_SYM | IPC_SYM |