Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial support for geo types (+ minor README improvements) #33

Merged
merged 6 commits into from
Jan 4, 2024

Conversation

cpg314
Copy link
Collaborator

@cpg314 cpg314 commented Dec 24, 2023

This adds support for native clickhouse geo data types: https://clickhouse.com/docs/en/sql-reference/data-types/geo

  • Point
  • Ring
  • Polygon
  • MultiPolygon

The approach taken is documented in 1eb61fd

The changes are tested with unit and integration tests.

In addition to these main changes, the README is updated to document all feature flags. It is now included in lib.rs, so that it will also display in the docs.rs documentation.

Alas it seems like Github does not support stacked PRs without the first PR being a branch of the original repo.
This is based on #32, only the 5 commits from today are new compared to the first PR. A proper diff can be viewed here: https://github.com/Protryon/klickhouse/pull/33/files/30cafa6c49dbf91f6c2463aaeeafc28b09299855..6372019814c1479e791a63e827834c931fa4b0ad

to_from_sql!(Polygon);
to_from_sql!(MultiPolygon);
#[cfg(feature = "geo-types")]
mod nav_types_conversions {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add in FromSql/ToSql implementations under the feature flag as well? Then derived types could directly use the geo_types types with no conversion.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, done

cpg314 added 6 commits January 4, 2024 19:39
This is to later allow efficiently (de)serializing geo values without having to deconstruct Values.
Clickhouse natively supported geo data types: https://clickhouse.com/docs/en/sql-reference/data-types/geo
- `Point`, which is an alias for `Tuple(Float64,Float64)`
- `Ring`, an alias for `Array(Point)`
- `Polygon`, an alias for `Array(Ring)`
- `MultiPolygon`, an alias for `Array(Polygon)`

To support them in `klickhouse`, it is not sufficient to create a wrapper type and implement `ToSql`/`FromSql`.
Indeed, these really are native types (a `Point` is returned as a `Point`, not as a `Tuple`), and this line would error: https://github.com/Protryon/klickhouse/blob/master/klickhouse/src/block.rs#L194

One simple solution would be to add 4 lines to `Type::from_str`
```rust
"Point" => Type::Tuple(vec![Type::Float64,Type::Float64]),
"Ring" => Type::Array(Box::new(Type::Tuple(vec![Type::Float64,Type::Float64]))),
// etc.
```
and provide `Point([f64; 2])`, `Ring(Vec<Polygon>)` newtypes, along with `ToSql`/`FromSql` implementations.

It is slightly unsatisfactory for two reasons:
1. The primitive types do not get exposed as such, but rather through their aliases.
2. The `{To,From}Sql` implementation on these newtypes require deconstructing and reconstruction (`into_iter`/`collect`) the inner collections.

This instead implements the geo types as native `klickhouse` types and values. The `Value` variants provide strong typing such as `Value::Polygon(Polygon)`, where `Ring(Vec<Point>)`, rather than a `Value::Ring(Vec<Value>)`. The downside is that we still need to transform the inner container to `Value`s when serializing rather than just swapping an `Value::Array` for a `Value::Ring`

To avoid code duplication with the `Array` and `Tuple` serializers/deserializers (or having the same inefficiency as 2. above), these are made generic. This allows e.g. directly constructing a `Ring(Vec<Point>)` without having to pass through a `Array(Vec<Value>)`.

The implementation is tested with:
- New roundtrip tests
- The `test_serialize` implementation test.
The integration test is adapted so that these functions are tested too.
@Protryon Protryon merged commit 44a06e9 into Protryon:master Jan 4, 2024
@cpg314 cpg314 deleted the geo branch January 4, 2024 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants