MyCATApache/Mycat-Server · error · IllegalArgumentException

Interval string was null

Error message

Interval %s string was null

What it means

fromSingleUnitString(unit, s) parses a single-unit interval like '3' with unit 'year' or 'month'. This IllegalArgumentException is thrown when the value string s is null; the offending unit name is included in the message.

Solutions

  1. Ensure a non-null value string is passed for the unit
  2. Default the value (e.g. "0") when absent before calling
  3. Catch IllegalArgumentException and treat null input as a distinct error path

Example fix

// before
CalendarInterval iv = CalendarInterval.fromSingleUnitString("month", stmt.getValue());
// after
String v = stmt.getValue();
CalendarInterval iv = CalendarInterval.fromSingleUnitString("month", v == null ? "0" : v);
Defensive patterns

Strategy: type-guard

Validate before calling

static String requireSingleUnitValue(String unit, String s) {
  if (s == null || s.trim().isEmpty()) throw new IllegalArgumentException("value for unit " + unit + " required");
  return s.trim();
}

Type guard

static boolean hasSingleUnitValue(String s) {
  return s != null && !s.trim().isEmpty();
}

Try / catch

try {
  iv = CalendarInterval.fromSingleUnitString(unit, s);
} catch (IllegalArgumentException e) {
  log.error("Null/invalid value for interval unit {}: {}", unit, e.getMessage());
  iv = CalendarInterval.ZERO;
}

Prevention

When it happens

Trigger: Calling CalendarInterval.fromSingleUnitString("month", null), typically when the SQL INTERVAL ... clause has no value or a config value is unset.

Common situations: Missing interval literal in generated SQL, null property/parameter fed into the parser.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/40345441a6bf722d. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/memory/unsafe/types/CalendarInterval.java:172

        // Hive allow nanosecond precision interval
        long nanos = toLongWithRange("nanosecond", m.group(7), 0L, 999999999L);
        result = new CalendarInterval(0, sign * (
          days * MICROS_PER_DAY + hours * MICROS_PER_HOUR + minutes * MICROS_PER_MINUTE +
          seconds * MICROS_PER_SECOND + nanos / 1000L));
      } catch (Exception e) {
        throw new IllegalArgumentException(
          "Error parsing interval day-time string: " + e.getMessage(), e);
      }
    }
    return result;
  }

  public static CalendarInterval fromSingleUnitString(String unit, String s)
      throws IllegalArgumentException {

    CalendarInterval result = null;
    if (s == null) {
      throw new IllegalArgumentException(String.format("Interval %s string was null", unit));
    }
    s = s.trim();
    Matcher m = quoteTrimPattern.matcher(s);
    if (!m.matches()) {
      throw new IllegalArgumentException(
        "Interval string does not match day-time format of 'd h:m:s.n': " + s);
    } else {
      try {
        if (unit.equals("year")) {
          int year = (int) toLongWithRange("year", m.group(1),
            Integer.MIN_VALUE / 12, Integer.MAX_VALUE / 12);
          result = new CalendarInterval(year * 12, 0L);

        } else if (unit.equals("month")) {
          int month = (int) toLongWithRange("month", m.group(1),
            Integer.MIN_VALUE, Integer.MAX_VALUE);
          result = new CalendarInterval(month, 0L);

View on GitHub (pinned to 65f8d8beb7)