Skip to content

feat: support interval * number, number * interval and interval / number - #26258

Open
RishavTiwari25 wants to merge 1 commit into
apache:mainfrom
RishavTiwari25:feat/interval-multiply-divide
Open

RishavTiwari25 wants to merge 1 commit into
apache:mainfrom
RishavTiwari25:feat/interval-multiply-divide

Conversation

@RishavTiwari25

Copy link
Copy Markdown

Which issue does this PR close?

Rationale for this change

Multiplying an interval by a number, which PostgreSQL and DuckDB both support, fails in DataFusion:

> SELECT interval '1 day' * 2;
Error during planning: Cannot get result type for temporal operation Interval(MonthDayNano) * Int64: ...
  Invalid interval arithmetic operation: Interval(MonthDayNano) * Interval(MonthDayNano)

> SELECT interval '1 hour' * 3.5;
Arrow error: Invalid argument error: Invalid interval arithmetic operation: Interval(MonthDayNano) * Float64

Dividing by an integer (interval '1 day' / 2) fails the same way, while interval '1 hour' / 1.5 already works.

The arrow side of #13850 (apache/arrow-rs#6335) is available in the arrow 60 release DataFusion uses: the kernels support Interval * Int64, Interval(MonthDayNano) * Float64 and Interval(MonthDayNano) / Float64. Two things on the DataFusion side still got in the way:

  • temporal_math_coercion coerced the numeric operand to Interval(MonthDayNano), which arrow rejects as Interval * Interval.
  • Result type probing and physical evaluation used mul_wrapping, but arrow's interval kernels only implement the checked mul.

What changes are included in this PR?

  • A new interval_number_coercion handles interval * number, number * interval and interval / number: the interval becomes Interval(MonthDayNano), an integer factor becomes Int64 (exact multiplication), and any other numeric factor or divisor becomes Float64. The old Interval * number => Interval * Interval arms are removed, so interval + 2 now fails with the generic "cannot coerce" error instead of a cast error.
  • BinaryTypeCoercer::get_result probes multiplication with mul, and BinaryExpr evaluates interval * number with mul, since the interval kernels do not implement the wrapping variant.

What is the testing strategy for this PR?

  • datetime/arith_interval_double.slt: the cases that were documented as failing now have expected results.
  • New datetime/arith_interval_integer.slt covers integer factors on both sides, division by an integer, NULL operands, column inputs, and the result type.
  • Existing datafusion-expr-common and datafusion-physical-expr tests.

Are there any user-facing changes?

interval * integer, integer * interval, interval * float, float * interval and interval / number are now supported and return Interval(MonthDayNano).

I used an AI coding assistant while working on this change; I have read the diff and the tests and can walk through them.

🤖 Generated with Claude Code

…/ number`

Multiplying an interval by a number failed to plan or execute, and dividing by
an integer failed, because `temporal_math_coercion` coerced the numeric operand
to `Interval(MonthDayNano)`, which arrow rejects as `Interval * Interval`, and
because result type probing and evaluation used `mul_wrapping`, which arrow's
interval kernels do not implement.

Add `interval_number_coercion`: the interval becomes `Interval(MonthDayNano)`,
an integer factor becomes `Int64` (exact), and any other numeric or NULL factor
or divisor becomes `Float64`. Probe and evaluate interval multiplication with
the checked `mul` kernel. Remove the old `Interval * number => Interval` arms.

Closes apache#13850

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions github-actions Bot added logical-expr Logical plan and expressions physical-expr Changes to the physical-expr crates sqllogictest SQL Logic Tests (.slt) labels Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

logical-expr Logical plan and expressions physical-expr Changes to the physical-expr crates sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support multiply and divide on intervals

1 participant