Commit 9f8593e8 authored by anozdrin/alik@ibm.'s avatar anozdrin/alik@ibm.
Browse files

Patch inspired by BUG#10491: Server returns data as charset

binary SHOW CREATE TABLE or SELECT FROM I_S.

The problem is that mysqldump generates incorrect dump for a table
with non-ASCII column name if the mysqldump's character set is
ASCII.

The fix is to:
  1. Switch character_set_client for the mysqldump's connection
  to binary before issuing SHOW CREATE TABLE statement in order
  to avoid conversion.
  
  2. Dump switch character_set_client statements to UTF8 and back
  for CREATE TABLE statement.
parent 20e7e987
Loading
Loading
Loading
Loading
+27 −3
Original line number Diff line number Diff line
@@ -992,6 +992,21 @@ static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res,
  return 0;
}


static int switch_character_set_results(MYSQL *mysql, const char *cs_name)
{
  char query_buffer[QUERY_LENGTH];
  size_t query_length;

  query_length= my_snprintf(query_buffer,
                            sizeof (query_buffer),
                            "SET SESSION character_set_results = '%s'",
                            (const char *) cs_name);

  return mysql_real_query(mysql, query_buffer, query_length);
}


/*
  Open a new .sql file to dump the table or view into

@@ -1671,7 +1686,10 @@ static uint get_table_structure(char *table, char *db, char *table_type,
      MYSQL_FIELD *field;

      my_snprintf(buff, sizeof(buff), "show create table %s", result_table);
      if (mysql_query_with_error_report(mysql, 0, buff))

      if (switch_character_set_results(mysql, "binary") ||
          mysql_query_with_error_report(mysql, &result, buff) ||
          switch_character_set_results(mysql, default_charset))
        DBUG_RETURN(0);

      if (path)
@@ -1702,7 +1720,6 @@ static uint get_table_structure(char *table, char *db, char *table_type,
        check_io(sql_file);
      }

      result= mysql_store_result(mysql);
      field= mysql_fetch_field_direct(result, 0);
      if (strcmp(field->name, "View") == 0)
      {
@@ -1794,7 +1811,14 @@ static uint get_table_structure(char *table, char *db, char *table_type,
      }

      row= mysql_fetch_row(result);
      fprintf(sql_file, "%s;\n", row[1]);

      fprintf(sql_file,
              "SET @saved_cs_client     = @@character_set_client;\n"
              "SET character_set_client = utf8;\n"
              "%s;\n"
              "SET character_set_client = @saved_cs_client;\n",
              row[1]);

      check_io(sql_file);
      mysql_free_result(result);
    }
+36 −0
Original line number Diff line number Diff line
@@ -93,55 +93,73 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l

USE `test`;
DROP TABLE IF EXISTS `t1`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t1` (
  `id` int(8) default NULL,
  `name` varchar(32) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
INSERT  DELAYED IGNORE INTO `t1` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
DROP TABLE IF EXISTS `t2`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t2` (
  `id` int(8) default NULL,
  `name` varchar(32) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
INSERT  DELAYED IGNORE INTO `t2` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
DROP TABLE IF EXISTS `t3`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t3` (
  `id` int(8) default NULL,
  `name` varchar(32) default NULL
) ENGINE=MEMORY DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

/*!40000 ALTER TABLE `t3` DISABLE KEYS */;
INSERT  DELAYED IGNORE INTO `t3` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t3` ENABLE KEYS */;
DROP TABLE IF EXISTS `t4`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t4` (
  `id` int(8) default NULL,
  `name` varchar(32) default NULL
) ENGINE=MEMORY DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

/*!40000 ALTER TABLE `t4` DISABLE KEYS */;
INSERT  DELAYED IGNORE INTO `t4` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t4` ENABLE KEYS */;
DROP TABLE IF EXISTS `t5`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t5` (
  `id` int(8) default NULL,
  `name` varchar(32) default NULL
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

/*!40000 ALTER TABLE `t5` DISABLE KEYS */;
INSERT  DELAYED IGNORE INTO `t5` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t5` ENABLE KEYS */;
DROP TABLE IF EXISTS `t6`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t6` (
  `id` int(8) default NULL,
  `name` varchar(32) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

/*!40000 ALTER TABLE `t6` DISABLE KEYS */;
INSERT  IGNORE INTO `t6` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
@@ -172,55 +190,73 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l

USE `test`;
DROP TABLE IF EXISTS `t1`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t1` (
  `id` int(8) default NULL,
  `name` varchar(32) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
INSERT  DELAYED INTO `t1` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
DROP TABLE IF EXISTS `t2`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t2` (
  `id` int(8) default NULL,
  `name` varchar(32) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
INSERT  DELAYED INTO `t2` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
DROP TABLE IF EXISTS `t3`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t3` (
  `id` int(8) default NULL,
  `name` varchar(32) default NULL
) ENGINE=MEMORY DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

/*!40000 ALTER TABLE `t3` DISABLE KEYS */;
INSERT  DELAYED INTO `t3` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t3` ENABLE KEYS */;
DROP TABLE IF EXISTS `t4`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t4` (
  `id` int(8) default NULL,
  `name` varchar(32) default NULL
) ENGINE=MEMORY DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

/*!40000 ALTER TABLE `t4` DISABLE KEYS */;
INSERT  DELAYED INTO `t4` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t4` ENABLE KEYS */;
DROP TABLE IF EXISTS `t5`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t5` (
  `id` int(8) default NULL,
  `name` varchar(32) default NULL
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

/*!40000 ALTER TABLE `t5` DISABLE KEYS */;
INSERT  DELAYED INTO `t5` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
/*!40000 ALTER TABLE `t5` ENABLE KEYS */;
DROP TABLE IF EXISTS `t6`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t6` (
  `id` int(8) default NULL,
  `name` varchar(32) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

/*!40000 ALTER TABLE `t6` DISABLE KEYS */;
INSERT INTO `t6` VALUES (1,'first value'),(2,'first value'),(3,'first value'),(4,'first value'),(5,'first value');
+180 −0

File changed.

Preview size limit exceeded, changes collapsed.

+9 −0
Original line number Diff line number Diff line
@@ -77,9 +77,12 @@ INSERT INTO t1 VALUES (1), (2);
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t1` (
  `a` int(11) default NULL
);
SET character_set_client = @saved_cs_client;

LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -108,9 +111,12 @@ UNLOCK TABLES;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t1` (
  `a` int(11) default NULL
);
SET character_set_client = @saved_cs_client;

LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
@@ -139,9 +145,12 @@ UNLOCK TABLES;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE IF EXISTS `t1`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `t1` (
  `a` int(11) default NULL
);
SET character_set_client = @saved_cs_client;

LOCK TABLES `t1` WRITE;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
+20 −0
Original line number Diff line number Diff line
@@ -1088,6 +1088,26 @@ DROP TABLE t1;
DROP VIEW v1;
DROP PROCEDURE p1;
DROP FUNCTION f1;
set names koi8r;
DROP DATABASE IF EXISTS mysqltest1;
CREATE DATABASE mysqltest1;
use mysqltest1;
CREATE TABLE t1(1 INT);

---> Dumping mysqltest1 to show_check.mysqltest1.sql


DROP DATABASE mysqltest1;


---> Restoring mysqltest1...
SHOW CREATE TABLE mysqltest1.t1;
Table	Create Table
t1	CREATE TABLE `t1` (
  `1` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP DATABASE mysqltest1;
use test;
flush status;
show variables like "log_queries_not_using_indexes";
Variable_name	Value
Loading