summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/lex.h1
-rw-r--r--sql/sp_rcontext.cc2
-rw-r--r--sql/sql_class.cc6
-rw-r--r--sql/sql_class.h23
-rw-r--r--sql/sql_error.cc3
-rw-r--r--sql/sql_error.h11
-rw-r--r--sql/sql_get_diagnostics.cc2
-rw-r--r--sql/sql_get_diagnostics.h3
-rw-r--r--sql/sql_insert.cc9
-rw-r--r--sql/sql_parse.cc1
-rw-r--r--sql/sql_prepare.cc4
-rw-r--r--sql/sql_signal.cc2
-rw-r--r--sql/sql_yacc.yy10
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