Client ServerDetect() guesses server type (Drizzle, MySQL) based on version number.

Bug #951788 reported by Henrik Ingo
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Drizzle
Fix Released
Medium
Ajaya Agrawal

Bug Description

drizzle/client/server_detect.cc has the following function:

**************************************************************
ServerDetect::ServerDetect(drizzle_con_st *connection) :
  type(SERVER_UNKNOWN_FOUND),
  version("")
{
  boost::match_flag_type flags = boost::match_default;

  // FIXME: Detecting capabilities from a version number is a recipe for
  // disaster, like we've seen with 15 years of JavaScript :-)
  // Anyway, as there is no MySQL 7.x yet, this will do for tonight.
  // I will get back to detect something tangible after the release (like
  // presence of some table or its record in DATA_DICTIONARY.
  boost::regex mysql_regex("^([3-6]\\.[0-9]+\\.[0-9]+)");
  boost::regex drizzle_regex7("^(20[0-9]{2}\\.(0[1-9]|1[012])\\.[0-9]+)");
  boost::regex drizzle_regex71("^([7-9]\\.[0-9]+\\.[0-9]+)");

  version= drizzle_con_server_version(connection);

  if (regex_search(version, drizzle_regex7, flags))
  {
    type= SERVER_DRIZZLE_FOUND;
  }
  else if (regex_search(version, drizzle_regex71, flags))
  {
    type= SERVER_DRIZZLE_FOUND;
  }
  else if (regex_search(version, mysql_regex, flags))
  {
    type= SERVER_MYSQL_FOUND;
  }
  else
  {
    std::cerr << "Server version not detectable. Assuming MySQL." << std::endl;
    type= SERVER_MYSQL_FOUND;
  }
}
**************************************************************

This is used by at least drizzledump to determine whether it is connected to a MySQL server or a Drizzle server. It will use different SQL syntax depending on server type. (MySQL syntax will fail on Drizzle and Drizzle syntax will garble character sets on MySQL.)

In addition to drizzledump, it seems the "DESCRIBE tablename" command in a drizzle client is different depending on the return value of this function: true/false vs 1/0. I don't know if that is significant. (But it made a few tests fail.)

The above check will obviously fail once MySQL releases a 7.1 version. Making conclusions based on a version number is a common anti-pattern in javascript, it always fails (already did). The fix is something where we know for real the server type and not just deduce it from version number.

If the only client that really needs this information is drizzledump, then my suggestion is to simply deprecate this function and build some check into drizzledump instead. For instance drizzledump can just do "SET NAMES UTF8" and if it works it is a MySQL server and if it is an error it is a Drizzle server. (Set names is what drizzledump wants to do in the first place.)

Tags: client

Related branches

Henrik Ingo (hingo)
Changed in drizzle:
status: New → Confirmed
importance: Undecided → Medium
Henrik Ingo (hingo)
tags: added: client
Revision history for this message
Henrik Ingo (hingo) wrote :

Note: It is worth emphasizing that testing whether "SET NAMES UTF8" works is an ok solution for drizzledump, however, if the intent is to replace this function with another implementation, then such a check of course isn't good because it alters state in the case of a MySQL server. If we want to implement a generic check, it needs to be readonly. One idea that comes to mind is "SELECT * FROM mysql.user LIMIT 1". A drizzled server shouldn't have a mysql schema or a mysql.user table, but of course it could have if someone created one just to make trouble. So this isn't foolproof either. Just illustrates that the whole idea of providing this kind of function is a bit shaky...

Revision history for this message
Stewart Smith (stewart) wrote : Re: [Bug 951788] Re: Client ServerDetect() guesses server type (Drizzle, MySQL) based on version number.

On Tue, 27 Mar 2012 08:34:45 -0000, Henrik Ingo <email address hidden> wrote:
> Note: It is worth emphasizing that testing whether "SET NAMES UTF8"
> works is an ok solution for drizzledump, however, if the intent is to
> replace this function with another implementation, then such a check of
> course isn't good because it alters state in the case of a MySQL server.
> If we want to implement a generic check, it needs to be readonly. One
> idea that comes to mind is "SELECT * FROM mysql.user LIMIT 1". A
> drizzled server shouldn't have a mysql schema or a mysql.user table, but
> of course it could have if someone created one just to make trouble. So
> this isn't foolproof either. Just illustrates that the whole idea of
> providing this kind of function is a bit shaky...

Surely we have some server variable that has the word Drizzle in
it.... I hope...

--
Stewart Smith

Ajaya Agrawal (ajayaa)
Changed in drizzle:
assignee: nobody → Ajaya Agrawal (aj--)
Revision history for this message
Henrik Ingo (hingo) wrote :

Good question. We have drizzle_protocol_bind_address (and other variables from the same plugin), however it is worth pointing out this plugin might not be loaded.

My suggestions yesterday was to check for character_set_results. If it exists, it is a MySQL server, if not it is a Drizzle server. This check is likely to work long into the future.

Revision history for this message
Ajaya Agrawal (ajayaa) wrote :

fixed and Proposed for merging!

Ajaya Agrawal (ajayaa)
Changed in drizzle:
status: Confirmed → Fix Committed
Stewart Smith (stewart)
Changed in drizzle:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.