Skip to main content

collapse_unused_generate_series

Function collapse_unused_generate_series 

Source
fn collapse_unused_generate_series(
    func: &mut TableFunc,
    exprs: &mut Vec<MirScalarExpr>,
)
Expand description

If func is an integer generate_series whose output values are unused, rewrites it in place into a RepeatRowNonNegative that emits the same number of rows. The caller must have established that the generated column is not demanded.

generate_series(start, stop, step) is inclusive of stop, so its cardinality is max(0, floor((stop - start) / step) + 1). We only rewrite when step is a known non-zero literal, which lets us specialize on its sign: truncating integer division (what DivInt64 does) coincides with floor division exactly when the dividend and divisor share a sign, which the emptiness guard guarantees. The guard also collapses the empty series to a count of zero, so the result is always non-negative.

When start and stop are also literals, the cardinality is computed here, exactly, in i128 (where no i64 inputs can overflow). If it does not fit in an i64 we decline to rewrite: the original FlatMap enumerates such a series without error (its iteration only ever visits in-range values), so its replacement must not error either.

When the bounds are not literals we synthesize the arithmetic, and the width we synthesize it in depends on step:

  • |step| == 1: i64, and the division (the identity or a negation) is elided, so the count is just (a - b) + 1. A literal subtracted bound is folded into a + (1 - b)a itself for generate_series(1, n). Here a - b overflows i64 only once the span reaches 2^63, which means the series has more than i64::MAX rows — infeasible, exactly what the literal path declines. So i64 arithmetic is exact for every feasible series, and an overflow only ever stands in for an effectively non-terminating enumeration.

  • |step| >= 2: numeric. A coarse step over near-opposite i64 extremes yields a feasible series (few rows) whose span nonetheless overflows i64, so i64 arithmetic would error where the original does not. numeric holds the full ~2^64 span comfortably and represents the quotient exactly (it needs at most ~20 significant digits, well under numeric’s 39), so the only place this can error is the final cast back to i64 — which happens exactly when the count itself exceeds i64, the same infeasible case the literal path declines.

Null inputs are handled by RepeatRowNonNegative itself: like generate_series, it is empty_on_null_input, so a null count yields no rows.