Skip to content

ddl: persisted region split-policy bounds bypass column type conversion #71395

Description

@D3Hunter

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.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    affects-9.0This bug affects the 9.0.x versions.component/ddlThis issue is related to DDL of TiDB.severity/moderatetype/bugThe issue is confirmed as a bug.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions