Skip to content

Conversation

@devanbenz
Copy link

@devanbenz devanbenz commented Dec 3, 2025

Implement date_part(part, expression)

Arguments

- part: Part of the date to return. The following date parts are supported:
   - year
    - quarter (emits value in inclusive range [1, 4] based on which quartile of the year the date is in)
    - month
    - week (week of the year)
    - day (day of the month)
    - hour
    - minute
    - second
    - millisecond
    - microsecond
    - nanosecond
    - dow (day of the week where Sunday is 0)
    - doy (day of the year)
    - epoch (seconds since Unix epoch)
    - isodow (day of the week where Monday is 0)
- expression: Time expression to operate on. Must be time VarRef

Example usage:

SELECT * FROM some_measurement
WHERE time >= now() - 10d AND time <= now() AND (date_part(time, dow) != 0 AND date_part(time, dow) != 6)
SELECT value, date_part('hour', time) FROM some_measurement

Please see #27001 (comment) for additional information on date_part limitations in 1.x.

@devanbenz devanbenz self-assigned this Dec 4, 2025
@devanbenz devanbenz linked an issue Dec 8, 2025 that may be closed by this pull request
@devanbenz devanbenz marked this pull request as ready for review December 9, 2025 21:50

const (
DatePartString = "date_part"
DatePartTimeString = "date_part_time"
Copy link
Member

Choose a reason for hiding this comment

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

What is date_part_time? I don't see any tests for it.

Copy link
Author

Choose a reason for hiding this comment

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

It's used to create a reference to time since time is an auxiliary field https://github.com/influxdata/influxdb/pull/27005/files#diff-609a7e16be956ed6386e1a4a4efadf600b7d4de7dcfea27330dc692d1e901dc8R930-R944 I'm going to create some ValueMapper tests for this.

Copy link
Author

Choose a reason for hiding this comment

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

@gwossum I can add tests for this but it would likely require exporting

type valueMapper struct {
and testing it. We don't currently have any valueMapper specific tests. It's basically just a struct filled with maps so we would likely just be testing go's map functionality, which may not be worth the effort?

Copy link
Contributor

@davidby-influx davidby-influx left a comment

Choose a reason for hiding this comment

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

Some changes from the first pass. Will review again after changes.

// Multiple selectors WITH date_part should also error
{s: `SELECT value, first(value), last(value), date_part('dow', time) FROM cpu`, err: `mixing multiple selector functions with tags or fields is not supported`},
// date_part subquery validation - cannot be sole field
{s: `SELECT date_part('dow', value) FROM (SELECT value FROM cpu)`, err: `date_part: second argument must be time VarRef`},
Copy link
Contributor

Choose a reason for hiding this comment

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

In the spec, it says:

expression: Time expression to operate on. Can be a constant, column, or function.

Here it looks like you are prohibiting anything not the time column. Which is correct?

Copy link
Author

Choose a reason for hiding this comment

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

I need to modify our version of the spec. I think it should only operate on the time column. For v3 they can decide if they would like to add more features and allow it to work on constants.

Copy link
Author

Choose a reason for hiding this comment

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

I just changed the spec in the PR description to match: #27001 I recall we had a conversation yesterday during standup about the usefulness of constant timestamps. I verified that for other functions in influxdb 1.x (math functions predominately) we don't allow constants, so implementing a constant here would be non-trivial.

Copy link
Contributor

@davidby-influx davidby-influx left a comment

Choose a reason for hiding this comment

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

Unify pseudo-constants

davidby-influx
davidby-influx previously approved these changes Dec 10, 2025
Copy link
Contributor

@davidby-influx davidby-influx left a comment

Choose a reason for hiding this comment

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

I'm not clear on how one part works, but if you have any other changes, also add an explanatory comment there, Not blocking.

DatePartTimeString = "date_part_time"

// DatePartArgCount is the amount of arguments required for date_part function
DatePartArgCount = 2
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice


exprStr, ok := args[0].(*influxql.StringLiteral)
if !ok {
return errors.New("date_part: first argument must be a string")
Copy link
Contributor

Choose a reason for hiding this comment

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

Not a blocker, but this could be a fmt.Errorf with a %T to print the type of arg[0] to help debug. See how that looks before implementing; it may not be useful or readable.

fmt.Errorf("date_part: first argument must be a string literal, not a %T", arg[0])

Copy link
Contributor

@davidby-influx davidby-influx left a comment

Choose a reason for hiding this comment

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

Some refactoring, and a question about which IteratorOptions we should be looking at.

Copy link
Contributor

@davidby-influx davidby-influx left a comment

Choose a reason for hiding this comment

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

LGTM.

Does date_part work in a GROUP BY clause? That's a common usage in SQL (e.g., are Mondays busier than Wednesdays?)

@devanbenz
Copy link
Author

LGTM.

Does date_part work in a GROUP BY clause? That's a common usage in SQL (e.g., are Mondays busier than Wednesdays?)

It does not currently. Since we only support time() in the GROUP BY clause at the moment I would need to plumb through a lot of existing code to get date_part working. I just went through all our GROUP BY code, I would need to modify our internal iterators to have specialized date_part keys in the iteration and use that as a grouping.

I would expect to spend a few more days to get it working.

@sanderson
Copy link
Contributor

sanderson commented Dec 12, 2025

I think it would be important to spend the time making date_part work in the GROUP BY clause or atleast being able to group by column aliases. For example:

SELECT  
  mean(temp)
WHERE
  time >= '2025-01-01T00:00:00Z'
  time < '2026-01-01T00:00:00Z'
GROUP BY
  date_part('month', time),
  date_part('year', time) AS year,
  location

OR

SELECT
  date_part('month', time) AS month,
  date_part('year', time) AS year,
  location,
  mean(temp)
WHERE
  time >= '2025-01-01T00:00:00Z'
  time < '2026-01-01T00:00:00Z'
GROUP BY
  month,
  year,
  location

Or something similar. I realize these both somewhat break InfluxQL conventions, but I think filtering and grouping by these values are the two most common use cases for this function. This will also make filtering/grouping by calendar units (week/month/year/etc.) possible in InfluxQL; things that have been requested for a long time.

@devanbenz
Copy link
Author

@sanderson I agree that it would be useful in the GROUP BY clause.

@philjb philjb added the 1.x label Dec 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[1.x] Add date_part scalar function to influxdb

6 participants