[MDEV-21782] lower_case_table_names system variable's usage message needs several fixes Created: 2020-02-19  Updated: 2023-04-27

Status: Open
Project: MariaDB Server
Component/s: Variables
Affects Version/s: 10.1.44, 10.2.31, 10.3.22, 10.4.12
Fix Version/s: 10.4

Type: Bug Priority: Major
Reporter: Geoff Montee (Inactive) Assignee: Ian Gilfillan
Resolution: Unresolved Votes: 1
Labels: None

Issue Links:
Relates
relates to MDEV-21780 event_scheduler system variable's usa... Open

 Description   

The lower_case_table_names system variable supports the values 0, 1, and 2. We can tell from the source code:

static Sys_var_uint Sys_lower_case_table_names(
       "lower_case_table_names",
       "If set to 1 table names are stored in lowercase on disk and table "
       "names will be case-insensitive.  Should be set to 2 if you are using "
       "a case insensitive file system",
       READ_ONLY GLOBAL_VAR(lower_case_table_names),
       CMD_LINE(OPT_ARG, OPT_LOWER_CASE_TABLE_NAMES),
       VALID_RANGE(0, 2),
#ifdef FN_NO_CASE_SENSE
    DEFAULT(1),
#else
    DEFAULT(0),
#endif
       BLOCK_SIZE(1));

https://github.com/MariaDB/server/blob/mariadb-10.4.12/sql/sys_vars.cc#L1462

We can see that the usage message only mentions the values 1 and 2:

MariaDB [(none)]> SELECT VARIABLE_COMMENT FROM information_schema.SYSTEM_VARIABLES WHERE VARIABLE_NAME='lower_case_table_names';
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| VARIABLE_COMMENT                                                                                                                                                      |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive.  Should be set to 2 if you are using a case insensitive file system |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.002 sec)

The message should also mention the value 0, and it should mention why that value would be used.

The message should also explain more about what the value 2 does. It currently explains absolutely nothing about it, other than "you should use it." On another strange note, why does the usage message make this claim?:

Should be set to 2 if you are using a case insensitive file system

That doesn't make sense when you look at the code. If you have a case-insensitive file system, then it defaults to 1:

#ifdef FN_NO_CASE_SENSE
    DEFAULT(1),

Why is the code ignoring its own recommendation?

It appears that this usage message needs several fixes.



 Comments   
Comment by Anel Husakovic [ 2020-02-20 ]

Why are documentation of mariadb KB (added before 6 yeaars 9 months revision) and enterprise different? greenman
Through code you can find checks if lower_case_table_names != 2 or similar which is used to follow the logic.

Comment by Geoff Montee (Inactive) [ 2020-02-20 ]

anel,

Why are documentation of mariadb KB (added before 6 yeaars 9 months revision) and enterprise different?

The system variable reference in the Enterprise Documentation was automatically extracted from the usage message in the server that this Jira issue is referring to.

The usage message in the server says this:

MariaDB [(none)]> SELECT VARIABLE_COMMENT FROM information_schema.SYSTEM_VARIABLES WHERE VARIABLE_NAME='lower_case_table_names';
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| VARIABLE_COMMENT                                                                                                                                                      |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive.  Should be set to 2 if you are using a case insensitive file system |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.002 sec)

And the Enterprise Documentation says this:

If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive. Should be set to 2 if you are using a case insensitive file system

You can see that they are exactly the same.

In my opinion, this usage message should be improved. It is missing a lot of information.

Comment by Ian Gilfillan [ 2020-02-20 ]

The description from the KB can be used here.

Comment by Geoff Montee (Inactive) [ 2020-02-20 ]

greenman,

The description from the KB can be used here.

I don't think the description from the KB can be used as-is. As far as I can tell, that description has some inaccuracies and omissions, so it would probably have to be fixed.

For example, it says this about lower_case_table_names=2:

If set to 2 (the default on Mac OS X), names are stored as declared, but compared in lowercase.

As far as I can tell, it is not true that this is the default value on Mac OS X. The source code only lists two default values:

#ifdef FN_NO_CASE_SENSE
    DEFAULT(1),
#else
    DEFAULT(0),
#endif

So if the OS is case sensitive, then the default value will be 0. If the OS is case insensitive, then the default value will be 1. There is no condition here that says that the default value would be 2 on Mac OS X. Am I missing something, or is the KB incorrect about this?

And for another example, the description from the KB also does not point out that lower_case_table_names=2 is totally invalid on Linux if the file system is case sensitive. If you try to set that value, then you will get a warning in the error log like the following, and your choice will be overridden:

Feb 20 00:00:53 ip-172-30-0-123 mysqld: 2020-02-20  0:00:53 0 [Warning] lower_case_table_names was set to 2, even though your the file system '/var/lib/mysql/' is case sensitive.  Now setting lower_case_table_names to 0 to avoid future problems.

Comment by Geoff Montee (Inactive) [ 2020-03-12 ]

For this reference to Mac OS X's default:

If set to 2 (the default on Mac OS X), names are stored as declared, but compared in lowercase.

Is it referring to this block of code?:

  if (!lower_case_table_names && lower_case_file_system == 1)
  {
    if (lower_case_table_names_used)
    {
      sql_print_error("The server option 'lower_case_table_names' is "
                      "configured to use case sensitive table names but the "
                      "data directory resides on a case-insensitive file system. "
                      "Please use a case sensitive file system for your data "
                      "directory or switch to a case-insensitive table name "
                      "mode.");
      return 1;
    }
    else
    {
      if (global_system_variables.log_warnings)
	sql_print_warning("Setting lower_case_table_names=2 because file "
                  "system for %s is case insensitive", mysql_real_data_home);
      SYSVAR_AUTOSIZE(lower_case_table_names, 2);
    }
  }

https://github.com/MariaDB/server/blob/mariadb-10.4.12/sql/mysqld.cc#L4431

If so, then I think it would be more accurate to describe it like this:

If set to 2, names are stored as declared, but compared in lowercase. The server automatically sets the variable to this value and logs a warning when it detects that the file system is case insensitive, and the variable is not already set to 1 or 2. For example, this would happen on Mac OS X when using HFS+ or APFS, except when APFS is used in case-sensitive mode.

Generated at Thu Feb 08 09:09:45 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.