Skip to content

fix: handle MaxUint64 boundary case in AUTO_INCREMENT to avoid returning 0 after restart#67244

Open
tiancaiamao wants to merge 2 commits intomasterfrom
fix-autoid-maxuint64
Open

fix: handle MaxUint64 boundary case in AUTO_INCREMENT to avoid returning 0 after restart#67244
tiancaiamao wants to merge 2 commits intomasterfrom
fix-autoid-maxuint64

Conversation

@tiancaiamao
Copy link
Contributor

@tiancaiamao tiancaiamao commented Mar 24, 2026

Problem

Ref #63455

When UPDATE id = -1 triggers AUTO_INCREMENT rebase to MaxUint64 (18446744073709551615), after TiDB restart, the allocator incorrectly returns 0 as the next ID, causing subsequent INSERT operations to fail with duplicate key errors.

Root Cause

  1. TiDB's AUTO_INCREMENT allocator only stores the end value in KV storage, NOT the base value
  2. When UPDATE id = -1 triggers ForceRebase(), it rebases to MaxUint64
  3. MaxUint64 is stored in KV as uint64 value (18446744073709551615)
  4. After TiDB restart, memory allocator is cleared (base and end reset to 0)
  5. Allocator reads from KV: currentEnd = MaxUint64 (read as int64 = -1)
  6. Allocator initializes: base = -1, end = -1
  7. NextGlobalAutoID() returns: maxv + 1 = -1 + 1 = 0
  8. Next INSERT uses ID = 0, but table already has id = 0Duplicate key error

The bug was in the NextGlobalAutoID() function in pkg/meta/autoid/autoid_service.go at line return maxv + 1, err. When maxv = -1 (MaxUint64 as int64), -1 + 1 = 0 is invalid for unsigned AUTO_INCREMENT (first valid ID is 1).

Solution

Add a MaxUint64 boundary check in NextGlobalAutoID() to detect when maxv == -1 for unsigned types and return ErrAutoincReadFailed error instead of returning 0.

Changes Made

  1. Modified pkg/meta/autoid/autoid_service.go:

    • Added check: if sp.isUnsigned && maxv == -1 { return 0, ErrAutoincReadFailed.GenWithStack(...) }
    • Only applies to unsigned types (sp.isUnsigned == true)
    • Returns descriptive error message
  2. Added test pkg/meta/autoid/autoid_maxuint64_test.go:

    • TestMaxUint64Boundary with 4 test cases
    • Verifies error is returned for unsigned type with maxv=-1
    • Verifies signed type behavior is unchanged
    • Verifies normal cases work correctly
    • Verifies MaxUint64 value casting behavior

Testing

  • Test passes: go test -v -run TestMaxUint64Boundary ./pkg/meta/autoid/
  • All test cases validate the fix logic

Verification

Worktree is based on clean origin/master commit: dffbd3e

Summary by CodeRabbit

Bug Fixes

  • Enhanced AUTO_INCREMENT handling by detecting and properly reporting errors when unsigned integer columns reach their maximum ID capacity, preventing potential data issues from numeric value wraparound.

Tests

  • Added comprehensive test coverage for AUTO_INCREMENT boundary conditions, thoroughly validating error behavior and numeric wraparound scenarios at maximum values for both signed and unsigned column types across multiple edge cases.

@ti-chi-bot
Copy link

ti-chi-bot bot commented Mar 24, 2026

Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@ti-chi-bot ti-chi-bot bot added the do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. label Mar 24, 2026
@pantheon-ai
Copy link

pantheon-ai bot commented Mar 24, 2026

Review Complete

Findings: 0 issues
Posted: 0
Duplicates/Skipped: 6

ℹ️ Learn more details on Pantheon AI.

@coderabbitai
Copy link

coderabbitai bot commented Mar 24, 2026

📝 Walkthrough

Walkthrough

The changes add boundary condition handling for unsigned AUTO_INCREMENT values in TiDB's auto-ID allocation system. When allocating IDs for unsigned columns that reach the maximum value (MaxUint64, represented as -1 in int64), the system now returns an error instead of wrapping to zero.

Changes

Cohort / File(s) Summary
Build Configuration
pkg/meta/autoid/BUILD.bazel
Updated autoid_test target to include new test file autoid_maxuint64_test.go, converted direct dependency to embed attribute, and increased shard_count from 11 to 12.
Auto-ID Service Logic
pkg/meta/autoid/autoid_service.go
Added boundary check in singlePointAlloc.NextGlobalAutoID() to detect when unsigned columns reach MaxUint64 (-1 in int64) and return ErrAutoincReadFailed error instead of wrapping to zero.
Boundary Condition Test
pkg/meta/autoid/autoid_maxuint64_test.go
New test file with TestMaxUint64Boundary containing subtests validating error conditions and wraparound behavior for both signed and unsigned columns at boundary values, plus non-boundary cases.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 When IDs climb to the peak so high,
MaxUint64 reaches the sky,
The boundary's caught with a careful test,
Now errors flow, preventing the nest,
Of wrapped zeros we'd rather not see! 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main fix: handling the MaxUint64 boundary case in AUTO_INCREMENT to prevent returning 0 after restart, which is the primary change across all modified files.
Description check ✅ Passed The description comprehensively addresses the template requirements: includes linked issue reference (#63455), detailed problem statement, root cause analysis, solution explanation, changes made, testing evidence, and verification information.
Linked Issues check ✅ Passed The PR successfully addresses the immediate allocator failure outlined in #63455 by detecting the MaxUint64 boundary condition (maxv == -1 for unsigned types) and returning an error instead of 0, preventing duplicate key failures after restart.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the MaxUint64 boundary issue: modifications to autoid_service.go implement the boundary check, BUILD.bazel integrates the new test file, and autoid_maxuint64_test.go validates the fix with comprehensive test cases.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-autoid-maxuint64

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.11.3)

Command failed


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ti-chi-bot ti-chi-bot bot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Mar 24, 2026
@tiprow
Copy link

tiprow bot commented Mar 24, 2026

Hi @tiancaiamao. Thanks for your PR.

PRs from untrusted users cannot be marked as trusted with /ok-to-test in this repo meaning untrusted PR authors can never trigger tests themselves. Collaborators can still trigger tests on the PR using /test all.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@ti-chi-bot ti-chi-bot bot added component/dumpling This is related to Dumpling of TiDB. component/statistics sig/planner SIG: Planner labels Mar 24, 2026
@hawkingrei
Copy link
Member

/ok-to-test

@ti-chi-bot ti-chi-bot bot added the ok-to-test Indicates a PR is ready to be tested. label Mar 24, 2026
…ing 0 after restart

Fixes #63455

Problem:
- When UPDATE id = -1 triggers rebase to MaxUint64 (18446744073709551615)
- After TiDB restart, allocator reads MaxUint64 from KV as -1 (int64)
- NextGlobalAutoID() incorrectly returns maxv + 1 = -1 + 1 = 0
- Subsequent INSERT operations fail with duplicate key errors

Solution:
- Add MaxUint64 boundary check in NextGlobalAutoID()
- Return ErrAutoincReadFailed instead of 0 when maxv is -1 for unsigned types
- Prevents allocator from returning invalid ID = 0

Test Case:
- Added TestMaxUint64Boundary to verify fix
- Tests scenario where lastAllocated = -1 (MaxUint64 as int64)
- Ensures error is returned instead of 0
@tiancaiamao tiancaiamao force-pushed the fix-autoid-maxuint64 branch from 9f9d7ca to 5344be5 Compare March 24, 2026 01:19
@ti-chi-bot ti-chi-bot bot removed the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Mar 24, 2026
@ti-chi-bot
Copy link

ti-chi-bot bot commented Mar 24, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign benjamin2037 for approval. For more information see the Code Review Process.
Please ensure that each of them provides their approval before proceeding.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ti-chi-bot ti-chi-bot bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Mar 24, 2026
@tiprow
Copy link

tiprow bot commented Mar 24, 2026

@tiancaiamao: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
fast_test_tiprow e036a30 link true /test fast_test_tiprow

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@ti-chi-bot
Copy link

ti-chi-bot bot commented Mar 24, 2026

@tiancaiamao: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
pull-lightning-integration-test 9f9d7ca link true /test pull-lightning-integration-test
pull-br-integration-test 9f9d7ca link true /test pull-br-integration-test
pull-build-next-gen e036a30 link true /test pull-build-next-gen
idc-jenkins-ci-tidb/build e036a30 link true /test build
pull-unit-test-ddlv1 e036a30 link true /test pull-unit-test-ddlv1
idc-jenkins-ci-tidb/unit-test e036a30 link true /test unit-test
pull-unit-test-next-gen e036a30 link true /test pull-unit-test-next-gen

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@ti-chi-bot
Copy link

ti-chi-bot bot commented Mar 24, 2026

[FORMAT CHECKER NOTIFICATION]

Notice: To remove the do-not-merge/needs-linked-issue label, please provide the linked issue number on one line in the PR body, for example: Issue Number: close #123 or Issue Number: ref #456.

📖 For more info, you can check the "Contribute Code" section in the development guide.


Notice: To remove the do-not-merge/needs-tests-checked label, please finished the tests then check the finished items in description.

For example:

Tests

  • Unit test
  • Integration test
  • Manual test (add detailed scripts or steps below)
  • No code

📖 For more info, you can check the "Contribute Code" section in the development guide.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
pkg/meta/autoid/autoid_maxuint64_test.go (2)

52-64: Clarify comment for signed case.

The comment "For signed type, maxv=-1 + 1 = 0 is valid" could be misleading. The key point is that for signed AUTO_INCREMENT, the value -1 stored in KV represents an actual allocation of -1 (not a boundary case), whereas for unsigned types, the int64 value -1 represents MaxUint64 (the boundary). Consider refining the comment to make this distinction clearer.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/meta/autoid/autoid_maxuint64_test.go` around lines 52 - 64, Update the
test comment in the t.Run "signed_maxv_minus_one_returns_zero" to clarify that
for signed AUTO_INCREMENT the stored KV value -1 represents an actual allocation
of -1 (so -1 + 1 = 0 is valid), whereas for unsigned types an int64 value of -1
represents MaxUint64 (a boundary case) and should be handled differently;
reference the variables maxv, isUnsigned, shouldReturnError and nextID in the
comment so readers understand the test verifies only the signed-path behavior.

34-95: Test validates logic but doesn't exercise actual code path.

The test re-implements the boundary check logic (isUnsigned && maxv == -1) rather than calling singlePointAlloc.NextGlobalAutoID(). This means:

  1. It won't catch regressions if the actual implementation changes
  2. It doesn't verify that ErrAutoincReadFailed is returned with the correct message

Consider adding an integration test that exercises the actual NextGlobalAutoID() method, even if it requires mocking the gRPC client to return maxv = -1. Alternatively, extract the boundary check into a testable helper function.

♻️ Example: Extract boundary check for direct testing

In autoid_service.go:

// checkUnsignedBoundary returns an error if maxv represents MaxUint64 for unsigned types.
func checkUnsignedBoundary(isUnsigned bool, maxv int64) error {
    if isUnsigned && maxv == -1 {
        return ErrAutoincReadFailed.GenWithStack("AUTO_INCREMENT has reached the maximum value for unsigned type")
    }
    return nil
}

Then in NextGlobalAutoID():

if err := checkUnsignedBoundary(sp.isUnsigned, maxv); err != nil {
    return 0, err
}

And test the helper directly:

func TestCheckUnsignedBoundary(t *testing.T) {
    err := checkUnsignedBoundary(true, -1)
    require.ErrorIs(t, err, ErrAutoincReadFailed)
    
    err = checkUnsignedBoundary(false, -1)
    require.NoError(t, err)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/meta/autoid/autoid_maxuint64_test.go` around lines 34 - 95, The test
re-implements the boundary logic instead of exercising the real code path;
update tests to either (A) call NextGlobalAutoID and assert it returns
ErrAutoincReadFailed (with the expected message) by mocking the gRPC client to
return maxv == -1 for an unsigned column, or (B) extract the boundary check into
a helper (e.g., checkUnsignedBoundary(isUnsigned bool, maxv int64)) used by
NextGlobalAutoID and add a unit test that calls checkUnsignedBoundary(true, -1)
expecting ErrAutoincReadFailed and checkUnsignedBoundary(false, -1) expecting no
error; ensure NextGlobalAutoID continues to call that helper.
pkg/meta/autoid/BUILD.bazel (1)

51-51: embed is unnecessary — the test file only uses public APIs (require from testify and arithmetic operations on int64/uint64). It doesn't access any unexported symbols.

Consider either:

  • Removing embed = [":autoid"] from line 51 and keeping :autoid in deps, or
  • Converting the test to use package autoid_test (black-box testing) and removing embed entirely.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/meta/autoid/BUILD.bazel` at line 51, The BUILD rule currently uses embed
= [":autoid"] even though the test only exercises public APIs; remove the
unnecessary embed attribute (delete the line embed = [":autoid"]) and keep
":autoid" in deps, or alternatively change the test's package declaration from
package autoid to package autoid_test (black‑box test) and then remove the embed
line; update either the BUILD rule (remove embed) or the test package (to
autoid_test) so embed is no longer required.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/meta/autoid/autoid_maxuint64_test.go`:
- Line 1: Update the license header in pkg/meta/autoid/autoid_maxuint64_test.go
by changing the copyright year from 2025 to 2026; locate the top-of-file comment
(the file header) and replace "2025 PingCAP, Inc." with "2026 PingCAP, Inc." so
the file reflects the current year.

In `@pkg/meta/autoid/autoid_service.go`:
- Around line 344-350: Add the same MaxUint64 boundary guard you added in
singlePointAlloc.NextGlobalAutoID to the other two implementations: in
allocator.NextGlobalAutoID() (autoid.go) and in
inMemoryAllocator.NextGlobalAutoID() (memid.go). Specifically, detect the case
where the input value equals -1 (MaxUint64 when cast to int64) for unsigned
allocators (use the same isUnsigned check or equivalent context) and return a
proper error (ErrAutoincReadFailed.GenWithStack with a message like
"AUTO_INCREMENT has reached the maximum value for unsigned type") instead of
returning 0; otherwise continue to return the incremented value as before.

---

Nitpick comments:
In `@pkg/meta/autoid/autoid_maxuint64_test.go`:
- Around line 52-64: Update the test comment in the t.Run
"signed_maxv_minus_one_returns_zero" to clarify that for signed AUTO_INCREMENT
the stored KV value -1 represents an actual allocation of -1 (so -1 + 1 = 0 is
valid), whereas for unsigned types an int64 value of -1 represents MaxUint64 (a
boundary case) and should be handled differently; reference the variables maxv,
isUnsigned, shouldReturnError and nextID in the comment so readers understand
the test verifies only the signed-path behavior.
- Around line 34-95: The test re-implements the boundary logic instead of
exercising the real code path; update tests to either (A) call NextGlobalAutoID
and assert it returns ErrAutoincReadFailed (with the expected message) by
mocking the gRPC client to return maxv == -1 for an unsigned column, or (B)
extract the boundary check into a helper (e.g., checkUnsignedBoundary(isUnsigned
bool, maxv int64)) used by NextGlobalAutoID and add a unit test that calls
checkUnsignedBoundary(true, -1) expecting ErrAutoincReadFailed and
checkUnsignedBoundary(false, -1) expecting no error; ensure NextGlobalAutoID
continues to call that helper.

In `@pkg/meta/autoid/BUILD.bazel`:
- Line 51: The BUILD rule currently uses embed = [":autoid"] even though the
test only exercises public APIs; remove the unnecessary embed attribute (delete
the line embed = [":autoid"]) and keep ":autoid" in deps, or alternatively
change the test's package declaration from package autoid to package autoid_test
(black‑box test) and then remove the embed line; update either the BUILD rule
(remove embed) or the test package (to autoid_test) so embed is no longer
required.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f7a4ccf3-99f4-4afb-931a-a0989715e223

📥 Commits

Reviewing files that changed from the base of the PR and between dffbd3e and e036a30.

📒 Files selected for processing (3)
  • pkg/meta/autoid/BUILD.bazel
  • pkg/meta/autoid/autoid_maxuint64_test.go
  • pkg/meta/autoid/autoid_service.go

@@ -0,0 +1,96 @@
// Copyright 2025 PingCAP, Inc.
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Update copyright year to 2026.

The current year is 2026, but the license header shows 2025. As per coding guidelines, update the year when creating new source files.

📝 Proposed fix
-// Copyright 2025 PingCAP, Inc.
+// Copyright 2026 PingCAP, Inc.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Copyright 2025 PingCAP, Inc.
// Copyright 2026 PingCAP, Inc.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/meta/autoid/autoid_maxuint64_test.go` at line 1, Update the license
header in pkg/meta/autoid/autoid_maxuint64_test.go by changing the copyright
year from 2025 to 2026; locate the top-of-file comment (the file header) and
replace "2025 PingCAP, Inc." with "2026 PingCAP, Inc." so the file reflects the
current year.

Comment on lines +344 to 350
// Fix: handle MaxUint64 boundary case
// When maxv is MaxUint64 (-1 in int64), adding 1 results in 0.
// We should return an error instead of allowing 0 for unsigned types.
if sp.isUnsigned && maxv == -1 {
return 0, ErrAutoincReadFailed.GenWithStack("AUTO_INCREMENT has reached the maximum value for unsigned type")
}
return maxv + 1, err
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check allocator.NextGlobalAutoID() implementation in autoid.go
rg -n -A 20 'func \(alloc \*allocator\) NextGlobalAutoID' pkg/meta/autoid/autoid.go

Repository: pingcap/tidb

Length of output: 899


🏁 Script executed:

#!/bin/bash
# Check for all autoid allocator types and their Next/Get patterns
rg -n "type.*allocator" pkg/meta/autoid/ | head -20

Repository: pingcap/tidb

Length of output: 607


🏁 Script executed:

#!/bin/bash
# Search for all return patterns with unsigned conversion in autoid package
rg -n "int64\(uint64" pkg/meta/autoid/

Repository: pingcap/tidb

Length of output: 578


🏁 Script executed:

#!/bin/bash
# Check context around autoid_service.go lines 344-350 to see what changed
git -C /tmp/repo log --oneline -20 -- pkg/meta/autoid/autoid_service.go 2>/dev/null || echo "Git not available, checking file directly"
cat -n pkg/meta/autoid/autoid_service.go | sed -n '340,355p'

Repository: pingcap/tidb

Length of output: 879


🏁 Script executed:

#!/bin/bash
# Check memid allocator implementation for unsigned handling
rg -n -B 5 "return int64\(uint64\(alloc.base\) \+ 1\)" pkg/meta/autoid/memid.go

Repository: pingcap/tidb

Length of output: 287


🏁 Script executed:

#!/bin/bash
# Check if memid allocator has isUnsigned field and where Alloc checks it
rg -n -A 30 "func \(alloc \*memAutoIDAllocator\) Alloc\(" pkg/meta/autoid/memid.go | head -50

Repository: pingcap/tidb

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Search for test coverage to understand if this boundary case is tested
rg -n "MaxUint64\|== -1\|0xffffffff" pkg/meta/autoid/ | grep -i test

Repository: pingcap/tidb

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Get more context on inMemoryAllocator implementation
cat -n pkg/meta/autoid/memid.go | sed -n '60,90p'

Repository: pingcap/tidb

Length of output: 1194


🏁 Script executed:

#!/bin/bash
# Check all NextGlobalAutoID implementations across allocator types
rg -n "func.*NextGlobalAutoID" pkg/meta/autoid/

Repository: pingcap/tidb

Length of output: 343


🏁 Script executed:

#!/bin/bash
# Verify if allocator struct and inMemoryAllocator both have isUnsigned field
rg -n "isUnsigned" pkg/meta/autoid/autoid.go pkg/meta/autoid/memid.go | head -20

Repository: pingcap/tidb

Length of output: 1467


The fix is correct for singlePointAlloc, but the same vulnerability exists in TWO other allocator implementations.

The boundary guard added to singlePointAlloc.NextGlobalAutoID() (lines 347–348) correctly prevents wrapping to 0 when maxv == -1 for unsigned types. However, two other Allocator interface implementations have the identical vulnerability:

  1. allocator.NextGlobalAutoID() in autoid.go:327: return int64(uint64(autoID) + 1), err
  2. inMemoryAllocator.NextGlobalAutoID() in memid.go:77: return int64(uint64(alloc.base) + 1), nil

Both will return 0 when the input equals -1 (MaxUint64 as int64) for unsigned types, without error handling.

Apply the same boundary guard to both allocator.NextGlobalAutoID() and inMemoryAllocator.NextGlobalAutoID() to fix this inconsistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/meta/autoid/autoid_service.go` around lines 344 - 350, Add the same
MaxUint64 boundary guard you added in singlePointAlloc.NextGlobalAutoID to the
other two implementations: in allocator.NextGlobalAutoID() (autoid.go) and in
inMemoryAllocator.NextGlobalAutoID() (memid.go). Specifically, detect the case
where the input value equals -1 (MaxUint64 when cast to int64) for unsigned
allocators (use the same isUnsigned check or equivalent context) and return a
proper error (ErrAutoincReadFailed.GenWithStack with a message like
"AUTO_INCREMENT has reached the maximum value for unsigned type") instead of
returning 0; otherwise continue to return the incremented value as before.

@codecov
Copy link

codecov bot commented Mar 24, 2026

Codecov Report

❌ Patch coverage is 0% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.2321%. Comparing base (dffbd3e) to head (e036a30).

Additional details and impacted files
@@               Coverage Diff                @@
##             master     #67244        +/-   ##
================================================
- Coverage   77.7966%   77.2321%   -0.5645%     
================================================
  Files          2022       1941        -81     
  Lines        554843     541628     -13215     
================================================
- Hits         431649     418311     -13338     
- Misses       121449     123315      +1866     
+ Partials       1745          2      -1743     
Flag Coverage Δ
integration 40.8342% <0.0000%> (-7.2823%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
dumpling 61.5065% <ø> (ø)
parser ∅ <ø> (∅)
br 48.7953% <ø> (-12.0510%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Labels

component/dumpling This is related to Dumpling of TiDB. component/statistics do-not-merge/needs-linked-issue do-not-merge/needs-tests-checked do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. ok-to-test Indicates a PR is ready to be tested. sig/planner SIG: Planner size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants