information_schema.VIEWS reports CASCADED instead of NONE for views without CHECK OPTION
- Dominant language
- Go
- Stars
- 40.5k
- Forks
- 6.2k
- PR merge metrics
- PR metrics pending
Description
## Bug Report
Please answer these questions before submitting your issue. Thanks!
### 1. Minimal reproduce step (Required)
```sql
CREATE TABLE t(a INT);
CREATE VIEW v_none AS SELECT * FROM t WHERE a > 1;
CREATE VIEW v_local AS SELECT * FROM t WHERE a > 1 WITH LOCAL CHECK OPTION;
CREATE VIEW v_cascaded AS SELECT * FROM t WHERE a > 1 WITH CASCADED CHECK OPTION;
SELECT TABLE_NAME, CHECK_OPTION
FROM information_schema.VIEWS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME IN ('v_none', 'v_local', 'v_cascaded')
ORDER BY TABLE_NAME;
```
### 2. What did you expect to see? (Required)
The same values as MySQL 8.0.46, which returns `NONE` for the view created without a check option:
```text
+------------+--------------+
| TABLE_NAME | CHECK_OPTION |
+------------+--------------+
| v_cascaded | CASCADED |
| v_local | LOCAL |
| v_none | NONE |
+------------+--------------+
```
MySQL lists `NONE` among the possible `CHECK_OPTION` values of `INFORMATION_SCHEMA.VIEWS`, and returns it for the statements above.
TiDB's own `INFORMATION_SCHEMA.VIEWS` documentation also lists `NONE` as a possible `CHECK_OPTION` value, although its current example shows `CASCADED` for `CREATE VIEW test.v1 AS SELECT 1`, which has no check-option clause.
### 3. What did you see instead? (Required)
TiDB reports `CASCADED` for `v_none`:
```text
+------------+--------------+
| TABLE_NAME | CHECK_OPTION |
+------------+--------------+
| v_cascaded | CASCADED |
| v_local | LOCAL |
| v_none | CASCADED |
+------------+--------------+
```
As a result, a view created without a check-option clause is indistinguishable in `information_schema.VIEWS` from one created with an explicit `WITH CASCADED CHECK OPTION`.
This can affect schema-diff tools, ORMs, and other clients that use `information_schema.VIEWS` to reconstruct view metadata, because the original check-option state cannot be recovered from the catalog.
In my test, `SHOW CREATE VIEW` also omitted the check-option clause for all three views, so it did not provide a way to recover this distinction either.
Likely cause, from reading the code:
- `ast.ViewCheckOption` only defines `CheckOptionLocal` and `CheckOptionCascaded` in `pkg/parser/ast/model.go`. There is no value representing the absence of a check-option clause.
- The `CreateViewStmt` action in `pkg/parser/parser.y` therefore assigns `ast.CheckOptionCascaded` when the clause is absent.
- `BuildViewInfo` in `pkg/ddl/create_table.go` persists that value as `model.ViewInfo.CheckOption`, which is stored as `view_checkoption` in the table metadata.
- `pkg/executor/infoschema_reader.go` renders `model.ViewInfo.CheckOption` directly into the `CHECK_OPTION` column.
Fixing this likely requires representing "no check option" as a distinct persisted state. Existing metadata already stores both an omitted clause and an explicit `CASCADED` clause as the same value, so the original form cannot be reconstructed for views that already exist. Introducing a new persisted state would also require deciding how it should behave across upgrades and downgrades.
This is separate from #71248. That PR adds parser support for the unqualified `WITH CHECK OPTION` syntax, for which `CASCADED` is the correct value. This issue is about views created without any check-option clause at all.
### 4. What is your TiDB version? (Required)
```text
Release Version: v8.5.3
Edition: Community
Git Commit Hash: dc2548aac79a712265e831cff2a3a896bc0a5a38
Git Branch: HEAD
UTC Build Time: 2025-07-31 13:54:43
GoVersion: go1.23.8
Race Enabled: false
Check Table Before Drop: false
Store: unistore
```
Also reproduced on `master` built locally with `unistore`.
Contributor guide
Research direction
Start with the CREATE VIEW action in pkg/parser/parser.y and ast.ViewCheckOption in pkg/parser/ast/model.go, then trace BuildViewInfo in pkg/ddl/create_table.go through pkg/executor/infoschema_reader.go. Reproduce the three SQL views from the issue and inspect existing metadata and compatibility tests. Done means INFORMATION_SCHEMA.VIEWS distinguishes no clause, LOCAL, and CASCADED without regressing metadata handling across upgrades or downgrades.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, sql
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100