Skip to content

fix: making version non-default - #213

Open
gord02 wants to merge 1 commit into
mainfrom
gordon.hamilton/optional-versioning
Open

fix: making version non-default#213
gord02 wants to merge 1 commit into
mainfrom
gordon.hamilton/optional-versioning

Conversation

@gord02

@gord02 gord02 commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Description

The version in the plan proto is currently always printed. This information ins't always necessary to view when printing a plan so we should print this primarily in verbose mode.

Type of Change

  • Bug fix

Testing

  • Added tests for new functionality
  • All existing tests pass

@gord02
gord02 marked this pull request as ready for review August 19, 2026 13:56
@gord02
gord02 requested review from a team and wackywendell as code owners August 19, 2026 13:56

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 770adadd16

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/textify/foundation.rs
impl Default for OutputOptions {
fn default() -> Self {
Self {
show_version: Visibility::Never,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve explicit versions in default output

Use Visibility::Required as the default rather than Never: when format() or the CLI converts a JSON/protobuf plan carrying an explicit version, this setting omits the entire section, and parsing the emitted text replaces the original version with default_plan_version(); a plan whose version is None likewise becomes versioned. Thus an ordinary conversion or round trip silently changes compatibility and producer metadata unless users know to opt into --show-plan-version.

AGENTS.md reference: AGENTS.md:L90-L92

Useful? React with 👍 / 👎.

Comment thread src/parser/structural.rs
Comment on lines +932 to +934
/// A document with no version(`=== Version null`) section gets
/// [`default_plan_version`](crate::default_plan_version);
///

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
/// A document with no version(`=== Version null`) section gets
/// [`default_plan_version`](crate::default_plan_version);
///

This comment doesn't fit here, it's the wrong level of detail here.

Also, this seems wrong anyway:

  • === Version null in the text should translate to unset Version in the protobuf
  • A missing Version section should translate to the 'default' plan version

Comment thread src/parser/structural.rs
state: State::Initial,
cursor: None,
version: None,
version: Some(default_plan_version()),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
version: Some(default_plan_version()),
// We set the version to our substrait-explain default.
// An explicitly set version (either null or with a
// version number / attributes) will override this.
// `None` here means 'explicitly unset'.
version: Some(default_plan_version()),

Given that its unusual to set something to Some by default and then override it to None, this could use explanation.

Comment thread src/cli.rs
Commands::Validate {
input,
output,
show_plan_version,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why are we adding this specifically to Validate? That seems odd...

Comment thread src/cli.rs
Comment on lines 80 to +81
show_literal_types,
show_plan_version,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think instead of adding these as separate options, we should add a --detailed flag which uses OutputOptions::verbose(). I'm not sure we need specific flags for every option; we don't have them now.

Comment thread src/cli.rs
Comment on lines +314 to +316
/// Show the plan's Substrait version (text output only)
#[arg(long)]
show_plan_version: bool,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why is this an option for Validate? What would it mean to enable / disable it?

Without good reason for adding it, I don't think we should.

Comment thread src/cli.rs
show_plan_version,
verbose,
..
} => self.run_validate_with_io(reader, writer, *show_plan_version, *verbose, registry),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Firstly, I think we should just drop show_plan_version as an option to Validate.

Secondly, even if there was a good reason to have this, we should add options here, not add each option one by one.

Comment thread tests/plan_roundtrip.rs

/// Round-trip `input` with the version section at the given visibility, leaving
/// every other option at its default.
fn roundtrip_showing_version(input: &str, show_version: Visibility) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is oddly specific. May I suggest:

pub fn roundtrip_plan(input: &str) {
    roundtrip_plan_with_options(input, &OutputOptions::default());
}

pub fn roundtrip_with_options(input: &str, options: &OutputOptions) {}

Then in your tests:

let options = OutputOptions {
    show_version: Visibility::Required,
    ..OutputOptions::default()
};

roundtrip_plan_with_options(plan, &options);

That's a more generally useful function, and both arguments (plan and options are at the same abstraction level.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Alternatively, this interface is getting complex enough now it's probably worth framing our data structures to fit:

struct Roundtrip<'a> {
    canonical: &'a str,
    equivalent_inputs: Vec<&'a str>,
    options: OutputOptions,
}

Then you can use it like so:

// Simple roundtrip
Roundtrip::new(plan).assert();

// with options
Roundtrip::new(plan)
    .with_options(OutputOptions {
        show_version: Visibility::Always,
        ..OutputOptions::default()
    })
    .assert();

// with a canonical and equivalent plan
Roundtrip::new(canonical)
    .also_accepts(equivalent)
    .assert();

This is a non-blocking suggestion - feel free to just do the roundtrip_with_options suggested above.

Comment thread API.md
Comment on lines 366 to +367
- `--show-literal-types` - Show type annotations on literals
- `--show-plan-version` - Show the plan's Substrait version

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
- `--show-literal-types` - Show type annotations on literals
- `--show-plan-version` - Show the plan's Substrait version
- `--detailed` - Show more detail on plans, including type annotations and plan version

Let's make this one option rather than two.

Comment thread API.md

- `-i, --input <FILE>` - Input file (default: stdin)
- `-o, --output <FILE>` - Output file (default: stdout)
- `--show-plan-version` - Show the plan's Substrait version

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
- `--show-plan-version` - Show the plan's Substrait version

Let's drop this, it doesn't make much sense as part of validate

Comment thread GRAMMAR.md
Comment on lines +159 to +173
#
# let no_section = r#"
# === Plan
# Root[result]
# Read[orders => quantity:i32?]
# "#;
#
# let plan = Parser::parse(no_section).unwrap();
# assert_eq!(plan.version, Some(default_plan_version()));
#
# // nothing and `null` are different inputs, and stay different.
# assert_ne!(
# Parser::parse(null_version).unwrap().version,
# Parser::parse(no_section).unwrap().version
# );

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
#
# let no_section = r#"
# === Plan
# Root[result]
# Read[orders => quantity:i32?]
# "#;
#
# let plan = Parser::parse(no_section).unwrap();
# assert_eq!(plan.version, Some(default_plan_version()));
#
# // nothing and `null` are different inputs, and stay different.
# assert_ne!(
# Parser::parse(null_version).unwrap().version,
# Parser::parse(no_section).unwrap().version
# );

You don't need a full test here asserting lots of things - the tests in GRAMMAR.md should merely assert that the example plan is accepted as valid input.

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