Skip to content

[Enhancement]: Add dynamic configuration for lower_case_table_names i…#156

Open
SimonChou12138 wants to merge 3 commits intooceanbase:developfrom
SimonChou12138:develop
Open

[Enhancement]: Add dynamic configuration for lower_case_table_names i…#156
SimonChou12138 wants to merge 3 commits intooceanbase:developfrom
SimonChou12138:develop

Conversation

@SimonChou12138
Copy link

@SimonChou12138 SimonChou12138 commented Feb 5, 2026

Task Description

Fix hardcoded table names in SQL queries to support lower_case_table_names system variable. This resolves issues where system tables cannot be found when lower_case_table_names=0 (case-sensitive mode) is configured.

Related to case-sensitivity handling for MySQL compatibility.

Solution Description

  1. Replace hardcoded table names with constants: Changed direct string literals like __all_server and __all_zone to use constants from ob_inner_table_schema_constants.h (e.g., OB_ALL_SERVER_TNAME, OB_ALL_ZONE_TNAME)

  2. Read lower_case_table_names from system variables: Modified bootstrap and schema initialization code to dynamically read the lower_case_table_names setting instead of hardcoding OB_LOWERCASE_AND_INSENSITIVE

  3. Support environment variable configuration: Added support for setting lower_case_table_names via the LOWER_CASE_TABLE_NAMES environment variable in main.cpp

  4. Set proper name_case_mode for system tables: Ensured system tables always use case-sensitive mode (OB_ORIGIN_AND_SENSITIVE) regardless of tenant settings, while user tables respect the tenant's lower_case_table_names configuration

Modified files:

  • src/observer/main.cpp
  • src/rootserver/ob_bootstrap.cpp
  • src/share/ob_locality_table_operator.cpp
  • src/share/schema/ob_schema_mgr.cpp
  • src/share/schema/ob_schema_utils.cpp
  • src/share/schema/ob_server_schema_service.cpp
  • src/storage/tx/wrs/ob_tenant_weak_read_cluster_service.cpp

Passed Regressions

  • Manually tested with lower_case_table_names=0 configuration
  • Verified system tables are accessible with case-sensitive mode
  • Confirmed bootstrap process completes successfully
  • Tested SQL queries against system tables work correctly
  • After making the modifications, I rebuilt and mirrored the image for running. Then, I added an environment variable to the Docker configuration to pull up the container. After verifying the settings and querying the configuration, I found that the parameter was effective
image

Upgrade Compatibility

This change is backward compatible:

  • Default behavior remains unchanged (defaults to lower_case_table_names=1)
  • Existing deployments will continue to work without modification
  • New configuration option is opt-in via environment variable or command-line parameter

Other Information

This fix improves MySQL compatibility by properly supporting the lower_case_table_names system variable, which is important for:

  • Cross-platform deployments (Linux/macOS/Windows)
  • Migration from MySQL databases with case-sensitive table names
  • Compliance with MySQL standard behavior

Release Note

Enhancement: Added proper support for lower_case_table_names system variable. System table names are now referenced using constants instead of hardcoded strings, enabling case-sensitive table name mode (lower_case_table_names=0) to work correctly. This improves MySQL compatibility and supports cross-platform deployments.

@CLAassistant
Copy link

CLAassistant commented Feb 5, 2026

CLA assistant check
All committers have signed the CLA.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to make table-name handling compatible with MySQL lower_case_table_names, removing hardcoded inner-table names and making name-case mode configurable during bootstrap/initialization (including via an environment variable).

Changes:

  • Replace hardcoded inner-table names in SQL strings with ob_inner_table_schema_constants.h constants.
  • Read lower_case_table_names dynamically from system-variable defaults during bootstrap/schema initialization (instead of hardcoding).
  • Allow setting lower_case_table_names via LOWER_CASE_TABLE_NAMES environment variable during process startup.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/observer/main.cpp Reads LOWER_CASE_TABLE_NAMES env var and injects lower_case_table_names into startup variables if not provided on cmdline.
src/rootserver/ob_bootstrap.cpp Uses SYS_VAR_LOWER_CASE_TABLE_NAMES to set arg.name_case_mode_ for sys-tenant creation.
src/share/ob_locality_table_operator.cpp Replaces __all_server / __all_zone literals with constants in a join query.
src/share/schema/ob_schema_mgr.cpp Changes how name_case_mode is applied when adding table schemas, with special handling for system tables.
src/share/schema/ob_schema_utils.cpp Sets name_case_mode during inner-table schema construction based on lower_case_table_names.
src/share/schema/ob_server_schema_service.cpp Initializes basic tenant sys-variable schema using lower_case_table_names default value.
src/storage/tx/wrs/ob_tenant_weak_read_cluster_service.cpp Replaces __all_server literal with OB_ALL_SERVER_TNAME in a SQL string.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +645 to +650
// Get name_case_mode from system variable BEFORE creating tables
ObNameCaseMode name_case_mode = OB_LOWERCASE_AND_INSENSITIVE; // default
if (OB_SUCC(ret) && construct_all) {
int64_t var_idx = ObSysVarsToIdxMap::get_store_idx(SYS_VAR_LOWER_CASE_TABLE_NAMES);
ObString lower_case_value = ObSysVariables::get_value(var_idx);

Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new code uses ObSysVarsToIdxMap and ObSysVariables, but this .cpp file doesn't include the header that declares them (e.g., share/system_variable/ob_system_variable.h). Relying on transitive includes is brittle and can break builds if include order changes; please add the required include(s) in this file.

Copilot uses AI. Check for mistakes.
Copy link
Author

@SimonChou12138 SimonChou12138 Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'll put it at the beginning. Even though it can run without it after the image is built and pulled up

Comment on lines 645 to 683
@@ -652,21 +677,26 @@ int ObSchemaUtils::construct_inner_table_schemas(
} else if (!construct_all && is_sys_tenant(tenant_id)
&& table_schema.get_table_id() == OB_ALL_CORE_TABLE_TID) {
// sys tenant's __all_core_table's schema is built separately in bootstrap
} else if (OB_FAIL(ObSchemaUtils::construct_tenant_space_full_table(
tenant_id, table_schema))) {
LOG_WARN("fail to construct tenant space table", KR(ret), K(tenant_id));
} else if (OB_FAIL(ObSysTableChecker::is_inner_table_exist(
tenant_id, table_schema, exist))) {
LOG_WARN("fail to check inner table exist",
KR(ret), K(tenant_id), K(table_schema));
} else if (!construct_all && !exist) {
// skip
} else if (OB_FAIL(tables.push_back(table_schema))) {
LOG_WARN("fail to push back table schema", KR(ret), K(table_schema));
} else if (OB_FAIL(ObSysTableChecker::append_sys_table_index_schemas(
tenant_id, table_schema.get_table_id(), tables))) {
LOG_WARN("fail to append sys table index schemas",
KR(ret), K(tenant_id), "table_id", table_schema.get_table_id());
} else {
// Set name_case_mode for system tables
table_schema.set_name_case_mode(name_case_mode);

Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

construct_inner_table_schemas() only reads SYS_VAR_LOWER_CASE_TABLE_NAMES when construct_all==true, but most call sites use the default (construct_all==false) when creating tenant inner tables. That means name_case_mode is forced to the hardcoded default (OB_LOWERCASE_AND_INSENSITIVE) in those paths, so lower_case_table_names=0 won't actually be honored during tenant schema construction.

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right.

if (OB_SUCC(ret) && construct_all) {
for (int64_t i = 0; i < tables.count(); ++i) {
ObTableSchema &table = tables.at(i);
table.set_name_case_mode(name_case_mode);
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sets name_case_mode for inner/system tables based on lower_case_table_names (and then applies it to all generated index/lob schemas too). That conflicts with the stated requirement (and the comment in ObSchemaMgr::add_table) that system tables should always use OB_ORIGIN_AND_SENSITIVE; with the current ObSchemaMgr logic preserving pre-set values, system tables can end up non-sensitive. Consider forcing OB_ORIGIN_AND_SENSITIVE here for inner tables, or ensure ObSchemaMgr overrides system tables unconditionally.

Suggested change
table.set_name_case_mode(name_case_mode);
// System/inner tables must always use OB_ORIGIN_AND_SENSITIVE, regardless of lower_case_table_names.
if (table.is_inner_table() || table.is_sys_table()) {
table.set_name_case_mode(OB_ORIGIN_AND_SENSITIVE);
} else {
table.set_name_case_mode(name_case_mode);
}

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right.

Comment on lines 2236 to 2247
// System tables ALWAYS use case-sensitive mode (OB_ORIGIN_AND_SENSITIVE = 0)
// regardless of tenant's lower_case_table_names setting
if (is_system_table) {
if (new_table_schema->get_name_case_mode() == OB_NAME_CASE_INVALID) {
// System table arrived with invalid mode - set it to case-sensitive
new_table_schema->set_name_case_mode(OB_ORIGIN_AND_SENSITIVE);
}
// Otherwise preserve the mode already set
} else {
// For user tables, use tenant's name_case_mode
new_table_schema->set_name_case_mode(mode);
}
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment says system tables ALWAYS use OB_ORIGIN_AND_SENSITIVE, but the implementation only sets it when the incoming schema's name_case_mode is invalid; otherwise it preserves whatever was set upstream. Since upstream code can now set inner tables to a non-sensitive mode, this can violate the intended invariant. If system tables must always be case-sensitive, set OB_ORIGIN_AND_SENSITIVE unconditionally for is_system_table.

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right.

Comment on lines 203 to 208
if (!has_lower_case_in_cmdline) {
const char *env_value = getenv("LOWER_CASE_TABLE_NAMES");
if (nullptr != env_value && strlen(env_value) > 0) {
ObString key("lower_case_table_names");
ObString value(env_value);
if (OB_FAIL(opts.variables_.push_back(std::make_pair(key, value)))) {
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parse_args() now uses getenv() and strlen(), but this file doesn't include /<stdlib.h> (for getenv) or /<string.h> (for strlen) on non-macOS builds. Please include the proper headers to avoid relying on transitive includes and to keep compilation portable.

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, input verification is indeed necessary

@SimonChou12138
Copy link
Author

@hnwyllmm Hello, could you please help review it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants