Bug Report
1. Minimal reproduce step (Required)
On a build where Region pre-splitting is enabled, create a table with a persisted table-level split policy whose bounds are string literals for an integer primary key:
CREATE TABLE t (
id BIGINT PRIMARY KEY
) SPLIT BETWEEN ('0') AND ('10000') REGIONS 4;
SHOW TABLE t REGIONS;
The same literal values are accepted by the one-shot statement:
SPLIT TABLE t BETWEEN ('0') AND ('10000') REGIONS 4;
The issue is in the persistent policy path used by CREATE TABLE ... SPLIT, ALTER TABLE ... SPLIT, and policy reapplication after table operations such as truncate or partition changes.
2. What did you expect to see? (Required)
Persisted split-policy bounds should have the same type-conversion behavior as the equivalent one-shot SPLIT TABLE statement. For the example above, '0' and '10000' should be converted to BIGINT values and create the requested record-region boundaries.
Invalid or unconvertible bounds should make the DDL fail rather than leaving a policy that is silently skipped later.
3. What did you see instead (Required)
The policy normalizer validates and stores the expressions without converting them to the target handle or index-column types. When the policy is later applied, it re-evaluates the stored SQL into untyped datums.
For the integer-primary-key example, both string datums have an internal integer field of zero. calculateIntBoundValue therefore observes equal lower and upper bounds, returns ErrInvalidSplitRegionRanges, and applySplitPoliciesForTable only logs the error. The DDL has accepted and persisted the policy, but the requested record-region splits are not created.
The same missing conversion can encode split keys with the wrong datum type for secondary-index policies and clustered common-handle policies, placing boundaries outside the intended key range.
The one-shot path is not affected: PlanBuilder.convertValue converts each bound to the corresponding column FieldType before split keys are generated.
4. What is your TiDB version? (Required)
Present on current master:
v9.0.0-beta.2.pre-2281-g773fbc3b16
773fbc3b1607a26ce29f32d3c45b5904d30a7b0a
The behavior was introduced with #65133 (ddl: support region split policy, commit 35d50f2b1277c3eb6280e84d923a46fb2a627a4d) and is independent of #71311. It was identified in this review comment.
Analysis
pkg/ddl/split_region.go:333 parses and evaluates persisted expressions but does not convert the result to the target column type.
pkg/ddl/split_region.go:348 only checks the bound count and expression evaluability before serializing the policy.
pkg/planner/core/planbuilder.go:5223 is the reference behavior: it evaluates then calls ConvertTo with the destination column FieldType.
Bug Report
1. Minimal reproduce step (Required)
On a build where Region pre-splitting is enabled, create a table with a persisted table-level split policy whose bounds are string literals for an integer primary key:
The same literal values are accepted by the one-shot statement:
The issue is in the persistent policy path used by
CREATE TABLE ... SPLIT,ALTER TABLE ... SPLIT, and policy reapplication after table operations such as truncate or partition changes.2. What did you expect to see? (Required)
Persisted split-policy bounds should have the same type-conversion behavior as the equivalent one-shot
SPLIT TABLEstatement. For the example above,'0'and'10000'should be converted toBIGINTvalues and create the requested record-region boundaries.Invalid or unconvertible bounds should make the DDL fail rather than leaving a policy that is silently skipped later.
3. What did you see instead (Required)
The policy normalizer validates and stores the expressions without converting them to the target handle or index-column types. When the policy is later applied, it re-evaluates the stored SQL into untyped datums.
For the integer-primary-key example, both string datums have an internal integer field of zero.
calculateIntBoundValuetherefore observes equal lower and upper bounds, returnsErrInvalidSplitRegionRanges, andapplySplitPoliciesForTableonly logs the error. The DDL has accepted and persisted the policy, but the requested record-region splits are not created.The same missing conversion can encode split keys with the wrong datum type for secondary-index policies and clustered common-handle policies, placing boundaries outside the intended key range.
The one-shot path is not affected:
PlanBuilder.convertValueconverts each bound to the corresponding columnFieldTypebefore split keys are generated.4. What is your TiDB version? (Required)
Present on current
master:The behavior was introduced with #65133 (
ddl: support region split policy, commit35d50f2b1277c3eb6280e84d923a46fb2a627a4d) and is independent of #71311. It was identified in this review comment.Analysis
pkg/ddl/split_region.go:333parses and evaluates persisted expressions but does not convert the result to the target column type.pkg/ddl/split_region.go:348only checks the bound count and expression evaluability before serializing the policy.pkg/planner/core/planbuilder.go:5223is the reference behavior: it evaluates then callsConvertTowith the destination columnFieldType.