Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-14432

mysqldump does not preserve case of table names in generated sql

Details

    Description

      The table name in the sql file generated by mysqldump is in lowercase. This only happens if the command arguments include a table name. If run without specifying a table the case of the table names is preserved.

      From looking at logs, it appears as if earlier versions used "show tables like ..." and the later versions use "select from information_schema.tables where table_name = ....".

      Interestingly there is a different result between like and =

      MariaDB [daves]> select table_name from information_schema.tables where table_schema = database() and table_name like 'BouncyCaps';
      +------------+
      | table_name |
      +------------+
      | BouncyCaps |
      +------------+
      1 row in set (0.00 sec)
       
      MariaDB [daves]>
      MariaDB [daves]> select table_name from information_schema.tables where table_schema = database() and table_name = 'BouncyCaps';
      +------------+
      | table_name |
      +------------+
      | bouncycaps |
      +------------+
      1 row in set (0.00 sec)
      

      Attachments

        Issue Links

          Activity

            you cannot get assigned, only people with write access to the repository can be assignees (that's how this Jira is configured).

            But it should not matter, just add a comment, saying you've reproduced this and you want to work on it — it'd be enough

            serg Sergei Golubchik added a comment - you cannot get assigned, only people with write access to the repository can be assignees (that's how this Jira is configured). But it should not matter, just add a comment, saying you've reproduced this and you want to work on it — it'd be enough

            Alright after reproducing this on Windows it seems the problem is not just in mysqldump it's on all queries relating lowercase/uppercase and for some reason this is the default value on Windows

            As mentioned in the knowledge base
            https://mariadb.com/kb/en/identifier-case-sensitivity/

            "The lower_case_table_names server system variable plays a key role. It determines whether table names, aliases and database names are compared in a case-sensitive manner. If set to 0 (the default on Unix-based systems), table names and aliases and database names are compared in a case-sensitive manner. If set to 1 (the default on Windows), names are stored in lowercase and not compared in a case-sensitive manner. If set to 2 (the default on Mac OS X), names are stored as declared, but compared in lowercase."

            I tried changing the ini file before bootstraping to have the default value as 0 not 1 but it logged an error because my machine's folders/directories are not case-sensitive
            Attached the log below when I tried to change it .. It should probably work if i change my file system's folders names but i think since the documentation has its default value as 1 it surely had a good reason right but I dont really see the point of having all names treated as lowercase being a good default value but could you let me know if ive got something wrong does it make sense to have this as a default value ?

            logfile.log

            Mohanad Khaled Mohanad Khaled added a comment - Alright after reproducing this on Windows it seems the problem is not just in mysqldump it's on all queries relating lowercase/uppercase and for some reason this is the default value on Windows As mentioned in the knowledge base https://mariadb.com/kb/en/identifier-case-sensitivity/ "The lower_case_table_names server system variable plays a key role. It determines whether table names, aliases and database names are compared in a case-sensitive manner. If set to 0 (the default on Unix-based systems), table names and aliases and database names are compared in a case-sensitive manner. If set to 1 (the default on Windows), names are stored in lowercase and not compared in a case-sensitive manner. If set to 2 (the default on Mac OS X), names are stored as declared, but compared in lowercase." I tried changing the ini file before bootstraping to have the default value as 0 not 1 but it logged an error because my machine's folders/directories are not case-sensitive Attached the log below when I tried to change it .. It should probably work if i change my file system's folders names but i think since the documentation has its default value as 1 it surely had a good reason right but I dont really see the point of having all names treated as lowercase being a good default value but could you let me know if ive got something wrong does it make sense to have this as a default value ? logfile.log

            Note that the problem comes from (see comments above): on case insensitive file system, if lower_case_table_names=2,
            the following query returns the table name in lowercase:

            MariaDB [test]> select table_name from information_schema.tables where table_schema = database() and table_name = 'BouncyCaps';
            +------------+
            | table_name |
            +------------+
            | bouncycaps |
            +------------+
            

            The reason for this appears to be:

            • information_schema.tables is populated in get_all_tables()
            • it invokes make_table_name_list() to create a list of tables
            • if the table name is specified explicitly via = X then lookup_field_vals->table_value.str is set and it simply returns X
            • after that get_all_tables() directly puts this "table name" into the corresponding column of the result
            • lookup_field_vals->table_value.str is set from the WHERE clause in get_lookup_field_values
            • and it uses make_ident_casedn() if lower_case_table_names is non-zero.

            so, lower_case_table_names is non-zero, get_lookup_field_values converts the value after = into lower case, make_table_name_list() uses this value as a table name without checking the file system, and get_all_tables() puts this "table name" in the TABLE_NAME column of the information_schema.tables

            two possible directions of fixing it:

            • remove make_ident_casedn(), may be it's not needed when lower_case_table_names=2 ?
            • set the TABLE_NAME correctly after the table is opened and the true name is known.
            serg Sergei Golubchik added a comment - Note that the problem comes from (see comments above): on case insensitive file system, if lower_case_table_names=2, the following query returns the table name in lowercase: MariaDB [test]> select table_name from information_schema.tables where table_schema = database () and table_name = 'BouncyCaps' ; + ------------+ | table_name | + ------------+ | bouncycaps | + ------------+ The reason for this appears to be: information_schema.tables is populated in get_all_tables() it invokes make_table_name_list() to create a list of tables if the table name is specified explicitly via = X then lookup_field_vals->table_value.str is set and it simply returns X after that get_all_tables() directly puts this "table name" into the corresponding column of the result lookup_field_vals->table_value.str is set from the WHERE clause in get_lookup_field_values and it uses make_ident_casedn() if lower_case_table_names is non-zero. so, lower_case_table_names is non-zero, get_lookup_field_values converts the value after = into lower case, make_table_name_list() uses this value as a table name without checking the file system, and get_all_tables() puts this "table name" in the TABLE_NAME column of the information_schema.tables two possible directions of fixing it: remove make_ident_casedn() , may be it's not needed when lower_case_table_names=2 ? set the TABLE_NAME correctly after the table is opened and the true name is known.

            Great thanks .. gonna a submit a PR for it rn .. on the earliest fix branch right or on 11.2.3 as mentioned earlier ?
            Also when getting the tables from frm it is also using casedn inside "fill_schema_table_from_frm()" so should this also be modified ?

            Mohanad Khaled Mohanad Khaled added a comment - Great thanks .. gonna a submit a PR for it rn .. on the earliest fix branch right or on 11.2.3 as mentioned earlier ? Also when getting the tables from frm it is also using casedn inside "fill_schema_table_from_frm()" so should this also be modified ?

            on the earliest affected branch that is less than 3 years old. That is, on 10.11, please.

            If you'll debug this you'll see that get_all_tables invokes either fill_schema_table_from_frm() or fill_schema_table_by_open() depending on what fields you select (it's OPEN_FRM_ONLY vs OPEN_FULL_TABLE).

            Make sure, your fix covers both code paths.

            serg Sergei Golubchik added a comment - on the earliest affected branch that is less than 3 years old. That is, on 10.11, please. If you'll debug this you'll see that get_all_tables invokes either fill_schema_table_from_frm() or fill_schema_table_by_open() depending on what fields you select (it's OPEN_FRM_ONLY vs OPEN_FULL_TABLE ). Make sure, your fix covers both code paths.

            People

              bar Alexander Barkov
              David Crimmins David Crimmins
              Votes:
              3 Vote for this issue
              Watchers:
              10 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.