Skip to content

feat(sql): arg_min and arg_max CHAR functions#6730

Merged
bluestreak01 merged 5 commits intomasterfrom
nw_arg_min_max_char
Mar 13, 2026
Merged

feat(sql): arg_min and arg_max CHAR functions#6730
bluestreak01 merged 5 commits intomasterfrom
nw_arg_min_max_char

Conversation

@nwoolmer
Copy link
Copy Markdown
Contributor

@nwoolmer nwoolmer commented Jan 30, 2026

Summary

Adds arg_max and arg_min function variants that accept a CHAR type for the value argument (left-hand side).

New functions

Function Signature Description
arg_max(AN) arg_max(char, timestamp) Returns char value at maximum timestamp
arg_max(AL) arg_max(char, long) Returns char value at maximum long
arg_max(AD) arg_max(char, double) Returns char value at maximum double
arg_min(AN) arg_min(char, timestamp) Returns char value at minimum timestamp
arg_min(AL) arg_min(char, long) Returns char value at minimum long
arg_min(AD) arg_min(char, double) Returns char value at minimum double

Usage examples

-- Find char value at maximum/minimum timestamp
SELECT arg_max(status, created_at), arg_min(status, created_at) FROM events;

-- With GROUP BY
SELECT category, arg_max(grade, score), arg_min(grade, score)
FROM results
GROUP BY category;

Notes

  • Null keys are ignored during aggregation
  • Null values are returned when the corresponding key is the max/min
  • All variants support parallel execution

@nwoolmer nwoolmer added the SQL Issues or changes relating to SQL execution label Jan 30, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 30, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 618ecbc4-48b5-4df2-ad82-ca4f1f715858

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Adds eight new group-by aggregation functions implementing arg_max and arg_min for char values across three key types (double, long, timestamp), with corresponding function factories and comprehensive test suites.

Changes

Cohort / File(s) Summary
ArgMax Char with Double Key
core/src/main/java/io/questdb/griffin/engine/functions/groupby/ArgMaxCharDoubleGroupByFunction.java, ArgMaxCharDoubleGroupByFunctionFactory.java
Implements arg_max aggregation that tracks maximum double key with corresponding char value; factory exposes signature arg_max(AD).
ArgMax Char with Long Key
core/src/main/java/io/questdb/griffin/engine/functions/groupby/ArgMaxCharLongGroupByFunction.java, ArgMaxCharLongGroupByFunctionFactory.java
Implements arg_max aggregation that tracks maximum long key with corresponding char value; factory exposes signature arg_max(AL).
ArgMax Char with Timestamp Key
core/src/main/java/io/questdb/griffin/engine/functions/groupby/ArgMaxCharTimestampGroupByFunction.java, ArgMaxCharTimestampGroupByFunctionFactory.java
Implements arg_max aggregation that tracks maximum timestamp key with corresponding char value; factory exposes signature arg_max(AN).
ArgMin Char with Double Key
core/src/main/java/io/questdb/griffin/engine/functions/groupby/ArgMinCharDoubleGroupByFunction.java, ArgMinCharDoubleGroupByFunctionFactory.java
Implements arg_min aggregation that tracks minimum double key with corresponding char value; factory exposes signature arg_min(AD).
ArgMin Char with Long Key
core/src/main/java/io/questdb/griffin/engine/functions/groupby/ArgMinCharLongGroupByFunction.java, ArgMinCharLongGroupByFunctionFactory.java
Implements arg_min aggregation that tracks minimum long key with corresponding char value; factory exposes signature arg_min(AL).
ArgMin Char with Timestamp Key
core/src/main/java/io/questdb/griffin/engine/functions/groupby/ArgMinCharTimestampGroupByFunction.java, ArgMinCharTimestampGroupByFunctionFactory.java
Implements arg_min aggregation that tracks minimum timestamp key with corresponding char value; factory exposes signature arg_min(AN).
Test Suite
core/src/test/java/io/questdb/test/griffin/engine/functions/groupby/ArgMaxCharDoubleGroupByFunctionFactoryTest.java, ArgMaxCharLongGroupByFunctionFactoryTest.java, ArgMaxCharTimestampGroupByFunctionFactoryTest.java, ArgMinCharDoubleGroupByFunctionFactoryTest.java, ArgMinCharLongGroupByFunctionFactoryTest.java, ArgMinCharTimestampGroupByFunctionFactoryTest.java
Comprehensive test coverage for all six variants including null handling, parallel execution, chunked data processing, group-by scenarios, and merge operations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

New feature

Suggested reviewers

  • bluestreak01
  • puzpuzpuz
🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive No pull request description was provided by the author, making it impossible to assess whether it relates to the changeset. Add a pull request description explaining the motivation, implementation details, and testing approach for the new CHAR-typed arg_min/arg_max functions.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely describes the main change: adding arg_min and arg_max functions for CHAR data type in SQL.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch nw_arg_min_max_char

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nwoolmer
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 30, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

1 similar comment
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 30, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

public void computeFirst(MapValue mapValue, Record record, long rowId) {
long key = keyArg.getTimestamp(record);
if (key == Numbers.LONG_NULL) {
mapValue.putChar(valueIndex, (char) 0);
Copy link
Copy Markdown
Contributor

@glasstiger glasstiger Mar 4, 2026

Choose a reason for hiding this comment

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

nit:
(char) 0 is hardcoded in 6 files instead of using Numbers.CHAR_NULL.
Not a bug (they are the same value), but using the constant would be more self-documenting.
The existing codebase uses Numbers.LONG_NULL and Double.NaN for those types, so the CHAR variant is slightly inconsistent.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Fixed — replaced all (char) 0 occurrences with Numbers.CHAR_NULL across all 6 implementation files (in computeFirst() and setNull()).

bluestreak01 and others added 2 commits March 9, 2026 18:50
Use Numbers.CHAR_NULL instead of hardcoded (char) 0 across all 6
implementation files for consistency with Numbers.LONG_NULL and
Double.NaN usage in other arg_min/arg_max variants.

Add missing test coverage: empty table, tie-breaking behavior (first
occurrence wins with strict >/<), and mixed null value + null key
combinations in the same dataset.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@glasstiger
Copy link
Copy Markdown
Contributor

[PR Coverage check]

😍 pass : 288 / 288 (100.00%)

file detail

path covered line new line coverage
🔵 io/questdb/griffin/engine/functions/groupby/ArgMinCharTimestampGroupByFunction.java 44 44 100.00%
🔵 io/questdb/griffin/engine/functions/groupby/ArgMaxCharTimestampGroupByFunction.java 44 44 100.00%
🔵 io/questdb/griffin/engine/functions/groupby/ArgMaxCharTimestampGroupByFunctionFactory.java 4 4 100.00%
🔵 io/questdb/griffin/engine/functions/groupby/ArgMaxCharLongGroupByFunctionFactory.java 4 4 100.00%
🔵 io/questdb/griffin/engine/functions/groupby/ArgMaxCharLongGroupByFunction.java 44 44 100.00%
🔵 io/questdb/griffin/engine/functions/groupby/ArgMinCharDoubleGroupByFunctionFactory.java 4 4 100.00%
🔵 io/questdb/griffin/engine/functions/groupby/ArgMaxCharDoubleGroupByFunctionFactory.java 4 4 100.00%
🔵 io/questdb/griffin/engine/functions/groupby/ArgMinCharTimestampGroupByFunctionFactory.java 4 4 100.00%
🔵 io/questdb/griffin/engine/functions/groupby/ArgMinCharLongGroupByFunction.java 44 44 100.00%
🔵 io/questdb/griffin/engine/functions/groupby/ArgMinCharLongGroupByFunctionFactory.java 4 4 100.00%
🔵 io/questdb/griffin/engine/functions/groupby/ArgMaxCharDoubleGroupByFunction.java 44 44 100.00%
🔵 io/questdb/griffin/engine/functions/groupby/ArgMinCharDoubleGroupByFunction.java 44 44 100.00%

@bluestreak01 bluestreak01 merged commit cb5c781 into master Mar 13, 2026
50 checks passed
@bluestreak01 bluestreak01 deleted the nw_arg_min_max_char branch March 13, 2026 11:35
maciulis pushed a commit to maciulis/questdb that referenced this pull request Mar 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

SQL Issues or changes relating to SQL execution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants