11-- -
22source : src / expr / src / scalar / func .rs
3- expression: "#[sqlfunc(output_type = \"mz_repr::ArrayRustType<String>\", propagates_nulls = true)]\nfn parse_ident<'a>(\n ident: &str,\n strict: bool,\n temp_storage: &'a RowArena,\n) -> Result<Datum<'a>, EvalError> {\n fn is_ident_start(c: char) -> bool {\n matches!(c, 'A'..='Z' | 'a'..='z' | '_' | '\\u{80}'..= char::MAX)\n }\n fn is_ident_cont(c: char) -> bool {\n matches!(c, '0'..='9' | '$') || is_ident_start(c)\n }\n let mut elems = vec![];\n let buf = &mut LexBuf::new(ident);\n let mut after_dot = false;\n buf.take_while(|ch| ch.is_ascii_whitespace());\n loop {\n let mut missing_ident = true;\n let c = buf.next();\n if c == Some('\"') {\n let s = buf.take_while(|ch| !matches!(ch, '\"'));\n if buf.next() != Some('\"') {\n return Err(EvalError::InvalidIdentifier {\n ident: ident.into(),\n detail: Some(\"String has unclosed double quotes.\".into()),\n });\n }\n elems.push(Datum::String(s));\n missing_ident = false;\n } else if c.map(is_ident_start).unwrap_or(false) {\n buf.prev();\n let s = buf.take_while(is_ident_cont);\n let s = temp_storage.push_string(s.to_ascii_lowercase());\n elems.push(Datum::String(s));\n missing_ident = false;\n }\n if missing_ident {\n if c == Some('.') {\n return Err(EvalError::InvalidIdentifier {\n ident: ident.into(),\n detail: Some(\"No valid identifier before \\\".\\\".\".into()),\n });\n } else if after_dot {\n return Err(EvalError::InvalidIdentifier {\n ident: ident.into(),\n detail: Some(\"No valid identifier after \\\".\\\".\".into()),\n });\n } else {\n return Err(EvalError::InvalidIdentifier {\n ident: ident.into(),\n detail: None,\n });\n }\n }\n buf.take_while(|ch| ch.is_ascii_whitespace());\n match buf.next() {\n Some('.') => {\n after_dot = true;\n buf.take_while(|ch| ch.is_ascii_whitespace());\n }\n Some(_) if strict => {\n return Err(EvalError::InvalidIdentifier {\n ident: ident.into(),\n detail: None,\n });\n }\n _ => break,\n }\n }\n Ok(\n temp_storage\n .try_make_datum(|packer| {\n packer\n .try_push_array(\n &[\n ArrayDimension {\n lower_bound: 1,\n length: elems.len(),\n },\n ],\n elems,\n )\n })?,\n )\n}\n"
3+ expression: "#[sqlfunc()]\nfn parse_ident<'a>(\n ident: &'a str,\n strict: bool,\n) -> Result<ArrayRustType<Cow<'a, str>>, EvalError> {\n fn is_ident_start(c: char) -> bool {\n matches!(c, 'A'..='Z' | 'a'..='z' | '_' | '\\u{80}'..= char::MAX)\n }\n fn is_ident_cont(c: char) -> bool {\n matches!(c, '0'..='9' | '$') || is_ident_start(c)\n }\n let mut elems = vec![];\n let buf = &mut LexBuf::new(ident);\n let mut after_dot = false;\n buf.take_while(|ch| ch.is_ascii_whitespace());\n loop {\n let mut missing_ident = true;\n let c = buf.next();\n if c == Some('\"') {\n let s = buf.take_while(|ch| !matches!(ch, '\"'));\n if buf.next() != Some('\"') {\n return Err(EvalError::InvalidIdentifier {\n ident: ident.into(),\n detail: Some(\"String has unclosed double quotes.\".into()),\n });\n }\n elems.push(Cow::Borrowed(s));\n missing_ident = false;\n } else if c.map(is_ident_start).unwrap_or(false) {\n buf.prev();\n let s = buf.take_while(is_ident_cont);\n elems.push(Cow::Owned(s.to_ascii_lowercase()));\n missing_ident = false;\n }\n if missing_ident {\n if c == Some('.') {\n return Err(EvalError::InvalidIdentifier {\n ident: ident.into(),\n detail: Some(\"No valid identifier before \\\".\\\".\".into()),\n });\n } else if after_dot {\n return Err(EvalError::InvalidIdentifier {\n ident: ident.into(),\n detail: Some(\"No valid identifier after \\\".\\\".\".into()),\n });\n } else {\n return Err(EvalError::InvalidIdentifier {\n ident: ident.into(),\n detail: None,\n });\n }\n }\n buf.take_while(|ch| ch.is_ascii_whitespace());\n match buf.next() {\n Some('.') => {\n after_dot = true;\n buf.take_while(|ch| ch.is_ascii_whitespace());\n }\n Some(_) if strict => {\n return Err(EvalError::InvalidIdentifier {\n ident: ident.into(),\n detail: None,\n });\n }\n _ => break,\n }\n }\n Ok(elems.into())\n}\n"
44-- -
55#[derive (
66 proptest_derive ::Arbitrary ,
@@ -19,22 +19,22 @@ pub struct ParseIdent;
1919impl < ' a> crate::func::binary::EagerBinaryFunc<' a > for ParseIdent {
2020 type Input1 = & ' a str;
2121 type Input2 = bool ;
22- type Output = Result <Datum < ' a >, EvalError>;
22+ type Output = Result <ArrayRustType < Cow < ' a, str> >, EvalError>;
2323 fn call (
2424 & self ,
2525 a : Self ::Input1 ,
2626 b : Self ::Input2 ,
2727 temp_storage : & ' a mz_repr::RowArena,
2828 ) -> Self ::Output {
29- parse_ident(a , b , temp_storage )
29+ parse_ident(a , b )
3030 }
3131 fn output_type (
3232 & self ,
3333 input_type_a : mz_repr ::SqlColumnType ,
3434 input_type_b : mz_repr ::SqlColumnType ,
3535 ) -> mz_repr ::SqlColumnType {
3636 use mz_repr: :AsColumnType ;
37- let output = < mz_repr :: ArrayRustType < String >> ::as_column_type();
37+ let output = Self :: Output ::as_column_type ();
3838 let propagates_nulls = crate ::func ::binary ::EagerBinaryFunc ::propagates_nulls (
3939 self ,
4040 );
@@ -46,23 +46,16 @@ impl<'a> crate::func::binary::EagerBinaryFunc<'a> for ParseIdent {
4646 && (input_type_a .nullable || input_type_b .nullable )),
4747 )
4848 }
49- fn introduces_nulls(& self) -> bool {
50- < mz_repr ::ArrayRustType <String > as ::mz_repr::DatumType<'_, ()>>::nullable()
51- }
52- fn propagates_nulls(& self) -> bool {
53- true
54- }
5549}
5650impl std ::fmt ::Display for ParseIdent {
5751 fn fmt (& self , f : & mut std ::fmt ::Formatter ) - > std ::fmt ::Result {
5852 f .write_str (stringify ! (parse_ident ))
5953 }
6054}
6155fn parse_ident <' a>(
62- ident: & str,
56+ ident : & ' a str,
6357 strict : bool ,
64- temp_storage: & 'a RowArena,
65- ) -> Result<Datum<'a>, EvalError> {
58+ ) -> Result <ArrayRustType <Cow <' a, str>>, EvalError> {
6659 fn is_ident_start (c : char ) -> bool {
6760 matches !(c , ' A' ..= ' Z' | ' a' ..= ' z' | ' _' | ' \u {80}' ..= char ::MAX )
6861 }
@@ -84,13 +77,12 @@ fn parse_ident<'a>(
8477 detail: Some (" String has unclosed double quotes." .into ()),
8578 });
8679 }
87- elems .push (Datum :: String (s ));
80+ elems .push (Cow :: Borrowed (s ));
8881 missing_ident = false ;
8982 } else if c .map (is_ident_start ).unwrap_or (false ) {
9083 buf .prev ();
9184 let s = buf .take_while (is_ident_cont );
92- let s = temp_storage .push_string (s .to_ascii_lowercase ());
93- elems .push (Datum ::String (s ));
85+ elems .push (Cow ::Owned (s .to_ascii_lowercase ()));
9486 missing_ident = false ;
9587 }
9688 if missing_ident {
@@ -126,19 +118,5 @@ fn parse_ident<'a>(
126118 _ => break ,
127119 }
128120 }
129- Ok(
130- temp_storage
131- .try_make_datum(|packer| {
132- packer
133- .try_push_array (
134- & [
135- ArrayDimension {
136- lower_bound: 1 ,
137- length: elems .len (),
138- },
139- ],
140- elems ,
141- )
142- } )?,
143- )
121+ Ok (elems .into ())
144122}
0 commit comments