risingwavelabs/risingwave · error
regexp_count() does not support the global option
Error message
regexp_count() does not support the global option
What it means
`regexp_count` returns the number of matches of a pattern, and a global ('g') flag is meaningless for counting since it only changes replace semantics. The regex option parser rejects a 'g' flag passed to `regexp_count` at signature-check time rather than silently ignoring it.
Solutions
- Remove the 'g' flag from the flags argument of regexp_count
- Use 'gi' style flags only for operations that support global matching, e.g. regexp_replace
- If counting is intended, note that regexp_count already counts all matches without 'g'
Example fix
-- before SELECT regexp_count(s, '\d+', 'g'); -- after SELECT regexp_count(s, '\d+', 'i');
Defensive patterns
Strategy: validation
Validate before calling
if flags.includes('g') throw new Error('regexp_count does not support the global option'); Try / catch
try { await rw.query(`SELECT regexp_count(${q(s)}, ${q(p)}, ${q(flags)})`) } catch (e) { if (String(e).includes('global option')) { /* retry without 'g' */ } else throw e; } Prevention
- Never copy flags from regexp_replace into regexp_count
- Remember regexp_count counts all matches without 'g'
- Centralize flag constants per function type
When it happens
Trigger: Calling `SELECT regexp_count(str, pattern, 'g')` — i.e. `RegexpCount` with a flags string containing the character 'g', checked in `from_pattern_flags_for_count`.
Common situations: Copy-pasting flags like 'gi' from a `regexp_replace` call (where 'g' is valid) into `regexp_count`; translating Postgres/other-dialect regex usage that allows global flags.
Related errors
- invalid regular expression option
- the first argument (vnode count) must be in range 1..=
- {0}
- {0}
- AFTER MATCH SKIP TO FIRST/LAST missing its target variable
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/d0f357b4852788e1.
Report an issue: GitHub.
Appendix: source
Thrown at src/expr/impl/src/scalar/regexp.rs:60
regex: RegexBuilder::new(&origin)
.build()
.map_err(|e| ExprError::Parse(e.to_report_string().into()))?,
global: options.global,
replacement: make_replacement(replacement),
})
}
pub fn from_pattern(pattern: &str) -> Result<Self> {
Self::new(pattern, "", "")
}
pub fn from_pattern_flags(pattern: &str, flags: &str) -> Result<Self> {
Self::new(pattern, flags, "")
}
pub fn from_pattern_flags_for_count(pattern: &str, flags: &str) -> Result<Self> {
if flags.contains('g') {
bail!("regexp_count() does not support the global option");
}
Self::new(pattern, flags, "")
}
pub fn from_pattern_replacement(pattern: &str, replacement: &str) -> Result<Self> {
Self::new(pattern, "", replacement)
}
pub fn from_pattern_replacement_flags(
pattern: &str,
replacement: &str,
flags: &str,
) -> Result<Self> {
Self::new(pattern, flags, replacement)
}
}
/// Construct the regex used to match and replace `\n` expression.View on GitHub (pinned to 6469eb736d)