apache/druid · error · DruidException

pattern must be a string literal

Error message

pattern must be a string literal

What it means

The regexp_extract expression macro requires its pattern argument (second argument) to be a compile-time string literal, because it precompiles the regex when the expression is parsed. A non-literal pattern (column, arithmetic expression, or non-string literal) cannot be precompiled, so validation fails.

Source

Thrown at processing/src/main/java/org/apache/druid/query/expression/RegexpExtractExprMacro.java:53

  private static final String FN_NAME = "regexp_extract";

  @Override
  public String name()
  {
    return FN_NAME;
  }

  @Override
  public Expr apply(final List<Expr> args)
  {
    validationHelperCheckAnyOfArgumentCount(args, 2, 3);

    final Expr arg = args.get(0);
    final Expr patternExpr = args.get(1);
    final Expr indexExpr = args.size() > 2 ? args.get(2) : null;

    if (!ExprUtils.isStringLiteral(patternExpr)) {
      throw validationFailed("pattern must be a string literal");
    }

    if (indexExpr != null && (!indexExpr.isLiteral() || !(indexExpr.getLiteralValue() instanceof Number))) {
      throw validationFailed("index must be a numeric literal");
    }

    // Precompile the pattern.
    final Pattern pattern = RegexpExprUtils.compilePattern((String) patternExpr.getLiteralValue(), FN_NAME);

    final int index = indexExpr == null ? 0 : ((Number) indexExpr.getLiteralValue()).intValue();

    class RegexpExtractExpr extends ExprMacroTable.BaseScalarMacroFunctionExpr
    {
      private RegexpExtractExpr(List<Expr> args)
      {
        super(RegexpExtractExprMacro.this, args);
      }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Inline the regex as a quoted string literal, e.g. REGEXP_EXTRACT(x, '([a-z]+)')
  2. Move variable patterns into a different construct (e.g. LOOKUP or application-side matching)
  3. Verify the literal is a string, not a number or NULL

Example fix

// before
REGEXP_EXTRACT(col, pattern_column)
// after
REGEXP_EXTRACT(col, '([0-9]+)')
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 macro.apply(args);
} catch (ExpressionValidationException e) {
  return ExprEval.of(null);
}

Prevention

When it happens

Trigger: Calling REGEXP_EXTRACT(expr, pattern) where pattern is a column reference, a concatenation expression, a number, or NULL instead of a quoted string literal.

Common situations: Passing a regex stored in a table column; forgetting quotes around the pattern so it parses as an identifier; generating expressions dynamically with non-literal patterns.

Related errors


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