Repository: prometheus/prometheus
File: promql/functions.go (Go)

Code before:
		if isRate && lastSample.F < prevSample.F {
			// Counter reset.
		} else {
			resultSample.F = lastSample.F - prevSample.F
		}
	case lastSample.H != nil && prevSample.H != nil:
		resultSample.H = lastSample.H.Copy()
		// irate should only be applied to counters.
		if isRate && (lastSample.H.CounterResetHint == histogram.GaugeType || prevSample.H.CounterResetHint == histogram.GaugeType) {
			annos.Add(annotations.NewNativeHistogramNotCounterWarning(metricName, args.PositionRange()))
		}
		// idelta should only be applied to gauges.
		if !isRate && (lastSample.H.CounterResetHint != histogram.GaugeType || prevSample.H.CounterResetHint != histogram.GaugeType) {
			annos.Add(annotations.NewNativeHistogramNotGaugeWarning(metricName, args.PositionRange()))
		}
		_, err := resultSample.H.Sub(prevSample.H)
		if err != nil {
			if errors.Is(err, histogram.ErrHistogramsIncompatibleSchema) {
				return out, annos.Add(annotations.NewMixedExponentialCustomHistogramsWarning(metricName, args.PositionRange()))
			} else if errors.Is(err, histogram.ErrHistogramsIncompatibleBounds) {
				return out, annos.Add(annotations.NewIncompatibleCustomBucketsHistogramsWarning(metricName, args.PositionRange()))
			}
		}
		// For counter resets
		if isRate && lastSample.H.DetectReset(prevSample.H) {
			_, err := resultSample.H.Add(prevSample.H)
			if err != nil {
				if errors.Is(err, histogram.ErrHistogramsIncompatibleSchema) {
					return out, annos.Add(annotations.NewMixedExponentialCustomHistogramsWarning(metricName, args.PositionRange()))
				} else if errors.Is(err, histogram.ErrHistogramsIncompatibleBounds) {
					return out, annos.Add(annotations.NewIncompatibleCustomBucketsHistogramsWarning(metricName, args.PositionRange()))
				}
			}
		}
		resultSample.H.CounterResetHint = histogram.GaugeType
		resultSample.H.Compact(0)
	default:
		// both the samples are different
		annos.Add(annotations.NewMixedFloatsHistogramsWarning(metricName, args.PositionRange()))
		return out, annos
	}

	if isRate {
		// Convert to per-second.
		if resultSample.H == nil {
			resultSample.F /= float64(sampledInterval) / 1000
		} else {
			resultSample.H.Div(float64(sampledInterval) / 1000)
		}
	}


Review comment (suggestion):
Instead of subtracting and then adding, let's to the counter reset detection first.

This will allow a result for `irate` even with incompatible buckets because it is simply seen as a counter reset, and the 2nd value is used for the rate. I think that's fine and maybe even to be preferred. (Maybe we should mention that in the docs and the spec as it might be surprising for the user.)

Code after:
			ss[0] = ss[1]
			ss[1] = s
		default:
			// In all other cases, we just make s the new 1st.
			// This establishes a correct order, even in the (irregular)
			// case of equal timestamps.
			ss[0] = s
		}
	}

	resultSample := ss[1]
	sampledInterval := ss[1].T - ss[0].T
	if sampledInterval == 0 {
		// Avoid dividing by 0.
		return out, nil
	}
	switch {
	case ss[1].H == nil && ss[0].H == nil:
		if !isRate || ss[1].F >= ss[0].F {
			// Gauge or counter without reset.
			resultSample.F = ss[1].F - ss[0].F
		}
		// In case of a counter reset, we leave resultSample at
		// its current value, which is already ss[1].
	case ss[1].H != nil && ss[0].H != nil:
		resultSample.H = ss[1].H.Copy()
		// irate should only be applied to counters.
		if isRate && (ss[1].H.CounterResetHint == histogram.GaugeType || ss[0].H.CounterResetHint == histogram.GaugeType) {
			annos.Add(annotations.NewNativeHistogramNotCounterWarning(metricName, args.PositionRange()))
		}
		// idelta should only be applied to gauges.
		if !isRate && (ss[1].H.CounterResetHint != histogram.GaugeType || ss[0].H.CounterResetHint != histogram.GaugeType) {
			annos.Add(annotations.NewNativeHistogramNotGaugeWarning(metricName, args.PositionRange()))
		}
		if !isRate || !ss[1].H.DetectReset(ss[0].H) {
			_, err := resultSample.H.Sub(ss[0].H)
			if errors.Is(err, histogram.ErrHistogramsIncompatibleSchema) {
				return out, annos.Add(annotations.NewMixedExponentialCustomHistogramsWarning(metricName, args.PositionRange()))
			} else if errors.Is(err, histogram.ErrHistogramsIncompatibleBounds) {
				return out, annos.Add(annotations.NewIncompatibleCustomBucketsHistogramsWarning(metricName, args.PositionRange()))
			}
		}
		resultSample.H.CounterResetHint = histogram.GaugeType
		resultSample.H.Compact(0)
	default:
		// Mix of a float and a histogram.
		return out, annos.Add(annotations.NewMixedFloatsHistogramsWarning(metricName, args.PositionRange()))
	}

	if isRate {
		// Convert to per-second.