transliterated from postgres/src/backend/utils/adt/misc.c
(ident: &'a str, strict: bool)
| 2242 | #[sqlfunc] |
| 2243 | // transliterated from postgres/src/backend/utils/adt/misc.c |
| 2244 | fn 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 |
nothing calls this directly
no test coverage detected