Bug #26426 Server doesn't send sql state on error during connection open
Submitted: 15 Feb 2007 21:17 Modified: 5 Mar 2007 20:50
Reporter: Andrey Hristov Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Documentation Severity:S3 (Non-critical)
Version:5.1.16, could be others OS:Any (All)
Assigned to: Paul DuBois CPU Architecture:Any

[15 Feb 2007 21:17] Andrey Hristov
Description:
One or two errors can occur just after opening the socket from the client. If there are too many connections, the server will call :

  if (thread_count - delayed_insert_threads >= max_connections+1 || abort_loop)
  {
    DBUG_PRINT("error",("Too many connections"));
    close_connection(thd, ER_CON_COUNT_ERROR, 1);
    delete thd;
    DBUG_VOID_RETURN;
  }

which will end in protocol.cc:
void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
{

There the following check is being done :
    if (thd->client_capabilities & CLIENT_PROTOCOL_41)
    {
      /* The first # is to make the protocol backward compatible */
      buff[2]= '#';
      pos= strmov(buff+3, mysql_errno_to_sqlstate(sql_errno));
    }

However, because of the way the handshaking is performed, the server sends the first packet and it could be an error packet. In this case the client hasn't sent anything, thus the server cannot know what are the client capabilities, they come in the authentication packet, which follows the greeting packet. Thus thd->client_capabilities is 0x0 and the SQL state, of at least ER_CON_COUNT_ERROR is not sent to the client. It should be "08004".

How to repeat:
Look at the code. Write a single program that opens connections and forgets them and inspect the sqlstate.
[19 Feb 2007 10:42] Sveta Smirnova
Thank you for the report.

Verified as described.
[27 Feb 2007 21:41] Konstantin Osipov
Stefan, please consider documenting this: we do not send sqlstate because if handshake fails, we don't know whether the client supports the protocol version that has SQLSTATEs.

If we decide to change this, we will partially break old clients.

Thanks,
[5 Mar 2007 20:50] Paul DuBois
Thank you for your bug report. This issue has been addressed in the documentation. The updated documentation will appear on our website shortly, and will be included in the next release of the relevant products.

Information added to the mysql_sqlstate() manual section:

If you call mysql_sqlstate() after mysql_real_connect() fails, 
mysql_sqlstate() might not return a useful value. For example, this
happens if a host is blocked by the server and the connection is 
closed without any SQLSTATE value being sent to the client.