SQL view updates lose SELECT * coverage for later-added columns
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 17.3k
- Forks
- 1.6k
- Avg merge
- 5d 10h
- Merged PRs (30d)
- 28
Description
Problem
A view created with SELECT * should include columns added to its source table later. But running ALTER VIEW ... AS (SELECT * ...) makes the view remember only the columns that exist today.
After someone adds a column, users who can read the view but not the source table may get permission errors when reading the new column through the view. SELECT * FROM v can fail too.
This problem exists before PR #7263. It does not require a retention policy or two operations running at the same time.
PR #7263 adds another way to trigger it: if a retention policy changes while CREATE VIEW is finishing, CREATE takes a recovery path with the same mistake. The policy change can even concern an unrelated materialized view. Normal CREATE remembers * correctly.
How to reproduce the existing ALTER problem
- Create a table
tand a viewvusingSELECT * FROM t. - Give a user SELECT permission on
v, but no direct SELECT permission ont. - As an administrator, run
ALTER VIEW v AS (SELECT * FROM t). - Add a column
wtotand wait for the database to apply the change. - As the user from step 2, run
SELECT w FROM vorSELECT * FROM v.
Expected: the user can read the new column through the view.
Reported result: the query requires direct SELECT permission on t.w and fails. Skipping step 3 lets the user read the new column normally.
Why it happens
The database stores which tables and columns a view uses. That list also controls which columns users may read through the view without direct permission on the source table.
Normal CREATE remembers both the original * and the columns the query needs after optimization. ALTER and the new CREATE recovery path look only at the optimized query, where * has already become a list of today's columns. They save that list and lose the promise to include future columns.
The timing overlap in CREATE only selects the broken path. The underlying mistake is that these paths build the list differently.
Evidence
The review of PR #7263, item 1 and its separate pre-existing finding, reports:
- Before the PR (
ae326748) and at the reviewed PR version (cca0dee6), CREATE keeps*but ALTER loses it:createdStar=true alteredStar=false. - When a test forces a policy change during CREATE, normal CREATE keeps
*but the recovery path loses it:controlStar=true racedStar=false. - In both broken cases, the user cannot read a later-added column with permission on the view alone.
These test results come from the linked review. We inspected the code for this follow-up but did not rerun those tests. The review lists its local logs under /tmp/pr7263-review-EDgeSF/; those logs are not attached to this issue.
Relevant code:
- ALTER before the PR.
- Normal CREATE.
- CREATE recovery path.
- Permission check for columns the view does not cover.
Impact
Moderate. Enterprise users who can read a view but not its source table may get lasting permission errors after someone adds a column. Retrying the query or restarting the server does not repair the saved column list.
The CREATE case requires two operations to overlap. The ALTER case does not. This issue does not show lost data, incorrect retention cleanup, or access to data the user should not see.
What to fix and test
- Have CREATE, ALTER and CREATE recovery use the same code to build the view's table and column list. Keep
*as well as columns needed by retention filters. - Add a test for ordinary ALTER and another that forces a policy change during CREATE recovery, rather than relying on chance timing.
- Check that the saved definition keeps
*and that a user with permission only on the view can read a later-added column, including after a restart. - Keep tests for views that name specific columns and for columns used by retention filters, so the fix does not grant more access than intended.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in core/src/main/java/io/questdb/griffin/SqlCompilerImpl.java, comparing the ALTER, normal CREATE, and CREATE recovery paths linked in the issue; also read the permission check in core/src/main/java/io/questdb/cairo/AbstractPartitionFrameCursorFactory.java. Add tests for ordinary ALTER and forced CREATE recovery, including restart behavior, later-added columns, specific-column views, and retention filters. Done means view-only users can read later-added columns without granting unintended access.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, sql
- Domain
- authorization, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100