Repository navigation
Conversation
`exec_and_print` parsed statements with `DFParser::parse_sql_with_dialect`,
which always uses the parser's built-in recursion limit. Setting
`datafusion.sql_parser.recursion_limit` therefore had no effect in the CLI:
> SET datafusion.sql_parser.recursion_limit = 100;
> SELECT abs(abs(... 60 levels ...));
SQL error: RecursionLimitExceeded (current limit: 50)
Build the parser with `DFParserBuilder` and the session's recursion limit,
the same way `SessionState::sql_to_statement` does.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Co-Authored-By: Claude Fable 5.1 <[email protected]>
edubraqd
marked this pull request as draft
September 4, 2026 13:19
Contributor
|
Closing per #24893 (comment) |
This was referenced Sep 27, 2026
Rich-T-kid
pushed a commit
to Rich-T-kid/datafusion
that referenced
this pull request
Oct 28, 2026
…ating input (apache#25807) ## Which issue does this PR close? - Closes apache#24913. ## Rationale for this change `datafusion.sql_parser.recursion_limit` has no effect in `datafusion-cli`. After `SET datafusion.sql_parser.recursion_limit = 200` (or `DATAFUSION_SQL_PARSER_RECURSION_LIMIT=200`), a query with 60 nested `abs(...)` calls still fails with `RecursionLimitExceeded (current limit: 51)` via `-c`, `-f` and the interactive shell, while the same query works through `SessionContext::sql`. Lowering the limit is ignored too. The CLI parses statements itself instead of going through `SessionState::sql_to_statement`, and only reads the dialect from the session config. There are two parse sites: - `exec_and_print` (`-c`, `-f`, rc files, and REPL execution) - `CliHelper::validate_input`, the REPL's rustyline validator, which rejects the line before it is executed The earlier attempt in apache#24914 fixed only the first one, so the REPL stayed broken. ## What changes are included in this PR? - `exec_and_print` parses with `DFParserBuilder::with_recursion_limit` using the session's limit, the same way `SessionState::sql_to_statement` does. - `CliHelper` gets a `recursion_limit` (default taken from `SqlParserOptions`) and a new `set_parser_options(&SqlParserOptions)` method that sets both the dialect and the recursion limit. `exec_from_repl` calls it once at the top of the REPL loop, before every read, so changes from SQL input, `\i` files and other backslash commands all reach the validator. `CliHelper::new` and `set_dialect` are unchanged, so this is additive. Not changed: - `is_open_quote_for_location` in `helper.rs` (tab completion for `LOCATION '...`) still uses the default parser. It already ignores the dialect, and a parse failure there only means no filename completion. - A single `-c` string or REPL line containing `SET ...; <query>` is parsed as a whole before the `SET` runs, so the new limit does not apply to the query in that same string. This matches how the dialect already behaves. Separate `-c` arguments, file lines, or REPL entries work. Something I noticed and did not special-case: with a limit of 1 or 2, even a `SET` statement fails to parse, so in the REPL you have to restart to recover (3 and above is fine). `SessionContext::sql` behaves the same way; the CLI just used to ignore the setting. ## What is the testing strategy for this PR? - Extended the existing `tests/sql/select.sql` fixture (`cli_quick_test` case `files`, `[email protected]`): it raises the limit and runs a 60-deep query, then lowers it to 5 and runs a 10-deep query. On `main` the snapshot shows the reverse (the deep query fails at 51, the shallow one succeeds). - New `helper.rs` unit test `sql_recursion_limit`, modelled on `sql_dialect`, for the REPL validator. - Manually checked a debug build with `-c`, the env var, and the interactive shell (via `script` for a pty). - Manual pty check of the REPL after `\i` (rustyline needs a terminal, so this is not an sqllogictest): `\i` a file that sets the limit to 100, then run a 60-deep query. Before the follow-up commit the query was held as incomplete and never ran; after it, the query runs. A `SET` typed directly and the default-limit rejection behave as before. Commands run: ```bash cargo test -p datafusion-cli --lib helper::tests cargo test -p datafusion-cli --test cli_integration cli_quick_test cargo test -p datafusion-cli cargo fmt --all cargo clippy -p datafusion-cli --all-targets --all-features -- -D warnings ``` ## Are there any user-facing changes? Yes: `datafusion.sql_parser.recursion_limit` is now respected by `datafusion-cli`. The only API change is the new public `CliHelper::set_parser_options` method (additive). --------- Co-authored-by: Andrew Lamb <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Which issue does this PR close?
datafusion-cliignoresdatafusion.sql_parser.recursion_limit#24913.Rationale for this change
exec_and_printparsed statements withDFParser::parse_sql_with_dialect, which always uses the parser's built-in recursion limit, soSET datafusion.sql_parser.recursion_limithad no effect in the CLI.What changes are included in this PR?
Build the parser with
DFParserBuilder, passing the dialect and the session'srecursion_limit, the same waySessionState::sql_to_statementdoes.Are these changes tested?
Yes.
exec_and_print_honours_parser_recursion_limitruns a 60-level nested expression: it fails withRecursionLimitExceededunder the default limit and succeeds once the session limit is raised to 100.Are there any user-facing changes?
datafusion.sql_parser.recursion_limitnow applies to statements run throughdatafusion-cli.