| 95 | } |
| 96 | |
| 97 | fn invoke_with_args(&self, args: ScalarFunctionArgs) -> Result<ColumnarValue> { |
| 98 | let len = args.args.iter().find_map(|arg| match arg { |
| 99 | ColumnarValue::Scalar(_) => None, |
| 100 | ColumnarValue::Array(a) => Some(a.len()), |
| 101 | }); |
| 102 | let is_scalar = len.is_none(); |
| 103 | let data_types = args.args[1..] |
| 104 | .iter() |
| 105 | .map(|arg| arg.data_type()) |
| 106 | .collect::<Vec<_>>(); |
| 107 | let fmt_type = args.args[0].data_type(); |
| 108 | |
| 109 | match &args.args[0] { |
| 110 | ColumnarValue::Scalar(ScalarValue::Null) => { |
| 111 | Ok(ColumnarValue::Scalar(ScalarValue::Utf8(None))) |
| 112 | } |
| 113 | ColumnarValue::Scalar(ScalarValue::Utf8(None)) => { |
| 114 | Ok(ColumnarValue::Scalar(ScalarValue::Utf8(None))) |
| 115 | } |
| 116 | ColumnarValue::Scalar(ScalarValue::LargeUtf8(None)) => { |
| 117 | Ok(ColumnarValue::Scalar(ScalarValue::LargeUtf8(None))) |
| 118 | } |
| 119 | ColumnarValue::Scalar(ScalarValue::Utf8View(None)) => { |
| 120 | Ok(ColumnarValue::Scalar(ScalarValue::Utf8View(None))) |
| 121 | } |
| 122 | ColumnarValue::Scalar(ScalarValue::Utf8(Some(fmt))) |
| 123 | | ColumnarValue::Scalar(ScalarValue::LargeUtf8(Some(fmt))) |
| 124 | | ColumnarValue::Scalar(ScalarValue::Utf8View(Some(fmt))) => { |
| 125 | let formatter = Formatter::parse(fmt, &data_types)?; |
| 126 | let mut result = Vec::with_capacity(len.unwrap_or(1)); |
| 127 | for i in 0..len.unwrap_or(1) { |
| 128 | let scalars = args.args[1..] |
| 129 | .iter() |
| 130 | .map(|arg| try_to_scalar(arg.clone(), i)) |
| 131 | .collect::<Result<Vec<_>>>()?; |
| 132 | let formatted = formatter.format(&scalars)?; |
| 133 | result.push(formatted); |
| 134 | } |
| 135 | if is_scalar { |
| 136 | let scalar_result = result.pop().unwrap(); |
| 137 | match fmt_type { |
| 138 | DataType::Utf8 => Ok(ColumnarValue::Scalar(ScalarValue::Utf8( |
| 139 | Some(scalar_result), |
| 140 | ))), |
| 141 | DataType::LargeUtf8 => Ok(ColumnarValue::Scalar( |
| 142 | ScalarValue::LargeUtf8(Some(scalar_result)), |
| 143 | )), |
| 144 | DataType::Utf8View => Ok(ColumnarValue::Scalar( |
| 145 | ScalarValue::Utf8View(Some(scalar_result)), |
| 146 | )), |
| 147 | _ => unreachable!(), |
| 148 | } |
| 149 | } else { |
| 150 | let array: ArrayRef = match fmt_type { |
| 151 | DataType::Utf8 => Arc::new(StringArray::from(result)), |
| 152 | DataType::LargeUtf8 => Arc::new(LargeStringArray::from(result)), |
| 153 | DataType::Utf8View => Arc::new(StringViewArray::from(result)), |
| 154 | _ => unreachable!(), |