From: MARK CALLAGHAN Date: October 27 2009 11:50pm Subject: Re: help -- how do I return an error? List-Archive: http://lists.mysql.com/internals/37454 Message-Id: MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable On Mon, Oct 19, 2009 at 7:33 PM, Marc Alff wrote: > > Hi Mark > > MARK CALLAGHAN wrote: >> I want to return an error in the patch I submitted for >> http://bugs.mysql.com/bug.php?id=3D48124 >> This document appears to be out of date: >> http://forge.mysql.com/wiki/MySQL_Internals_Error_Messages >> >> How do I return an error for a SQL command? There is my_message, >> my_error, my_printf_error and push_warning in MySQL source. Most of >> these are not described by the URL above. >> > > To raise an error: > > Without parameters: > =A0my_error(ER_SIGNAL_BAD_CONDITION_TYPE, MYF(0)); > > With parameters: > =A0 =A0my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH)= , > =A0 =A0 =A0 =A0 =A0 MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH); > > To raise a warning: > > Without parameters: > =A0push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, > =A0 =A0ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE)); > > With parameters: > =A0 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, > =A0 =A0 ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED), > =A0 =A0 main_view->view_db.str, main_view->view_name.str); > > If you use code starting in 5.5, you may look at THD::raise_error() and > friends also. > > Things to avoid (and yes, there are plenty of bad examples in the code): > - "ER_XXX, "plain text" --> should be ER_XXX, ER(ER_XXX), and the text > should be in errmsg.txt > - printf in buffer + "ER_XXX, buffer" --> likewise > - push_warning / push_warning_printf with a level of WARN_LEVEL_ERROR: > that's a bug. > > Now, the real issue is if you want to return a *new* error. > > This area, and the process around it to allow everybody to change the > code while keeping compatibility between releases (and have the same > error numbers for the same thing) is a major pain point, still unresolved= . > > Below is the procedure used by development: > > The first step is to add an entry in the file sql/share/errmsg.txt, at > the *end*. > > This is important so that the message text is not hard coded in the > source, and can be translated for other languages. > > For example: > ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER 0K000 > =A0 =A0 =A0 =A0eng "RESIGNAL when handler not active" > > "0K000" is optional, it's the SQLSTATE for this error. > > Errors should be named ER_XXX, warnings WARN_XXX (not always followed). > > The next question is whether the message contains printf-like parameters > or not. > When using %s parameters, please consider a max size like "%-.64s" > instead of just "%s" to protect from overflows when printing the message > with bad data. > > This is for releases that are not GA yet, since creating new error codes > has no impact on existing applications. > > For code already GA, if you follow this, then it will create merge > issues between your errmsg.txt and mysql errmsg.txt, and create > conflicts with error numbering later, which is why the generic > ER_UNKNOWN_ERROR + hard coded message text is suggested. > Keep in mind that even if conflicts may not visible now, they will > happen at the next upgrade, so this area is sensitive. > > For new errors, to maintain compatibility, the choices are then limited t= o: > > my_printf_error(ER_UNKNOWN_ERROR, > =A0"Some error text here, without parameters", > =A0MYF(0)); > > my_printf_error(ER_UNKNOWN_ERROR, > =A0"Some error text here, with the '%-.64s' parameter value" > =A0 MYF(0), a_parameter); > > push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, > =A0 =A0ER_UNKNOWN_ERROR, "Some warning text here, without parameters"); > > push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, > =A0 =A0 ER_UNKNOWN_ERROR, "Some warning text here, with the '%-.64s' > parameter value", > =A0 =A0 a_parameter); > > There are still several problems here: > - the text is hard coded again (no hope of translation), > - there is only 1 error code to choose from, which makes it hard for an > application to sort things out if several enhancements needs new errors > for different things, and if a client / stored procedure needs special > logic based on the error *code* (as opposed to a human looking at the > error *text*). > > All this is only a work around, if there is no existing error message > from errmsg.txt that can be reused, so the best hope is to find a "close > enough" existing message :( > > Regards, > -- Marc > > In which cases must my_error be called? The function create_file in sql_class.cc doesn't call my_error when my_create and init_io_cache fail. Does it assume that my_create and init_io_cache took care of that? I added code that called my_seek() and when the input is a pipe, my_seek() returns an error and my_errno=3D=3DESPIPE. But clients hang if my new code returns -1 without calling my_error. --=20 Mark Callaghan mdcallag@stripped