pingcap / pingcap/tidb

[Column Masking] MEDIUM: RENAME TABLE doesn't sync sys table metadata

Open
#67,045 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Severity
MEDIUM

## Description
Policy metadata stores `db_name`/`table_name`. RENAME TABLE only modifies table metadata, but **does not update** the corresponding rows in `mysql.tidb_masking_policy`.

Later `onAlterMaskingPolicy` uses the old name with `TableByName()` for validation. After rename, it reports table doesn't exist and cancels the job.

## Impact
Users cannot modify/enable/disable the same policy after renaming the table (functional bug that confuses operations).

## Example
```sql
-- 1. Create table and policy
CREATE TABLE db1.old_table (id INT, col VARCHAR(100));
CREATE MASKING POLICY p AS MASK_FULL(col) ENABLE;
ALTER TABLE db1.old_table MODIFY COLUMN col VARCHAR(100) WITH MASKING POLICY p ENABLE;

-- 2. Rename table
RENAME TABLE db1.old_table TO db1.new_table;

-- 3. Try to modify policy - fails!
ALTER TABLE db1.new_table MODIFY COLUMN col VARCHAR(100) WITH MASKING POLICY p DISABLE;
-- Error: table db1.old_table doesn't exist
```

## Related Code Locations
- `pkg/ddl/table.go:782` - rename table implementation has no masking-policy sys table sync
- `pkg/infoschema/masking_policy_loader.go:165` - sys table loader directly reads db_name/table_name
- `pkg/ddl/masking_policy.go:139` - alter worker validation depends on TableByName(policy.DBName, policy.TableName)
- `pkg/ddl/masking_policy.go:265` - validation implementation
- `pkg/ddl/masking_policy.go:534` - only syncs policy.TableName when "modifying column"

## Root Cause
1. `mysql.tidb_masking_policy` stores `db_name` and `table_name` strings
2. RENAME TABLE only updates the table's own metadata, not policy metadata referencing the table
3. Later operations (ALTER/ENABLE/DISABLE) use old table name to find table, causing failure

## Proposed Fix

**Option A (Recommended)**: Update sys table during RENAME TABLE

In the rename table job, update `db_name`/`table_name` in `mysql.tidb_masking_policy` by `table_id` (and `db_name` for cross-database rename).

**Option B**: Use table_id validation
Make `validateMaskingPolicyTarget` validate based on `TableID`/`ColumnID` and backfill latest name when necessary.

## Parent Issue
Relates to #65744

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.