Bug #21373 Old tables with '@' in their name cannot be opened
Submitted: 31 Jul 2006 20:46 Modified: 12 Dec 2007 22:04
Reporter: Ingo Strüwing Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Charsets Severity:S2 (Serious)
Version:5.1.12 OS:Linux (Linux)
Assigned to: Alexander Barkov CPU Architecture:Any

[31 Jul 2006 20:46] Ingo Strüwing
Description:
Tables from pre-5.1 with a '@' in their name cannot be opened unless prefixed with '#mysql50#'. The below test result shows the misbehaviour:

! DROP TABLE IF EXISTS `t@1`, `#mysql50#t%1`, `#mysql50#t@1`;
! CREATE TABLE `t@1` (c1 INT);
! INSERT INTO  `t@1` VALUES (1);
! DROP   TABLE `t@1`;
! CREATE TABLE `#mysql50#t%1` (c1 INT);
! INSERT INTO  `t%1` VALUES (1);
! DROP   TABLE `#mysql50#t%1`;
! CREATE TABLE `#mysql50#t@1` (c1 INT);
! INSERT INTO  `t@1` VALUES (1);
! ERROR 42S02: Table 'test.t@1' doesn't exist
! DROP   TABLE `#mysql50#t@1`;

How to repeat:
# For demo purposes
--disable_abort_on_error

#
# Bug#????? - Old tables with '@' in their name cannot be opened
#
--disable_warnings
DROP TABLE IF EXISTS `t@1`, `#mysql50#t%1`, `#mysql50#t@1`;
--enable_warnings
#
# How everything goes with encoded name and '@' in it.
CREATE TABLE `t@1` (c1 INT);
INSERT INTO  `t@1` VALUES (1);
DROP   TABLE `t@1`;
#
# How everything goes with non-encoded name and non-'@' in it.
# Prefix '#mysql50#' suppresses encoding. Needed for create and drop.
# On open encoded and non-encoded names are tried.
CREATE TABLE `#mysql50#t%1` (c1 INT);
INSERT INTO  `t%1` VALUES (1);
DROP   TABLE `#mysql50#t%1`;
#
# Old table with '@' does not work.
CREATE TABLE `#mysql50#t@1` (c1 INT);
INSERT INTO  `t@1` VALUES (1);
DROP   TABLE `#mysql50#t@1`;

Suggested fix:
In table.cc:open_table_def() these lines look suspicious:

      strxmov(path, share->normalized_path.str, reg_ext, NullS);
      if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
      {
        if (strchr(share->table_name.str, '@'))
          goto err_not_open;
        /* Try unecoded 5.0 name */

Perhaps the check for '@' is wrong?
[2 Aug 2006 14:22] Sergei Golubchik
One of the bugs here - there was never an intention to let #mysql50# to allow _creation_ of new tables, it was only implelented to support reading of old tables.
[2 Aug 2006 14:30] Sergei Golubchik
The check for '@' is also wrong. Probably it must be

  if (!strchr(share->path.str, '@'))
    goto err_not_open;
[25 Sep 2006 6:01] Alexander Barkov
This is intentional behavior, added when fixing bug#17142.
We don't try to open old file names having '@' - not to
confuse with a new 5.1 encoded name. One must run "mysql_upgrade"
to make these old tables available.

IRC log from discussion with Monty:

Mar 02 16:16:32
monty> How about making it easy so that if a name contains @
monty> then you don't try to reopen it with the old name
monty> This will still ensure that things works for most users
monty> when they emigrate and people with @ in their table names
monty> must run the upgrade script
[25 Sep 2006 13:01] Sergei Golubchik
Still the second bug - one can create a table using #mysql50# prefix to bypass encoding - still exists. The correct behaviour should be - #mysql50# prefix in create table is encoded, it has no special treatment.
[2 Oct 2007 10:32] Alexander Barkov
Agreed that this is not a bug. Setting to "Documenting".

To doc team:

Please consider documenting two things in 5.1 manual:

1. the prefix "#mysql50#" in table names has its own special
   meaning and one should never use names with this prefix
   in CREATE TABLE.

2. when upgrading from 5.0 to 5.1, old tables having '@' sign
   in their names may not be opened by 5.1 server,
   so they should be dumped and restored.
[12 Dec 2007 22:04] Paul DuBois
I have added Bar's suggested notes (from [2 Oct 12:32] entry) to the manual. They will
appear here:

http://dev.mysql.com/doc/refman/5.1/en/identifier-mapping.html
http://dev.mysql.com/doc/refman/5.1/en/upgrading-from-5-0.html