vitessio/vitess · warning · errNonConstantRegexp
non-constant regexp
Error message
non-constant regexp
What it means
The regexp compiler in the eval engine requires the pattern argument to be a constant expression so it can be compiled once at plan time. errNonConstantRegexp is returned by compileConstantRegex when the pattern argument (or another required argument) is not a constant, e.g. a column reference or non-deterministic expression.
Source
Thrown at go/vt/vtgate/evalengine/fn_regexp.go:212
case icuregex.LookBehindLimit:
err = vterrors.NewError(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.RegexpLookBehindLimit, compileErr.Error())
case icuregex.MissingCloseBracket:
err = vterrors.NewError(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.RegexpMissingCloseBracket, compileErr.Error())
case icuregex.InvalidRange:
err = vterrors.NewError(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.RegexpInvalidRange, compileErr.Error())
case icuregex.PatternTooBig:
err = vterrors.NewError(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.RegexpPatternTooBig, compileErr.Error())
case icuregex.InvalidCaptureGroupName:
err = vterrors.NewError(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.RegexpInvalidCaptureGroup, compileErr.Error())
default:
err = vterrors.NewError(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.RegexpInternal, compileErr.Error())
}
}
return nil, err
}
var errNonConstantRegexp = errors.New("non-constant regexp")
func compileConstantRegex(c *compiler, args TupleExpr, pat, mt int, cs collations.TypedCollation, flags icuregex.RegexpFlag, f string) (*icuregex.Pattern, error) {
pattern := args[pat]
if !pattern.constant() {
return nil, errNonConstantRegexp
}
var err error
staticEnv := EmptyExpressionEnv(c.env)
pattern, err = simplifyExpr(staticEnv, pattern)
if err != nil {
return nil, err
}
if len(args) > mt {
fl := args[mt]
if !fl.constant() {
return nil, errNonConstantRegexp
}View on GitHub (pinned to 01a25a7d17)
Solutions
- Use a constant string literal for the regexp pattern
- Move variable-pattern matching out of SQL or evaluate via a different approach
- Ensure the pattern expression is one the compiler recognizes as constant (e.g. a literal or constant foldable expression)
Example fix
// before SELECT * FROM t WHERE name RLIKE pattern_col; // after SELECT * FROM t WHERE name RLIKE '^[A-Za-z]+$';
Defensive patterns
Strategy: try-catch
Validate before calling
if expr, ok := patternExpr.(sqlparser.Literal); !ok || expr.Type != sqlparser.StrVal {
return errors.New("regexp pattern must be a constant string")
} Try / catch
pat, err := compileConstantRegex(c, args, patIdx, mtIdx, cs, flags, fnName)
if errors.Is(err, errNonConstantRegexp) {
// fall back to runtime evaluation or reject the plan
} Prevention
- Use string literals for REGEXP/RLIKE patterns
- Keep regexp patterns out of columns and bound variables when using the plan compiler
- Document the constant-pattern requirement in query-writing guidelines
When it happens
Trigger: Using RLIKE/REGEXP/REGEXP_REPLACE (or related functions) where the pattern is derived from a column, parameter, or runtime expression rather than a literal.
Common situations: Queries like `col RLIKE other_col` or patterns built from user input passed as bound parameters in the plan compiler path.
Related errors
- Invalid JSON path expression.
- error running vtexplain: %w
- --batch-size only allowed when all queries are CREATE TABLE|
- query not supported by vexec
- UnescapeID err: invalid input identifier '%s'
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/cd0c8ac6d1350842.
Report an issue: GitHub.