Skip to content

Conversation

@prmoore77
Copy link

Summary

  • Adds a thread-local recursion guard to prevent infinite recursion when binding views during DuckLakeSchemaEntry::Scan()
  • Uses RAII pattern for exception-safe guard management

Problem

When DuckLakeSchemaEntry::Scan() iterates through catalog entries, it attempts to bind unbound views by calling view_entry.Bind(context). However, Bind() internally calls CreateViewInfo::FromCreateView() which parses the view's SQL. This can trigger catalog lookups (e.g., for GetSimilarEntry when resolving references), which in turn calls Scan() again - creating infinite recursion that exhausts the stack.

Stack Trace (abbreviated)

EXC_BAD_ACCESS (code=2, address=0x1707dbff0)  // stack guard page hit

frame #0: std::string::size()
frame #1: duckdb::StringUtil::EndsWith()
...
frame #N: duckdb::DuckLakeViewEntry::Bind()
frame #N+1: duckdb::DuckLakeSchemaEntry::Scan()
frame #N+2: duckdb::GetSimilarEntry()
frame #N+3: duckdb::TryLookupEntry()
frame #N+4: duckdb::DuckLakeViewEntry::Bind()
... (repeats ~1700 times until stack overflow)

Solution

Added a thread-local g_binding_views_in_scan flag that prevents recursive view binding during Scan operations. The BindingGuard RAII struct ensures the flag is properly reset even if exceptions occur.

Test plan

  • Verified fix prevents stack overflow when querying information_schema.tables with DuckLake catalog containing views
  • Unit tests (if applicable)

🤖 Generated with Claude Code

…Scan

When DuckLakeSchemaEntry::Scan() iterates through catalog entries, it
attempts to bind unbound views by calling view_entry.Bind(context).
However, Bind() internally calls CreateViewInfo::FromCreateView() which
parses the view's SQL. This can trigger catalog lookups (e.g., for
GetSimilarEntry when resolving references), which in turn calls Scan()
again - creating infinite recursion that exhausts the stack.

This fix adds a thread-local recursion guard that prevents view binding
during a recursive Scan() call. The guard uses RAII for exception safety.
@pdet
Copy link
Collaborator

pdet commented Jan 5, 2026

Hi @prmoore77 thanks for the PR.

Can you retarget it to V1.4 and add a SQLTest that triggers the issue? Can you also add tests with recursive views?

@prmoore77
Copy link
Author

Hi @prmoore77 thanks for the PR.

Can you retarget it to V1.4 and add a SQLTest that triggers the issue? Can you also add tests with recursive views?

Hi @pdet - sure thing. I'll work to build a solid test case. I had encountered this issue while troubleshooting a GizmoSQL customer issue (with DuckLake). I had imported their PostgreSQL catalog data - and when I attempted to: SELECT * FROM information_schema.tables; - I encountered this segfault.

I'm not sure which view(s) caused the issue, but I'll work to narrow it down, and will update this PR...

@pdet
Copy link
Collaborator

pdet commented Jan 5, 2026

Hi @prmoore77 thanks for the PR.
Can you retarget it to V1.4 and add a SQLTest that triggers the issue? Can you also add tests with recursive views?

Hi @pdet - sure thing. I'll work to build a solid test case. I had encountered this issue while troubleshooting a GizmoSQL customer issue (with DuckLake). I had imported their PostgreSQL catalog data - and when I attempted to: SELECT * FROM information_schema.tables; - I encountered this segfault.

I'm not sure which view(s) caused the issue, but I'll work to narrow it down, and will update this PR...

Thanks, Philip! Let me know if you have any questions or if I can be of any help!

@pdet
Copy link
Collaborator

pdet commented Jan 9, 2026

Closing this as it is superseded by #681

@pdet pdet closed this Jan 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants