[Enhancement]: Add dynamic configuration for lower_case_table_names i…#156
[Enhancement]: Add dynamic configuration for lower_case_table_names i…#156SimonChou12138 wants to merge 3 commits intooceanbase:developfrom
Conversation
…nstead of hard coding
There was a problem hiding this comment.
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.hconstants. - Read
lower_case_table_namesdynamically from system-variable defaults during bootstrap/schema initialization (instead of hardcoding). - Allow setting
lower_case_table_namesviaLOWER_CASE_TABLE_NAMESenvironment 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.
| // 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); | ||
|
|
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Okay, I'll put it at the beginning. Even though it can run without it after the image is built and pulled up
| @@ -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); | |||
|
|
|||
There was a problem hiding this comment.
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.
src/share/schema/ob_schema_utils.cpp
Outdated
| 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); |
There was a problem hiding this comment.
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.
| 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); | |
| } |
| // 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); | ||
| } |
There was a problem hiding this comment.
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.
src/observer/main.cpp
Outdated
| 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)))) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
You are right, input verification is indeed necessary
|
@hnwyllmm Hello, could you please help review it |
Task Description
Fix hardcoded table names in SQL queries to support
lower_case_table_namessystem variable. This resolves issues where system tables cannot be found whenlower_case_table_names=0(case-sensitive mode) is configured.Related to case-sensitivity handling for MySQL compatibility.
Solution Description
Replace hardcoded table names with constants: Changed direct string literals like
__all_serverand__all_zoneto use constants fromob_inner_table_schema_constants.h(e.g.,OB_ALL_SERVER_TNAME,OB_ALL_ZONE_TNAME)Read
lower_case_table_namesfrom system variables: Modified bootstrap and schema initialization code to dynamically read thelower_case_table_namessetting instead of hardcodingOB_LOWERCASE_AND_INSENSITIVESupport environment variable configuration: Added support for setting
lower_case_table_namesvia theLOWER_CASE_TABLE_NAMESenvironment variable inmain.cppSet proper
name_case_modefor system tables: Ensured system tables always use case-sensitive mode (OB_ORIGIN_AND_SENSITIVE) regardless of tenant settings, while user tables respect the tenant'slower_case_table_namesconfigurationModified files:
src/observer/main.cppsrc/rootserver/ob_bootstrap.cppsrc/share/ob_locality_table_operator.cppsrc/share/schema/ob_schema_mgr.cppsrc/share/schema/ob_schema_utils.cppsrc/share/schema/ob_server_schema_service.cppsrc/storage/tx/wrs/ob_tenant_weak_read_cluster_service.cppPassed Regressions
lower_case_table_names=0configurationUpgrade Compatibility
This change is backward compatible:
lower_case_table_names=1)Other Information
This fix improves MySQL compatibility by properly supporting the
lower_case_table_namessystem variable, which is important for:Release Note
Enhancement: Added proper support for
lower_case_table_namessystem 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.