Bug #27424 Falcon: crash if case sensitive database names
Submitted: 25 Mar 2007 17:01 Modified: 3 Dec 2007 14:26
Reporter: Peter Gulutzan Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Falcon storage engine Severity:S3 (Non-critical)
Version:5.2.4-falcon-alpha-debug OS:Linux (SUSE 10.0 / 64-bit)
Assigned to: Jim Starkey CPU Architecture:Any

[25 Mar 2007 17:01] Peter Gulutzan
Description:
If I have a database named A and a database named
a, with Falcon and MyISAM tables, mysqld soon crashes.

This resembles
Bug#22166 Falcon: case insensitive table names
The differences are: this time the database names
are case sensitive, and and there's a crash.

How to repeat:
create database A;
create database a;
create table A.t (s1 char(5)) engine=falcon;
create table a.t (s1 char(5)) engine=falcon; /* error */
create table a.T (s1 char(5)) engine=falcon; /* error */
create table a.t (s1 char(5)) engine=myisam;
alter table a.t engine=falcon; /* error */
/* mysqld says Duplicate FIELDS.SYSTEM */
insert into a.t values ('a');
delete from A.t;
insert into A.t values ('A'); /* crash */
[26 Mar 2007 12:31] MySQL Verification Team
Thank you for the bug report. Verified as described on FC 6 32-bit.

mysql> delete from A.t;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into A.t values ('A'); /* crash */
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql>
[23 Oct 2007 19:47] Kevin Lewis
Bug 27424 is a subtle variation on the table name mapping imbroglio.  
The sequence that shows the bug is:

    create table zip (n int) engine=falcon;
    create table ZIP(s varchar(10)) engine=myisam;
    alter table ZIP engine=falcon;
    select * from zip;
    <crunch>

This, of course, only happens on Linux.  On Windows, the sequence 
properly fails with the second "create table".

What actually happens is this:

    mysql> alter table ZIP engine=falcon;

    Breakpoint 13, StorageInterface::create (this=0x312a780,
        mySqlName=0x44887250 "./foo/#sql-7264_1", form=0x44886180,
    info=0x44888e70)
        at ha_falcon.cpp:633

    Breakpoint 16, StorageInterface::open (this=0x312a7a0,
    name=0x312a368 "./foo/#sql-7264_1",
        mode=2, test_if_locked=2) at ha_falcon.cpp:395

    Breakpoint 9, StorageInterface::rename_table (this=0x31282a0,
        from=0x44887740 "./foo/#sql-7264_1", to=0x44887540 "./foo/ZIP")
    at ha_falcon.cpp:1304
    <this correctly fails>

    Breakpoint 15, StorageInterface::delete_table (this=0x3128538,
        tableName=0x44887ba0 "./foo/ZIP") at ha_falcon.cpp:821

The problem is with the unnecessary and incorrect call to 
StorageInterface::delete_table, presumably as part of the server 
recovery from the failed rename_table.  While the pathname "./foo/ZIP" 
is distinct from "./foo/zip", both map to the same internal Falcon table 
FOO.ZIP, which is then deleted.  The next reference to "zip" references 
a deleted table and crashes the server.

I suppose we could (and should) bounce this to the server group, but I 
suspect that would cause the bug to stay open until the table naming 
rules are normalized, which is not likely to happen in our lifetimes.

The next best alternative is to fix the Falcon storage interface to not 
drop ambiguous table names.  My concern is that the cavalier attitude 
towards table name rules in the server may lead to undroppable tables on 
some platform or other.

> Chris Powers wrote:
> Jim,
>
> I wonder if we could somehow use a unique hash key (e.g. SHA-1) 
> generated from the fully qualified path to map paths to tableshares?

That's not the problem.  The current pathname lookup scheme works just 
fine.  The problem is that "./foo/zip" and "./foo/ZIP" map to different 
storage interface tables but the same internal Falcon table.  This 
wouldn't be a problem if the server applied standard -- or even 
consistent -- rules to table name mapping, but it doesn't.  But there is 
no platform where the server handling table names correctly.  The 
platform differences, sadly, are that the server diverges from the 
standard differently on different platforms.

The Falcon solution -- and it isn't a good solution, just the best of 
poor alternatives-- is to disallow combinations of table names that 
would lead to different behaviors on different platforms.  We do our own 
mapping from server pathnames to internal Falcon table names based on 
our best guess of the user's intentions.  There is no guarantee that we 
will get it right, but we can guarantee that non-ambiguous table names 
will be tabled unambiguously.

The bottom line is that we handle all portable cases correctly and 
reject all non-portable cases consistently.  This is incompatible with 
other storage engines, but it is very hard to be compatible with a 
server that isn't compatible with itself.
[29 Oct 2007 3:16] Kevin Lewis
Jim says he know what is going on here.
[1 Nov 2007 21:11] Jim Starkey
The server was trying to delete an non-existent table after a failed rename. 

The fix was to validate table paths as part of delete_table.
[30 Nov 2007 2:39] Hakan Küçükyılmaz
Does not crash anymore:

[03:39] root@(none)>insert into A.t values ('A');
Query OK, 1 row affected (0.00 sec)
[3 Dec 2007 14:26] MC Brown
A note has been added to the 6.0.4 changelog: 

Mixing differently cased tables between MyISAM and Falcon tables would cause a crash.