46 #include "sql_error.h"
47 #include "sp_rcontext.h"
173 Sql_condition::Sql_condition()
175 m_class_origin((const char*) NULL, 0, & my_charset_utf8_bin),
176 m_subclass_origin((const char*) NULL, 0, & my_charset_utf8_bin),
177 m_constraint_catalog((const char*) NULL, 0, & my_charset_utf8_bin),
178 m_constraint_schema((const char*) NULL, 0, & my_charset_utf8_bin),
179 m_constraint_name((const char*) NULL, 0, & my_charset_utf8_bin),
180 m_catalog_name((const char*) NULL, 0, & my_charset_utf8_bin),
181 m_schema_name((const char*) NULL, 0, & my_charset_utf8_bin),
182 m_table_name((const char*) NULL, 0, & my_charset_utf8_bin),
183 m_column_name((const char*) NULL, 0, & my_charset_utf8_bin),
184 m_cursor_name((const char*) NULL, 0, & my_charset_utf8_bin),
190 memset(m_returned_sqlstate, 0,
sizeof(m_returned_sqlstate));
193 void Sql_condition::init(
MEM_ROOT *mem_root)
195 DBUG_ASSERT(mem_root != NULL);
196 DBUG_ASSERT(m_mem_root == NULL);
197 m_mem_root= mem_root;
200 void Sql_condition::clear()
202 m_class_origin.length(0);
203 m_subclass_origin.length(0);
204 m_constraint_catalog.length(0);
205 m_constraint_schema.length(0);
206 m_constraint_name.length(0);
207 m_catalog_name.length(0);
208 m_schema_name.length(0);
209 m_table_name.length(0);
210 m_column_name.length(0);
211 m_cursor_name.length(0);
212 m_message_text.length(0);
214 m_level= Sql_condition::WARN_LEVEL_ERROR;
217 Sql_condition::Sql_condition(
MEM_ROOT *mem_root)
219 m_class_origin((const char*) NULL, 0, & my_charset_utf8_bin),
220 m_subclass_origin((const char*) NULL, 0, & my_charset_utf8_bin),
221 m_constraint_catalog((const char*) NULL, 0, & my_charset_utf8_bin),
222 m_constraint_schema((const char*) NULL, 0, & my_charset_utf8_bin),
223 m_constraint_name((const char*) NULL, 0, & my_charset_utf8_bin),
224 m_catalog_name((const char*) NULL, 0, & my_charset_utf8_bin),
225 m_schema_name((const char*) NULL, 0, & my_charset_utf8_bin),
226 m_table_name((const char*) NULL, 0, & my_charset_utf8_bin),
227 m_column_name((const char*) NULL, 0, & my_charset_utf8_bin),
228 m_cursor_name((const char*) NULL, 0, & my_charset_utf8_bin),
234 DBUG_ASSERT(mem_root != NULL);
235 memset(m_returned_sqlstate, 0,
sizeof(m_returned_sqlstate));
240 size_t len= src->length();
243 char* copy= (
char*) alloc_root(mem_root, len + 1);
246 memcpy(copy, src->ptr(), len);
248 dst->set(copy, len, src->charset());
256 Sql_condition::copy_opt_attributes(
const Sql_condition *cond)
258 DBUG_ASSERT(
this != cond);
259 copy_string(m_mem_root, & m_class_origin, & cond->m_class_origin);
260 copy_string(m_mem_root, & m_subclass_origin, & cond->m_subclass_origin);
261 copy_string(m_mem_root, & m_constraint_catalog, & cond->m_constraint_catalog);
262 copy_string(m_mem_root, & m_constraint_schema, & cond->m_constraint_schema);
263 copy_string(m_mem_root, & m_constraint_name, & cond->m_constraint_name);
264 copy_string(m_mem_root, & m_catalog_name, & cond->m_catalog_name);
265 copy_string(m_mem_root, & m_schema_name, & cond->m_schema_name);
266 copy_string(m_mem_root, & m_table_name, & cond->m_table_name);
267 copy_string(m_mem_root, & m_column_name, & cond->m_column_name);
268 copy_string(m_mem_root, & m_cursor_name, & cond->m_cursor_name);
272 Sql_condition::set(uint sql_errno,
const char* sqlstate,
273 Sql_condition::enum_warning_level
level,
const char*
msg)
275 DBUG_ASSERT(sql_errno != 0);
276 DBUG_ASSERT(sqlstate != NULL);
277 DBUG_ASSERT(msg != NULL);
279 m_sql_errno= sql_errno;
280 memcpy(m_returned_sqlstate, sqlstate, SQLSTATE_LENGTH);
281 m_returned_sqlstate[SQLSTATE_LENGTH]=
'\0';
284 set_builtin_message_text(msg);
289 Sql_condition::set_builtin_message_text(
const char* str)
297 copy= strdup_root(m_mem_root, str);
298 m_message_text.set(copy, strlen(copy), error_message_charset_info);
299 DBUG_ASSERT(! m_message_text.is_alloced());
305 return m_message_text.ptr();
311 return m_message_text.length();
315 Sql_condition::set_sqlstate(
const char* sqlstate)
317 memcpy(m_returned_sqlstate, sqlstate, SQLSTATE_LENGTH);
318 m_returned_sqlstate[SQLSTATE_LENGTH]=
'\0';
322 { STRING_WITH_LEN(
"ISO 9075") },
323 { STRING_WITH_LEN(
"MySQL") }
326 void Sql_condition::set_class_origins()
331 cls[0]= m_returned_sqlstate[0];
332 cls[1]= m_returned_sqlstate[1];
335 DBUG_ASSERT(my_isdigit(&my_charset_latin1, cls[0]) ||
336 my_isupper(&my_charset_latin1, cls[0]));
338 DBUG_ASSERT(my_isdigit(&my_charset_latin1, cls[1]) ||
339 my_isupper(&my_charset_latin1, cls[1]));
350 if (((cls[0] >=
'0' && cls[0] <=
'4') || (cls[0] >=
'A' && cls[0] <=
'H')) &&
351 ((cls[1] >=
'0' && cls[1] <=
'9') || (cls[1] >=
'A' && cls[1] <=
'Z')))
354 m_class_origin.set_ascii(sqlstate_origin[0].str,
355 sqlstate_origin[0].length);
357 m_subclass_origin.set_ascii(sqlstate_origin[0].str,
358 sqlstate_origin[0].length);
363 m_class_origin.set_ascii(sqlstate_origin[1].str, sqlstate_origin[1].length);
364 if (!memcmp(m_returned_sqlstate + 2, STRING_WITH_LEN(
"000")))
366 m_subclass_origin.set_ascii(sqlstate_origin[0].str,
367 sqlstate_origin[0].length);
370 m_subclass_origin.set_ascii(sqlstate_origin[1].str,
371 sqlstate_origin[1].length);
375 Diagnostics_area::Diagnostics_area()
376 : m_main_wi(0, false)
378 push_warning_info(&m_main_wi);
380 reset_diagnostics_area();
383 Diagnostics_area::Diagnostics_area(ulonglong warning_info_id,
384 bool allow_unlimited_warnings)
385 : m_main_wi(warning_info_id, allow_unlimited_warnings)
387 push_warning_info(&m_main_wi);
389 reset_diagnostics_area();
401 DBUG_ENTER(
"reset_diagnostics_area");
403 set_overwrite_status(
false);
409 m_statement_warn_count= 0;
411 get_warning_info()->clear_error_condition();
426 ulonglong last_insert_id,
429 DBUG_ENTER(
"set_ok_status");
430 DBUG_ASSERT(! is_set());
435 if (is_error() || is_disabled())
438 m_statement_warn_count= current_statement_warn_count();
439 m_affected_rows= affected_rows;
440 m_last_insert_id= last_insert_id;
442 strmake(m_message, message,
sizeof(m_message) - 1);
457 DBUG_ENTER(
"set_eof_status");
459 DBUG_ASSERT(! is_set());
464 if (is_error() || is_disabled())
472 m_statement_warn_count= (thd->sp_runtime_ctx ?
474 current_statement_warn_count());
493 mysql_errno_to_sqlstate(sql_errno),
512 const char *sqlstate,
515 DBUG_ENTER(
"set_error_status");
521 DBUG_ASSERT(! is_set() || m_can_overwrite_status);
524 DBUG_ASSERT(message);
527 DBUG_ASSERT(sqlstate);
538 m_sql_errno= sql_errno;
539 memcpy(m_sqlstate, sqlstate, SQLSTATE_LENGTH);
540 m_sqlstate[SQLSTATE_LENGTH]=
'\0';
541 strmake(m_message, message,
sizeof(m_message)-1);
543 get_warning_info()->set_error_condition(error_condition);
561 DBUG_ASSERT(! is_set());
565 Warning_info::Warning_info(ulonglong warn_id_arg,
bool allow_unlimited_warnings)
566 :m_current_statement_warn_count(0),
567 m_current_row_for_warning(1),
568 m_warn_id(warn_id_arg),
569 m_error_condition(NULL),
570 m_allow_unlimited_warnings(allow_unlimited_warnings),
574 init_sql_alloc(&m_warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
576 memset(m_warn_count, 0,
sizeof(m_warn_count));
579 Warning_info::~Warning_info()
581 free_root(&m_warn_root,MYF(0));
585 bool Warning_info::has_sql_condition(
const char *message_str,
586 ulong message_length)
const
601 void Warning_info::clear(ulonglong new_id)
605 m_marked_sql_conditions.empty();
606 free_root(&m_warn_root, MYF(0));
607 memset(m_warn_count, 0,
sizeof(m_warn_count));
608 m_current_statement_warn_count= 0;
609 m_current_row_for_warning= 1;
610 clear_error_condition();
614 void Warning_info::append_warning_info(THD *thd,
const Warning_info *source)
618 const Sql_condition *src_error_condition = source->get_error_condition();
623 Sql_condition *new_error= Warning_info::push_warning(thd, err);
625 if (src_error_condition && src_error_condition == err)
626 set_error_condition(new_error);
628 if (source->is_marked_for_removal(err))
629 mark_condition_for_removal(new_error);
652 if (cond->
get_level() == Sql_condition::WARN_LEVEL_ERROR)
657 if (src_wi->is_marked_for_removal(cond))
658 wi->mark_condition_for_removal(new_condition);
663 void Warning_info::mark_sql_conditions_for_removal()
665 Sql_condition_list::Iterator it(m_warn_list);
669 mark_condition_for_removal(cond);
673 void Warning_info::remove_marked_sql_conditions()
680 m_warn_list.remove(cond);
682 m_current_statement_warn_count--;
683 if (cond == m_error_condition)
684 m_error_condition= NULL;
687 m_marked_sql_conditions.empty();
691 bool Warning_info::is_marked_for_removal(
const Sql_condition *cond)
const
707 void Warning_info::reserve_space(THD *thd, uint count)
709 while (m_warn_list.elements() &&
710 (m_warn_list.elements() + count) > thd->variables.max_error_count)
711 m_warn_list.remove(m_warn_list.front());
715 uint sql_errno,
const char* sqlstate,
716 Sql_condition::enum_warning_level
level,
723 if (m_allow_unlimited_warnings ||
724 m_warn_list.elements() < thd->variables.max_error_count)
729 cond->set(sql_errno, sqlstate, level, msg);
730 m_warn_list.push_back(cond);
733 m_warn_count[(uint) level]++;
736 m_current_statement_warn_count++;
749 new_condition->copy_opt_attributes(sql_condition);
751 return new_condition;
765 void push_warning(THD *thd, Sql_condition::enum_warning_level level,
766 uint
code,
const char *msg)
768 DBUG_ENTER(
"push_warning");
769 DBUG_PRINT(
"enter", (
"code: %d, msg: %s", code, msg));
776 DBUG_ASSERT(level != Sql_condition::WARN_LEVEL_ERROR);
778 if (level == Sql_condition::WARN_LEVEL_ERROR)
779 level= Sql_condition::WARN_LEVEL_WARN;
781 (void) thd->raise_condition(code, NULL, level, msg);
798 void push_warning_printf(THD *thd, Sql_condition::enum_warning_level level,
799 uint code,
const char *format, ...)
802 char warning[MYSQL_ERRMSG_SIZE];
803 DBUG_ENTER(
"push_warning_printf");
804 DBUG_PRINT(
"enter",(
"warning: %u", code));
806 DBUG_ASSERT(code != 0);
807 DBUG_ASSERT(format != NULL);
809 va_start(args,format);
810 my_vsnprintf_ex(&my_charset_utf8_general_ci, warning,
811 sizeof(warning), format, args);
813 push_warning(thd, level, code, warning);
836 { C_STRING_WITH_LEN(
"Note") },
837 { C_STRING_WITH_LEN(
"Warning") },
838 { C_STRING_WITH_LEN(
"Error") },
839 { C_STRING_WITH_LEN(
"?") }
842 bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
845 DBUG_ENTER(
"mysqld_show_warnings");
847 DBUG_ASSERT(thd->get_stmt_da()->is_warning_info_read_only());
853 if (thd->protocol->send_result_set_metadata(&field_list,
854 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
858 SELECT_LEX *sel= &thd->lex->select_lex;
859 SELECT_LEX_UNIT *unit= &thd->lex->unit;
863 unit->set_limit(sel);
866 thd->get_stmt_da()->sql_conditions();
870 if (!(levels_to_show & ((ulong) 1 << err->
get_level())))
872 if (++idx <= unit->offset_limit_cnt)
874 if (idx > unit->select_limit_cnt)
876 protocol->prepare_for_resend();
878 warning_level_names[err->
get_level()].length,
879 system_charset_info);
883 system_charset_info);
884 if (protocol->write())
889 thd->get_stmt_da()->set_warning_info_read_only(FALSE);
895 ErrConvString::ErrConvString(
double nr)
898 DBUG_ASSERT(
sizeof(err_buffer) > DBL_DIG + 8);
899 buf_length= my_gcvt(nr, MY_GCVT_ARG_DOUBLE,
900 sizeof(err_buffer) - 1, err_buffer, NULL);
905 ErrConvString::ErrConvString(
const my_decimal *nr)
907 int len=
sizeof(err_buffer);
908 (void) decimal2string((
decimal_t *) nr, err_buffer, &len, 0, 0, 0);
909 buf_length= (uint) len;
913 ErrConvString::ErrConvString(
const struct st_mysql_time *ltime, uint dec)
915 buf_length= my_TIME_to_str(ltime, err_buffer,
916 MY_MIN(dec, DATETIME_MAX_DECIMALS));
933 uint err_conv(
char *buff,
size_t to_length,
const char *from,
937 const char *from_start= from;
940 DBUG_ASSERT(to_length > 0);
942 if (from_cs == &my_charset_bin)
948 if ((uint)(from - from_start) >= from_length ||
955 char_code= ((uchar) *from);
956 if (char_code >= 0x20 && char_code <= 0x7E)
964 if (res + 4 >= to_length)
969 res+= my_snprintf(to, 5,
"\\x%02X", (uint) char_code);
978 res= copy_and_convert(to, to_length, system_charset_info,
979 from, from_length, from_cs, &errors);
1002 uint32 convert_error_message(
char *to, uint32 to_length,
1004 const char *from, uint32 from_length,
1009 const uchar *from_end= (
const uchar*) from+from_length;
1012 my_charset_conv_mb_wc mb_wc= from_cs->cset->mb_wc;
1013 my_charset_conv_wc_mb wc_mb;
1014 uint error_count= 0;
1017 DBUG_ASSERT(to_length > 0);
1020 to_end= (uchar*) (to + to_length);
1022 if (!to_cs || from_cs == to_cs || to_cs == &my_charset_bin)
1024 length= MY_MIN(to_length, from_length);
1025 memmove(to, from, length);
1030 wc_mb= to_cs->cset->wc_mb;
1033 if ((cnvres= (*mb_wc)(from_cs, &wc, (uchar*) from, from_end)) > 0)
1039 else if (cnvres == MY_CS_ILSEQ)
1041 wc= (ulong) (uchar) *from;
1047 if ((cnvres= (*wc_mb)(to_cs, wc, (uchar*) to, to_end)) > 0)
1049 else if (cnvres == MY_CS_ILUNI)
1051 length= (wc <= 0xFFFF) ? 6 : 9 ;
1052 if ((uchar*)(to + length) >= to_end)
1054 cnvres= my_snprintf(to, 9,
1055 (wc <= 0xFFFF) ?
"\\%04X" :
"\\+%06X", (uint) wc);
1063 *errors= error_count;
1064 return (uint32) (to - to_start);
1079 bool is_sqlstate_valid(
const LEX_STRING *sqlstate)
1081 if (sqlstate->length != 5)
1084 for (
int i= 0 ;
i < 5 ; ++
i)
1086 char c = sqlstate->str[
i];
1088 if ((c <
'0' ||
'9' < c) &&
1089 (c <
'A' ||
'Z' < c))