Skip to content

feat(pivotp): add group-by mode (closes #3697)#3698

Merged
jqnatividad merged 5 commits into
masterfrom
3697-pivotp-simple
Apr 12, 2026
Merged

feat(pivotp): add group-by mode (closes #3697)#3698
jqnatividad merged 5 commits into
masterfrom
3697-pivotp-simple

Conversation

@jqnatividad

Copy link
Copy Markdown
Collaborator

Summary

  • Adds group-by mode to pivotp — when <on-cols> is omitted, performs a Polars group_by + aggregate instead of a pivot
  • Solves the simplest analytical use case: counting rows per group (e.g. qsv pivotp --index GROUP --agg len data.csv)
  • --grand-total, --maintain-order, and all aggregation functions work in group-by mode
  • Rejects pivot-only flags (--subtotal, --validate, --sort-columns) with clear error messages

Example (from issue #3697)

$ echo "GROUP,NAME\nG1,N1\nG2,N1\nG3,N2\nG4,N2\nG5,N1\nG5,N2\nG5,N3" > test.csv

$ qsv pivotp --grand-total --index GROUP --agg len test.csv
GROUP,count
G1,1
G2,1
G3,1
G4,1
G5,3
Grand Total,7

Test plan

  • 13 new group-by mode tests added (basic count, grand total, sum, multi-index, multi-values, maintain-order, custom label, 4 error cases)
  • All 34 existing pivot tests pass unchanged (47 total)
  • cargo clippy clean
  • Manual test with exact data from issue pivotp does not allow simplest use case #3697

Closes #3697

🤖 Generated with Claude Code

jqnatividad and others added 3 commits April 11, 2026 17:44
Support a group-by mode when <on-cols> is omitted: updated USAGE/help text to document PIVOT vs GROUP-BY modes, made positional args optional (arg_on_cols/arg_input -> Option), and resolved positional parsing to detect mode. In group-by mode, --index is required, --agg defaults to count/len (smart -> len), and --values can be omitted to produce a single count column; several pivot-only flags (--subtotal, --validate, --sort-columns) are rejected in group-by mode. Implemented separate execution paths: group-by uses group_by/group_by_stable with appropriate aggregation expressions, while pivot retains the existing pivot logic (on_columns discovery, validation, order restoration, and optional column sorting). Also adjusted input path handling for LazyCsvReader and pschema lookup to use the resolved input string.
…rden dispatch

- Reject `--agg none` during group-by validation instead of silently
  falling through to count
- Remove dead if/else branch where both arms returned "smart"
- Replace catch-all `_ =>` in group-by agg match with explicit `"len" | "smart"`
  arm and `unreachable!()` to prevent silent divergence from pivot-mode dispatch
- Add cross-reference comments between the two aggregation match blocks
- Add safety comments explaining why unwrap() calls in pivot mode are sound
- Fix USAGE text: --agg smart resolves to len (count), not defaults to len
- Add test for --agg none rejection in group-by mode

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…refs

Move the `--agg none` group-by validation after `to_lowercase()` so that
`--agg None` and `--agg NONE` are also rejected with a friendly error
instead of hitting `unreachable!()` and panicking.

Replace fragile `~line NNN` cross-references in comments with
landmark-based descriptions that won't drift with edits.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jqnatividad jqnatividad requested a review from Copilot April 11, 2026 22:00
@codacy-production

codacy-production Bot commented Apr 11, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 20 complexity

Metric Results
Complexity 20

View in Codacy

TIP This summary will be updated as you push new changes. Give us feedback

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a new “group-by mode” to qsv pivotp when <on-cols> is omitted, enabling simple group_by + aggregate workflows (e.g., counts per group) while keeping existing pivot behavior intact.

Changes:

  • Updated pivotp CLI/arg parsing and help text to support both pivot mode (<on-cols> <input>) and group-by mode (<input>).
  • Implemented a Polars group-by execution path (including support for --grand-total and --maintain-order) and mode-specific flag validation.
  • Added a new suite of group-by mode tests, including success cases and error cases.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
src/cmd/pivotp.rs Adds group-by mode execution path, positional-arg resolution, mode-specific validations, and updated CLI documentation.
tests/test_pivotp.rs Adds new tests covering group-by mode behavior (counts, sums, multi-index/values, totals) and error scenarios.

Comment thread src/cmd/pivotp.rs
Comment thread src/cmd/pivotp.rs Outdated
Comment thread tests/test_pivotp.rs
Comment thread src/cmd/pivotp.rs Outdated
…ests

- Use len() instead of count() in group-by agg expressions for null-
  consistency with pivot mode's Expr::Element.len()
- Reject --agg item in group-by mode with clear error (no single-value
  semantics equivalent)
- Update --maintain-order help text to describe both modes
- Skip index_order computation when --maintain-order is set (rely on
  group_by_stable); keep lazy pipeline for non-maintain-order case
- Assert stderr error messages in all error-case tests
- Add --agg item error test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

Comment thread src/cmd/pivotp.rs Outdated
Comment thread src/cmd/pivotp.rs
Comment thread src/cmd/pivotp.rs Outdated
- Use mode-aware "Invalid {group-by|pivot} aggregation function" error
- Clarify --col-separator is ignored in group-by mode
- Clarify --grand-total sums numeric non-index columns

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jqnatividad

Copy link
Copy Markdown
Collaborator Author

resolves #3697

@jqnatividad jqnatividad merged commit 905d6a0 into master Apr 12, 2026
15 of 18 checks passed
@jqnatividad jqnatividad deleted the 3697-pivotp-simple branch April 12, 2026 00:14
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.

pivotp does not allow simplest use case

2 participants