Concatenates the text representations of all the arguments. NULL arguments are ignored. concat('abcde', 2, NULL, 22) = 'abcde222'
(&self, args: ScalarFunctionArgs)
| 107 | /// Concatenates the text representations of all the arguments. NULL arguments are ignored. |
| 108 | /// concat('abcde', 2, NULL, 22) = 'abcde222' |
| 109 | fn invoke_with_args(&self, args: ScalarFunctionArgs) -> Result<ColumnarValue> { |
| 110 | let ScalarFunctionArgs { args, .. } = args; |
| 111 | |
| 112 | let arg_types: Vec<DataType> = args.iter().map(|c| c.data_type()).collect(); |
| 113 | let return_datatype = deduce_return_type(&arg_types); |
| 114 | |
| 115 | let array_len = args.iter().find_map(|x| match x { |
| 116 | ColumnarValue::Array(array) => Some(array.len()), |
| 117 | _ => None, |
| 118 | }); |
| 119 | |
| 120 | // Scalar |
| 121 | if array_len.is_none() { |
| 122 | let mut values: Vec<&[u8]> = Vec::with_capacity(args.len()); |
| 123 | for arg in &args { |
| 124 | let ColumnarValue::Scalar(scalar) = arg else { |
| 125 | return internal_err!("concat expected scalar value, got {arg:?}"); |
| 126 | }; |
| 127 | if let ScalarValue::Binary(Some(value)) = scalar { |
| 128 | values.push(value); |
| 129 | } else { |
| 130 | match scalar.try_as_str() { |
| 131 | Some(Some(v)) => values.push(v.as_bytes()), |
| 132 | Some(None) => {} // null literal |
| 133 | None => plan_err!( |
| 134 | "Concat function does not support scalar type {}", |
| 135 | scalar |
| 136 | )?, |
| 137 | } |
| 138 | } |
| 139 | } |
| 140 | let concat_bytes = values.concat(); |
| 141 | let result = std::str::from_utf8(&concat_bytes) |
| 142 | .map_err(|_| exec_datafusion_err!("invalid UTF-8 in binary literal"))? |
| 143 | .to_string(); |
| 144 | |
| 145 | return match return_datatype { |
| 146 | DataType::Utf8View => { |
| 147 | Ok(ColumnarValue::Scalar(ScalarValue::Utf8View(Some(result)))) |
| 148 | } |
| 149 | DataType::Utf8 => { |
| 150 | Ok(ColumnarValue::Scalar(ScalarValue::Utf8(Some(result)))) |
| 151 | } |
| 152 | DataType::LargeUtf8 => { |
| 153 | Ok(ColumnarValue::Scalar(ScalarValue::LargeUtf8(Some(result)))) |
| 154 | } |
| 155 | other => { |
| 156 | plan_err!("Concat function does not support datatype of {other}") |
| 157 | } |
| 158 | }; |
| 159 | } |
| 160 | |
| 161 | // Array |
| 162 | let len = array_len.unwrap(); |
| 163 | let mut data_size = 0; |
| 164 | let mut columns = Vec::with_capacity(args.len()); |
| 165 | |
| 166 | for arg in &args { |