Skip to content

feat: allow configuring datafusion-cli history file location#23797

Open
dariocurr wants to merge 2 commits into
apache:mainfrom
dariocurr:cli/configurable-history-file-location
Open

feat: allow configuring datafusion-cli history file location#23797
dariocurr wants to merge 2 commits into
apache:mainfrom
dariocurr:cli/configurable-history-file-location

Conversation

@dariocurr

@dariocurr dariocurr commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

datafusion-cli's interactive REPL hardcodes its rustyline history file as the relative path .history. Because the path is relative, the history file is created (and looked up) in whatever directory the CLI happens to be launched from, so every working directory silently accumulates its own hidden .history file with no way to point it somewhere else.

What changes are included in this PR?

  • Add a --history-file <PATH> CLI flag to datafusion-cli, validated at parse time (rejects a path that is an existing directory, or whose parent directory doesn't exist).
  • Add a DATAFUSION_HISTORY_FILE environment variable as an alternative way to set it (e.g. for scripted/containerized setups). The --history-file flag takes precedence over the environment variable.
  • The existing default behavior (.history, relative to the current directory) is unchanged when neither is set, so this is non-breaking.
  • exec_from_repl now takes a ReplOptions struct (new datafusion-cli/src/repl_options.rs module, mirroring the existing print_options module) instead of hardcoding .history twice. ReplOptions::default() centralizes both the .history fallback and the DATAFUSION_HISTORY_FILE env var resolution in one place.
  • Updated datafusion-cli/examples/cli-session-context.rs (the only other caller of exec_from_repl) and docs/source/user-guide/cli/usage.md accordingly.

Are these changes tested?

This is a small, mostly mechanical CLI argument-plumbing change with no new branching logic worth unit-testing in isolation (the added validator mirrors the existing parse_valid_file/parse_valid_data_dir helpers, which aren't separately unit-tested either). I manually verified end-to-end via the built binary:

  • Default (.history in cwd, unchanged behavior)
  • --history-file <path> override
  • DATAFUSION_HISTORY_FILE=<path> override
  • --history-file taking precedence over DATAFUSION_HISTORY_FILE when both are set
  • --history-file pointing at a non-existent parent directory fails fast with a clear error instead of a late rustyline error

Existing datafusion-cli unit tests pass (cargo test -p datafusion-cli --lib --bins).

Are there any user-facing changes?

Yes: a new --history-file CLI flag and DATAFUSION_HISTORY_FILE environment variable, documented in docs/source/user-guide/cli/usage.md. No breaking changes; default behavior is unchanged.

datafusion-cli hardcoded the interactive shell's rustyline history as
the relative path `.history`, so every launch directory silently got
its own history file with no way to point it elsewhere.

Add a `--history-file <PATH>` flag and a `DATAFUSION_HISTORY_FILE`
environment variable (flag takes precedence), keeping `.history` as
the default so existing behavior is unchanged.

Closes apache#23796.
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Jul 22, 2026
@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown

Thank you for opening this pull request!

Reviewer note: cargo-semver-checks reported the current version number is not SemVer-compatible with the changes in this pull request (compared against the base branch).

Details
     Cloning apache/main
    Building datafusion-cli v54.1.0 (current)
       Built [ 179.943s] (current)
     Parsing datafusion-cli v54.1.0 (current)
      Parsed [   0.034s] (current)
    Building datafusion-cli v54.1.0 (baseline)
       Built [ 179.759s] (baseline)
     Parsing datafusion-cli v54.1.0 (baseline)
      Parsed [   0.034s] (baseline)
    Checking datafusion-cli v54.1.0 -> v54.1.0 (no change; assume patch)
     Checked [   0.120s] 223 checks: 222 pass, 1 fail, 0 warn, 30 skip

--- failure function_parameter_count_changed: pub fn parameter count changed ---

Description:
A publicly-visible function now takes a different number of parameters.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#fn-change-arity
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.49.0/src/lints/function_parameter_count_changed.ron

Failed in:
  datafusion_cli::exec::exec_from_repl now takes 3 parameters instead of 2, in /home/runner/work/datafusion/datafusion/datafusion-cli/src/exec.rs:130

     Summary semver requires new major version: 1 major and 0 minor checks failed
    Finished [ 363.004s] datafusion-cli

@github-actions github-actions Bot added the auto detected api change Auto detected API change label Jul 22, 2026
@dariocurr

Copy link
Copy Markdown
Contributor Author

Re the cargo-semver-checks note above: this is an expected, intentional minor breaking change. exec_from_repl gained a required history_file: Option<&Path> parameter so the interactive shell's history location can be configured (this PR's whole purpose); the only in-tree caller besides main.rs is datafusion-cli/examples/cli-session-context.rs, which has been updated accordingly.

Per the API health policy, could a committer add the api change label to this PR? I don't have push access to add it myself.

Comment thread datafusion-cli/src/exec.rs Outdated
pub async fn exec_from_repl(
ctx: &dyn CliSessionContext,
print_options: &mut PrintOptions,
history_file: Option<&Path>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be better instead of just adding an Option<&Path>,
to declare some struct like perhaps

#[non_exhaustive]
#[derive(Default)]
struct OtherOptions {
    history_path: Option<PathBuf>,
}

Or manually implement default to default to ".history" here in the struct than in the function.
Then if any new options are needed which have default values, we don't have to change the abi again to add them, because they should just get picked up by the non_exhaustive/default combo.

@ratmice ratmice Jul 24, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should clarify that I'm just a drive-by reviewer, not really a maintainer or anything so take my suggestions for what their worth, perhaps the maintainers will have conflicting ideas.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took this suggestion and pushed an update: exec_from_repl now takes a ReplOptions struct (in its own new module, datafusion-cli/src/repl_options.rs, mirroring how PrintOptions gets its own module) instead of the raw Option<&Path>.

I kept it as a plain, exhaustively-constructed struct rather than adding #[non_exhaustive] + partial-construction-via-Default, so it stays consistent with PrintOptions's existing convention in this same crate (plain struct, named-field construction at each call site) rather than introducing a second, different pattern for "options" structs. So this doesn't fully close the door on future signature churn the way your suggestion would, but it does give us a dedicated place to add REPL-specific options later without touching PrintOptions, and it let me centralize both the .history default and the DATAFUSION_HISTORY_FILE env var resolution into ReplOptions::default() instead of duplicating that logic across callers. Thanks for the pointer to the pattern either way!

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good thinking to keep it consistent, we could always add #[non_exhaustive] to both in follow up patch if that is desired.

This update introduces a new `ReplOptions` struct to manage the history file configuration for the DataFusion CLI. The `exec_from_repl` function has been modified to accept `ReplOptions`, allowing users to specify a custom history file path. The default behavior remains unchanged, defaulting to `.history` if no path is provided. This change enhances the flexibility of the CLI's interactive shell experience.
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.63%. Comparing base (dfe0f26) to head (55c1045).
⚠️ Report is 58 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #23797      +/-   ##
==========================================
- Coverage   80.71%   80.63%   -0.09%     
==========================================
  Files        1089     1091       +2     
  Lines      368760   370720    +1960     
  Branches   368760   370720    +1960     
==========================================
+ Hits       297636   298918    +1282     
- Misses      53377    53959     +582     
- Partials    17747    17843      +96     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto detected api change Auto detected API change documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

datafusion-cli: allow configuring the location of the interactive shell's history file

3 participants