sql_error.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 1995-2002 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA */
  13. /**********************************************************************
  14. This file contains the implementation of error and warnings related
  15.   - Whenever an error or warning occurred, it pushes it to a warning list
  16.     that the user can retrieve with SHOW WARNINGS or SHOW ERRORS.
  17.   - For each statement, we return the number of warnings generated from this
  18.     command.  Note that this can be different from @@warning_count as
  19.     we reset the warning list only for questions that uses a table.
  20.     This is done to allow on to do:
  21.     INSERT ...;
  22.     SELECT @@warning_count;
  23.     SHOW WARNINGS;
  24.     (If we would reset after each command, we could not retrieve the number
  25.      of warnings)
  26.   - When client requests the information using SHOW command, then 
  27.     server processes from this list and returns back in the form of 
  28.     resultset.
  29.     Supported syntaxes:
  30.     SHOW [COUNT(*)] ERRORS [LIMIT [offset,] rows]
  31.     SHOW [COUNT(*)] WARNINGS [LIMIT [offset,] rows]
  32.     SELECT @@warning_count, @@error_count;
  33. ***********************************************************************/
  34. #include "mysql_priv.h"
  35. /*
  36.   Store a new message in an error object
  37.   This is used to in group_concat() to register how many warnings we actually
  38.   got after the query has been executed.
  39. */
  40. void MYSQL_ERROR::set_msg(THD *thd, const char *msg_arg)
  41. {
  42.   msg= strdup_root(&thd->warn_root, msg_arg);
  43. }
  44. /*
  45.   Reset all warnings for the thread
  46.   SYNOPSIS
  47.     mysql_reset_errors()
  48.     thd Thread handle
  49.   IMPLEMENTATION
  50.     Don't reset warnings if this has already been called for this query.
  51.     This may happen if one gets a warning during the parsing stage,
  52.     in which case push_warnings() has already called this function.
  53. */  
  54. void mysql_reset_errors(THD *thd)
  55. {
  56.   DBUG_ENTER("mysql_reset_errors");
  57.   if (thd->query_id != thd->warn_id)
  58.   {
  59.     thd->warn_id= thd->query_id;
  60.     free_root(&thd->warn_root,MYF(0));
  61.     bzero((char*) thd->warn_count, sizeof(thd->warn_count));
  62.     thd->warn_list.empty();
  63.     thd->row_count= 1; // by default point to row 1
  64.   }
  65.   DBUG_VOID_RETURN;
  66. }
  67. /* 
  68.   Push the warning/error to error list if there is still room in the list
  69.   SYNOPSIS
  70.     push_warning()
  71.     thd Thread handle
  72.     level Severity of warning (note, warning, error ...)
  73.     code Error number
  74.     msg Clear error message
  75.     
  76.   RETURN
  77.     pointer on MYSQL_ERROR object
  78. */
  79. MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, 
  80.                           uint code, const char *msg)
  81. {
  82.   MYSQL_ERROR *err= 0;
  83.   DBUG_ENTER("push_warning");
  84.   if (level == MYSQL_ERROR::WARN_LEVEL_NOTE && !(thd->options & OPTION_SQL_NOTES))
  85.     return(0);
  86.   query_cache_abort(&thd->net);
  87.   if (thd->query_id != thd->warn_id)
  88.     mysql_reset_errors(thd);
  89.   if (thd->warn_list.elements < thd->variables.max_error_count)
  90.   {
  91.     /*
  92.       The following code is here to change the allocation to not
  93.       use the thd->mem_root, which is freed after each query
  94.     */
  95.     MEM_ROOT *old_root= thd->mem_root;
  96.     thd->mem_root= &thd->warn_root;
  97.     err= new MYSQL_ERROR(thd, code, level, msg);
  98.     if (err)
  99.       thd->warn_list.push_back(err);
  100.     thd->mem_root= old_root;
  101.   }
  102.   thd->warn_count[(uint) level]++;
  103.   thd->total_warn_count++;
  104.   DBUG_RETURN(err);
  105. }
  106. /*
  107.   Push the warning/error to error list if there is still room in the list
  108.   SYNOPSIS
  109.     push_warning_printf()
  110.     thd Thread handle
  111.     level Severity of warning (note, warning, error ...)
  112.     code Error number
  113.     msg Clear error message
  114. */
  115. void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
  116.  uint code, const char *format, ...)
  117. {
  118.   va_list args;
  119.   char    warning[ERRMSGSIZE+20];
  120.   DBUG_ENTER("push_warning_printf");
  121.   DBUG_PRINT("enter",("warning: %u", code));
  122.   
  123.   va_start(args,format);
  124.   my_vsnprintf(warning, sizeof(warning), format, args);
  125.   va_end(args);
  126.   push_warning(thd, level, code, warning);
  127.   DBUG_VOID_RETURN;
  128. }
  129. /*
  130.   Send all notes, errors or warnings to the client in a result set
  131.   SYNOPSIS
  132.     mysqld_show_warnings()
  133.     thd Thread handler
  134.     levels_to_show Bitmap for which levels to show
  135.   DESCRIPTION
  136.     Takes into account the current LIMIT
  137.   RETURN VALUES
  138.     0 ok
  139.     1 Error sending data to client
  140. */
  141. static const char *warning_level_names[]= {"Note", "Warning", "Error", "?"};
  142. static int warning_level_length[]= { 4, 7, 5, 1 };
  143. my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
  144. {  
  145.   List<Item> field_list;
  146.   DBUG_ENTER("mysqld_show_warnings");
  147.   field_list.push_back(new Item_empty_string("Level", 7));
  148.   field_list.push_back(new Item_return_int("Code",4, MYSQL_TYPE_LONG));
  149.   field_list.push_back(new Item_empty_string("Message",MYSQL_ERRMSG_SIZE));
  150.   if (thd->protocol->send_fields(&field_list,1))
  151.     DBUG_RETURN(1);
  152.   MYSQL_ERROR *err;
  153.   SELECT_LEX *sel= &thd->lex->select_lex;
  154.   ha_rows offset= sel->offset_limit, limit= sel->select_limit;
  155.   Protocol *protocol=thd->protocol;
  156.   
  157.   List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
  158.   while ((err= it++))
  159.   {
  160.     /* Skip levels that the user is not interested in */
  161.     if (!(levels_to_show & ((ulong) 1 << err->level)))
  162.       continue;
  163.     if (offset)
  164.     {
  165.       offset--;
  166.       continue;
  167.     }
  168.     if (limit-- == 0)
  169.       break;
  170.     protocol->prepare_for_resend();
  171.     protocol->store(warning_level_names[err->level],
  172.     warning_level_length[err->level], system_charset_info);
  173.     protocol->store((uint32) err->code);
  174.     protocol->store(err->msg, strlen(err->msg), system_charset_info);
  175.     if (protocol->write())
  176.       DBUG_RETURN(1);
  177.   }
  178.   send_eof(thd);  
  179.   DBUG_RETURN(0);
  180. }