A view can be suggested as the fix for an unresolved table inside its own body
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 39.9k
- Forks
- 3.4k
- Avg merge
- 6h 51m
- Merged PRs (30d)
- 232
Description
Bug description
When a table name inside a view's body does not resolve, the "Did you mean …?" suggestion list
can include the view currently being resolved. Taking that suggestion makes the view select
from itself, which then fails as a cycle.
Mechanism
The table-suggestion candidate set is built in posthog/hogql/database/database.py, ending at
line 875:
return difflib.get_close_matches(name, sorted(candidates), n=limit, cutoff=0.7)
The candidates include every view name:
candidates.update(self._view_table_names)
There is already one self-exclusion, but it only drops a candidate equal to the queried name:
# Drop any candidate that matches the input — suggesting `persons` for `persons`
# is noise …
candidates = {c for c in candidates if c.casefold() != lowered}
The name being resolved is by definition not the enclosing view's name (otherwise it would have
resolved), so the enclosing view survives that filter and stays eligible as a near match.
Why the data to fix it already exists, but does not reach the suggestion site
Two resolvers track "am I inside a view" differently:
posthog/hogql/resolver.py:384—self.current_view_depth: int = 0, a counterproducts/data_modeling/backend/models/modeling.py:165—self.resolving_views: set[str], a name set
A counter can say how deep the resolution is, but not which view it is inside, so the base
resolver cannot exclude it. The data-modeling resolver does know the name, but nothing in
modeling.py filters suggestions (no reference to suggest, cutoff, or get_close_matches),
so the name never reaches the candidate filter either.
Suggested direction
Carry the enclosing view name down to the suggestion site and exclude it, rather than adding a
second self-check at the call site. Lifting the name set into the base resolver would fix every
path at once.
If that lift happens, note that the discard-in-finally pattern in modeling.py:294 is not
safe once a view can be entered twice on different branches — it needs add-if-absent /
remove-what-I-added.
Notes
Traced in the code on master today. Not executed.
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 posthog/hogql/database/database.py around line 875, then read the view-tracking logic in posthog/hogql/resolver.py:384 and products/data_modeling/backend/models/modeling.py:165 and :294. Trace how the enclosing view name could reach suggestion generation, and verify that suggestions for unresolved tables no longer include that view, including nested or repeated resolution paths.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100