apache/druid · error · DruidException

pattern must be a STRING literal

Error message

pattern must be a STRING literal

What it means

The regexp_like macro's RegexpLikeExpr constructor compiles the pattern eagerly at parse time and therefore requires the pattern (second argument) to be a string literal. Any non-literal or non-string value triggers this validation failure.

Source

Thrown at processing/src/main/java/org/apache/druid/query/expression/RegexpLikeExprMacro.java:84

      return ExpressionType.LONG;
    }
  }

  /**
   * Expr when pattern is a literal.
   */
  class RegexpLikeExpr extends BaseRegexpLikeExpr
  {
    private final Expr arg;
    private final Pattern pattern;

    private RegexpLikeExpr(List<Expr> args)
    {
      super(args);

      final Expr patternExpr = args.get(1);
      if (!ExprUtils.isStringLiteral(patternExpr)) {
        throw validationFailed("pattern must be a STRING literal");
      }

      final String patternString = (String) patternExpr.getLiteralValue();
      this.arg = args.get(0);
      this.pattern = RegexpExprUtils.compilePattern(patternString, FN_NAME);
    }

    @Nonnull
    @Override
    public ExprEval<?> eval(final ObjectBinding bindings)
    {
      final String s = arg.eval(bindings).asString();
      if (s == null) {
        return ExprEval.ofLong(null);
      } else {
        final Matcher matcher = pattern.matcher(s);
        return ExprEval.ofLongBoolean(matcher.find());
      }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Supply the pattern as a quoted string literal
  2. Cast or restructure so the regex is fixed at query-writing time
  3. Use REGEXP operator alternatives in SQL that accept expressions if dynamic patterns are needed

Example fix

// before
REGEXP_LIKE(col, 123)
// after
REGEXP_LIKE(col, '123')
Defensive patterns

Strategy: validation

Validate before calling

if (!(patternExpr instanceof LiteralExpr) || !(((LiteralExpr) patternExpr).getValue() instanceof String)) {
  throw new IllegalArgumentException("pattern must be a string literal");
}

Type guard

static boolean isStringLiteral(Expr e) {
  return ExprUtils.isStringLiteral(e);
}

Try / catch

try {
  return expr.eval(bindings);
} catch (ExpressionValidationException e) {
  return ExprEval.ofLong(null);
}

Prevention

When it happens

Trigger: REGEXP_LIKE(expr, pattern) where pattern is a column, a non-literal expression, or a literal of non-string type (number/boolean/null).

Common situations: Patterns read from data or config at runtime; numeric literal passed instead of string; generated native JSON where the pattern field is a JSON number.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/1bebff5af18db781. Report an issue: GitHub.