Kontinuation commented on code in PR #1:
URL: https://github.com/apache/sedona-db/pull/1#discussion_r2310108000
##########
rust/sedona-functions/src/sd_format.rs:
##########
@@ -113,39 +97,236 @@ impl SedonaScalarKernel for SDFormatGeometry {
}
}
- let executor = WkbExecutor::new(&arg_types[0..1], &args[0..1]);
+ let formatted_type = sedona_type_to_formatted_type(&arg_types[0])?;
+ if formatted_type == arg_types[0] {
+ // No change in type, the input data does not have geospatial
columns that we can format,
+ // so just return the input value
+ return Ok(args[0].clone());
+ }
+
+ columnar_value_to_formatted_value(&arg_types[0], &args[0],
maybe_width_hint)
+ }
+}
+
+fn sedona_type_to_formatted_type(sedona_type: &SedonaType) ->
Result<SedonaType> {
+ match sedona_type {
+ SedonaType::Wkb(_, _) | SedonaType::WkbView(_, _) =>
Ok(SedonaType::Arrow(DataType::Utf8)),
+ SedonaType::Arrow(arrow_type) => {
+ // dive into the arrow type and translate geospatial types into
Utf8
+ match arrow_type {
+ DataType::Struct(fields) => {
+ let mut new_fields = Vec::with_capacity(fields.len());
+ for field in fields {
+ let new_field = field_to_formatted_field(field)?;
+ new_fields.push(Arc::new(new_field));
+ }
+ Ok(SedonaType::Arrow(DataType::Struct(new_fields.into())))
+ }
+ DataType::List(field) => {
+ let new_field = field_to_formatted_field(field)?;
+ Ok(SedonaType::Arrow(DataType::List(Arc::new(new_field))))
+ }
+ DataType::ListView(field) => {
+ let new_field = field_to_formatted_field(field)?;
+
Ok(SedonaType::Arrow(DataType::ListView(Arc::new(new_field))))
+ }
+ _ => Ok(sedona_type.clone()),
+ }
+ }
+ }
+}
+
+fn field_to_formatted_field(field: &Field) -> Result<Field> {
+ let new_type =
sedona_type_to_formatted_type(&SedonaType::from_data_type(field.data_type())?)?;
+ let new_field = field.clone().with_data_type(new_type.data_type());
+ Ok(new_field)
+}
+
+fn columnar_value_to_formatted_value(
+ sedona_type: &SedonaType,
+ columnar_value: &ColumnarValue,
+ maybe_width_hint: Option<usize>,
+) -> Result<ColumnarValue> {
+ match sedona_type {
+ SedonaType::Wkb(_, _) | SedonaType::WkbView(_, _) => {
+ geospatial_value_to_formatted_value(sedona_type, columnar_value,
maybe_width_hint)
+ }
+ SedonaType::Arrow(arrow_type) => match arrow_type {
+ DataType::Struct(fields) => match columnar_value {
+ ColumnarValue::Array(array) => {
+ let struct_array = array.as_struct();
+ let formatted_struct_array =
+ struct_value_to_formatted_value(fields, struct_array,
maybe_width_hint)?;
+ Ok(ColumnarValue::Array(Arc::new(formatted_struct_array)))
+ }
+ ColumnarValue::Scalar(ScalarValue::Struct(struct_array)) => {
+ let formatted_struct_array =
+ struct_value_to_formatted_value(fields, struct_array,
maybe_width_hint)?;
+ Ok(ColumnarValue::Scalar(ScalarValue::Struct(Arc::new(
+ formatted_struct_array,
+ ))))
+ }
+ _ => internal_err!("Unsupported struct columnar value"),
+ },
+ DataType::List(field) => match columnar_value {
+ ColumnarValue::Array(array) => {
+ let list_array = array.as_list::<i32>();
+ let formatted_list_array =
+ list_value_to_formatted_value(field, list_array,
maybe_width_hint)?;
+ Ok(ColumnarValue::Array(Arc::new(formatted_list_array)))
+ }
+ ColumnarValue::Scalar(ScalarValue::List(list_array)) => {
+ let formatted_list_array =
+ list_value_to_formatted_value(field, list_array,
maybe_width_hint)?;
+ Ok(ColumnarValue::Scalar(ScalarValue::List(Arc::new(
+ formatted_list_array,
+ ))))
+ }
+ _ => internal_err!("Unsupported list columnar value"),
+ },
+ DataType::ListView(field) => match columnar_value {
+ ColumnarValue::Array(array) => {
+ let list_array = array.as_list_view::<i32>();
+ let formatted_list_array =
+ list_view_value_to_formatted_value(field, list_array,
maybe_width_hint)?;
+ Ok(ColumnarValue::Array(Arc::new(formatted_list_array)))
+ }
+ _ => internal_err!("Unsupported list view columnar value"),
+ },
+ _ => Ok(columnar_value.clone()),
+ },
+ }
+}
+
+/// Implementation format geometry or geography
+///
+/// This is very similar to ST_AsText except it respects the width_hint by
+/// stopping the render for each item when too many characters have been
written.
+fn geospatial_value_to_formatted_value(
+ sedona_type: &SedonaType,
+ geospatial_value: &ColumnarValue,
+ maybe_width_hint: Option<usize>,
+) -> Result<ColumnarValue> {
+ let arg_types: &[SedonaType] = std::slice::from_ref(sedona_type);
+ let args: &[ColumnarValue] = std::slice::from_ref(geospatial_value);
Review Comment:
I'd like to keep it as is.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]