MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / parse_ident

Function parse_ident

src/expr/src/scalar/func.rs:2244–2321  ·  view source on GitHub ↗

transliterated from postgres/src/backend/utils/adt/misc.c

(ident: &'a str, strict: bool)

Source from the content-addressed store, hash-verified

2242#[sqlfunc]
2243// transliterated from postgres/src/backend/utils/adt/misc.c
2244fn parse_ident<'a>(ident: &'a str, strict: bool) -> Result<ArrayRustType<Cow<'a, str>>, EvalError> {
2245 fn is_ident_start(c: char) -> bool {
2246 matches!(c, 'A'..='Z' | 'a'..='z' | '_' | '\u{80}'..=char::MAX)
2247 }
2248
2249 fn is_ident_cont(c: char) -> bool {
2250 matches!(c, '0'..='9' | '$') || is_ident_start(c)
2251 }
2252
2253 let mut elems = vec![];
2254 let buf = &mut LexBuf::new(ident);
2255
2256 let mut after_dot = false;
2257
2258 buf.take_while(|ch| ch.is_ascii_whitespace());
2259
2260 loop {
2261 let mut missing_ident = true;
2262
2263 let c = buf.next();
2264
2265 if c == Some('"') {
2266 let s = buf.take_while(|ch| !matches!(ch, '"'));
2267
2268 if buf.next() != Some('"') {
2269 return Err(EvalError::InvalidIdentifier {
2270 ident: ident.into(),
2271 detail: Some("String has unclosed double quotes.".into()),
2272 });
2273 }
2274 elems.push(Cow::Borrowed(s));
2275 missing_ident = false;
2276 } else if c.map(is_ident_start).unwrap_or(false) {
2277 buf.prev();
2278 let s = buf.take_while(is_ident_cont);
2279 elems.push(Cow::Owned(s.to_ascii_lowercase()));
2280 missing_ident = false;
2281 }
2282
2283 if missing_ident {
2284 if c == Some('.') {
2285 return Err(EvalError::InvalidIdentifier {
2286 ident: ident.into(),
2287 detail: Some("No valid identifier before \".\".".into()),
2288 });
2289 } else if after_dot {
2290 return Err(EvalError::InvalidIdentifier {
2291 ident: ident.into(),
2292 detail: Some("No valid identifier after \".\".".into()),
2293 });
2294 } else {
2295 return Err(EvalError::InvalidIdentifier {
2296 ident: ident.into(),
2297 detail: None,
2298 });
2299 }
2300 }
2301

Callers

nothing calls this directly

Calls 5

take_whileMethod · 0.80
prevMethod · 0.80
nextMethod · 0.45
pushMethod · 0.45
mapMethod · 0.45

Tested by

no test coverage detected