MyCATApache/Mycat-Server · error · IllegalArgumentException

Interval day-time string was null

Error message

Interval day-time string was null

What it means

Thrown by CalendarInterval.fromDayTimeString when the caller passes a null string instead of a day-time interval literal. It is a fail-fast null guard at the top of the parse method; any string input (even empty or malformed) passes this check and is handled later, so the error fires only when s == null. Callers should validate non-null input before parsing, e.g. reject empty connection-string interval parameters upstream.

Solutions

  1. Check for null before calling fromDayTimeString and substitute a default or reject the input
  2. Ensure the SQL literal/config value is actually set (not NULL/empty)
  3. Catch IllegalArgumentException and handle the null-input case explicitly

Example fix

// before
CalendarInterval iv = CalendarInterval.fromDayTimeString(cfg.get("interval"));
// after
String s = cfg.get("interval");
if (s == null || s.trim().isEmpty()) { throw new IllegalArgumentException("interval config is required"); }
CalendarInterval iv = CalendarInterval.fromDayTimeString(s);
Defensive patterns

Strategy: type-guard

Validate before calling

static String requireNonNullInterval(String s) {
  if (s == null || s.trim().isEmpty()) throw new IllegalArgumentException("interval value required");
  return s.trim();
}

Type guard

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

Try / catch

try {
  iv = CalendarInterval.fromDayTimeString(s);
} catch (IllegalArgumentException e) {
  if (s == null) { iv = CalendarInterval.ZERO; } else throw e;
}

Prevention

When it happens

Trigger: Calling CalendarInterval.fromDayTimeString(null) directly, or passing a null column/config value through to the parser without a null check.

Common situations: Unset configuration properties, NULL values from upstream ETL passed into interval parsing, missing query literal.

Related errors


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

Appendix: source

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

        int months = (int) toLongWithRange("month", m.group(3), 0, 11);
        result = new CalendarInterval(sign * (years * 12 + months), 0);
      } catch (Exception e) {
        throw new IllegalArgumentException(
          "Error parsing interval year-month string: " + e.getMessage(), e);
      }
    }
    return result;
  }

  /**
   * Parse dayTime string in form: [-]d HH:mm:ss.nnnnnnnnn
   *
   * adapted from HiveIntervalDayTime.valueOf
   */
  public static CalendarInterval fromDayTimeString(String s) throws IllegalArgumentException {
    CalendarInterval result = null;
    if (s == null) {
      throw new IllegalArgumentException("Interval day-time string was null");
    }
    s = s.trim();
    Matcher m = dayTimePattern.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 {
        int sign = m.group(1) != null && m.group(1).equals("-") ? -1 : 1;
        long days = toLongWithRange("day", m.group(2), 0, Integer.MAX_VALUE);
        long hours = toLongWithRange("hour", m.group(3), 0, 23);
        long minutes = toLongWithRange("minute", m.group(4), 0, 59);
        long seconds = toLongWithRange("second", m.group(5), 0, 59);
        // 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));

View on GitHub (pinned to 65f8d8beb7)