{"record":{"id":"d0f357b4852788e1","repo":"risingwavelabs/risingwave","slug":"regexp-count-does-not-support-the-global-option","errorCode":null,"errorMessage":"regexp_count() does not support the global option","messagePattern":"regexp_count\\(\\) does not support the global option","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/expr/impl/src/scalar/regexp.rs","lineNumber":60,"sourceCode":"            regex: RegexBuilder::new(&origin)\n                .build()\n                .map_err(|e| ExprError::Parse(e.to_report_string().into()))?,\n            global: options.global,\n            replacement: make_replacement(replacement),\n        })\n    }\n\n    pub fn from_pattern(pattern: &str) -> Result<Self> {\n        Self::new(pattern, \"\", \"\")\n    }\n\n    pub fn from_pattern_flags(pattern: &str, flags: &str) -> Result<Self> {\n        Self::new(pattern, flags, \"\")\n    }\n\n    pub fn from_pattern_flags_for_count(pattern: &str, flags: &str) -> Result<Self> {\n        if flags.contains('g') {\n            bail!(\"regexp_count() does not support the global option\");\n        }\n        Self::new(pattern, flags, \"\")\n    }\n\n    pub fn from_pattern_replacement(pattern: &str, replacement: &str) -> Result<Self> {\n        Self::new(pattern, \"\", replacement)\n    }\n\n    pub fn from_pattern_replacement_flags(\n        pattern: &str,\n        replacement: &str,\n        flags: &str,\n    ) -> Result<Self> {\n        Self::new(pattern, flags, replacement)\n    }\n}\n\n/// Construct the regex used to match and replace `\\n` expression.","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/expr/impl/src/scalar/regexp.rs#L42-L78","documentation":"`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.","triggerScenarios":"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`.","commonSituations":"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.","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'"],"exampleFix":"-- before\nSELECT regexp_count(s, '\\d+', 'g');\n-- after\nSELECT regexp_count(s, '\\d+', 'i');","handlingStrategy":"validation","validationCode":"if flags.includes('g') throw new Error('regexp_count does not support the global option');","typeGuard":null,"tryCatchPattern":"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; }","preventionTips":["Never copy flags from regexp_replace into regexp_count","Remember regexp_count counts all matches without 'g'","Centralize flag constants per function type"],"tags":["sql","regex","arguments"],"backgroundTag":"unsupported-flag-value","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}