From 19918928c59e43bd9d8b5f0bc58ffbf6702ed232 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Tue, 8 Oct 2024 19:38:44 -0700 Subject: [PATCH 01/36] feat: add function to aggregate path into a geojson path (#4798) * feat: add geojson function to aggregate paths * test: add sqlness results * test: add sqlness * refactor: corrected to aggregation function * chore: update comments * fix: make linter happy again * refactor: rename to remove `geo` from `geojson` function name The return type is not geojson at all. It's just compatible with geojson's coordinates part and superset's deckgl path plugin. --- src/common/function/src/scalars/aggregate.rs | 3 + .../function/src/scalars/aggregate/argmax.rs | 5 +- .../function/src/scalars/aggregate/argmin.rs | 5 +- .../function/src/scalars/aggregate/diff.rs | 4 +- .../function/src/scalars/aggregate/mean.rs | 4 +- .../function/src/scalars/aggregate/polyval.rs | 3 +- .../scalars/aggregate/scipy_stats_norm_cdf.rs | 4 +- .../scalars/aggregate/scipy_stats_norm_pdf.rs | 4 +- src/common/function/src/scalars/geo.rs | 2 + .../function/src/scalars/geo/encoding.rs | 223 ++++++++++++++++++ .../function/src/scalars/geo/helpers.rs | 61 +++++ src/common/macro/src/aggr_func.rs | 18 +- src/common/macro/tests/test_derive.rs | 2 +- src/datatypes/src/data_type.rs | 9 + src/query/src/tests/my_sum_udaf_example.rs | 1 + .../standalone/common/function/geo.result | 25 ++ .../cases/standalone/common/function/geo.sql | 13 + 17 files changed, 367 insertions(+), 19 deletions(-) create mode 100644 src/common/function/src/scalars/geo/encoding.rs create mode 100644 src/common/function/src/scalars/geo/helpers.rs diff --git a/src/common/function/src/scalars/aggregate.rs b/src/common/function/src/scalars/aggregate.rs index c6875a680c..f7ce316b6c 100644 --- a/src/common/function/src/scalars/aggregate.rs +++ b/src/common/function/src/scalars/aggregate.rs @@ -31,6 +31,7 @@ pub use polyval::PolyvalAccumulatorCreator; pub use scipy_stats_norm_cdf::ScipyStatsNormCdfAccumulatorCreator; pub use scipy_stats_norm_pdf::ScipyStatsNormPdfAccumulatorCreator; +use super::geo::encoding::JsonPathEncodeFunctionCreator; use crate::function_registry::FunctionRegistry; /// A function creates `AggregateFunctionCreator`. @@ -91,5 +92,7 @@ impl AggregateFunctions { register_aggr_func!("argmin", 1, ArgminAccumulatorCreator); register_aggr_func!("scipystatsnormcdf", 2, ScipyStatsNormCdfAccumulatorCreator); register_aggr_func!("scipystatsnormpdf", 2, ScipyStatsNormPdfAccumulatorCreator); + + register_aggr_func!("json_encode_path", 3, JsonPathEncodeFunctionCreator); } } diff --git a/src/common/function/src/scalars/aggregate/argmax.rs b/src/common/function/src/scalars/aggregate/argmax.rs index c5c5264f19..4749ff9a3a 100644 --- a/src/common/function/src/scalars/aggregate/argmax.rs +++ b/src/common/function/src/scalars/aggregate/argmax.rs @@ -16,7 +16,10 @@ use std::cmp::Ordering; use std::sync::Arc; use common_macro::{as_aggr_func_creator, AggrFuncTypeStore}; -use common_query::error::{BadAccumulatorImplSnafu, CreateAccumulatorSnafu, Result}; +use common_query::error::{ + BadAccumulatorImplSnafu, CreateAccumulatorSnafu, InvalidInputStateSnafu, Result, +}; +use common_query::logical_plan::accumulator::AggrFuncTypeStore; use common_query::logical_plan::{Accumulator, AggregateFunctionCreator}; use common_query::prelude::*; use datatypes::prelude::*; diff --git a/src/common/function/src/scalars/aggregate/argmin.rs b/src/common/function/src/scalars/aggregate/argmin.rs index 7233f43b77..fe89184460 100644 --- a/src/common/function/src/scalars/aggregate/argmin.rs +++ b/src/common/function/src/scalars/aggregate/argmin.rs @@ -16,7 +16,10 @@ use std::cmp::Ordering; use std::sync::Arc; use common_macro::{as_aggr_func_creator, AggrFuncTypeStore}; -use common_query::error::{BadAccumulatorImplSnafu, CreateAccumulatorSnafu, Result}; +use common_query::error::{ + BadAccumulatorImplSnafu, CreateAccumulatorSnafu, InvalidInputStateSnafu, Result, +}; +use common_query::logical_plan::accumulator::AggrFuncTypeStore; use common_query::logical_plan::{Accumulator, AggregateFunctionCreator}; use common_query::prelude::*; use datatypes::prelude::*; diff --git a/src/common/function/src/scalars/aggregate/diff.rs b/src/common/function/src/scalars/aggregate/diff.rs index b83ed6d004..25d1614e4b 100644 --- a/src/common/function/src/scalars/aggregate/diff.rs +++ b/src/common/function/src/scalars/aggregate/diff.rs @@ -17,8 +17,10 @@ use std::sync::Arc; use common_macro::{as_aggr_func_creator, AggrFuncTypeStore}; use common_query::error::{ - CreateAccumulatorSnafu, DowncastVectorSnafu, FromScalarValueSnafu, Result, + CreateAccumulatorSnafu, DowncastVectorSnafu, FromScalarValueSnafu, InvalidInputStateSnafu, + Result, }; +use common_query::logical_plan::accumulator::AggrFuncTypeStore; use common_query::logical_plan::{Accumulator, AggregateFunctionCreator}; use common_query::prelude::*; use datatypes::prelude::*; diff --git a/src/common/function/src/scalars/aggregate/mean.rs b/src/common/function/src/scalars/aggregate/mean.rs index 3dc3e18535..ed66c90bdb 100644 --- a/src/common/function/src/scalars/aggregate/mean.rs +++ b/src/common/function/src/scalars/aggregate/mean.rs @@ -17,8 +17,10 @@ use std::sync::Arc; use common_macro::{as_aggr_func_creator, AggrFuncTypeStore}; use common_query::error::{ - BadAccumulatorImplSnafu, CreateAccumulatorSnafu, DowncastVectorSnafu, Result, + BadAccumulatorImplSnafu, CreateAccumulatorSnafu, DowncastVectorSnafu, InvalidInputStateSnafu, + Result, }; +use common_query::logical_plan::accumulator::AggrFuncTypeStore; use common_query::logical_plan::{Accumulator, AggregateFunctionCreator}; use common_query::prelude::*; use datatypes::prelude::*; diff --git a/src/common/function/src/scalars/aggregate/polyval.rs b/src/common/function/src/scalars/aggregate/polyval.rs index ae6ca101c4..bc3986fd0e 100644 --- a/src/common/function/src/scalars/aggregate/polyval.rs +++ b/src/common/function/src/scalars/aggregate/polyval.rs @@ -18,8 +18,9 @@ use std::sync::Arc; use common_macro::{as_aggr_func_creator, AggrFuncTypeStore}; use common_query::error::{ self, BadAccumulatorImplSnafu, CreateAccumulatorSnafu, DowncastVectorSnafu, - FromScalarValueSnafu, InvalidInputColSnafu, Result, + FromScalarValueSnafu, InvalidInputColSnafu, InvalidInputStateSnafu, Result, }; +use common_query::logical_plan::accumulator::AggrFuncTypeStore; use common_query::logical_plan::{Accumulator, AggregateFunctionCreator}; use common_query::prelude::*; use datatypes::prelude::*; diff --git a/src/common/function/src/scalars/aggregate/scipy_stats_norm_cdf.rs b/src/common/function/src/scalars/aggregate/scipy_stats_norm_cdf.rs index e6c92225a6..09a9c820d8 100644 --- a/src/common/function/src/scalars/aggregate/scipy_stats_norm_cdf.rs +++ b/src/common/function/src/scalars/aggregate/scipy_stats_norm_cdf.rs @@ -17,8 +17,10 @@ use std::sync::Arc; use common_macro::{as_aggr_func_creator, AggrFuncTypeStore}; use common_query::error::{ self, BadAccumulatorImplSnafu, CreateAccumulatorSnafu, DowncastVectorSnafu, - FromScalarValueSnafu, GenerateFunctionSnafu, InvalidInputColSnafu, Result, + FromScalarValueSnafu, GenerateFunctionSnafu, InvalidInputColSnafu, InvalidInputStateSnafu, + Result, }; +use common_query::logical_plan::accumulator::AggrFuncTypeStore; use common_query::logical_plan::{Accumulator, AggregateFunctionCreator}; use common_query::prelude::*; use datatypes::prelude::*; diff --git a/src/common/function/src/scalars/aggregate/scipy_stats_norm_pdf.rs b/src/common/function/src/scalars/aggregate/scipy_stats_norm_pdf.rs index 3045ae8665..2d5025ea3a 100644 --- a/src/common/function/src/scalars/aggregate/scipy_stats_norm_pdf.rs +++ b/src/common/function/src/scalars/aggregate/scipy_stats_norm_pdf.rs @@ -17,8 +17,10 @@ use std::sync::Arc; use common_macro::{as_aggr_func_creator, AggrFuncTypeStore}; use common_query::error::{ self, BadAccumulatorImplSnafu, CreateAccumulatorSnafu, DowncastVectorSnafu, - FromScalarValueSnafu, GenerateFunctionSnafu, InvalidInputColSnafu, Result, + FromScalarValueSnafu, GenerateFunctionSnafu, InvalidInputColSnafu, InvalidInputStateSnafu, + Result, }; +use common_query::logical_plan::accumulator::AggrFuncTypeStore; use common_query::logical_plan::{Accumulator, AggregateFunctionCreator}; use common_query::prelude::*; use datatypes::prelude::*; diff --git a/src/common/function/src/scalars/geo.rs b/src/common/function/src/scalars/geo.rs index 8ad6a7aef2..37b6c0704b 100644 --- a/src/common/function/src/scalars/geo.rs +++ b/src/common/function/src/scalars/geo.rs @@ -13,8 +13,10 @@ // limitations under the License. use std::sync::Arc; +pub(crate) mod encoding; mod geohash; mod h3; +mod helpers; use geohash::{GeohashFunction, GeohashNeighboursFunction}; diff --git a/src/common/function/src/scalars/geo/encoding.rs b/src/common/function/src/scalars/geo/encoding.rs new file mode 100644 index 0000000000..0600120598 --- /dev/null +++ b/src/common/function/src/scalars/geo/encoding.rs @@ -0,0 +1,223 @@ +// Copyright 2023 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::sync::Arc; + +use common_error::ext::{BoxedError, PlainError}; +use common_error::status_code::StatusCode; +use common_macro::{as_aggr_func_creator, AggrFuncTypeStore}; +use common_query::error::{self, InvalidFuncArgsSnafu, InvalidInputStateSnafu, Result}; +use common_query::logical_plan::accumulator::AggrFuncTypeStore; +use common_query::logical_plan::{Accumulator, AggregateFunctionCreator}; +use common_query::prelude::AccumulatorCreatorFunction; +use common_time::Timestamp; +use datatypes::prelude::ConcreteDataType; +use datatypes::value::{ListValue, Value}; +use datatypes::vectors::VectorRef; +use snafu::{ensure, ResultExt}; + +use super::helpers::{ensure_columns_len, ensure_columns_n}; + +/// Accumulator of lat, lng, timestamp tuples +#[derive(Debug)] +pub struct JsonPathAccumulator { + timestamp_type: ConcreteDataType, + lat: Vec>, + lng: Vec>, + timestamp: Vec>, +} + +impl JsonPathAccumulator { + fn new(timestamp_type: ConcreteDataType) -> Self { + Self { + lat: Vec::default(), + lng: Vec::default(), + timestamp: Vec::default(), + timestamp_type, + } + } +} + +impl Accumulator for JsonPathAccumulator { + fn state(&self) -> Result> { + Ok(vec![ + Value::List(ListValue::new( + self.lat.iter().map(|i| Value::from(*i)).collect(), + ConcreteDataType::float64_datatype(), + )), + Value::List(ListValue::new( + self.lng.iter().map(|i| Value::from(*i)).collect(), + ConcreteDataType::float64_datatype(), + )), + Value::List(ListValue::new( + self.timestamp.iter().map(|i| Value::from(*i)).collect(), + self.timestamp_type.clone(), + )), + ]) + } + + fn update_batch(&mut self, columns: &[VectorRef]) -> Result<()> { + // update batch as in datafusion just provides the accumulator original + // input. + // + // columns is vec of [`lat`, `lng`, `timestamp`] + // where + // - `lat` is a vector of `Value::Float64` or similar type. Each item in + // the vector is a row in given dataset. + // - so on so forth for `lng` and `timestamp` + ensure_columns_n!(columns, 3); + + let lat = &columns[0]; + let lng = &columns[1]; + let ts = &columns[2]; + + let size = lat.len(); + + for idx in 0..size { + self.lat.push(lat.get(idx).as_f64_lossy()); + self.lng.push(lng.get(idx).as_f64_lossy()); + self.timestamp.push(ts.get(idx).as_timestamp()); + } + + Ok(()) + } + + fn merge_batch(&mut self, states: &[VectorRef]) -> Result<()> { + // merge batch as in datafusion gives state accumulated from the data + // returned from child accumulators' state() call + // In our particular implementation, the data structure is like + // + // states is vec of [`lat`, `lng`, `timestamp`] + // where + // - `lat` is a vector of `Value::List`. Each item in the list is all + // coordinates from a child accumulator. + // - so on so forth for `lng` and `timestamp` + + ensure_columns_n!(states, 3); + + let lat_lists = &states[0]; + let lng_lists = &states[1]; + let ts_lists = &states[2]; + + let len = lat_lists.len(); + + for idx in 0..len { + if let Some(lat_list) = lat_lists + .get(idx) + .as_list() + .map_err(BoxedError::new) + .context(error::ExecuteSnafu)? + { + for v in lat_list.items() { + self.lat.push(v.as_f64_lossy()); + } + } + + if let Some(lng_list) = lng_lists + .get(idx) + .as_list() + .map_err(BoxedError::new) + .context(error::ExecuteSnafu)? + { + for v in lng_list.items() { + self.lng.push(v.as_f64_lossy()); + } + } + + if let Some(ts_list) = ts_lists + .get(idx) + .as_list() + .map_err(BoxedError::new) + .context(error::ExecuteSnafu)? + { + for v in ts_list.items() { + self.timestamp.push(v.as_timestamp()); + } + } + } + + Ok(()) + } + + fn evaluate(&self) -> Result { + let mut work_vec: Vec<(&Option, &Option, &Option)> = self + .lat + .iter() + .zip(self.lng.iter()) + .zip(self.timestamp.iter()) + .map(|((a, b), c)| (a, b, c)) + .collect(); + + // sort by timestamp, we treat null timestamp as 0 + work_vec.sort_unstable_by_key(|tuple| tuple.2.unwrap_or_else(|| Timestamp::new_second(0))); + + let result = serde_json::to_string( + &work_vec + .into_iter() + // note that we transform to lng,lat for geojson compatibility + .map(|(lat, lng, _)| vec![lng, lat]) + .collect::>>>(), + ) + .map_err(|e| { + BoxedError::new(PlainError::new( + format!("Serialization failure: {}", e), + StatusCode::EngineExecuteQuery, + )) + }) + .context(error::ExecuteSnafu)?; + + Ok(Value::String(result.into())) + } +} + +/// This function accept rows of lat, lng and timestamp, sort with timestamp and +/// encoding them into a geojson-like path. +/// +/// Example: +/// +/// ```sql +/// SELECT json_encode_path(lat, lon, timestamp) FROM table [group by ...]; +/// ``` +/// +#[as_aggr_func_creator] +#[derive(Debug, Default, AggrFuncTypeStore)] +pub struct JsonPathEncodeFunctionCreator {} + +impl AggregateFunctionCreator for JsonPathEncodeFunctionCreator { + fn creator(&self) -> AccumulatorCreatorFunction { + let creator: AccumulatorCreatorFunction = Arc::new(move |types: &[ConcreteDataType]| { + let ts_type = types[2].clone(); + Ok(Box::new(JsonPathAccumulator::new(ts_type))) + }); + + creator + } + + fn output_type(&self) -> Result { + Ok(ConcreteDataType::string_datatype()) + } + + fn state_types(&self) -> Result> { + let input_types = self.input_types()?; + ensure!(input_types.len() == 3, InvalidInputStateSnafu); + + let timestamp_type = input_types[2].clone(); + + Ok(vec![ + ConcreteDataType::list_datatype(ConcreteDataType::float64_datatype()), + ConcreteDataType::list_datatype(ConcreteDataType::float64_datatype()), + ConcreteDataType::list_datatype(timestamp_type), + ]) + } +} diff --git a/src/common/function/src/scalars/geo/helpers.rs b/src/common/function/src/scalars/geo/helpers.rs new file mode 100644 index 0000000000..f07eaefb15 --- /dev/null +++ b/src/common/function/src/scalars/geo/helpers.rs @@ -0,0 +1,61 @@ +// Copyright 2023 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +macro_rules! ensure_columns_len { + ($columns:ident) => { + ensure!( + $columns.windows(2).all(|c| c[0].len() == c[1].len()), + InvalidFuncArgsSnafu { + err_msg: "The length of input columns are in different size" + } + ) + }; + ($column_a:ident, $column_b:ident, $($column_n:ident),*) => { + ensure!( + { + let mut result = $column_a.len() == $column_b.len(); + $( + result = result && ($column_a.len() == $column_n.len()); + )* + result + } + InvalidFuncArgsSnafu { + err_msg: "The length of input columns are in different size" + } + ) + }; +} + +pub(super) use ensure_columns_len; + +macro_rules! ensure_columns_n { + ($columns:ident, $n:literal) => { + ensure!( + $columns.len() == $n, + InvalidFuncArgsSnafu { + err_msg: format!( + "The length of arguments is not correct, expect {}, provided : {}", + stringify!($n), + $columns.len() + ), + } + ); + + if $n > 1 { + ensure_columns_len!($columns); + } + }; +} + +pub(super) use ensure_columns_n; diff --git a/src/common/macro/src/aggr_func.rs b/src/common/macro/src/aggr_func.rs index 4c3ccccdee..2e17e70b5a 100644 --- a/src/common/macro/src/aggr_func.rs +++ b/src/common/macro/src/aggr_func.rs @@ -21,23 +21,19 @@ use syn::{parse_macro_input, DeriveInput, ItemStruct}; pub(crate) fn impl_aggr_func_type_store(ast: &DeriveInput) -> TokenStream { let name = &ast.ident; let gen = quote! { - use common_query::logical_plan::accumulator::AggrFuncTypeStore; - use common_query::error::{InvalidInputStateSnafu, Error as QueryError}; - use datatypes::prelude::ConcreteDataType; - - impl AggrFuncTypeStore for #name { - fn input_types(&self) -> std::result::Result, QueryError> { + impl common_query::logical_plan::accumulator::AggrFuncTypeStore for #name { + fn input_types(&self) -> std::result::Result, common_query::error::Error> { let input_types = self.input_types.load(); - snafu::ensure!(input_types.is_some(), InvalidInputStateSnafu); + snafu::ensure!(input_types.is_some(), common_query::error::InvalidInputStateSnafu); Ok(input_types.as_ref().unwrap().as_ref().clone()) } - fn set_input_types(&self, input_types: Vec) -> std::result::Result<(), QueryError> { + fn set_input_types(&self, input_types: Vec) -> std::result::Result<(), common_query::error::Error> { let old = self.input_types.swap(Some(std::sync::Arc::new(input_types.clone()))); if let Some(old) = old { - snafu::ensure!(old.len() == input_types.len(), InvalidInputStateSnafu); + snafu::ensure!(old.len() == input_types.len(), common_query::error::InvalidInputStateSnafu); for (x, y) in old.iter().zip(input_types.iter()) { - snafu::ensure!(x == y, InvalidInputStateSnafu); + snafu::ensure!(x == y, common_query::error::InvalidInputStateSnafu); } } Ok(()) @@ -51,7 +47,7 @@ pub(crate) fn impl_as_aggr_func_creator(_args: TokenStream, input: TokenStream) let mut item_struct = parse_macro_input!(input as ItemStruct); if let syn::Fields::Named(ref mut fields) = item_struct.fields { let result = syn::Field::parse_named.parse2(quote! { - input_types: arc_swap::ArcSwapOption> + input_types: arc_swap::ArcSwapOption> }); match result { Ok(field) => fields.named.push(field), diff --git a/src/common/macro/tests/test_derive.rs b/src/common/macro/tests/test_derive.rs index 9c648c788d..c614800572 100644 --- a/src/common/macro/tests/test_derive.rs +++ b/src/common/macro/tests/test_derive.rs @@ -24,5 +24,5 @@ struct Foo {} fn test_derive() { let _ = Foo::default(); assert_fields!(Foo: input_types); - assert_impl_all!(Foo: std::fmt::Debug, Default, AggrFuncTypeStore); + assert_impl_all!(Foo: std::fmt::Debug, Default, common_query::logical_plan::accumulator::AggrFuncTypeStore); } diff --git a/src/datatypes/src/data_type.rs b/src/datatypes/src/data_type.rs index 495c47dc5f..12f5c8d1f2 100644 --- a/src/datatypes/src/data_type.rs +++ b/src/datatypes/src/data_type.rs @@ -249,6 +249,15 @@ impl ConcreteDataType { ] } + pub fn timestamps() -> Vec { + vec![ + ConcreteDataType::timestamp_second_datatype(), + ConcreteDataType::timestamp_millisecond_datatype(), + ConcreteDataType::timestamp_microsecond_datatype(), + ConcreteDataType::timestamp_nanosecond_datatype(), + ] + } + /// Convert arrow data type to [ConcreteDataType]. /// /// # Panics diff --git a/src/query/src/tests/my_sum_udaf_example.rs b/src/query/src/tests/my_sum_udaf_example.rs index 8220dcf72d..63653ffbce 100644 --- a/src/query/src/tests/my_sum_udaf_example.rs +++ b/src/query/src/tests/my_sum_udaf_example.rs @@ -19,6 +19,7 @@ use std::sync::Arc; use common_function::scalars::aggregate::AggregateFunctionMeta; use common_macro::{as_aggr_func_creator, AggrFuncTypeStore}; use common_query::error::{CreateAccumulatorSnafu, Result as QueryResult}; +use common_query::logical_plan::accumulator::AggrFuncTypeStore; use common_query::logical_plan::{Accumulator, AggregateFunctionCreator}; use common_query::prelude::*; use common_recordbatch::{RecordBatch, RecordBatches}; diff --git a/tests/cases/standalone/common/function/geo.result b/tests/cases/standalone/common/function/geo.result index 8954447650..4f9d168ac0 100644 --- a/tests/cases/standalone/common/function/geo.result +++ b/tests/cases/standalone/common/function/geo.result @@ -236,3 +236,28 @@ SELECT geohash_neighbours(37.76938, -122.3889, 11); | [9q8yygxnefv, 9q8yygxnefu, 9q8yygxnefs, 9q8yygxnefk, 9q8yygxnefm, 9q8yygxnefq, 9q8yygxnefw, 9q8yygxnefy] | +----------------------------------------------------------------------------------------------------------+ +SELECT json_encode_path(37.76938, -122.3889, 1728083375::TimestampSecond); + ++----------------------------------------------------------------------------------------------------------------------+ +| json_encode_path(Float64(37.76938),Float64(-122.3889),arrow_cast(Int64(1728083375),Utf8("Timestamp(Second, None)"))) | ++----------------------------------------------------------------------------------------------------------------------+ +| [[-122.3889,37.76938]] | ++----------------------------------------------------------------------------------------------------------------------+ + +SELECT json_encode_path(lat, lon, ts) +FROM( + SELECT 37.76938 AS lat, -122.3889 AS lon, 1728083375::TimestampSecond AS ts + UNION ALL + SELECT 37.76928 AS lat, -122.3839 AS lon, 1728083373::TimestampSecond AS ts + UNION ALL + SELECT 37.76930 AS lat, -122.3820 AS lon, 1728083379::TimestampSecond AS ts + UNION ALL + SELECT 37.77001 AS lat, -122.3888 AS lon, 1728083372::TimestampSecond AS ts +); + ++-------------------------------------------------------------------------------------+ +| json_encode_path(lat,lon,ts) | ++-------------------------------------------------------------------------------------+ +| [[-122.3888,37.77001],[-122.3839,37.76928],[-122.3889,37.76938],[-122.382,37.7693]] | ++-------------------------------------------------------------------------------------+ + diff --git a/tests/cases/standalone/common/function/geo.sql b/tests/cases/standalone/common/function/geo.sql index be2b3947bb..cd9d403e6e 100644 --- a/tests/cases/standalone/common/function/geo.sql +++ b/tests/cases/standalone/common/function/geo.sql @@ -66,3 +66,16 @@ SELECT geohash(37.76938, -122.3889, 11::UInt32); SELECT geohash(37.76938, -122.3889, 11::UInt64); SELECT geohash_neighbours(37.76938, -122.3889, 11); + +SELECT json_encode_path(37.76938, -122.3889, 1728083375::TimestampSecond); + +SELECT json_encode_path(lat, lon, ts) +FROM( + SELECT 37.76938 AS lat, -122.3889 AS lon, 1728083375::TimestampSecond AS ts + UNION ALL + SELECT 37.76928 AS lat, -122.3839 AS lon, 1728083373::TimestampSecond AS ts + UNION ALL + SELECT 37.76930 AS lat, -122.3820 AS lon, 1728083379::TimestampSecond AS ts + UNION ALL + SELECT 37.77001 AS lat, -122.3888 AS lon, 1728083372::TimestampSecond AS ts +); From 0dd11f53f55ff1b342fda40d20a5125f568b244a Mon Sep 17 00:00:00 2001 From: Kaifeng Zheng <100595273+Kev1n8@users.noreply.github.com> Date: Wed, 9 Oct 2024 15:11:57 +0800 Subject: [PATCH 02/36] feat: add json format output for http interface (#4797) * feat: json output format for http * feat: add json result test case * fix: typo and refactor a piece of code * fix: cargo check * move affected_rows to top level --- src/servers/src/http.rs | 32 +++++++ src/servers/src/http/handler.rs | 2 + src/servers/src/http/json_result.rs | 137 ++++++++++++++++++++++++++++ tests-integration/tests/http.rs | 18 +++- 4 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 src/servers/src/http/json_result.rs diff --git a/src/servers/src/http.rs b/src/servers/src/http.rs index a2b72b548b..953ff9e73a 100644 --- a/src/servers/src/http.rs +++ b/src/servers/src/http.rs @@ -59,6 +59,7 @@ use crate::http::error_result::ErrorResponse; use crate::http::greptime_result_v1::GreptimedbV1Response; use crate::http::influxdb::{influxdb_health, influxdb_ping, influxdb_write_v1, influxdb_write_v2}; use crate::http::influxdb_result_v1::InfluxdbV1Response; +use crate::http::json_result::JsonResponse; use crate::http::prometheus::{ build_info_query, format_query, instant_query, label_values_query, labels_query, range_query, series_query, @@ -97,6 +98,7 @@ pub mod error_result; pub mod greptime_manage_resp; pub mod greptime_result_v1; pub mod influxdb_result_v1; +pub mod json_result; pub mod table_result; #[cfg(any(test, feature = "testing"))] @@ -279,6 +281,7 @@ pub enum ResponseFormat { #[default] GreptimedbV1, InfluxdbV1, + Json, } impl ResponseFormat { @@ -289,6 +292,7 @@ impl ResponseFormat { "table" => Some(ResponseFormat::Table), "greptimedb_v1" => Some(ResponseFormat::GreptimedbV1), "influxdb_v1" => Some(ResponseFormat::InfluxdbV1), + "json" => Some(ResponseFormat::Json), _ => None, } } @@ -300,6 +304,7 @@ impl ResponseFormat { ResponseFormat::Table => "table", ResponseFormat::GreptimedbV1 => "greptimedb_v1", ResponseFormat::InfluxdbV1 => "influxdb_v1", + ResponseFormat::Json => "json", } } } @@ -356,6 +361,7 @@ pub enum HttpResponse { Error(ErrorResponse), GreptimedbV1(GreptimedbV1Response), InfluxdbV1(InfluxdbV1Response), + Json(JsonResponse), } impl HttpResponse { @@ -366,6 +372,7 @@ impl HttpResponse { HttpResponse::Table(resp) => resp.with_execution_time(execution_time).into(), HttpResponse::GreptimedbV1(resp) => resp.with_execution_time(execution_time).into(), HttpResponse::InfluxdbV1(resp) => resp.with_execution_time(execution_time).into(), + HttpResponse::Json(resp) => resp.with_execution_time(execution_time).into(), HttpResponse::Error(resp) => resp.with_execution_time(execution_time).into(), } } @@ -375,6 +382,7 @@ impl HttpResponse { HttpResponse::Csv(resp) => resp.with_limit(limit).into(), HttpResponse::Table(resp) => resp.with_limit(limit).into(), HttpResponse::GreptimedbV1(resp) => resp.with_limit(limit).into(), + HttpResponse::Json(resp) => resp.with_limit(limit).into(), _ => self, } } @@ -407,6 +415,7 @@ impl IntoResponse for HttpResponse { HttpResponse::Table(resp) => resp.into_response(), HttpResponse::GreptimedbV1(resp) => resp.into_response(), HttpResponse::InfluxdbV1(resp) => resp.into_response(), + HttpResponse::Json(resp) => resp.into_response(), HttpResponse::Error(resp) => resp.into_response(), } } @@ -452,6 +461,12 @@ impl From for HttpResponse { } } +impl From for HttpResponse { + fn from(value: JsonResponse) -> Self { + HttpResponse::Json(value) + } +} + async fn serve_api(Extension(api): Extension) -> impl IntoApiResponse { Json(api) } @@ -1131,6 +1146,7 @@ mod test { ResponseFormat::Csv, ResponseFormat::Table, ResponseFormat::Arrow, + ResponseFormat::Json, ] { let recordbatches = RecordBatches::try_new(schema.clone(), vec![recordbatch.clone()]).unwrap(); @@ -1141,6 +1157,7 @@ mod test { ResponseFormat::Table => TableResponse::from_output(outputs).await, ResponseFormat::GreptimedbV1 => GreptimedbV1Response::from_output(outputs).await, ResponseFormat::InfluxdbV1 => InfluxdbV1Response::from_output(outputs, None).await, + ResponseFormat::Json => JsonResponse::from_output(outputs).await, }; match json_resp { @@ -1210,6 +1227,21 @@ mod test { assert_eq!(rb.num_columns(), 2); assert_eq!(rb.num_rows(), 4); } + + HttpResponse::Json(resp) => { + let output = &resp.output()[0]; + if let GreptimeQueryOutput::Records(r) = output { + assert_eq!(r.num_rows(), 4); + assert_eq!(r.num_cols(), 2); + assert_eq!(r.schema.column_schemas[0].name, "numbers"); + assert_eq!(r.schema.column_schemas[0].data_type, "UInt32"); + assert_eq!(r.rows[0][0], serde_json::Value::from(1)); + assert_eq!(r.rows[0][1], serde_json::Value::Null); + } else { + panic!("invalid output type"); + } + } + HttpResponse::Error(err) => unreachable!("{err:?}"), } } diff --git a/src/servers/src/http/handler.rs b/src/servers/src/http/handler.rs index 1befc22240..4925c79639 100644 --- a/src/servers/src/http/handler.rs +++ b/src/servers/src/http/handler.rs @@ -39,6 +39,7 @@ use crate::http::csv_result::CsvResponse; use crate::http::error_result::ErrorResponse; use crate::http::greptime_result_v1::GreptimedbV1Response; use crate::http::influxdb_result_v1::InfluxdbV1Response; +use crate::http::json_result::JsonResponse; use crate::http::table_result::TableResponse; use crate::http::{ ApiState, Epoch, GreptimeOptionsConfigState, GreptimeQueryOutput, HttpRecordsOutput, @@ -138,6 +139,7 @@ pub async fn sql( ResponseFormat::Table => TableResponse::from_output(outputs).await, ResponseFormat::GreptimedbV1 => GreptimedbV1Response::from_output(outputs).await, ResponseFormat::InfluxdbV1 => InfluxdbV1Response::from_output(outputs, epoch).await, + ResponseFormat::Json => JsonResponse::from_output(outputs).await, }; if let Some(limit) = query_params.limit { diff --git a/src/servers/src/http/json_result.rs b/src/servers/src/http/json_result.rs new file mode 100644 index 0000000000..bf4e4d7770 --- /dev/null +++ b/src/servers/src/http/json_result.rs @@ -0,0 +1,137 @@ +// Copyright 2023 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use axum::http::{header, HeaderValue}; +use axum::response::{IntoResponse, Response}; +use common_error::status_code::StatusCode; +use common_query::Output; +use mime_guess::mime; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Map, Value}; + +use super::process_with_limit; +use crate::http::error_result::ErrorResponse; +use crate::http::header::{GREPTIME_DB_HEADER_EXECUTION_TIME, GREPTIME_DB_HEADER_FORMAT}; +use crate::http::{handler, GreptimeQueryOutput, HttpResponse, ResponseFormat}; + +/// The json format here is different from the default json output of `GreptimedbV1` result. +/// `JsonResponse` is intended to make it easier for user to consume data. +#[derive(Serialize, Deserialize, Debug, JsonSchema)] +pub struct JsonResponse { + output: Vec, + execution_time_ms: u64, +} + +impl JsonResponse { + pub async fn from_output(outputs: Vec>) -> HttpResponse { + match handler::from_output(outputs).await { + Err(err) => HttpResponse::Error(err), + Ok((output, _)) => { + if output.len() > 1 { + HttpResponse::Error(ErrorResponse::from_error_message( + StatusCode::InvalidArguments, + "cannot output multi-statements result in json format".to_string(), + )) + } else { + HttpResponse::Json(JsonResponse { + output, + execution_time_ms: 0, + }) + } + } + } + } + + pub fn output(&self) -> &[GreptimeQueryOutput] { + &self.output + } + + pub fn with_execution_time(mut self, execution_time: u64) -> Self { + self.execution_time_ms = execution_time; + self + } + + pub fn execution_time_ms(&self) -> u64 { + self.execution_time_ms + } + + pub fn with_limit(mut self, limit: usize) -> Self { + self.output = process_with_limit(self.output, limit); + self + } +} + +impl IntoResponse for JsonResponse { + fn into_response(mut self) -> Response { + debug_assert!( + self.output.len() <= 1, + "self.output has extra elements: {}", + self.output.len() + ); + + let execution_time = self.execution_time_ms; + let payload = match self.output.pop() { + None => String::default(), + Some(GreptimeQueryOutput::AffectedRows(n)) => json!({ + "data": [], + "affected_rows": n, + "execution_time_ms": execution_time, + }) + .to_string(), + + Some(GreptimeQueryOutput::Records(records)) => { + let schema = records.schema(); + + let data: Vec> = records + .rows + .iter() + .map(|row| { + schema + .column_schemas + .iter() + .enumerate() + .map(|(i, col)| (col.name.clone(), row[i].clone())) + .collect::>() + }) + .collect(); + + json!({ + "data": data, + "execution_time_ms": execution_time, + }) + .to_string() + } + }; + + ( + [ + ( + header::CONTENT_TYPE, + HeaderValue::from_static(mime::APPLICATION_JSON.as_ref()), + ), + ( + GREPTIME_DB_HEADER_FORMAT.clone(), + HeaderValue::from_static(ResponseFormat::Json.as_str()), + ), + ( + GREPTIME_DB_HEADER_EXECUTION_TIME.clone(), + HeaderValue::from(execution_time), + ), + ], + payload, + ) + .into_response() + } +} diff --git a/tests-integration/tests/http.rs b/tests-integration/tests/http.rs index f70df8176a..7a030aad56 100644 --- a/tests-integration/tests/http.rs +++ b/tests-integration/tests/http.rs @@ -182,6 +182,22 @@ pub async fn test_sql_api(store_type: StorageType) { })).unwrap() ); + // test json result format + let res = client + .get("/v1/sql?format=json&sql=select * from numbers limit 10") + .send() + .await; + assert_eq!(res.status(), StatusCode::OK); + + let body = res.json::().await; + let data = body.get("data").expect("Missing 'data' field in response"); + + let expected = json!([ + {"number": 0}, {"number": 1}, {"number": 2}, {"number": 3}, {"number": 4}, + {"number": 5}, {"number": 6}, {"number": 7}, {"number": 8}, {"number": 9} + ]); + assert_eq!(data, &expected); + // test insert and select let res = client .get("/v1/sql?sql=insert into demo values('host', 66.6, 1024, 0)") @@ -1307,7 +1323,7 @@ transform: .send() .await; assert_eq!(res.status(), StatusCode::OK); - let body: serde_json::Value = res.json().await; + let body: Value = res.json().await; let schema = &body["schema"]; let rows = &body["rows"]; assert_eq!( From a8ed3db0aa272396c5818d42303e263a8faf4be4 Mon Sep 17 00:00:00 2001 From: discord9 <55937128+discord9@users.noreply.github.com> Date: Wed, 9 Oct 2024 17:37:27 +0800 Subject: [PATCH 03/36] feat: Merge sort Logical plan (#4768) * feat(WIP): MergeSort * wip * feat: MergeSort LogicalPlan * update sqlness result * Apply suggestions from code review Co-authored-by: Lei, HUANG <6406592+v0y4g3r@users.noreply.github.com> * refactor: per review advice * refactor: more per review * chore: per review --------- Co-authored-by: Ruihang Xia Co-authored-by: Lei, HUANG <6406592+v0y4g3r@users.noreply.github.com> --- src/query/src/dist_plan.rs | 3 +- src/query/src/dist_plan/analyzer.rs | 4 +- src/query/src/dist_plan/commutativity.rs | 9 +- src/query/src/dist_plan/merge_scan.rs | 8 ++ src/query/src/dist_plan/merge_sort.rs | 124 ++++++++++++++++++ src/query/src/dist_plan/planner.rs | 62 ++++++++- src/query/src/query_engine/state.rs | 3 +- .../explain/multi_partitions.result | 2 +- .../standalone/common/order/order_by.result | 2 +- 9 files changed, 207 insertions(+), 10 deletions(-) create mode 100644 src/query/src/dist_plan/merge_sort.rs diff --git a/src/query/src/dist_plan.rs b/src/query/src/dist_plan.rs index 6ab93d4e1d..b2bad029c4 100644 --- a/src/query/src/dist_plan.rs +++ b/src/query/src/dist_plan.rs @@ -15,8 +15,9 @@ mod analyzer; mod commutativity; mod merge_scan; +mod merge_sort; mod planner; pub use analyzer::DistPlannerAnalyzer; pub use merge_scan::{MergeScanExec, MergeScanLogicalPlan}; -pub use planner::DistExtensionPlanner; +pub use planner::{DistExtensionPlanner, MergeSortExtensionPlanner}; diff --git a/src/query/src/dist_plan/analyzer.rs b/src/query/src/dist_plan/analyzer.rs index c182eee1cd..335c23c58a 100644 --- a/src/query/src/dist_plan/analyzer.rs +++ b/src/query/src/dist_plan/analyzer.rs @@ -160,7 +160,6 @@ impl PlanRewriter { { return true; } - match Categorizer::check_plan(plan, self.partition_cols.clone()) { Commutativity::Commutative => {} Commutativity::PartialCommutative => { @@ -265,9 +264,10 @@ impl PlanRewriter { // add merge scan as the new root let mut node = MergeScanLogicalPlan::new(on_node, false).into_logical_plan(); + // expand stages for new_stage in self.stage.drain(..) { - node = new_stage.with_new_exprs(new_stage.expressions(), vec![node.clone()])? + node = new_stage.with_new_exprs(new_stage.expressions(), vec![node.clone()])?; } self.set_expanded(); diff --git a/src/query/src/dist_plan/commutativity.rs b/src/query/src/dist_plan/commutativity.rs index c6b3ca2c62..8166400b8f 100644 --- a/src/query/src/dist_plan/commutativity.rs +++ b/src/query/src/dist_plan/commutativity.rs @@ -21,6 +21,7 @@ use promql::extension_plan::{ EmptyMetric, InstantManipulate, RangeManipulate, SeriesDivide, SeriesNormalize, }; +use crate::dist_plan::merge_sort::{merge_sort_transformer, MergeSortLogicalPlan}; use crate::dist_plan::MergeScanLogicalPlan; #[allow(dead_code)] @@ -68,8 +69,9 @@ impl Categorizer { } // sort plan needs to consider column priority - // We can implement a merge-sort on partial ordered data - Commutativity::PartialCommutative + // Change Sort to MergeSort which assumes the input streams are already sorted hence can be more efficient + // We should ensure the number of partition is not smaller than the number of region at present. Otherwise this would result in incorrect output. + Commutativity::ConditionalCommutative(Some(Arc::new(merge_sort_transformer))) } LogicalPlan::Join(_) => Commutativity::NonCommutative, LogicalPlan::CrossJoin(_) => Commutativity::NonCommutative, @@ -118,7 +120,8 @@ impl Categorizer { || name == SeriesNormalize::name() || name == RangeManipulate::name() || name == SeriesDivide::name() - || name == MergeScanLogicalPlan::name() => + || name == MergeScanLogicalPlan::name() + || name == MergeSortLogicalPlan::name() => { Commutativity::Unimplemented } diff --git a/src/query/src/dist_plan/merge_scan.rs b/src/query/src/dist_plan/merge_scan.rs index a3fb8004cf..8ed77eabd4 100644 --- a/src/query/src/dist_plan/merge_scan.rs +++ b/src/query/src/dist_plan/merge_scan.rs @@ -298,6 +298,14 @@ impl MergeScanExec { pub fn sub_stage_metrics(&self) -> Vec { self.sub_stage_metrics.lock().unwrap().clone() } + + pub fn partition_count(&self) -> usize { + self.target_partition + } + + pub fn region_count(&self) -> usize { + self.regions.len() + } } impl ExecutionPlan for MergeScanExec { diff --git a/src/query/src/dist_plan/merge_sort.rs b/src/query/src/dist_plan/merge_sort.rs new file mode 100644 index 0000000000..df0a9fda10 --- /dev/null +++ b/src/query/src/dist_plan/merge_sort.rs @@ -0,0 +1,124 @@ +// Copyright 2023 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Merge sort logical plan for distributed query execution, roughly corresponding to the +//! `SortPreservingMergeExec` operator in datafusion +//! + +use std::fmt; +use std::sync::Arc; + +use datafusion_common::{DataFusionError, Result}; +use datafusion_expr::{Expr, Extension, LogicalPlan, UserDefinedLogicalNodeCore}; + +/// MergeSort Logical Plan, have same field as `Sort`, but indicate it is a merge sort, +/// which assume each input partition is a sorted stream, and will use `SortPreserveingMergeExec` +/// to merge them into a single sorted stream. +#[derive(Hash, PartialEq, Eq, Clone)] +pub struct MergeSortLogicalPlan { + pub expr: Vec, + pub input: Arc, + pub fetch: Option, +} + +impl fmt::Debug for MergeSortLogicalPlan { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + UserDefinedLogicalNodeCore::fmt_for_explain(self, f) + } +} + +impl MergeSortLogicalPlan { + pub fn new(input: Arc, expr: Vec, fetch: Option) -> Self { + Self { input, expr, fetch } + } + + pub fn name() -> &'static str { + "MergeSort" + } + + /// Create a [`LogicalPlan::Extension`] node from this merge sort plan + pub fn into_logical_plan(self) -> LogicalPlan { + LogicalPlan::Extension(Extension { + node: Arc::new(self), + }) + } + + /// Convert self to a [`Sort`] logical plan with same input and expressions + pub fn into_sort(self) -> LogicalPlan { + LogicalPlan::Sort(datafusion::logical_expr::Sort { + input: self.input.clone(), + expr: self.expr, + fetch: self.fetch, + }) + } +} + +impl UserDefinedLogicalNodeCore for MergeSortLogicalPlan { + fn name(&self) -> &str { + Self::name() + } + + // Allow optimization here + fn inputs(&self) -> Vec<&LogicalPlan> { + vec![self.input.as_ref()] + } + + fn schema(&self) -> &datafusion_common::DFSchemaRef { + self.input.schema() + } + + // Allow further optimization + fn expressions(&self) -> Vec { + self.expr.clone() + } + + fn fmt_for_explain(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "MergeSort: ")?; + for (i, expr_item) in self.expr.iter().enumerate() { + if i > 0 { + write!(f, ", ")?; + } + write!(f, "{expr_item}")?; + } + if let Some(a) = self.fetch { + write!(f, ", fetch={a}")?; + } + Ok(()) + } + + fn with_exprs_and_inputs( + &self, + exprs: Vec, + mut inputs: Vec, + ) -> Result { + let mut zelf = self.clone(); + zelf.expr = exprs; + zelf.input = Arc::new(inputs.pop().ok_or_else(|| { + DataFusionError::Internal("Expected exactly one input with MergeSort".to_string()) + })?); + Ok(zelf) + } +} + +/// Turn `Sort` into `MergeSort` if possible +pub fn merge_sort_transformer(plan: &LogicalPlan) -> Option { + if let LogicalPlan::Sort(sort) = plan { + Some( + MergeSortLogicalPlan::new(sort.input.clone(), sort.expr.clone(), sort.fetch) + .into_logical_plan(), + ) + } else { + None + } +} diff --git a/src/query/src/dist_plan/planner.rs b/src/query/src/dist_plan/planner.rs index a94a798461..833ff1c9bc 100644 --- a/src/query/src/dist_plan/planner.rs +++ b/src/query/src/dist_plan/planner.rs @@ -25,7 +25,7 @@ use datafusion::execution::context::SessionState; use datafusion::physical_plan::ExecutionPlan; use datafusion::physical_planner::{ExtensionPlanner, PhysicalPlanner}; use datafusion_common::tree_node::{TreeNode, TreeNodeRecursion, TreeNodeVisitor}; -use datafusion_common::TableReference; +use datafusion_common::{DataFusionError, TableReference}; use datafusion_expr::{LogicalPlan, UserDefinedLogicalNode}; use session::context::QueryContext; use snafu::{OptionExt, ResultExt}; @@ -35,9 +35,69 @@ use table::table::adapter::DfTableProviderAdapter; use table::table_name::TableName; use crate::dist_plan::merge_scan::{MergeScanExec, MergeScanLogicalPlan}; +use crate::dist_plan::merge_sort::MergeSortLogicalPlan; use crate::error::{CatalogSnafu, TableNotFoundSnafu}; use crate::region_query::RegionQueryHandlerRef; +/// Planner for convert merge sort logical plan to physical plan +/// it is currently a fallback to sort, and doesn't change the execution plan: +/// `MergeSort(MergeScan) -> Sort(MergeScan) - to physical plan -> ...` +/// It should be applied after `DistExtensionPlanner` +/// +/// (Later when actually impl this merge sort) +/// +/// We should ensure the number of partition is not smaller than the number of region at present. Otherwise this would result in incorrect output. +pub struct MergeSortExtensionPlanner {} + +#[async_trait] +impl ExtensionPlanner for MergeSortExtensionPlanner { + async fn plan_extension( + &self, + planner: &dyn PhysicalPlanner, + node: &dyn UserDefinedLogicalNode, + _logical_inputs: &[&LogicalPlan], + physical_inputs: &[Arc], + session_state: &SessionState, + ) -> Result>> { + if let Some(merge_sort) = node.as_any().downcast_ref::() { + if let LogicalPlan::Extension(ext) = &merge_sort.input.as_ref() + && ext + .node + .as_any() + .downcast_ref::() + .is_some() + { + let merge_scan_exec = physical_inputs + .first() + .and_then(|p| p.as_any().downcast_ref::()) + .ok_or(DataFusionError::Internal(format!( + "Expect MergeSort's input is a MergeScanExec, found {:?}", + physical_inputs + )))?; + + let partition_cnt = merge_scan_exec.partition_count(); + let region_cnt = merge_scan_exec.region_count(); + // if partition >= region, we know that every partition stream of merge scan is ordered + // and we only need to do a merge sort, otherwise fallback to quick sort + let can_merge_sort = partition_cnt >= region_cnt; + if can_merge_sort { + // TODO(discord9): use `SortPreversingMergeExec here` + } + // for now merge sort only exist in logical plan, and have the same effect as `Sort` + // doesn't change the execution plan, this will change in the future + let ret = planner + .create_physical_plan(&merge_sort.clone().into_sort(), session_state) + .await?; + Ok(Some(ret)) + } else { + Ok(None) + } + } else { + Ok(None) + } + } +} + pub struct DistExtensionPlanner { catalog_manager: CatalogManagerRef, region_query_handler: RegionQueryHandlerRef, diff --git a/src/query/src/query_engine/state.rs b/src/query/src/query_engine/state.rs index f0e2ef53a5..97386e9b2d 100644 --- a/src/query/src/query_engine/state.rs +++ b/src/query/src/query_engine/state.rs @@ -42,7 +42,7 @@ use promql::extension_plan::PromExtensionPlanner; use table::table::adapter::DfTableProviderAdapter; use table::TableRef; -use crate::dist_plan::{DistExtensionPlanner, DistPlannerAnalyzer}; +use crate::dist_plan::{DistExtensionPlanner, DistPlannerAnalyzer, MergeSortExtensionPlanner}; use crate::optimizer::count_wildcard::CountWildcardToTimeIndexRule; use crate::optimizer::parallelize_scan::ParallelizeScan; use crate::optimizer::remove_duplicate::RemoveDuplicate; @@ -295,6 +295,7 @@ impl DfQueryPlanner { catalog_manager, region_query_handler, ))); + planners.push(Arc::new(MergeSortExtensionPlanner {})); } Self { physical_planner: DefaultPhysicalPlanner::with_extension_planners(planners), diff --git a/tests/cases/distributed/explain/multi_partitions.result b/tests/cases/distributed/explain/multi_partitions.result index 6bbb6abb8e..c06869d459 100644 --- a/tests/cases/distributed/explain/multi_partitions.result +++ b/tests/cases/distributed/explain/multi_partitions.result @@ -25,7 +25,7 @@ explain SELECT * FROM demo WHERE ts > cast(1000000000 as timestamp) ORDER BY hos +-+-+ | plan_type_| plan_| +-+-+ -| logical_plan_| Sort: demo.host ASC NULLS LAST_| +| logical_plan_| MergeSort: demo.host ASC NULLS LAST_| |_|_MergeScan [is_placeholder=false]_| | physical_plan | SortPreservingMergeExec: [host@0 ASC NULLS LAST]_| |_|_SortExec: expr=[host@0 ASC NULLS LAST], preserve_partitioning=[true]_| diff --git a/tests/cases/standalone/common/order/order_by.result b/tests/cases/standalone/common/order/order_by.result index f6385537c3..8cf92d9fbf 100644 --- a/tests/cases/standalone/common/order/order_by.result +++ b/tests/cases/standalone/common/order/order_by.result @@ -294,7 +294,7 @@ explain analyze select tag from t where num > 6 order by ts desc limit 2; +-+-+-+ | 0_| 0_|_GlobalLimitExec: skip=0, fetch=2 REDACTED |_|_|_SortPreservingMergeExec: [ts@1 DESC] REDACTED -|_|_|_SortExec: TopK(fetch=2), expr=[ts@1 DESC], preserve_partitioning=[true] REDACTED +|_|_|_SortExec: expr=[ts@1 DESC], preserve_partitioning=[true] REDACTED |_|_|_MergeScanExec: REDACTED |_|_|_| | 1_| 0_|_GlobalLimitExec: skip=0, fetch=2 REDACTED From 288fdc31453f7db461a6218328850bfc45081d39 Mon Sep 17 00:00:00 2001 From: Yohan Wal <59358312+CookiePieWw@users.noreply.github.com> Date: Thu, 10 Oct 2024 22:15:34 +0800 Subject: [PATCH 04/36] feat: json_path_exists udf (#4807) * feat: json_path_exists udf * chore: fix comments * fix: caution when copy&paste QAQ --- src/common/function/src/scalars/json.rs | 3 + .../src/scalars/json/json_path_exists.rs | 172 ++++++++++++++++++ .../common/function/json/json.result | 33 ++++ .../standalone/common/function/json/json.sql | 8 + 4 files changed, 216 insertions(+) create mode 100644 src/common/function/src/scalars/json/json_path_exists.rs create mode 100644 tests/cases/standalone/common/function/json/json.result create mode 100644 tests/cases/standalone/common/function/json/json.sql diff --git a/src/common/function/src/scalars/json.rs b/src/common/function/src/scalars/json.rs index 279577b495..133eb145a7 100644 --- a/src/common/function/src/scalars/json.rs +++ b/src/common/function/src/scalars/json.rs @@ -15,6 +15,7 @@ use std::sync::Arc; mod json_get; mod json_is; +mod json_path_exists; mod json_to_string; mod parse_json; @@ -46,5 +47,7 @@ impl JsonFunction { registry.register(Arc::new(JsonIsBool)); registry.register(Arc::new(JsonIsArray)); registry.register(Arc::new(JsonIsObject)); + + registry.register(Arc::new(json_path_exists::JsonPathExistsFunction)); } } diff --git a/src/common/function/src/scalars/json/json_path_exists.rs b/src/common/function/src/scalars/json/json_path_exists.rs new file mode 100644 index 0000000000..9254b5f396 --- /dev/null +++ b/src/common/function/src/scalars/json/json_path_exists.rs @@ -0,0 +1,172 @@ +// Copyright 2023 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::fmt::{self, Display}; + +use common_query::error::{InvalidFuncArgsSnafu, Result, UnsupportedInputDataTypeSnafu}; +use common_query::prelude::Signature; +use datafusion::logical_expr::Volatility; +use datatypes::data_type::ConcreteDataType; +use datatypes::prelude::VectorRef; +use datatypes::scalars::ScalarVectorBuilder; +use datatypes::vectors::{BooleanVectorBuilder, MutableVector}; +use snafu::ensure; + +use crate::function::{Function, FunctionContext}; + +/// Check if the given JSON data contains the given JSON path. +#[derive(Clone, Debug, Default)] +pub struct JsonPathExistsFunction; + +const NAME: &str = "json_path_exists"; + +impl Function for JsonPathExistsFunction { + fn name(&self) -> &str { + NAME + } + + fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result { + Ok(ConcreteDataType::boolean_datatype()) + } + + fn signature(&self) -> Signature { + Signature::exact( + vec![ + ConcreteDataType::json_datatype(), + ConcreteDataType::string_datatype(), + ], + Volatility::Immutable, + ) + } + + fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { + ensure!( + columns.len() == 2, + InvalidFuncArgsSnafu { + err_msg: format!( + "The length of the args is not correct, expect exactly two, have: {}", + columns.len() + ), + } + ); + let jsons = &columns[0]; + let paths = &columns[1]; + + let size = jsons.len(); + let datatype = jsons.data_type(); + let mut results = BooleanVectorBuilder::with_capacity(size); + + match datatype { + // JSON data type uses binary vector + ConcreteDataType::Binary(_) => { + for i in 0..size { + let json = jsons.get_ref(i); + let path = paths.get_ref(i); + + let json = json.as_binary(); + let path = path.as_string(); + let result = match (json, path) { + (Ok(Some(json)), Ok(Some(path))) => { + let json_path = jsonb::jsonpath::parse_json_path(path.as_bytes()); + match json_path { + Ok(json_path) => jsonb::path_exists(json, json_path).ok(), + Err(_) => None, + } + } + _ => None, + }; + + results.push(result); + } + } + _ => { + return UnsupportedInputDataTypeSnafu { + function: NAME, + datatypes: columns.iter().map(|c| c.data_type()).collect::>(), + } + .fail(); + } + } + + Ok(results.to_vector()) + } +} + +impl Display for JsonPathExistsFunction { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "JSON_PATH_EXISTS") + } +} + +#[cfg(test)] +mod tests { + use std::sync::Arc; + + use common_query::prelude::TypeSignature; + use datatypes::scalars::ScalarVector; + use datatypes::vectors::{BinaryVector, StringVector}; + + use super::*; + + #[test] + fn test_json_path_exists_function() { + let json_path_exists = JsonPathExistsFunction; + + assert_eq!("json_path_exists", json_path_exists.name()); + assert_eq!( + ConcreteDataType::boolean_datatype(), + json_path_exists + .return_type(&[ConcreteDataType::json_datatype()]) + .unwrap() + ); + + assert!(matches!(json_path_exists.signature(), + Signature { + type_signature: TypeSignature::Exact(valid_types), + volatility: Volatility::Immutable + } if valid_types == vec![ConcreteDataType::json_datatype(), ConcreteDataType::string_datatype()] + )); + + let json_strings = [ + r#"{"a": {"b": 2}, "b": 2, "c": 3}"#, + r#"{"a": 4, "b": {"c": 6}, "c": 6}"#, + r#"{"a": 7, "b": 8, "c": {"a": 7}}"#, + r#"{"a": 7, "b": 8, "c": {"a": 7}}"#, + ]; + let paths = vec!["$.a.b.c", "$.b", "$.c.a", ".d"]; + let results = [false, true, true, false]; + + let jsonbs = json_strings + .iter() + .map(|s| { + let value = jsonb::parse_value(s.as_bytes()).unwrap(); + value.to_vec() + }) + .collect::>(); + + let json_vector = BinaryVector::from_vec(jsonbs); + let path_vector = StringVector::from_vec(paths); + let args: Vec = vec![Arc::new(json_vector), Arc::new(path_vector)]; + let vector = json_path_exists + .eval(FunctionContext::default(), &args) + .unwrap(); + + assert_eq!(4, vector.len()); + for (i, gt) in results.iter().enumerate() { + let result = vector.get_ref(i); + let result = result.as_boolean().unwrap().unwrap(); + assert_eq!(*gt, result); + } + } +} diff --git a/tests/cases/standalone/common/function/json/json.result b/tests/cases/standalone/common/function/json/json.result new file mode 100644 index 0000000000..bae3313548 --- /dev/null +++ b/tests/cases/standalone/common/function/json/json.result @@ -0,0 +1,33 @@ +--- json_path_exists --- +SELECT json_path_exists(parse_json('{"a": 1, "b": 2}'), '$.a'); + ++--------------------------------------------------------------------+ +| json_path_exists(parse_json(Utf8("{"a": 1, "b": 2}")),Utf8("$.a")) | ++--------------------------------------------------------------------+ +| true | ++--------------------------------------------------------------------+ + +SELECT json_path_exists(parse_json('{"a": 1, "b": 2}'), '$.c'); + ++--------------------------------------------------------------------+ +| json_path_exists(parse_json(Utf8("{"a": 1, "b": 2}")),Utf8("$.c")) | ++--------------------------------------------------------------------+ +| false | ++--------------------------------------------------------------------+ + +SELECT json_path_exists(parse_json('[1, 2]'), '[0]'); + ++----------------------------------------------------------+ +| json_path_exists(parse_json(Utf8("[1, 2]")),Utf8("[0]")) | ++----------------------------------------------------------+ +| true | ++----------------------------------------------------------+ + +SELECT json_path_exists(parse_json('[1, 2]'), '[2]'); + ++----------------------------------------------------------+ +| json_path_exists(parse_json(Utf8("[1, 2]")),Utf8("[2]")) | ++----------------------------------------------------------+ +| false | ++----------------------------------------------------------+ + diff --git a/tests/cases/standalone/common/function/json/json.sql b/tests/cases/standalone/common/function/json/json.sql new file mode 100644 index 0000000000..76914e2575 --- /dev/null +++ b/tests/cases/standalone/common/function/json/json.sql @@ -0,0 +1,8 @@ +--- json_path_exists --- +SELECT json_path_exists(parse_json('{"a": 1, "b": 2}'), '$.a'); + +SELECT json_path_exists(parse_json('{"a": 1, "b": 2}'), '$.c'); + +SELECT json_path_exists(parse_json('[1, 2]'), '[0]'); + +SELECT json_path_exists(parse_json('[1, 2]'), '[2]'); From 695ff1e03713c554b50eb9f6245dbebc8decb91c Mon Sep 17 00:00:00 2001 From: Weny Xu Date: Fri, 11 Oct 2024 10:40:51 +0800 Subject: [PATCH 05/36] feat: expose `RegionMigrationManagerRef` (#4812) * chore: expose `RegionMigrationProcedureTask` * fix: fix typos * chore: expose `tracker` --- src/meta-srv/src/procedure/region_migration.rs | 6 ++++-- src/meta-srv/src/procedure/region_migration/manager.rs | 4 ++-- src/meta-srv/src/region/supervisor.rs | 8 ++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/meta-srv/src/procedure/region_migration.rs b/src/meta-srv/src/procedure/region_migration.rs index 9b5bdfc006..72b886418c 100644 --- a/src/meta-srv/src/procedure/region_migration.rs +++ b/src/meta-srv/src/procedure/region_migration.rs @@ -43,8 +43,10 @@ use common_procedure::error::{ Error as ProcedureError, FromJsonSnafu, Result as ProcedureResult, ToJsonSnafu, }; use common_procedure::{Context as ProcedureContext, LockKey, Procedure, Status, StringKey}; -pub use manager::RegionMigrationProcedureTask; -use manager::{RegionMigrationProcedureGuard, RegionMigrationProcedureTracker}; +use manager::RegionMigrationProcedureGuard; +pub use manager::{ + RegionMigrationManagerRef, RegionMigrationProcedureTask, RegionMigrationProcedureTracker, +}; use serde::{Deserialize, Serialize}; use snafu::{OptionExt, ResultExt}; use store_api::storage::RegionId; diff --git a/src/meta-srv/src/procedure/region_migration/manager.rs b/src/meta-srv/src/procedure/region_migration/manager.rs index 01ea887ca9..1059c1794a 100644 --- a/src/meta-srv/src/procedure/region_migration/manager.rs +++ b/src/meta-srv/src/procedure/region_migration/manager.rs @@ -44,7 +44,7 @@ pub struct RegionMigrationManager { } #[derive(Default, Clone)] -pub(crate) struct RegionMigrationProcedureTracker { +pub struct RegionMigrationProcedureTracker { running_procedures: Arc>>, } @@ -149,7 +149,7 @@ impl RegionMigrationManager { } /// Returns the [`RegionMigrationProcedureTracker`]. - pub(crate) fn tracker(&self) -> &RegionMigrationProcedureTracker { + pub fn tracker(&self) -> &RegionMigrationProcedureTracker { &self.tracker } diff --git a/src/meta-srv/src/region/supervisor.rs b/src/meta-srv/src/region/supervisor.rs index 8367acbb26..80f6c84865 100644 --- a/src/meta-srv/src/region/supervisor.rs +++ b/src/meta-srv/src/region/supervisor.rs @@ -223,7 +223,7 @@ impl RegionFailureDetectorController for RegionFailureDetectorControl { .send(Event::RegisterFailureDetectors(detecting_regions)) .await { - error!(err; "RegionSupervisor is stop receiving heartbeat"); + error!(err; "RegionSupervisor has stop receiving heartbeat."); } } @@ -233,7 +233,7 @@ impl RegionFailureDetectorController for RegionFailureDetectorControl { .send(Event::DeregisterFailureDetectors(detecting_regions)) .await { - error!(err; "RegionSupervisor is stop receiving heartbeat"); + error!(err; "RegionSupervisor has stop receiving heartbeat."); } } } @@ -251,13 +251,13 @@ impl HeartbeatAcceptor { /// Accepts heartbeats from datanodes. pub(crate) async fn accept(&self, heartbeat: DatanodeHeartbeat) { if let Err(err) = self.sender.send(Event::HeartbeatArrived(heartbeat)).await { - error!(err; "RegionSupervisor is stop receiving heartbeat"); + error!(err; "RegionSupervisor has stop receiving heartbeat."); } } } impl RegionSupervisor { - /// Returns a a mpsc channel with a buffer capacity of 1024 for sending and receiving `Event` messages. + /// Returns a mpsc channel with a buffer capacity of 1024 for sending and receiving `Event` messages. pub(crate) fn channel() -> (Sender, Receiver) { tokio::sync::mpsc::channel(1024) } From 4b34f610aa35d8847c7d713cd7bb588e571f5df3 Mon Sep 17 00:00:00 2001 From: jeremyhi Date: Fri, 11 Oct 2024 11:13:49 +0800 Subject: [PATCH 06/36] feat: information extension (#4811) * feat: information extension * Update manager.rs Co-authored-by: Weny Xu * chore: by comment --------- Co-authored-by: Weny Xu --- src/catalog/src/error.rs | 7 +- src/catalog/src/kvbackend/manager.rs | 26 ++-- .../src/system_schema/information_schema.rs | 42 ++++++- .../information_schema/cluster_info.rs | 69 ++--------- .../information_schema/procedure_info.rs | 83 ++----------- .../information_schema/region_statistics.rs | 30 +---- src/catalog/src/system_schema/utils.rs | 55 ++------- src/catalog/src/table_source.rs | 6 +- src/cmd/src/cli/repl.rs | 6 +- src/cmd/src/flownode.rs | 7 +- src/cmd/src/frontend.rs | 8 +- src/cmd/src/lib.rs | 76 ++++++++++++ src/cmd/src/standalone.rs | 112 ++++++++++++++++-- tests-integration/src/cluster.rs | 6 +- tests-integration/src/standalone.rs | 4 +- 15 files changed, 284 insertions(+), 253 deletions(-) diff --git a/src/catalog/src/error.rs b/src/catalog/src/error.rs index dd7071b095..0d9e96ab6a 100644 --- a/src/catalog/src/error.rs +++ b/src/catalog/src/error.rs @@ -89,9 +89,8 @@ pub enum Error { location: Location, }, - #[snafu(display("Failed to get procedure client in {mode} mode"))] - GetProcedureClient { - mode: String, + #[snafu(display("Failed to get information extension client"))] + GetInformationExtension { #[snafu(implicit)] location: Location, }, @@ -301,7 +300,7 @@ impl ErrorExt for Error { | Error::CacheNotFound { .. } | Error::CastManager { .. } | Error::Json { .. } - | Error::GetProcedureClient { .. } + | Error::GetInformationExtension { .. } | Error::ProcedureIdNotFound { .. } => StatusCode::Unexpected, Error::ViewPlanColumnsChanged { .. } => StatusCode::InvalidArguments, diff --git a/src/catalog/src/kvbackend/manager.rs b/src/catalog/src/kvbackend/manager.rs index e3377afbe1..ca20805d37 100644 --- a/src/catalog/src/kvbackend/manager.rs +++ b/src/catalog/src/kvbackend/manager.rs @@ -21,7 +21,6 @@ use common_catalog::consts::{ DEFAULT_CATALOG_NAME, DEFAULT_SCHEMA_NAME, INFORMATION_SCHEMA_NAME, NUMBERS_TABLE_ID, PG_CATALOG_NAME, }; -use common_config::Mode; use common_error::ext::BoxedError; use common_meta::cache::{LayeredCacheRegistryRef, ViewInfoCacheRef}; use common_meta::key::catalog_name::CatalogNameKey; @@ -34,7 +33,6 @@ use common_meta::kv_backend::KvBackendRef; use common_procedure::ProcedureManagerRef; use futures_util::stream::BoxStream; use futures_util::{StreamExt, TryStreamExt}; -use meta_client::client::MetaClient; use moka::sync::Cache; use partition::manager::{PartitionRuleManager, PartitionRuleManagerRef}; use session::context::{Channel, QueryContext}; @@ -50,7 +48,7 @@ use crate::error::{ CacheNotFoundSnafu, GetTableCacheSnafu, InvalidTableInfoInCatalogSnafu, ListCatalogsSnafu, ListSchemasSnafu, ListTablesSnafu, Result, TableMetadataManagerSnafu, }; -use crate::information_schema::InformationSchemaProvider; +use crate::information_schema::{InformationExtensionRef, InformationSchemaProvider}; use crate::kvbackend::TableCacheRef; use crate::system_schema::pg_catalog::PGCatalogProvider; use crate::system_schema::SystemSchemaProvider; @@ -63,9 +61,8 @@ use crate::CatalogManager; /// comes from `SystemCatalog`, which is static and read-only. #[derive(Clone)] pub struct KvBackendCatalogManager { - mode: Mode, - /// Only available in `Distributed` mode. - meta_client: Option>, + /// Provides the extension methods for the `information_schema` tables + information_extension: InformationExtensionRef, /// Manages partition rules. partition_manager: PartitionRuleManagerRef, /// Manages table metadata. @@ -82,15 +79,13 @@ const CATALOG_CACHE_MAX_CAPACITY: u64 = 128; impl KvBackendCatalogManager { pub fn new( - mode: Mode, - meta_client: Option>, + information_extension: InformationExtensionRef, backend: KvBackendRef, cache_registry: LayeredCacheRegistryRef, procedure_manager: Option, ) -> Arc { Arc::new_cyclic(|me| Self { - mode, - meta_client, + information_extension, partition_manager: Arc::new(PartitionRuleManager::new( backend.clone(), cache_registry @@ -118,20 +113,15 @@ impl KvBackendCatalogManager { }) } - /// Returns the server running mode. - pub fn running_mode(&self) -> &Mode { - &self.mode - } - pub fn view_info_cache(&self) -> Result { self.cache_registry.get().context(CacheNotFoundSnafu { name: "view_info_cache", }) } - /// Returns the `[MetaClient]`. - pub fn meta_client(&self) -> Option> { - self.meta_client.clone() + /// Returns the [`InformationExtension`]. + pub fn information_extension(&self) -> InformationExtensionRef { + self.information_extension.clone() } pub fn partition_manager(&self) -> PartitionRuleManagerRef { diff --git a/src/catalog/src/system_schema/information_schema.rs b/src/catalog/src/system_schema/information_schema.rs index 9fa31b85fd..4101887cb4 100644 --- a/src/catalog/src/system_schema/information_schema.rs +++ b/src/catalog/src/system_schema/information_schema.rs @@ -32,7 +32,11 @@ use std::collections::HashMap; use std::sync::{Arc, Weak}; use common_catalog::consts::{self, DEFAULT_CATALOG_NAME, INFORMATION_SCHEMA_NAME}; +use common_error::ext::ErrorExt; +use common_meta::cluster::NodeInfo; +use common_meta::datanode::RegionStat; use common_meta::key::flow::FlowMetadataManager; +use common_procedure::ProcedureInfo; use common_recordbatch::SendableRecordBatchStream; use datatypes::schema::SchemaRef; use lazy_static::lazy_static; @@ -45,7 +49,7 @@ use views::InformationSchemaViews; use self::columns::InformationSchemaColumns; use super::{SystemSchemaProviderInner, SystemTable, SystemTableRef}; -use crate::error::Result; +use crate::error::{Error, Result}; use crate::system_schema::information_schema::cluster_info::InformationSchemaClusterInfo; use crate::system_schema::information_schema::flows::InformationSchemaFlows; use crate::system_schema::information_schema::information_memory_table::get_schema_columns; @@ -318,3 +322,39 @@ where InformationTable::to_stream(self, request) } } + +pub type InformationExtensionRef = Arc + Send + Sync>; + +/// The `InformationExtension` trait provides the extension methods for the `information_schema` tables. +#[async_trait::async_trait] +pub trait InformationExtension { + type Error: ErrorExt; + + /// Gets the nodes information. + async fn nodes(&self) -> std::result::Result, Self::Error>; + + /// Gets the procedures information. + async fn procedures(&self) -> std::result::Result, Self::Error>; + + /// Gets the region statistics. + async fn region_stats(&self) -> std::result::Result, Self::Error>; +} + +pub struct NoopInformationExtension; + +#[async_trait::async_trait] +impl InformationExtension for NoopInformationExtension { + type Error = Error; + + async fn nodes(&self) -> std::result::Result, Self::Error> { + Ok(vec![]) + } + + async fn procedures(&self) -> std::result::Result, Self::Error> { + Ok(vec![]) + } + + async fn region_stats(&self) -> std::result::Result, Self::Error> { + Ok(vec![]) + } +} diff --git a/src/catalog/src/system_schema/information_schema/cluster_info.rs b/src/catalog/src/system_schema/information_schema/cluster_info.rs index e85e210304..1ab700497c 100644 --- a/src/catalog/src/system_schema/information_schema/cluster_info.rs +++ b/src/catalog/src/system_schema/information_schema/cluster_info.rs @@ -17,13 +17,10 @@ use std::time::Duration; use arrow_schema::SchemaRef as ArrowSchemaRef; use common_catalog::consts::INFORMATION_SCHEMA_CLUSTER_INFO_TABLE_ID; -use common_config::Mode; use common_error::ext::BoxedError; -use common_meta::cluster::{ClusterInfo, NodeInfo, NodeStatus}; -use common_meta::peer::Peer; +use common_meta::cluster::NodeInfo; use common_recordbatch::adapter::RecordBatchStreamAdapter; use common_recordbatch::{RecordBatch, SendableRecordBatchStream}; -use common_telemetry::warn; use common_time::timestamp::Timestamp; use datafusion::execution::TaskContext; use datafusion::physical_plan::stream::RecordBatchStreamAdapter as DfRecordBatchStreamAdapter; @@ -40,7 +37,7 @@ use snafu::ResultExt; use store_api::storage::{ScanRequest, TableId}; use super::CLUSTER_INFO; -use crate::error::{CreateRecordBatchSnafu, InternalSnafu, ListNodesSnafu, Result}; +use crate::error::{CreateRecordBatchSnafu, InternalSnafu, Result}; use crate::system_schema::information_schema::{InformationTable, Predicates}; use crate::system_schema::utils; use crate::CatalogManager; @@ -70,7 +67,6 @@ const INIT_CAPACITY: usize = 42; pub(super) struct InformationSchemaClusterInfo { schema: SchemaRef, catalog_manager: Weak, - start_time_ms: u64, } impl InformationSchemaClusterInfo { @@ -78,7 +74,6 @@ impl InformationSchemaClusterInfo { Self { schema: Self::schema(), catalog_manager, - start_time_ms: common_time::util::current_time_millis() as u64, } } @@ -100,11 +95,7 @@ impl InformationSchemaClusterInfo { } fn builder(&self) -> InformationSchemaClusterInfoBuilder { - InformationSchemaClusterInfoBuilder::new( - self.schema.clone(), - self.catalog_manager.clone(), - self.start_time_ms, - ) + InformationSchemaClusterInfoBuilder::new(self.schema.clone(), self.catalog_manager.clone()) } } @@ -144,7 +135,6 @@ impl InformationTable for InformationSchemaClusterInfo { struct InformationSchemaClusterInfoBuilder { schema: SchemaRef, - start_time_ms: u64, catalog_manager: Weak, peer_ids: Int64VectorBuilder, @@ -158,11 +148,7 @@ struct InformationSchemaClusterInfoBuilder { } impl InformationSchemaClusterInfoBuilder { - fn new( - schema: SchemaRef, - catalog_manager: Weak, - start_time_ms: u64, - ) -> Self { + fn new(schema: SchemaRef, catalog_manager: Weak) -> Self { Self { schema, catalog_manager, @@ -174,56 +160,17 @@ impl InformationSchemaClusterInfoBuilder { start_times: TimestampMillisecondVectorBuilder::with_capacity(INIT_CAPACITY), uptimes: StringVectorBuilder::with_capacity(INIT_CAPACITY), active_times: StringVectorBuilder::with_capacity(INIT_CAPACITY), - start_time_ms, } } /// Construct the `information_schema.cluster_info` virtual table async fn make_cluster_info(&mut self, request: Option) -> Result { let predicates = Predicates::from_scan_request(&request); - let mode = utils::running_mode(&self.catalog_manager)?.unwrap_or(Mode::Standalone); - - match mode { - Mode::Standalone => { - let build_info = common_version::build_info(); - - self.add_node_info( - &predicates, - NodeInfo { - // For the standalone: - // - id always 0 - // - empty string for peer_addr - peer: Peer { - id: 0, - addr: "".to_string(), - }, - last_activity_ts: -1, - status: NodeStatus::Standalone, - version: build_info.version.to_string(), - git_commit: build_info.commit_short.to_string(), - // Use `self.start_time_ms` instead. - // It's not precise but enough. - start_time_ms: self.start_time_ms, - }, - ); - } - Mode::Distributed => { - if let Some(meta_client) = utils::meta_client(&self.catalog_manager)? { - let node_infos = meta_client - .list_nodes(None) - .await - .map_err(BoxedError::new) - .context(ListNodesSnafu)?; - - for node_info in node_infos { - self.add_node_info(&predicates, node_info); - } - } else { - warn!("Could not find meta client in distributed mode."); - } - } + let information_extension = utils::information_extension(&self.catalog_manager)?; + let node_infos = information_extension.nodes().await?; + for node_info in node_infos { + self.add_node_info(&predicates, node_info); } - self.finish() } diff --git a/src/catalog/src/system_schema/information_schema/procedure_info.rs b/src/catalog/src/system_schema/information_schema/procedure_info.rs index 56c36c2210..6e3c0b1f46 100644 --- a/src/catalog/src/system_schema/information_schema/procedure_info.rs +++ b/src/catalog/src/system_schema/information_schema/procedure_info.rs @@ -14,14 +14,10 @@ use std::sync::{Arc, Weak}; -use api::v1::meta::{ProcedureMeta, ProcedureStatus}; use arrow_schema::SchemaRef as ArrowSchemaRef; use common_catalog::consts::INFORMATION_SCHEMA_PROCEDURE_INFO_TABLE_ID; -use common_config::Mode; use common_error::ext::BoxedError; -use common_meta::ddl::{ExecutorContext, ProcedureExecutor}; -use common_meta::rpc::procedure; -use common_procedure::{ProcedureInfo, ProcedureState}; +use common_procedure::ProcedureInfo; use common_recordbatch::adapter::RecordBatchStreamAdapter; use common_recordbatch::{RecordBatch, SendableRecordBatchStream}; use common_time::timestamp::Timestamp; @@ -38,10 +34,7 @@ use snafu::ResultExt; use store_api::storage::{ScanRequest, TableId}; use super::PROCEDURE_INFO; -use crate::error::{ - ConvertProtoDataSnafu, CreateRecordBatchSnafu, GetProcedureClientSnafu, InternalSnafu, - ListProceduresSnafu, ProcedureIdNotFoundSnafu, Result, -}; +use crate::error::{CreateRecordBatchSnafu, InternalSnafu, Result}; use crate::system_schema::information_schema::{InformationTable, Predicates}; use crate::system_schema::utils; use crate::CatalogManager; @@ -167,45 +160,11 @@ impl InformationSchemaProcedureInfoBuilder { /// Construct the `information_schema.procedure_info` virtual table async fn make_procedure_info(&mut self, request: Option) -> Result { let predicates = Predicates::from_scan_request(&request); - let mode = utils::running_mode(&self.catalog_manager)?.unwrap_or(Mode::Standalone); - match mode { - Mode::Standalone => { - if let Some(procedure_manager) = utils::procedure_manager(&self.catalog_manager)? { - let procedures = procedure_manager - .list_procedures() - .await - .map_err(BoxedError::new) - .context(ListProceduresSnafu)?; - for procedure in procedures { - self.add_procedure( - &predicates, - procedure.state.as_str_name().to_string(), - procedure, - ); - } - } else { - return GetProcedureClientSnafu { mode: "standalone" }.fail(); - } - } - Mode::Distributed => { - if let Some(meta_client) = utils::meta_client(&self.catalog_manager)? { - let procedures = meta_client - .list_procedures(&ExecutorContext::default()) - .await - .map_err(BoxedError::new) - .context(ListProceduresSnafu)?; - for procedure in procedures.procedures { - self.add_procedure_info(&predicates, procedure)?; - } - } else { - return GetProcedureClientSnafu { - mode: "distributed", - } - .fail(); - } - } - }; - + let information_extension = utils::information_extension(&self.catalog_manager)?; + let procedures = information_extension.procedures().await?; + for (status, procedure_info) in procedures { + self.add_procedure(&predicates, status, procedure_info); + } self.finish() } @@ -247,34 +206,6 @@ impl InformationSchemaProcedureInfoBuilder { self.lock_keys.push(Some(&lock_keys)); } - fn add_procedure_info( - &mut self, - predicates: &Predicates, - procedure: ProcedureMeta, - ) -> Result<()> { - let pid = match procedure.id { - Some(pid) => pid, - None => return ProcedureIdNotFoundSnafu {}.fail(), - }; - let pid = procedure::pb_pid_to_pid(&pid) - .map_err(BoxedError::new) - .context(ConvertProtoDataSnafu)?; - let status = ProcedureStatus::try_from(procedure.status) - .map(|v| v.as_str_name()) - .unwrap_or("Unknown") - .to_string(); - let procedure_info = ProcedureInfo { - id: pid, - type_name: procedure.type_name, - start_time_ms: procedure.start_time_ms, - end_time_ms: procedure.end_time_ms, - state: ProcedureState::Running, - lock_keys: procedure.lock_keys, - }; - self.add_procedure(predicates, status, procedure_info); - Ok(()) - } - fn finish(&mut self) -> Result { let columns: Vec = vec![ Arc::new(self.procedure_ids.finish()), diff --git a/src/catalog/src/system_schema/information_schema/region_statistics.rs b/src/catalog/src/system_schema/information_schema/region_statistics.rs index 07b94ede54..e92558acd0 100644 --- a/src/catalog/src/system_schema/information_schema/region_statistics.rs +++ b/src/catalog/src/system_schema/information_schema/region_statistics.rs @@ -16,13 +16,10 @@ use std::sync::{Arc, Weak}; use arrow_schema::SchemaRef as ArrowSchemaRef; use common_catalog::consts::INFORMATION_SCHEMA_REGION_STATISTICS_TABLE_ID; -use common_config::Mode; use common_error::ext::BoxedError; -use common_meta::cluster::ClusterInfo; use common_meta::datanode::RegionStat; use common_recordbatch::adapter::RecordBatchStreamAdapter; use common_recordbatch::{DfSendableRecordBatchStream, RecordBatch, SendableRecordBatchStream}; -use common_telemetry::tracing::warn; use datafusion::execution::TaskContext; use datafusion::physical_plan::stream::RecordBatchStreamAdapter as DfRecordBatchStreamAdapter; use datafusion::physical_plan::streaming::PartitionStream as DfPartitionStream; @@ -34,7 +31,7 @@ use snafu::ResultExt; use store_api::storage::{ScanRequest, TableId}; use super::{InformationTable, REGION_STATISTICS}; -use crate::error::{CreateRecordBatchSnafu, InternalSnafu, ListRegionStatsSnafu, Result}; +use crate::error::{CreateRecordBatchSnafu, InternalSnafu, Result}; use crate::information_schema::Predicates; use crate::system_schema::utils; use crate::CatalogManager; @@ -167,28 +164,11 @@ impl InformationSchemaRegionStatisticsBuilder { request: Option, ) -> Result { let predicates = Predicates::from_scan_request(&request); - let mode = utils::running_mode(&self.catalog_manager)?.unwrap_or(Mode::Standalone); - - match mode { - Mode::Standalone => { - // TODO(weny): implement it - } - Mode::Distributed => { - if let Some(meta_client) = utils::meta_client(&self.catalog_manager)? { - let region_stats = meta_client - .list_region_stats() - .await - .map_err(BoxedError::new) - .context(ListRegionStatsSnafu)?; - for region_stat in region_stats { - self.add_region_statistic(&predicates, region_stat); - } - } else { - warn!("Meta client is not available"); - } - } + let information_extension = utils::information_extension(&self.catalog_manager)?; + let region_stats = information_extension.region_stats().await?; + for region_stat in region_stats { + self.add_region_statistic(&predicates, region_stat); } - self.finish() } diff --git a/src/catalog/src/system_schema/utils.rs b/src/catalog/src/system_schema/utils.rs index b9786bc260..8d8af84bf0 100644 --- a/src/catalog/src/system_schema/utils.rs +++ b/src/catalog/src/system_schema/utils.rs @@ -12,48 +12,33 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub mod tables; +use std::sync::Weak; -use std::sync::{Arc, Weak}; - -use common_config::Mode; use common_meta::key::TableMetadataManagerRef; -use common_procedure::ProcedureManagerRef; -use meta_client::client::MetaClient; use snafu::OptionExt; -use crate::error::{Result, UpgradeWeakCatalogManagerRefSnafu}; +use crate::error::{GetInformationExtensionSnafu, Result, UpgradeWeakCatalogManagerRefSnafu}; +use crate::information_schema::InformationExtensionRef; use crate::kvbackend::KvBackendCatalogManager; use crate::CatalogManager; -/// Try to get the server running mode from `[CatalogManager]` weak reference. -pub fn running_mode(catalog_manager: &Weak) -> Result> { +pub mod tables; + +/// Try to get the `[InformationExtension]` from `[CatalogManager]` weak reference. +pub fn information_extension( + catalog_manager: &Weak, +) -> Result { let catalog_manager = catalog_manager .upgrade() .context(UpgradeWeakCatalogManagerRefSnafu)?; - Ok(catalog_manager + let information_extension = catalog_manager .as_any() .downcast_ref::() - .map(|manager| manager.running_mode()) - .copied()) -} + .map(|manager| manager.information_extension()) + .context(GetInformationExtensionSnafu)?; -/// Try to get the `[MetaClient]` from `[CatalogManager]` weak reference. -pub fn meta_client(catalog_manager: &Weak) -> Result>> { - let catalog_manager = catalog_manager - .upgrade() - .context(UpgradeWeakCatalogManagerRefSnafu)?; - - let meta_client = match catalog_manager - .as_any() - .downcast_ref::() - { - None => None, - Some(manager) => manager.meta_client(), - }; - - Ok(meta_client) + Ok(information_extension) } /// Try to get the `[TableMetadataManagerRef]` from `[CatalogManager]` weak reference. @@ -69,17 +54,3 @@ pub fn table_meta_manager( .downcast_ref::() .map(|manager| manager.table_metadata_manager_ref().clone())) } - -/// Try to get the `[ProcedureManagerRef]` from `[CatalogManager]` weak reference. -pub fn procedure_manager( - catalog_manager: &Weak, -) -> Result> { - let catalog_manager = catalog_manager - .upgrade() - .context(UpgradeWeakCatalogManagerRefSnafu)?; - - Ok(catalog_manager - .as_any() - .downcast_ref::() - .and_then(|manager| manager.procedure_manager())) -} diff --git a/src/catalog/src/table_source.rs b/src/catalog/src/table_source.rs index 09d3d9d2fd..ca9c5b89d3 100644 --- a/src/catalog/src/table_source.rs +++ b/src/catalog/src/table_source.rs @@ -259,7 +259,6 @@ mod tests { use arrow::datatypes::{DataType, Field, Schema, SchemaRef}; use cache::{build_fundamental_cache_registry, with_default_composite_cache_registry}; - use common_config::Mode; use common_meta::cache::{CacheRegistryBuilder, LayeredCacheRegistryBuilder}; use common_meta::key::TableMetadataManager; use common_meta::kv_backend::memory::MemoryKvBackend; @@ -269,6 +268,8 @@ mod tests { use datafusion::logical_expr::builder::LogicalTableSource; use datafusion::logical_expr::{col, lit, LogicalPlan, LogicalPlanBuilder}; + use crate::information_schema::NoopInformationExtension; + struct MockDecoder; impl MockDecoder { pub fn arc() -> Arc { @@ -323,8 +324,7 @@ mod tests { ); let catalog_manager = KvBackendCatalogManager::new( - Mode::Standalone, - None, + Arc::new(NoopInformationExtension), backend.clone(), layered_cache_registry, None, diff --git a/src/cmd/src/cli/repl.rs b/src/cmd/src/cli/repl.rs index b55b1c44d6..0138471227 100644 --- a/src/cmd/src/cli/repl.rs +++ b/src/cmd/src/cli/repl.rs @@ -46,12 +46,12 @@ use substrait::{DFLogicalSubstraitConvertor, SubstraitPlan}; use crate::cli::cmd::ReplCommand; use crate::cli::helper::RustylineHelper; use crate::cli::AttachCommand; -use crate::error; use crate::error::{ CollectRecordBatchesSnafu, ParseSqlSnafu, PlanStatementSnafu, PrettyPrintRecordBatchesSnafu, ReadlineSnafu, ReplCreationSnafu, RequestDatabaseSnafu, Result, StartMetaClientSnafu, SubstraitEncodeLogicalPlanSnafu, }; +use crate::{error, DistributedInformationExtension}; /// Captures the state of the repl, gathers commands and executes them one by one pub struct Repl { @@ -275,9 +275,9 @@ async fn create_query_engine(meta_addr: &str) -> Result { .build(), ); + let information_extension = Arc::new(DistributedInformationExtension::new(meta_client.clone())); let catalog_manager = KvBackendCatalogManager::new( - Mode::Distributed, - Some(meta_client.clone()), + information_extension, cached_meta_backend.clone(), layered_cache_registry, None, diff --git a/src/cmd/src/flownode.rs b/src/cmd/src/flownode.rs index 78dfc90607..d2a8454085 100644 --- a/src/cmd/src/flownode.rs +++ b/src/cmd/src/flownode.rs @@ -41,7 +41,7 @@ use crate::error::{ MissingConfigSnafu, Result, ShutdownFlownodeSnafu, StartFlownodeSnafu, }; use crate::options::{GlobalOptions, GreptimeOptions}; -use crate::{log_versions, App}; +use crate::{log_versions, App, DistributedInformationExtension}; pub const APP_NAME: &str = "greptime-flownode"; @@ -269,9 +269,10 @@ impl StartCommand { .build(), ); + let information_extension = + Arc::new(DistributedInformationExtension::new(meta_client.clone())); let catalog_manager = KvBackendCatalogManager::new( - opts.mode, - Some(meta_client.clone()), + information_extension, cached_meta_backend.clone(), layered_cache_registry.clone(), None, diff --git a/src/cmd/src/frontend.rs b/src/cmd/src/frontend.rs index 7678e90c88..2f10b722c7 100644 --- a/src/cmd/src/frontend.rs +++ b/src/cmd/src/frontend.rs @@ -38,7 +38,6 @@ use frontend::server::Services; use meta_client::{MetaClientOptions, MetaClientType}; use query::stats::StatementStatistics; use servers::tls::{TlsMode, TlsOption}; -use servers::Mode; use snafu::{OptionExt, ResultExt}; use tracing_appender::non_blocking::WorkerGuard; @@ -47,7 +46,7 @@ use crate::error::{ Result, StartFrontendSnafu, }; use crate::options::{GlobalOptions, GreptimeOptions}; -use crate::{log_versions, App}; +use crate::{log_versions, App, DistributedInformationExtension}; type FrontendOptions = GreptimeOptions; @@ -316,9 +315,10 @@ impl StartCommand { .build(), ); + let information_extension = + Arc::new(DistributedInformationExtension::new(meta_client.clone())); let catalog_manager = KvBackendCatalogManager::new( - Mode::Distributed, - Some(meta_client.clone()), + information_extension, cached_meta_backend.clone(), layered_cache_registry.clone(), None, diff --git a/src/cmd/src/lib.rs b/src/cmd/src/lib.rs index 5797ef5a85..80e1628bc0 100644 --- a/src/cmd/src/lib.rs +++ b/src/cmd/src/lib.rs @@ -15,7 +15,17 @@ #![feature(assert_matches, let_chains)] use async_trait::async_trait; +use catalog::information_schema::InformationExtension; +use client::api::v1::meta::ProcedureStatus; +use common_error::ext::BoxedError; +use common_meta::cluster::{ClusterInfo, NodeInfo}; +use common_meta::datanode::RegionStat; +use common_meta::ddl::{ExecutorContext, ProcedureExecutor}; +use common_meta::rpc::procedure; +use common_procedure::{ProcedureInfo, ProcedureState}; use common_telemetry::{error, info}; +use meta_client::MetaClientRef; +use snafu::ResultExt; use crate::error::Result; @@ -94,3 +104,69 @@ fn log_env_flags() { info!("argument: {}", argument); } } + +pub struct DistributedInformationExtension { + meta_client: MetaClientRef, +} + +impl DistributedInformationExtension { + pub fn new(meta_client: MetaClientRef) -> Self { + Self { meta_client } + } +} + +#[async_trait::async_trait] +impl InformationExtension for DistributedInformationExtension { + type Error = catalog::error::Error; + + async fn nodes(&self) -> std::result::Result, Self::Error> { + self.meta_client + .list_nodes(None) + .await + .map_err(BoxedError::new) + .context(catalog::error::ListNodesSnafu) + } + + async fn procedures(&self) -> std::result::Result, Self::Error> { + let procedures = self + .meta_client + .list_procedures(&ExecutorContext::default()) + .await + .map_err(BoxedError::new) + .context(catalog::error::ListProceduresSnafu)? + .procedures; + let mut result = Vec::with_capacity(procedures.len()); + for procedure in procedures { + let pid = match procedure.id { + Some(pid) => pid, + None => return catalog::error::ProcedureIdNotFoundSnafu {}.fail(), + }; + let pid = procedure::pb_pid_to_pid(&pid) + .map_err(BoxedError::new) + .context(catalog::error::ConvertProtoDataSnafu)?; + let status = ProcedureStatus::try_from(procedure.status) + .map(|v| v.as_str_name()) + .unwrap_or("Unknown") + .to_string(); + let procedure_info = ProcedureInfo { + id: pid, + type_name: procedure.type_name, + start_time_ms: procedure.start_time_ms, + end_time_ms: procedure.end_time_ms, + state: ProcedureState::Running, + lock_keys: procedure.lock_keys, + }; + result.push((status, procedure_info)); + } + + Ok(result) + } + + async fn region_stats(&self) -> std::result::Result, Self::Error> { + self.meta_client + .list_region_stats() + .await + .map_err(BoxedError::new) + .context(catalog::error::ListRegionStatsSnafu) + } +} diff --git a/src/cmd/src/standalone.rs b/src/cmd/src/standalone.rs index 4335bd5447..d4a0d823c9 100644 --- a/src/cmd/src/standalone.rs +++ b/src/cmd/src/standalone.rs @@ -17,14 +17,18 @@ use std::{fs, path}; use async_trait::async_trait; use cache::{build_fundamental_cache_registry, with_default_composite_cache_registry}; +use catalog::information_schema::InformationExtension; use catalog::kvbackend::KvBackendCatalogManager; use clap::Parser; +use client::api::v1::meta::RegionRole; use common_base::Plugins; use common_catalog::consts::{MIN_USER_FLOW_ID, MIN_USER_TABLE_ID}; use common_config::{metadata_store_dir, Configurable, KvBackendConfig}; use common_error::ext::BoxedError; use common_meta::cache::LayeredCacheRegistryBuilder; use common_meta::cache_invalidator::CacheInvalidatorRef; +use common_meta::cluster::{NodeInfo, NodeStatus}; +use common_meta::datanode::RegionStat; use common_meta::ddl::flow_meta::{FlowMetadataAllocator, FlowMetadataAllocatorRef}; use common_meta::ddl::table_meta::{TableMetadataAllocator, TableMetadataAllocatorRef}; use common_meta::ddl::{DdlContext, NoopRegionFailureDetectorControl, ProcedureExecutorRef}; @@ -33,10 +37,11 @@ use common_meta::key::flow::{FlowMetadataManager, FlowMetadataManagerRef}; use common_meta::key::{TableMetadataManager, TableMetadataManagerRef}; use common_meta::kv_backend::KvBackendRef; use common_meta::node_manager::NodeManagerRef; +use common_meta::peer::Peer; use common_meta::region_keeper::MemoryRegionKeeper; use common_meta::sequence::SequenceBuilder; use common_meta::wal_options_allocator::{WalOptionsAllocator, WalOptionsAllocatorRef}; -use common_procedure::ProcedureManagerRef; +use common_procedure::{ProcedureInfo, ProcedureManagerRef}; use common_telemetry::info; use common_telemetry::logging::{LoggingOptions, TracingOptions}; use common_time::timezone::set_default_timezone; @@ -44,6 +49,7 @@ use common_version::{short_version, version}; use common_wal::config::DatanodeWalConfig; use datanode::config::{DatanodeOptions, ProcedureConfig, RegionEngineConfig, StorageConfig}; use datanode::datanode::{Datanode, DatanodeBuilder}; +use datanode::region_server::RegionServer; use file_engine::config::EngineConfig as FileEngineConfig; use flow::{FlowWorkerManager, FlownodeBuilder, FrontendInvoker}; use frontend::frontend::FrontendOptions; @@ -478,9 +484,18 @@ impl StartCommand { .build(), ); + let datanode = DatanodeBuilder::new(dn_opts, plugins.clone()) + .with_kv_backend(kv_backend.clone()) + .build() + .await + .context(StartDatanodeSnafu)?; + + let information_extension = Arc::new(StandaloneInformationExtension::new( + datanode.region_server(), + procedure_manager.clone(), + )); let catalog_manager = KvBackendCatalogManager::new( - dn_opts.mode, - None, + information_extension, kv_backend.clone(), layered_cache_registry.clone(), Some(procedure_manager.clone()), @@ -489,12 +504,6 @@ impl StartCommand { let table_metadata_manager = Self::create_table_metadata_manager(kv_backend.clone()).await?; - let datanode = DatanodeBuilder::new(dn_opts, plugins.clone()) - .with_kv_backend(kv_backend.clone()) - .build() - .await - .context(StartDatanodeSnafu)?; - let flow_metadata_manager = Arc::new(FlowMetadataManager::new(kv_backend.clone())); let flow_builder = FlownodeBuilder::new( Default::default(), @@ -644,6 +653,91 @@ impl StartCommand { } } +struct StandaloneInformationExtension { + region_server: RegionServer, + procedure_manager: ProcedureManagerRef, + start_time_ms: u64, +} + +impl StandaloneInformationExtension { + pub fn new(region_server: RegionServer, procedure_manager: ProcedureManagerRef) -> Self { + Self { + region_server, + procedure_manager, + start_time_ms: common_time::util::current_time_millis() as u64, + } + } +} + +#[async_trait::async_trait] +impl InformationExtension for StandaloneInformationExtension { + type Error = catalog::error::Error; + + async fn nodes(&self) -> std::result::Result, Self::Error> { + let build_info = common_version::build_info(); + let node_info = NodeInfo { + // For the standalone: + // - id always 0 + // - empty string for peer_addr + peer: Peer { + id: 0, + addr: "".to_string(), + }, + last_activity_ts: -1, + status: NodeStatus::Standalone, + version: build_info.version.to_string(), + git_commit: build_info.commit_short.to_string(), + // Use `self.start_time_ms` instead. + // It's not precise but enough. + start_time_ms: self.start_time_ms, + }; + Ok(vec![node_info]) + } + + async fn procedures(&self) -> std::result::Result, Self::Error> { + self.procedure_manager + .list_procedures() + .await + .map_err(BoxedError::new) + .map(|procedures| { + procedures + .into_iter() + .map(|procedure| { + let status = procedure.state.as_str_name().to_string(); + (status, procedure) + }) + .collect::>() + }) + .context(catalog::error::ListProceduresSnafu) + } + + async fn region_stats(&self) -> std::result::Result, Self::Error> { + let stats = self + .region_server + .reportable_regions() + .into_iter() + .map(|stat| { + let region_stat = self + .region_server + .region_statistic(stat.region_id) + .unwrap_or_default(); + RegionStat { + id: stat.region_id, + rcus: 0, + wcus: 0, + approximate_bytes: region_stat.estimated_disk_size() as i64, + engine: stat.engine, + role: RegionRole::from(stat.role).into(), + memtable_size: region_stat.memtable_size, + manifest_size: region_stat.manifest_size, + sst_size: region_stat.sst_size, + } + }) + .collect::>(); + Ok(stats) + } +} + #[cfg(test)] mod tests { use std::default::Default; diff --git a/tests-integration/src/cluster.rs b/tests-integration/src/cluster.rs index ad2c3e369f..44e5946769 100644 --- a/tests-integration/src/cluster.rs +++ b/tests-integration/src/cluster.rs @@ -23,6 +23,7 @@ use cache::{build_fundamental_cache_registry, with_default_composite_cache_regis use catalog::kvbackend::{CachedMetaKvBackendBuilder, KvBackendCatalogManager, MetaKvBackend}; use client::client_manager::NodeClients; use client::Client; +use cmd::DistributedInformationExtension; use common_base::Plugins; use common_grpc::channel_manager::{ChannelConfig, ChannelManager}; use common_meta::cache::{CacheRegistryBuilder, LayeredCacheRegistryBuilder}; @@ -366,9 +367,10 @@ impl GreptimeDbClusterBuilder { .build(), ); + let information_extension = + Arc::new(DistributedInformationExtension::new(meta_client.clone())); let catalog_manager = KvBackendCatalogManager::new( - Mode::Distributed, - Some(meta_client.clone()), + information_extension, cached_meta_backend.clone(), cache_registry.clone(), None, diff --git a/tests-integration/src/standalone.rs b/tests-integration/src/standalone.rs index 123614e436..47095ecc65 100644 --- a/tests-integration/src/standalone.rs +++ b/tests-integration/src/standalone.rs @@ -15,6 +15,7 @@ use std::sync::Arc; use cache::{build_fundamental_cache_registry, with_default_composite_cache_registry}; +use catalog::information_schema::NoopInformationExtension; use catalog::kvbackend::KvBackendCatalogManager; use cmd::error::StartFlownodeSnafu; use cmd::standalone::StandaloneOptions; @@ -146,8 +147,7 @@ impl GreptimeDbStandaloneBuilder { ); let catalog_manager = KvBackendCatalogManager::new( - Mode::Standalone, - None, + Arc::new(NoopInformationExtension), kv_backend.clone(), cache_registry.clone(), Some(procedure_manager.clone()), From d168bde22622f8f7ac90ca8e0a31a05cc03e5aae Mon Sep 17 00:00:00 2001 From: Yingwen Date: Fri, 11 Oct 2024 12:16:37 +0800 Subject: [PATCH 07/36] feat!: move v1/prof API to debug/prof (#4810) * feat!: move v1/prof to debug/prof * docs: update readme * docs: move prof docs to docs dir * chore: update message * feat!: remove v1/prof * docs: update mem prof docs --- .../how-to/how-to-profile-cpu.md | 6 ++--- .../how-to/how-to-profile-memory.md | 13 ++++++---- src/servers/src/http.rs | 25 ++++++++++--------- 3 files changed, 24 insertions(+), 20 deletions(-) rename src/servers/src/http/pprof/README.md => docs/how-to/how-to-profile-cpu.md (71%) rename src/common/mem-prof/README.md => docs/how-to/how-to-profile-memory.md (67%) diff --git a/src/servers/src/http/pprof/README.md b/docs/how-to/how-to-profile-cpu.md similarity index 71% rename from src/servers/src/http/pprof/README.md rename to docs/how-to/how-to-profile-cpu.md index b8393ae3f5..b73c85ea2f 100644 --- a/src/servers/src/http/pprof/README.md +++ b/docs/how-to/how-to-profile-cpu.md @@ -9,7 +9,7 @@ cargo build --features=pprof ## HTTP API Sample at 99 Hertz, for 5 seconds, output report in [protobuf format](https://github.com/google/pprof/blob/master/proto/profile.proto). ```bash -curl -s '0:4000/v1/prof/cpu' > /tmp/pprof.out +curl -s '0:4000/debug/prof/cpu' > /tmp/pprof.out ``` Then you can use `pprof` command with the protobuf file. @@ -19,10 +19,10 @@ go tool pprof -top /tmp/pprof.out Sample at 99 Hertz, for 60 seconds, output report in flamegraph format. ```bash -curl -s '0:4000/v1/prof/cpu?seconds=60&output=flamegraph' > /tmp/pprof.svg +curl -s '0:4000/debug/prof/cpu?seconds=60&output=flamegraph' > /tmp/pprof.svg ``` Sample at 49 Hertz, for 10 seconds, output report in text format. ```bash -curl -s '0:4000/v1/prof/cpu?seconds=10&frequency=49&output=text' > /tmp/pprof.txt +curl -s '0:4000/debug/prof/cpu?seconds=10&frequency=49&output=text' > /tmp/pprof.txt ``` diff --git a/src/common/mem-prof/README.md b/docs/how-to/how-to-profile-memory.md similarity index 67% rename from src/common/mem-prof/README.md rename to docs/how-to/how-to-profile-memory.md index da1bbae9f0..7211683190 100644 --- a/src/common/mem-prof/README.md +++ b/docs/how-to/how-to-profile-memory.md @@ -12,10 +12,10 @@ brew install jemalloc sudo apt install libjemalloc-dev ``` -### [flamegraph](https://github.com/brendangregg/FlameGraph) +### [flamegraph](https://github.com/brendangregg/FlameGraph) ```bash -curl https://raw.githubusercontent.com/brendangregg/FlameGraph/master/flamegraph.pl > ./flamegraph.pl +curl https://raw.githubusercontent.com/brendangregg/FlameGraph/master/flamegraph.pl > ./flamegraph.pl ``` ### Build GreptimeDB with `mem-prof` feature. @@ -35,7 +35,7 @@ MALLOC_CONF=prof:true,lg_prof_interval:28 ./target/debug/greptime standalone sta Dump memory profiling data through HTTP API: ```bash -curl localhost:4000/v1/prof/mem > greptime.hprof +curl localhost:4000/debug/prof/mem > greptime.hprof ``` You can periodically dump profiling data and compare them to find the delta memory usage. @@ -45,6 +45,9 @@ You can periodically dump profiling data and compare them to find the delta memo To create flamegraph according to dumped profiling data: ```bash -jeprof --svg --base= > output.svg -``` +sudo apt install -y libjemalloc-dev +jeprof --collapse | ./flamegraph.pl > mem-prof.svg + +jeprof --base --collapse | ./flamegraph.pl > output.svg +``` diff --git a/src/servers/src/http.rs b/src/servers/src/http.rs index 953ff9e73a..67309b7244 100644 --- a/src/servers/src/http.rs +++ b/src/servers/src/http.rs @@ -730,6 +730,7 @@ impl HttpServer { authorize::check_http_auth, )), ) + // Handlers for debug, we don't expect a timeout. .nest( "/debug", Router::new() @@ -737,19 +738,19 @@ impl HttpServer { .route( "/log_level", routing::get(dyn_log::dyn_log_handler).post(dyn_log::dyn_log_handler), - ), - ) - // Handlers for debug, we don't expect a timeout. - .nest( - &format!("/{HTTP_API_VERSION}/prof"), - Router::new() - .route( - "/cpu", - routing::get(pprof::pprof_handler).post(pprof::pprof_handler), ) - .route( - "/mem", - routing::get(mem_prof::mem_prof_handler).post(mem_prof::mem_prof_handler), + .nest( + "/prof", + Router::new() + .route( + "/cpu", + routing::get(pprof::pprof_handler).post(pprof::pprof_handler), + ) + .route( + "/mem", + routing::get(mem_prof::mem_prof_handler) + .post(mem_prof::mem_prof_handler), + ), ), ) } From 7dd0e3ab37264d11a7deec619ecb3845eb249705 Mon Sep 17 00:00:00 2001 From: "Lei, HUANG" <6406592+v0y4g3r@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:23:01 +0800 Subject: [PATCH 08/36] fix: Panic in UNION ALL queries (#4796) * fix/union_all_panic: Improve MetricCollector by incrementing level and fix underflow issue; add tests for UNION ALL queries * chore: remove useless documentation * fix/union_all_panic: Add order by clause to UNION ALL select queries in tests --- src/common/recordbatch/src/adapter.rs | 4 ++-- tests/cases/standalone/common/select/union_all.result | 10 ++++++++++ tests/cases/standalone/common/select/union_all.sql | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 tests/cases/standalone/common/select/union_all.result create mode 100644 tests/cases/standalone/common/select/union_all.sql diff --git a/src/common/recordbatch/src/adapter.rs b/src/common/recordbatch/src/adapter.rs index 85236381b2..98f4d0a38a 100644 --- a/src/common/recordbatch/src/adapter.rs +++ b/src/common/recordbatch/src/adapter.rs @@ -329,6 +329,7 @@ impl ExecutionPlanVisitor for MetricCollector { level: self.current_level, metrics: vec![], }); + self.current_level += 1; return Ok(true); }; @@ -365,8 +366,7 @@ impl ExecutionPlanVisitor for MetricCollector { } fn post_visit(&mut self, _plan: &dyn ExecutionPlan) -> std::result::Result { - // the last minus will underflow - self.current_level = self.current_level.wrapping_sub(1); + self.current_level -= 1; Ok(true) } } diff --git a/tests/cases/standalone/common/select/union_all.result b/tests/cases/standalone/common/select/union_all.result new file mode 100644 index 0000000000..54332e1254 --- /dev/null +++ b/tests/cases/standalone/common/select/union_all.result @@ -0,0 +1,10 @@ +SELECT 123 as a, 'h' as b UNION ALL SELECT 456 as a, 'e' as b UNION ALL SELECT 789 as a, 'l' as b order by a; + ++-----+---+ +| a | b | ++-----+---+ +| 123 | h | +| 456 | e | +| 789 | l | ++-----+---+ + diff --git a/tests/cases/standalone/common/select/union_all.sql b/tests/cases/standalone/common/select/union_all.sql new file mode 100644 index 0000000000..207d8463fc --- /dev/null +++ b/tests/cases/standalone/common/select/union_all.sql @@ -0,0 +1 @@ +SELECT 123 as a, 'h' as b UNION ALL SELECT 456 as a, 'e' as b UNION ALL SELECT 789 as a, 'l' as b order by a; From a61c0bd1d8a16b208266bbac92f3b8fe2cbdf594 Mon Sep 17 00:00:00 2001 From: Ruihang Xia Date: Fri, 11 Oct 2024 18:02:45 +0800 Subject: [PATCH 09/36] fix: error in admin function is not formatted properly (#4820) Signed-off-by: Ruihang Xia --- src/operator/src/statement/admin.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/operator/src/statement/admin.rs b/src/operator/src/statement/admin.rs index 37e6acf966..6c0413c2aa 100644 --- a/src/operator/src/statement/admin.rs +++ b/src/operator/src/statement/admin.rs @@ -59,7 +59,7 @@ impl StatementExecutor { .map(|arg| { let FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(value))) = arg else { return error::BuildAdminFunctionArgsSnafu { - msg: "unsupported function arg {arg}", + msg: format!("unsupported function arg {arg}"), } .fail(); }; @@ -200,7 +200,7 @@ fn values_to_vectors_by_valid_types( } error::BuildAdminFunctionArgsSnafu { - msg: "failed to cast {value}", + msg: format!("failed to cast {value}"), } .fail() }) From 0f907ef99e5d2cc2a8ea40ea72b564173ad3a0d2 Mon Sep 17 00:00:00 2001 From: Weny Xu Date: Fri, 11 Oct 2024 19:32:15 +0800 Subject: [PATCH 10/36] fix: correct table name formatting (#4819) --- src/common/meta/src/ddl/utils.rs | 9 +++++---- src/common/meta/src/key/table_name.rs | 11 +++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/common/meta/src/ddl/utils.rs b/src/common/meta/src/ddl/utils.rs index fd1737a3e6..b1608d40e3 100644 --- a/src/common/meta/src/ddl/utils.rs +++ b/src/common/meta/src/ddl/utils.rs @@ -18,6 +18,7 @@ use common_procedure::error::Error as ProcedureError; use snafu::{ensure, OptionExt, ResultExt}; use store_api::metric_engine_consts::LOGICAL_TABLE_METADATA_KEY; use table::metadata::TableId; +use table::table_reference::TableReference; use crate::ddl::DetectingRegion; use crate::error::{Error, OperateDatanodeSnafu, Result, TableNotFoundSnafu, UnsupportedSnafu}; @@ -109,8 +110,8 @@ pub async fn check_and_get_physical_table_id( .table_name_manager() .get(physical_table_name) .await? - .context(TableNotFoundSnafu { - table_name: physical_table_name.to_string(), + .with_context(|| TableNotFoundSnafu { + table_name: TableReference::from(physical_table_name).to_string(), }) .map(|table| table.table_id()) } @@ -123,8 +124,8 @@ pub async fn get_physical_table_id( .table_name_manager() .get(logical_table_name) .await? - .context(TableNotFoundSnafu { - table_name: logical_table_name.to_string(), + .with_context(|| TableNotFoundSnafu { + table_name: TableReference::from(logical_table_name).to_string(), }) .map(|table| table.table_id())?; diff --git a/src/common/meta/src/key/table_name.rs b/src/common/meta/src/key/table_name.rs index a632e3a233..e508c5e877 100644 --- a/src/common/meta/src/key/table_name.rs +++ b/src/common/meta/src/key/table_name.rs @@ -21,6 +21,7 @@ use serde::{Deserialize, Serialize}; use snafu::OptionExt; use table::metadata::TableId; use table::table_name::TableName; +use table::table_reference::TableReference; use super::{MetadataKey, MetadataValue, TABLE_NAME_KEY_PATTERN, TABLE_NAME_KEY_PREFIX}; use crate::error::{Error, InvalidMetadataSnafu, Result}; @@ -122,6 +123,16 @@ impl From> for TableName { } } +impl<'a> From> for TableReference<'a> { + fn from(value: TableNameKey<'a>) -> Self { + Self { + catalog: value.catalog, + schema: value.schema, + table: value.table, + } + } +} + impl<'a> TryFrom<&'a str> for TableNameKey<'a> { type Error = Error; From 4bb1f4f18447685fd1536e4fddafb0c9a6bb116e Mon Sep 17 00:00:00 2001 From: Weny Xu Date: Fri, 11 Oct 2024 20:48:53 +0800 Subject: [PATCH 11/36] feat: introduce `LeadershipChangeNotifier` and `LeadershipChangeListener` (#4817) * feat: introduce `LeadershipChangeNotifier` * refactor: use `LeadershipChangeNotifier` * chore: apply suggestions from CR * chore: apply suggestions from CR * chore: adjust log styling --- src/common/meta/src/error.rs | 18 ++- src/common/meta/src/leadership_notifier.rs | 156 +++++++++++++++++++ src/common/meta/src/lib.rs | 1 + src/common/meta/src/wal_options_allocator.rs | 17 ++ src/meta-srv/src/lib.rs | 1 - src/meta-srv/src/metasrv.rs | 62 ++++---- src/meta-srv/src/procedure.rs | 30 ++++ src/meta-srv/src/region/supervisor.rs | 19 +++ 8 files changed, 270 insertions(+), 34 deletions(-) create mode 100644 src/common/meta/src/leadership_notifier.rs diff --git a/src/common/meta/src/error.rs b/src/common/meta/src/error.rs index 849ee28948..0e7709df0b 100644 --- a/src/common/meta/src/error.rs +++ b/src/common/meta/src/error.rs @@ -147,6 +147,20 @@ pub enum Error { source: common_procedure::Error, }, + #[snafu(display("Failed to start procedure manager"))] + StartProcedureManager { + #[snafu(implicit)] + location: Location, + source: common_procedure::Error, + }, + + #[snafu(display("Failed to stop procedure manager"))] + StopProcedureManager { + #[snafu(implicit)] + location: Location, + source: common_procedure::Error, + }, + #[snafu(display( "Failed to get procedure output, procedure id: {procedure_id}, error: {err_msg}" ))] @@ -715,7 +729,9 @@ impl ErrorExt for Error { SubmitProcedure { source, .. } | QueryProcedure { source, .. } - | WaitProcedure { source, .. } => source.status_code(), + | WaitProcedure { source, .. } + | StartProcedureManager { source, .. } + | StopProcedureManager { source, .. } => source.status_code(), RegisterProcedureLoader { source, .. } => source.status_code(), External { source, .. } => source.status_code(), OperateDatanode { source, .. } => source.status_code(), diff --git a/src/common/meta/src/leadership_notifier.rs b/src/common/meta/src/leadership_notifier.rs new file mode 100644 index 0000000000..4ba65d1adc --- /dev/null +++ b/src/common/meta/src/leadership_notifier.rs @@ -0,0 +1,156 @@ +// Copyright 2023 Greptime Team +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::sync::Arc; + +use async_trait::async_trait; +use common_telemetry::error; + +use crate::error::Result; + +pub type LeadershipChangeNotifierCustomizerRef = Arc; + +/// A trait for customizing the leadership change notifier. +pub trait LeadershipChangeNotifierCustomizer: Send + Sync { + fn customize(&self, notifier: &mut LeadershipChangeNotifier); +} + +/// A trait for handling leadership change events in a distributed system. +#[async_trait] +pub trait LeadershipChangeListener: Send + Sync { + /// Returns the listener name. + fn name(&self) -> &str; + + /// Called when the node transitions to the leader role. + async fn on_leader_start(&self) -> Result<()>; + + /// Called when the node transitions to the follower role. + async fn on_leader_stop(&self) -> Result<()>; +} + +/// A notifier for leadership change events. +#[derive(Default)] +pub struct LeadershipChangeNotifier { + listeners: Vec>, +} + +impl LeadershipChangeNotifier { + /// Adds a listener to the notifier. + pub fn add_listener(&mut self, listener: Arc) { + self.listeners.push(listener); + } + + /// Notify all listeners that the node has become a leader. + pub async fn notify_on_leader_start(&self) { + for listener in &self.listeners { + if let Err(err) = listener.on_leader_start().await { + error!( + err; + "Failed to notify listener: {}, event 'on_leader_start'", + listener.name() + ); + } + } + } + + /// Notify all listeners that the node has become a follower. + pub async fn notify_on_leader_stop(&self) { + for listener in &self.listeners { + if let Err(err) = listener.on_leader_stop().await { + error!( + err; + "Failed to notify listener: {}, event: 'on_follower_start'", + listener.name() + ); + } + } + } +} + +#[cfg(test)] +mod tests { + use std::sync::atomic::{AtomicBool, Ordering}; + use std::sync::Arc; + + use super::*; + + struct MockListener { + name: String, + on_leader_start_fn: Option Result<()> + Send + Sync>>, + on_follower_start_fn: Option Result<()> + Send + Sync>>, + } + + #[async_trait::async_trait] + impl LeadershipChangeListener for MockListener { + fn name(&self) -> &str { + &self.name + } + + async fn on_leader_start(&self) -> Result<()> { + if let Some(f) = &self.on_leader_start_fn { + return f(); + } + Ok(()) + } + + async fn on_leader_stop(&self) -> Result<()> { + if let Some(f) = &self.on_follower_start_fn { + return f(); + } + Ok(()) + } + } + + #[tokio::test] + async fn test_leadership_change_notifier() { + let mut notifier = LeadershipChangeNotifier::default(); + let listener1 = Arc::new(MockListener { + name: "listener1".to_string(), + on_leader_start_fn: None, + on_follower_start_fn: None, + }); + let called_on_leader_start = Arc::new(AtomicBool::new(false)); + let called_on_follower_start = Arc::new(AtomicBool::new(false)); + let called_on_leader_start_moved = called_on_leader_start.clone(); + let called_on_follower_start_moved = called_on_follower_start.clone(); + let listener2 = Arc::new(MockListener { + name: "listener2".to_string(), + on_leader_start_fn: Some(Box::new(move || { + called_on_leader_start_moved.store(true, Ordering::Relaxed); + Ok(()) + })), + on_follower_start_fn: Some(Box::new(move || { + called_on_follower_start_moved.store(true, Ordering::Relaxed); + Ok(()) + })), + }); + + notifier.add_listener(listener1); + notifier.add_listener(listener2); + + let listener1 = notifier.listeners.first().unwrap(); + let listener2 = notifier.listeners.get(1).unwrap(); + + assert_eq!(listener1.name(), "listener1"); + assert_eq!(listener2.name(), "listener2"); + + notifier.notify_on_leader_start().await; + assert!(!called_on_follower_start.load(Ordering::Relaxed)); + assert!(called_on_leader_start.load(Ordering::Relaxed)); + + notifier.notify_on_leader_stop().await; + assert!(called_on_follower_start.load(Ordering::Relaxed)); + assert!(called_on_leader_start.load(Ordering::Relaxed)); + } +} diff --git a/src/common/meta/src/lib.rs b/src/common/meta/src/lib.rs index 1dd658890c..158350bc32 100644 --- a/src/common/meta/src/lib.rs +++ b/src/common/meta/src/lib.rs @@ -32,6 +32,7 @@ pub mod heartbeat; pub mod instruction; pub mod key; pub mod kv_backend; +pub mod leadership_notifier; pub mod lock_key; pub mod metrics; pub mod node_manager; diff --git a/src/common/meta/src/wal_options_allocator.rs b/src/common/meta/src/wal_options_allocator.rs index ba0c6f407f..283f43b9a8 100644 --- a/src/common/meta/src/wal_options_allocator.rs +++ b/src/common/meta/src/wal_options_allocator.rs @@ -17,6 +17,7 @@ pub mod kafka; use std::collections::HashMap; use std::sync::Arc; +use async_trait::async_trait; use common_wal::config::MetasrvWalConfig; use common_wal::options::{KafkaWalOptions, WalOptions, WAL_OPTIONS_KEY}; use snafu::ResultExt; @@ -24,6 +25,7 @@ use store_api::storage::{RegionId, RegionNumber}; use crate::error::{EncodeWalOptionsSnafu, Result}; use crate::kv_backend::KvBackendRef; +use crate::leadership_notifier::LeadershipChangeListener; use crate::wal_options_allocator::kafka::topic_manager::TopicManager as KafkaTopicManager; /// Allocates wal options in region granularity. @@ -94,6 +96,21 @@ impl WalOptionsAllocator { } } +#[async_trait] +impl LeadershipChangeListener for WalOptionsAllocator { + fn name(&self) -> &str { + "WalOptionsAllocator" + } + + async fn on_leader_start(&self) -> Result<()> { + self.start().await + } + + async fn on_leader_stop(&self) -> Result<()> { + Ok(()) + } +} + /// Allocates a wal options for each region. The allocated wal options is encoded immediately. pub fn allocate_region_wal_options( regions: Vec, diff --git a/src/meta-srv/src/lib.rs b/src/meta-srv/src/lib.rs index 717edc92b2..01b48f1da0 100644 --- a/src/meta-srv/src/lib.rs +++ b/src/meta-srv/src/lib.rs @@ -40,7 +40,6 @@ pub mod selector; pub mod service; pub mod state; pub mod table_meta_alloc; - pub use crate::error::Result; mod greptimedb_telemetry; diff --git a/src/meta-srv/src/metasrv.rs b/src/meta-srv/src/metasrv.rs index de7d54aa65..3cdb64e1e0 100644 --- a/src/meta-srv/src/metasrv.rs +++ b/src/meta-srv/src/metasrv.rs @@ -29,6 +29,9 @@ use common_meta::cache_invalidator::CacheInvalidatorRef; use common_meta::ddl::ProcedureExecutorRef; use common_meta::key::TableMetadataManagerRef; use common_meta::kv_backend::{KvBackendRef, ResettableKvBackend, ResettableKvBackendRef}; +use common_meta::leadership_notifier::{ + LeadershipChangeNotifier, LeadershipChangeNotifierCustomizerRef, +}; use common_meta::peer::Peer; use common_meta::region_keeper::MemoryRegionKeeperRef; use common_meta::wal_options_allocator::WalOptionsAllocatorRef; @@ -56,6 +59,7 @@ use crate::handler::HeartbeatHandlerGroupRef; use crate::lease::lookup_datanode_peer; use crate::lock::DistLockRef; use crate::procedure::region_migration::manager::RegionMigrationManagerRef; +use crate::procedure::ProcedureManagerListenerAdapter; use crate::pubsub::{PublisherRef, SubscriptionManagerRef}; use crate::region::supervisor::RegionSupervisorTickerRef; use crate::selector::{Selector, SelectorType}; @@ -291,17 +295,15 @@ pub type SelectorRef = Arc>; pub struct MetaStateHandler { - procedure_manager: ProcedureManagerRef, - wal_options_allocator: WalOptionsAllocatorRef, subscribe_manager: Option, greptimedb_telemetry_task: Arc, leader_cached_kv_backend: Arc, - region_supervisor_ticker: Option, + leadership_change_notifier: LeadershipChangeNotifier, state: StateRef, } impl MetaStateHandler { - pub async fn on_become_leader(&self) { + pub async fn on_leader_start(&self) { self.state.write().unwrap().next_state(become_leader(false)); if let Err(e) = self.leader_cached_kv_backend.load().await { @@ -310,33 +312,19 @@ impl MetaStateHandler { self.state.write().unwrap().next_state(become_leader(true)); } - if let Some(ticker) = self.region_supervisor_ticker.as_ref() { - ticker.start(); - } - - if let Err(e) = self.procedure_manager.start().await { - error!(e; "Failed to start procedure manager"); - } - - if let Err(e) = self.wal_options_allocator.start().await { - error!(e; "Failed to start wal options allocator"); - } + self.leadership_change_notifier + .notify_on_leader_start() + .await; self.greptimedb_telemetry_task.should_report(true); } - pub async fn on_become_follower(&self) { + pub async fn on_leader_stop(&self) { self.state.write().unwrap().next_state(become_follower()); - // Stops the procedures. - if let Err(e) = self.procedure_manager.stop().await { - error!(e; "Failed to stop procedure manager"); - } - - if let Some(ticker) = self.region_supervisor_ticker.as_ref() { - // Stops the supervisor ticker. - ticker.stop(); - } + self.leadership_change_notifier + .notify_on_leader_stop() + .await; // Suspends reporting. self.greptimedb_telemetry_task.should_report(false); @@ -410,15 +398,25 @@ impl Metasrv { greptimedb_telemetry_task .start() .context(StartTelemetryTaskSnafu)?; - let region_supervisor_ticker = self.region_supervisor_ticker.clone(); + + // Builds leadership change notifier. + let mut leadership_change_notifier = LeadershipChangeNotifier::default(); + leadership_change_notifier.add_listener(self.wal_options_allocator.clone()); + leadership_change_notifier + .add_listener(Arc::new(ProcedureManagerListenerAdapter(procedure_manager))); + if let Some(region_supervisor_ticker) = &self.region_supervisor_ticker { + leadership_change_notifier.add_listener(region_supervisor_ticker.clone() as _); + } + if let Some(customizer) = self.plugins.get::() { + customizer.customize(&mut leadership_change_notifier); + } + let state_handler = MetaStateHandler { greptimedb_telemetry_task, subscribe_manager, - procedure_manager, - wal_options_allocator: self.wal_options_allocator.clone(), state: self.state.clone(), leader_cached_kv_backend: leader_cached_kv_backend.clone(), - region_supervisor_ticker, + leadership_change_notifier, }; let _handle = common_runtime::spawn_global(async move { loop { @@ -429,12 +427,12 @@ impl Metasrv { info!("Leader's cache has bean cleared on leader change: {msg}"); match msg { LeaderChangeMessage::Elected(_) => { - state_handler.on_become_leader().await; + state_handler.on_leader_start().await; } LeaderChangeMessage::StepDown(leader) => { error!("Leader :{:?} step down", leader); - state_handler.on_become_follower().await; + state_handler.on_leader_stop().await; } } } @@ -448,7 +446,7 @@ impl Metasrv { } } - state_handler.on_become_follower().await; + state_handler.on_leader_stop().await; }); // Register candidate and keep lease in background. diff --git a/src/meta-srv/src/procedure.rs b/src/meta-srv/src/procedure.rs index 1f430654d2..8e696723e8 100644 --- a/src/meta-srv/src/procedure.rs +++ b/src/meta-srv/src/procedure.rs @@ -12,7 +12,37 @@ // See the License for the specific language governing permissions and // limitations under the License. +use async_trait::async_trait; +use common_meta::error::{self, Result}; +use common_meta::leadership_notifier::LeadershipChangeListener; +use common_procedure::ProcedureManagerRef; +use snafu::ResultExt; + pub mod region_migration; #[cfg(test)] mod tests; pub mod utils; + +#[derive(Clone)] +pub struct ProcedureManagerListenerAdapter(pub ProcedureManagerRef); + +#[async_trait] +impl LeadershipChangeListener for ProcedureManagerListenerAdapter { + fn name(&self) -> &str { + "ProcedureManager" + } + + async fn on_leader_start(&self) -> Result<()> { + self.0 + .start() + .await + .context(error::StartProcedureManagerSnafu) + } + + async fn on_leader_stop(&self) -> Result<()> { + self.0 + .stop() + .await + .context(error::StopProcedureManagerSnafu) + } +} diff --git a/src/meta-srv/src/region/supervisor.rs b/src/meta-srv/src/region/supervisor.rs index 80f6c84865..32da666f2b 100644 --- a/src/meta-srv/src/region/supervisor.rs +++ b/src/meta-srv/src/region/supervisor.rs @@ -16,10 +16,12 @@ use std::fmt::Debug; use std::sync::{Arc, Mutex}; use std::time::Duration; +use async_trait::async_trait; use common_meta::datanode::Stat; use common_meta::ddl::{DetectingRegion, RegionFailureDetectorController}; use common_meta::key::MAINTENANCE_KEY; use common_meta::kv_backend::KvBackendRef; +use common_meta::leadership_notifier::LeadershipChangeListener; use common_meta::peer::PeerLookupServiceRef; use common_meta::{ClusterId, DatanodeId}; use common_runtime::JoinHandle; @@ -129,6 +131,23 @@ pub struct RegionSupervisorTicker { sender: Sender, } +#[async_trait] +impl LeadershipChangeListener for RegionSupervisorTicker { + fn name(&self) -> &'static str { + "RegionSupervisorTicker" + } + + async fn on_leader_start(&self) -> common_meta::error::Result<()> { + self.start(); + Ok(()) + } + + async fn on_leader_stop(&self) -> common_meta::error::Result<()> { + self.stop(); + Ok(()) + } +} + impl RegionSupervisorTicker { pub(crate) fn new(tick_interval: Duration, sender: Sender) -> Self { Self { From aaa9b329085de638e5122bf132c239359dba65d6 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Fri, 11 Oct 2024 10:57:54 -0700 Subject: [PATCH 12/36] feat: add more h3 functions (#4770) * feat: add more h3 grid functions * feat: add more traversal functions * refactor: update some function definitions * style: format * refactor: avoid creating slice in nested loop * feat: ensure column number and length * refactor: fix lint warnings * refactor: merge main * Apply suggestions from code review Co-authored-by: LFC <990479+MichaelScofield@users.noreply.github.com> * Update src/common/function/src/scalars/geo/h3.rs Co-authored-by: LFC <990479+MichaelScofield@users.noreply.github.com> * style: format --------- Co-authored-by: LFC <990479+MichaelScofield@users.noreply.github.com> --- src/common/function/src/scalars/geo.rs | 29 +- src/common/function/src/scalars/geo/h3.rs | 728 +++++++++++++----- .../standalone/common/function/geo.result | 59 +- .../cases/standalone/common/function/geo.sql | 22 +- 4 files changed, 595 insertions(+), 243 deletions(-) diff --git a/src/common/function/src/scalars/geo.rs b/src/common/function/src/scalars/geo.rs index 37b6c0704b..e47a1de9f2 100644 --- a/src/common/function/src/scalars/geo.rs +++ b/src/common/function/src/scalars/geo.rs @@ -29,18 +29,31 @@ impl GeoFunctions { // geohash registry.register(Arc::new(GeohashFunction)); registry.register(Arc::new(GeohashNeighboursFunction)); - // h3 family + + // h3 index registry.register(Arc::new(h3::H3LatLngToCell)); registry.register(Arc::new(h3::H3LatLngToCellString)); + + // h3 index inspection registry.register(Arc::new(h3::H3CellBase)); - registry.register(Arc::new(h3::H3CellCenterChild)); - registry.register(Arc::new(h3::H3CellCenterLat)); - registry.register(Arc::new(h3::H3CellCenterLng)); registry.register(Arc::new(h3::H3CellIsPentagon)); - registry.register(Arc::new(h3::H3CellParent)); - registry.register(Arc::new(h3::H3CellResolution)); - registry.register(Arc::new(h3::H3CellToString)); - registry.register(Arc::new(h3::H3IsNeighbour)); registry.register(Arc::new(h3::H3StringToCell)); + registry.register(Arc::new(h3::H3CellToString)); + registry.register(Arc::new(h3::H3CellCenterLatLng)); + registry.register(Arc::new(h3::H3CellResolution)); + + // h3 hierarchical grid + registry.register(Arc::new(h3::H3CellCenterChild)); + registry.register(Arc::new(h3::H3CellParent)); + registry.register(Arc::new(h3::H3CellToChildren)); + registry.register(Arc::new(h3::H3CellToChildrenSize)); + registry.register(Arc::new(h3::H3CellToChildPos)); + registry.register(Arc::new(h3::H3ChildPosToCell)); + + // h3 grid traversal + registry.register(Arc::new(h3::H3GridDisk)); + registry.register(Arc::new(h3::H3GridDiskDistances)); + registry.register(Arc::new(h3::H3GridDistance)); + registry.register(Arc::new(h3::H3GridPathCells)); } } diff --git a/src/common/function/src/scalars/geo/h3.rs b/src/common/function/src/scalars/geo/h3.rs index 672fbfd714..00c567d8d7 100644 --- a/src/common/function/src/scalars/geo/h3.rs +++ b/src/common/function/src/scalars/geo/h3.rs @@ -20,18 +20,71 @@ use common_query::error::{self, InvalidFuncArgsSnafu, Result}; use common_query::prelude::{Signature, TypeSignature}; use datafusion::logical_expr::Volatility; use datatypes::prelude::ConcreteDataType; -use datatypes::scalars::ScalarVectorBuilder; -use datatypes::value::Value; +use datatypes::scalars::{Scalar, ScalarVectorBuilder}; +use datatypes::value::{ListValue, Value}; use datatypes::vectors::{ - BooleanVectorBuilder, Float64VectorBuilder, MutableVector, StringVectorBuilder, - UInt64VectorBuilder, UInt8VectorBuilder, VectorRef, + BooleanVectorBuilder, Int32VectorBuilder, ListVectorBuilder, MutableVector, + StringVectorBuilder, UInt64VectorBuilder, UInt8VectorBuilder, VectorRef, }; use derive_more::Display; use h3o::{CellIndex, LatLng, Resolution}; +use once_cell::sync::Lazy; use snafu::{ensure, ResultExt}; +use super::helpers::{ensure_columns_len, ensure_columns_n}; use crate::function::{Function, FunctionContext}; +static CELL_TYPES: Lazy> = Lazy::new(|| { + vec![ + ConcreteDataType::int64_datatype(), + ConcreteDataType::uint64_datatype(), + ] +}); + +static COORDINATE_TYPES: Lazy> = Lazy::new(|| { + vec![ + ConcreteDataType::float32_datatype(), + ConcreteDataType::float64_datatype(), + ] +}); +static RESOLUTION_TYPES: Lazy> = Lazy::new(|| { + vec![ + ConcreteDataType::int8_datatype(), + ConcreteDataType::int16_datatype(), + ConcreteDataType::int32_datatype(), + ConcreteDataType::int64_datatype(), + ConcreteDataType::uint8_datatype(), + ConcreteDataType::uint16_datatype(), + ConcreteDataType::uint32_datatype(), + ConcreteDataType::uint64_datatype(), + ] +}); +static DISTANCE_TYPES: Lazy> = Lazy::new(|| { + vec![ + ConcreteDataType::int8_datatype(), + ConcreteDataType::int16_datatype(), + ConcreteDataType::int32_datatype(), + ConcreteDataType::int64_datatype(), + ConcreteDataType::uint8_datatype(), + ConcreteDataType::uint16_datatype(), + ConcreteDataType::uint32_datatype(), + ConcreteDataType::uint64_datatype(), + ] +}); + +static POSITION_TYPES: Lazy> = Lazy::new(|| { + vec![ + ConcreteDataType::int8_datatype(), + ConcreteDataType::int16_datatype(), + ConcreteDataType::int32_datatype(), + ConcreteDataType::int64_datatype(), + ConcreteDataType::uint8_datatype(), + ConcreteDataType::uint16_datatype(), + ConcreteDataType::uint32_datatype(), + ConcreteDataType::uint64_datatype(), + ] +}); + /// Function that returns [h3] encoding cellid for a given geospatial coordinate. /// /// [h3]: https://h3geo.org/ @@ -50,20 +103,8 @@ impl Function for H3LatLngToCell { fn signature(&self) -> Signature { let mut signatures = Vec::new(); - for coord_type in &[ - ConcreteDataType::float32_datatype(), - ConcreteDataType::float64_datatype(), - ] { - for resolution_type in &[ - ConcreteDataType::int8_datatype(), - ConcreteDataType::int16_datatype(), - ConcreteDataType::int32_datatype(), - ConcreteDataType::int64_datatype(), - ConcreteDataType::uint8_datatype(), - ConcreteDataType::uint16_datatype(), - ConcreteDataType::uint32_datatype(), - ConcreteDataType::uint64_datatype(), - ] { + for coord_type in COORDINATE_TYPES.as_slice() { + for resolution_type in RESOLUTION_TYPES.as_slice() { signatures.push(TypeSignature::Exact(vec![ // latitude coord_type.clone(), @@ -78,15 +119,7 @@ impl Function for H3LatLngToCell { } fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { - ensure!( - columns.len() == 3, - InvalidFuncArgsSnafu { - err_msg: format!( - "The length of the args is not correct, expect 3, provided : {}", - columns.len() - ), - } - ); + ensure_columns_n!(columns, 3); let lat_vec = &columns[0]; let lon_vec = &columns[1]; @@ -142,20 +175,8 @@ impl Function for H3LatLngToCellString { fn signature(&self) -> Signature { let mut signatures = Vec::new(); - for coord_type in &[ - ConcreteDataType::float32_datatype(), - ConcreteDataType::float64_datatype(), - ] { - for resolution_type in &[ - ConcreteDataType::int8_datatype(), - ConcreteDataType::int16_datatype(), - ConcreteDataType::int32_datatype(), - ConcreteDataType::int64_datatype(), - ConcreteDataType::uint8_datatype(), - ConcreteDataType::uint16_datatype(), - ConcreteDataType::uint32_datatype(), - ConcreteDataType::uint64_datatype(), - ] { + for coord_type in COORDINATE_TYPES.as_slice() { + for resolution_type in RESOLUTION_TYPES.as_slice() { signatures.push(TypeSignature::Exact(vec![ // latitude coord_type.clone(), @@ -170,15 +191,7 @@ impl Function for H3LatLngToCellString { } fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { - ensure!( - columns.len() == 3, - InvalidFuncArgsSnafu { - err_msg: format!( - "The length of the args is not correct, expect 3, provided : {}", - columns.len() - ), - } - ); + ensure_columns_n!(columns, 3); let lat_vec = &columns[0]; let lon_vec = &columns[1]; @@ -234,15 +247,7 @@ impl Function for H3CellToString { } fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { - ensure!( - columns.len() == 1, - InvalidFuncArgsSnafu { - err_msg: format!( - "The length of the args is not correct, expect 1, provided : {}", - columns.len() - ), - } - ); + ensure_columns_n!(columns, 1); let cell_vec = &columns[0]; let size = cell_vec.len(); @@ -280,15 +285,7 @@ impl Function for H3StringToCell { } fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { - ensure!( - columns.len() == 1, - InvalidFuncArgsSnafu { - err_msg: format!( - "The length of the args is not correct, expect 1, provided : {}", - columns.len() - ), - } - ); + ensure_columns_n!(columns, 1); let string_vec = &columns[0]; let size = string_vec.len(); @@ -319,18 +316,20 @@ impl Function for H3StringToCell { } } -/// Function that returns centroid latitude of given cell id +/// Function that returns centroid latitude and longitude of given cell id #[derive(Clone, Debug, Default, Display)] #[display("{}", self.name())] -pub struct H3CellCenterLat; +pub struct H3CellCenterLatLng; -impl Function for H3CellCenterLat { +impl Function for H3CellCenterLatLng { fn name(&self) -> &str { - "h3_cell_center_lat" + "h3_cell_center_latlng" } fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result { - Ok(ConcreteDataType::float64_datatype()) + Ok(ConcreteDataType::list_datatype( + ConcreteDataType::float64_datatype(), + )) } fn signature(&self) -> Signature { @@ -338,69 +337,26 @@ impl Function for H3CellCenterLat { } fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { - ensure!( - columns.len() == 1, - InvalidFuncArgsSnafu { - err_msg: format!( - "The length of the args is not correct, expect 1, provided : {}", - columns.len() - ), - } - ); + ensure_columns_n!(columns, 1); let cell_vec = &columns[0]; let size = cell_vec.len(); - let mut results = Float64VectorBuilder::with_capacity(size); + let mut results = + ListVectorBuilder::with_type_capacity(ConcreteDataType::float64_datatype(), size); for i in 0..size { let cell = cell_from_value(cell_vec.get(i))?; - let lat = cell.map(|cell| LatLng::from(cell).lat()); + let latlng = cell.map(LatLng::from); - results.push(lat); - } - - Ok(results.to_vector()) - } -} - -/// Function that returns centroid longitude of given cell id -#[derive(Clone, Debug, Default, Display)] -#[display("{}", self.name())] -pub struct H3CellCenterLng; - -impl Function for H3CellCenterLng { - fn name(&self) -> &str { - "h3_cell_center_lng" - } - - fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result { - Ok(ConcreteDataType::float64_datatype()) - } - - fn signature(&self) -> Signature { - signature_of_cell() - } - - fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { - ensure!( - columns.len() == 1, - InvalidFuncArgsSnafu { - err_msg: format!( - "The length of the args is not correct, expect 1, provided : {}", - columns.len() - ), + if let Some(latlng) = latlng { + let result = ListValue::new( + vec![latlng.lat().into(), latlng.lng().into()], + ConcreteDataType::float64_datatype(), + ); + results.push(Some(result.as_scalar_ref())); + } else { + results.push(None); } - ); - - let cell_vec = &columns[0]; - let size = cell_vec.len(); - let mut results = Float64VectorBuilder::with_capacity(size); - - for i in 0..size { - let cell = cell_from_value(cell_vec.get(i))?; - let lat = cell.map(|cell| LatLng::from(cell).lng()); - - results.push(lat); } Ok(results.to_vector()) @@ -470,15 +426,7 @@ impl Function for H3CellBase { } fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { - ensure!( - columns.len() == 1, - InvalidFuncArgsSnafu { - err_msg: format!( - "The length of the args is not correct, expect 1, provided : {}", - columns.len() - ), - } - ); + ensure_columns_n!(columns, 1); let cell_vec = &columns[0]; let size = cell_vec.len(); @@ -514,15 +462,7 @@ impl Function for H3CellIsPentagon { } fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { - ensure!( - columns.len() == 1, - InvalidFuncArgsSnafu { - err_msg: format!( - "The length of the args is not correct, expect 1, provided : {}", - columns.len() - ), - } - ); + ensure_columns_n!(columns, 1); let cell_vec = &columns[0]; let size = cell_vec.len(); @@ -558,15 +498,7 @@ impl Function for H3CellCenterChild { } fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { - ensure!( - columns.len() == 2, - InvalidFuncArgsSnafu { - err_msg: format!( - "The length of the args is not correct, expect 2, provided : {}", - columns.len() - ), - } - ); + ensure_columns_n!(columns, 2); let cell_vec = &columns[0]; let res_vec = &columns[1]; @@ -606,15 +538,7 @@ impl Function for H3CellParent { } fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { - ensure!( - columns.len() == 2, - InvalidFuncArgsSnafu { - err_msg: format!( - "The length of the args is not correct, expect 2, provided : {}", - columns.len() - ), - } - ); + ensure_columns_n!(columns, 2); let cell_vec = &columns[0]; let res_vec = &columns[1]; @@ -633,48 +557,323 @@ impl Function for H3CellParent { } } -/// Function that checks if two cells are neighbour +/// Function that returns children cell list #[derive(Clone, Debug, Default, Display)] #[display("{}", self.name())] -pub struct H3IsNeighbour; +pub struct H3CellToChildren; -impl Function for H3IsNeighbour { +impl Function for H3CellToChildren { fn name(&self) -> &str { - "h3_is_neighbour" + "h3_cell_to_children" } fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result { - Ok(ConcreteDataType::boolean_datatype()) + Ok(ConcreteDataType::list_datatype( + ConcreteDataType::uint64_datatype(), + )) } fn signature(&self) -> Signature { - signature_of_double_cell() + signature_of_cell_and_resolution() } fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { - ensure!( - columns.len() == 2, - InvalidFuncArgsSnafu { - err_msg: format!( - "The length of the args is not correct, expect 2, provided : {}", - columns.len() - ), - } - ); + ensure_columns_n!(columns, 2); let cell_vec = &columns[0]; - let cell2_vec = &columns[1]; + let res_vec = &columns[1]; let size = cell_vec.len(); - let mut results = BooleanVectorBuilder::with_capacity(size); + let mut results = + ListVectorBuilder::with_type_capacity(ConcreteDataType::uint64_datatype(), size); + + for i in 0..size { + let cell = cell_from_value(cell_vec.get(i))?; + let res = value_to_resolution(res_vec.get(i))?; + let result = cell.map(|cell| { + let children: Vec = cell + .children(res) + .map(|child| Value::from(u64::from(child))) + .collect(); + ListValue::new(children, ConcreteDataType::uint64_datatype()) + }); + + if let Some(list_value) = result { + results.push(Some(list_value.as_scalar_ref())); + } else { + results.push(None); + } + } + + Ok(results.to_vector()) + } +} + +/// Function that returns children cell count +#[derive(Clone, Debug, Default, Display)] +#[display("{}", self.name())] +pub struct H3CellToChildrenSize; + +impl Function for H3CellToChildrenSize { + fn name(&self) -> &str { + "h3_cell_to_children_size" + } + + fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result { + Ok(ConcreteDataType::uint64_datatype()) + } + + fn signature(&self) -> Signature { + signature_of_cell_and_resolution() + } + + fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { + ensure_columns_n!(columns, 2); + + let cell_vec = &columns[0]; + let res_vec = &columns[1]; + let size = cell_vec.len(); + let mut results = UInt64VectorBuilder::with_capacity(size); + + for i in 0..size { + let cell = cell_from_value(cell_vec.get(i))?; + let res = value_to_resolution(res_vec.get(i))?; + let result = cell.map(|cell| cell.children_count(res)); + results.push(result); + } + + Ok(results.to_vector()) + } +} + +/// Function that returns the cell position if its parent at given resolution +#[derive(Clone, Debug, Default, Display)] +#[display("{}", self.name())] +pub struct H3CellToChildPos; + +impl Function for H3CellToChildPos { + fn name(&self) -> &str { + "h3_cell_to_child_pos" + } + + fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result { + Ok(ConcreteDataType::uint64_datatype()) + } + + fn signature(&self) -> Signature { + signature_of_cell_and_resolution() + } + + fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { + ensure_columns_n!(columns, 2); + + let cell_vec = &columns[0]; + let res_vec = &columns[1]; + let size = cell_vec.len(); + let mut results = UInt64VectorBuilder::with_capacity(size); + + for i in 0..size { + let cell = cell_from_value(cell_vec.get(i))?; + let res = value_to_resolution(res_vec.get(i))?; + let result = cell.and_then(|cell| cell.child_position(res)); + results.push(result); + } + + Ok(results.to_vector()) + } +} + +/// Function that returns the cell at given position of the parent at given resolution +#[derive(Clone, Debug, Default, Display)] +#[display("{}", self.name())] +pub struct H3ChildPosToCell; + +impl Function for H3ChildPosToCell { + fn name(&self) -> &str { + "h3_child_pos_to_cell" + } + + fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result { + Ok(ConcreteDataType::uint64_datatype()) + } + + fn signature(&self) -> Signature { + let mut signatures = + Vec::with_capacity(POSITION_TYPES.len() * CELL_TYPES.len() * RESOLUTION_TYPES.len()); + for position_type in POSITION_TYPES.as_slice() { + for cell_type in CELL_TYPES.as_slice() { + for resolution_type in RESOLUTION_TYPES.as_slice() { + signatures.push(TypeSignature::Exact(vec![ + position_type.clone(), + cell_type.clone(), + resolution_type.clone(), + ])); + } + } + } + Signature::one_of(signatures, Volatility::Stable) + } + + fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { + ensure_columns_n!(columns, 3); + + let pos_vec = &columns[0]; + let cell_vec = &columns[1]; + let res_vec = &columns[2]; + let size = cell_vec.len(); + let mut results = UInt64VectorBuilder::with_capacity(size); + + for i in 0..size { + let cell = cell_from_value(cell_vec.get(i))?; + let pos = value_to_position(pos_vec.get(i))?; + let res = value_to_resolution(res_vec.get(i))?; + let result = cell.and_then(|cell| cell.child_at(pos, res).map(u64::from)); + results.push(result); + } + + Ok(results.to_vector()) + } +} + +/// Function that returns cells with k distances of given cell +#[derive(Clone, Debug, Default, Display)] +#[display("{}", self.name())] +pub struct H3GridDisk; + +impl Function for H3GridDisk { + fn name(&self) -> &str { + "h3_grid_disk" + } + + fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result { + Ok(ConcreteDataType::list_datatype( + ConcreteDataType::uint64_datatype(), + )) + } + + fn signature(&self) -> Signature { + signature_of_cell_and_distance() + } + + fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { + ensure_columns_n!(columns, 2); + + let cell_vec = &columns[0]; + let k_vec = &columns[1]; + let size = cell_vec.len(); + let mut results = + ListVectorBuilder::with_type_capacity(ConcreteDataType::uint64_datatype(), size); + + for i in 0..size { + let cell = cell_from_value(cell_vec.get(i))?; + let k = value_to_distance(k_vec.get(i))?; + + let result = cell.map(|cell| { + let children: Vec = cell + .grid_disk::>(k) + .into_iter() + .map(|child| Value::from(u64::from(child))) + .collect(); + ListValue::new(children, ConcreteDataType::uint64_datatype()) + }); + + if let Some(list_value) = result { + results.push(Some(list_value.as_scalar_ref())); + } else { + results.push(None); + } + } + + Ok(results.to_vector()) + } +} + +/// Function that returns all cells within k distances of given cell +#[derive(Clone, Debug, Default, Display)] +#[display("{}", self.name())] +pub struct H3GridDiskDistances; + +impl Function for H3GridDiskDistances { + fn name(&self) -> &str { + "h3_grid_disk_distances" + } + + fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result { + Ok(ConcreteDataType::list_datatype( + ConcreteDataType::uint64_datatype(), + )) + } + + fn signature(&self) -> Signature { + signature_of_cell_and_distance() + } + + fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { + ensure_columns_n!(columns, 2); + + let cell_vec = &columns[0]; + let k_vec = &columns[1]; + let size = cell_vec.len(); + let mut results = + ListVectorBuilder::with_type_capacity(ConcreteDataType::uint64_datatype(), size); + + for i in 0..size { + let cell = cell_from_value(cell_vec.get(i))?; + let k = value_to_distance(k_vec.get(i))?; + + let result = cell.map(|cell| { + let children: Vec = cell + .grid_disk_distances::>(k) + .into_iter() + .map(|(child, _distance)| Value::from(u64::from(child))) + .collect(); + ListValue::new(children, ConcreteDataType::uint64_datatype()) + }); + + if let Some(list_value) = result { + results.push(Some(list_value.as_scalar_ref())); + } else { + results.push(None); + } + } + + Ok(results.to_vector()) + } +} + +/// Function that returns distance between two cells +#[derive(Clone, Debug, Default, Display)] +#[display("{}", self.name())] +pub struct H3GridDistance; + +impl Function for H3GridDistance { + fn name(&self) -> &str { + "h3_grid_distance" + } + fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result { + Ok(ConcreteDataType::int32_datatype()) + } + + fn signature(&self) -> Signature { + signature_of_double_cells() + } + + fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { + ensure_columns_n!(columns, 2); + + let cell_this_vec = &columns[0]; + let cell_that_vec = &columns[1]; + let size = cell_this_vec.len(); + + let mut results = Int32VectorBuilder::with_capacity(size); for i in 0..size { let result = match ( - cell_from_value(cell_vec.get(i))?, - cell_from_value(cell2_vec.get(i))?, + cell_from_value(cell_this_vec.get(i))?, + cell_from_value(cell_that_vec.get(i))?, ) { (Some(cell_this), Some(cell_that)) => { - let is_neighbour = cell_this - .is_neighbor_with(cell_that) + let dist = cell_this + .grid_distance(cell_that) .map_err(|e| { BoxedError::new(PlainError::new( format!("H3 error: {}", e), @@ -682,7 +881,7 @@ impl Function for H3IsNeighbour { )) }) .context(error::ExecuteSnafu)?; - Some(is_neighbour) + Some(dist) } _ => None, }; @@ -694,6 +893,73 @@ impl Function for H3IsNeighbour { } } +/// Function that returns path cells between two cells +#[derive(Clone, Debug, Default, Display)] +#[display("{}", self.name())] +pub struct H3GridPathCells; + +impl Function for H3GridPathCells { + fn name(&self) -> &str { + "h3_grid_path_cells" + } + + fn return_type(&self, _input_types: &[ConcreteDataType]) -> Result { + Ok(ConcreteDataType::list_datatype( + ConcreteDataType::uint64_datatype(), + )) + } + + fn signature(&self) -> Signature { + signature_of_double_cells() + } + + fn eval(&self, _func_ctx: FunctionContext, columns: &[VectorRef]) -> Result { + ensure_columns_n!(columns, 2); + + let cell_this_vec = &columns[0]; + let cell_that_vec = &columns[1]; + let size = cell_this_vec.len(); + let mut results = + ListVectorBuilder::with_type_capacity(ConcreteDataType::uint64_datatype(), size); + + for i in 0..size { + let result = match ( + cell_from_value(cell_this_vec.get(i))?, + cell_from_value(cell_that_vec.get(i))?, + ) { + (Some(cell_this), Some(cell_that)) => { + let cells = cell_this + .grid_path_cells(cell_that) + .and_then(|x| x.collect::, _>>()) + .map_err(|e| { + BoxedError::new(PlainError::new( + format!("H3 error: {}", e), + StatusCode::EngineExecuteQuery, + )) + }) + .context(error::ExecuteSnafu)?; + Some(ListValue::new( + cells + .into_iter() + .map(|c| Value::from(u64::from(c))) + .collect(), + ConcreteDataType::uint64_datatype(), + )) + } + _ => None, + }; + + if let Some(list_value) = result { + results.push(Some(list_value.as_scalar_ref())); + } else { + results.push(None); + } + } + + Ok(results.to_vector()) + } +} + fn value_to_resolution(v: Value) -> Result { let r = match v { Value::Int8(v) => v as u8, @@ -716,26 +982,59 @@ fn value_to_resolution(v: Value) -> Result { .context(error::ExecuteSnafu) } +macro_rules! ensure_and_coerce { + ($compare:expr, $coerce:expr) => {{ + ensure!( + $compare, + InvalidFuncArgsSnafu { + err_msg: "Argument was outside of acceptable range " + } + ); + Ok($coerce) + }}; +} + +fn value_to_position(v: Value) -> Result { + match v { + Value::Int8(v) => ensure_and_coerce!(v >= 0, v as u64), + Value::Int16(v) => ensure_and_coerce!(v >= 0, v as u64), + Value::Int32(v) => ensure_and_coerce!(v >= 0, v as u64), + Value::Int64(v) => ensure_and_coerce!(v >= 0, v as u64), + Value::UInt8(v) => Ok(v as u64), + Value::UInt16(v) => Ok(v as u64), + Value::UInt32(v) => Ok(v as u64), + Value::UInt64(v) => Ok(v), + _ => unreachable!(), + } +} + +fn value_to_distance(v: Value) -> Result { + match v { + Value::Int8(v) => ensure_and_coerce!(v >= 0, v as u32), + Value::Int16(v) => ensure_and_coerce!(v >= 0, v as u32), + Value::Int32(v) => ensure_and_coerce!(v >= 0, v as u32), + Value::Int64(v) => ensure_and_coerce!(v >= 0, v as u32), + Value::UInt8(v) => Ok(v as u32), + Value::UInt16(v) => Ok(v as u32), + Value::UInt32(v) => Ok(v), + Value::UInt64(v) => Ok(v as u32), + _ => unreachable!(), + } +} + fn signature_of_cell() -> Signature { - let mut signatures = Vec::new(); - for cell_type in &[ - ConcreteDataType::uint64_datatype(), - ConcreteDataType::int64_datatype(), - ] { + let mut signatures = Vec::with_capacity(CELL_TYPES.len()); + for cell_type in CELL_TYPES.as_slice() { signatures.push(TypeSignature::Exact(vec![cell_type.clone()])); } Signature::one_of(signatures, Volatility::Stable) } -fn signature_of_double_cell() -> Signature { - let mut signatures = Vec::new(); - let cell_types = &[ - ConcreteDataType::uint64_datatype(), - ConcreteDataType::int64_datatype(), - ]; - for cell_type in cell_types { - for cell_type2 in cell_types { +fn signature_of_double_cells() -> Signature { + let mut signatures = Vec::with_capacity(CELL_TYPES.len() * CELL_TYPES.len()); + for cell_type in CELL_TYPES.as_slice() { + for cell_type2 in CELL_TYPES.as_slice() { signatures.push(TypeSignature::Exact(vec![ cell_type.clone(), cell_type2.clone(), @@ -747,21 +1046,9 @@ fn signature_of_double_cell() -> Signature { } fn signature_of_cell_and_resolution() -> Signature { - let mut signatures = Vec::new(); - for cell_type in &[ - ConcreteDataType::uint64_datatype(), - ConcreteDataType::int64_datatype(), - ] { - for resolution_type in &[ - ConcreteDataType::int8_datatype(), - ConcreteDataType::int16_datatype(), - ConcreteDataType::int32_datatype(), - ConcreteDataType::int64_datatype(), - ConcreteDataType::uint8_datatype(), - ConcreteDataType::uint16_datatype(), - ConcreteDataType::uint32_datatype(), - ConcreteDataType::uint64_datatype(), - ] { + let mut signatures = Vec::with_capacity(CELL_TYPES.len() * RESOLUTION_TYPES.len()); + for cell_type in CELL_TYPES.as_slice() { + for resolution_type in RESOLUTION_TYPES.as_slice() { signatures.push(TypeSignature::Exact(vec![ cell_type.clone(), resolution_type.clone(), @@ -771,6 +1058,19 @@ fn signature_of_cell_and_resolution() -> Signature { Signature::one_of(signatures, Volatility::Stable) } +fn signature_of_cell_and_distance() -> Signature { + let mut signatures = Vec::with_capacity(CELL_TYPES.len() * DISTANCE_TYPES.len()); + for cell_type in CELL_TYPES.as_slice() { + for distance_type in DISTANCE_TYPES.as_slice() { + signatures.push(TypeSignature::Exact(vec![ + cell_type.clone(), + distance_type.clone(), + ])); + } + } + Signature::one_of(signatures, Volatility::Stable) +} + fn cell_from_value(v: Value) -> Result> { let cell = match v { Value::Int64(v) => Some( diff --git a/tests/cases/standalone/common/function/geo.result b/tests/cases/standalone/common/function/geo.result index 4f9d168ac0..75caeb886b 100644 --- a/tests/cases/standalone/common/function/geo.result +++ b/tests/cases/standalone/common/function/geo.result @@ -102,35 +102,58 @@ SELECT h3_cell_to_string(h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64)) AS c | 88283082e7fffff | 613196570438926335 | +-----------------+--------------------+ -SELECT h3_cell_center_lat(h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64)) AS cell_center_lat, h3_cell_center_lng(h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64)) AS cell_center_lng; +SELECT h3_cell_center_latlng(h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64)) AS cell_center; -+-------------------+---------------------+ -| cell_center_lat | cell_center_lng | -+-------------------+---------------------+ -| 37.77246152245501 | -122.39010997087324 | -+-------------------+---------------------+ ++------------------------------------------+ +| cell_center | ++------------------------------------------+ +| [37.77246152245501, -122.39010997087324] | ++------------------------------------------+ SELECT h3_cell_resolution(cell) AS resolution, h3_cell_base(cell) AS base, h3_cell_is_pentagon(cell) AS pentagon, h3_cell_parent(cell, 6::UInt64) AS parent, + h3_cell_to_children(cell, 10::UInt64) AS children, + h3_cell_to_children_size(cell, 10) AS children_count, + h3_cell_to_child_pos(cell, 6) AS child_pos, + h3_child_pos_to_cell(25, cell, 11) AS child FROM (SELECT h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64) AS cell); -+------------+------+----------+--------------------+ -| resolution | base | pentagon | parent | -+------------+------+----------+--------------------+ -| 8 | 20 | false | 604189371209351167 | -+------------+------+----------+--------------------+ ++------------+------+----------+--------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------+-----------+--------------------+ +| resolution | base | pentagon | parent | children | children_count | child_pos | child | ++------------+------+----------+--------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------+-----------+--------------------+ +| 8 | 20 | false | 604189371209351167 | [622203769691602943, 622203769691635711, 622203769691668479, 622203769691701247, 622203769691734015, 622203769691766783, 622203769691799551, 622203769691865087, 622203769691897855, 622203769691930623, 622203769691963391, 622203769691996159, 622203769692028927, 622203769692061695, 622203769692127231, 622203769692159999, 622203769692192767, 622203769692225535, 622203769692258303, 622203769692291071, 622203769692323839, 622203769692389375, 622203769692422143, 622203769692454911, 622203769692487679, 622203769692520447, 622203769692553215, 622203769692585983, 622203769692651519, 622203769692684287, 622203769692717055, 622203769692749823, 622203769692782591, 622203769692815359, 622203769692848127, 622203769692913663, 622203769692946431, 622203769692979199, 622203769693011967, 622203769693044735, 622203769693077503, 622203769693110271, 622203769693175807, 622203769693208575, 622203769693241343, 622203769693274111, 622203769693306879, 622203769693339647, 622203769693372415] | 49 | 45 | 626707369319059455 | ++------------+------+----------+--------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------+-----------+--------------------+ -SELECT h3_is_neighbour(cell1, cell2) -FROM (SELECT h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64) AS cell1, h3_latlng_to_cell(36.76938, -122.3889, 8::UInt64) AS cell2); +SELECT + h3_grid_disk(cell, 0) AS current_cell, + h3_grid_disk(cell, 3) AS grids, + h3_grid_disk_distances(cell, 3) AS all_grids, +FROM (SELECT h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64) AS cell); -+------------------------------+ -| h3_is_neighbour(cell1,cell2) | -+------------------------------+ -| false | -+------------------------------+ ++----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| current_cell | grids | all_grids | ++----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| [613196570438926335] | [613196570438926335, 613196570436829183, 613196569755254783, 613196570378108927, 613196570373914623, 613196570434732031, 613196570432634879, 613196570445217791, 613196570250182655, 613196569753157631, 613196569744769023, 613196569746866175, 613196570369720319, 613196570365526015, 613196570376011775, 613196570336165887, 613196570344554495, 613196570443120639, 613196570441023487, 613196570220822527, 613196570258571263, 613196570248085503, 613196570254376959, 613196569757351935, 613196569748963327, 613196569751060479, 613196569686048767, 613196569688145919, 613196570371817471, 613196570367623167, 613196570394886143, 613196570338263039, 613196570331971583, 613196570340360191, 613196570405371903, 613196570403274751, 613196570216628223] | [613196570438926335, 613196570436829183, 613196569755254783, 613196570378108927, 613196570373914623, 613196570434732031, 613196570432634879, 613196570445217791, 613196570250182655, 613196569753157631, 613196569744769023, 613196569746866175, 613196570369720319, 613196570365526015, 613196570376011775, 613196570336165887, 613196570344554495, 613196570443120639, 613196570441023487, 613196570220822527, 613196570258571263, 613196570248085503, 613196570254376959, 613196569757351935, 613196569748963327, 613196569751060479, 613196569686048767, 613196569688145919, 613196570371817471, 613196570367623167, 613196570394886143, 613196570338263039, 613196570331971583, 613196570340360191, 613196570405371903, 613196570403274751, 613196570216628223] | ++----------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +SELECT + h3_grid_distance(cell1, cell2) AS distance, + h3_grid_path_cells(cell1, cell2) AS path_cells, +FROM + ( + SELECT + h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64) AS cell1, + h3_latlng_to_cell(39.634, -104.999, 8::UInt64) AS cell2 + ); + ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| distance | path_cells | ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| 1612 | [613196570438926335, 613196569755254783, 613196569744769023, 613196569748963327, 613196569669271551, 613196569673465855, 613196569763643391, 613196569767837695, 613196570023690239, 613196570021593087, 613196570025787391, 613196569998524415, 613196570002718719, 613196570040467455, 613196570029981695, 613196570034175999, 613196572437512191, 613196572441706495, 613196572414443519, 613196572418637823, 613196572456386559, 613196572445900799, 613196572450095103, 613196572705947647, 613196572710141951, 613196572691267583, 613196572680781823, 613196572684976127, 613196572722724863, 613196572726919167, 613196592932978687, 613196592937172991, 613196592421273599, 613196592410787839, 613196592414982143, 613196592452730879, 613196592456925183, 613196592261890047, 613196592266084351, 613196592689709055, 613196592679223295, 613196592683417599, 613196592496771071, 613196592500965375, 613196592538714111, 613196592528228351, 613196592532422655, 613196587587338239, 613196587591532543, 613196587396497407, 613196587400691711, 613196587438440447, 613196587427954687, 613196587432148991, 613196586916249599, 613196586920443903, 613196587664932863, 613196587669127167, 613196587706875903, 613196587704778751, 613196587708973055, 613196587681710079, 613196587685904383, 613196593444683775, 613196593434198015, 613196593438392319, 613196593476141055, 613196593480335359, 613196593453072383, 613196593457266687, 613196593713119231, 613196593702633471, 613196593706827775, 613196593744576511, 613196593748770815, 613196593729896447, 613196593719410687, 613196593723604991, 613196962272903167, 613196962277097471, 613196962249834495, 613196962254028799, 613196962291777535, 613196962281291775, 613196962285486079, 613196961601814527, 613196961606008831, 613196961578745855, 613196961582940159, 613196961620688895, 613196961610203135, 613196961614397439, 613196961931067391, 613196961935261695, 613196961855569919, 613196961845084159, 613196961849278463, 613196961887027199, 613196961891221503, 613196956830793727, 613196956834988031, 613196956755296255, 613196956744810495, 613196956749004799, 613196956786753535, 613196956790947839, 613196957099229183, 613196957103423487, 613196957023731711, 613196957021634559, 613196957025828863, 613196957116006399, 613196957120200703, 613196962878980095, 613196962868494335, 613196962872688639, 613196962792996863, 613196962797191167, 613196962887368703, 613196962891563007, 613196963147415551, 613196963136929791, 613196963141124095, 613196963061432319, 613196963065626623, 613196963164192767, 613196963153707007, 613196963157901311, 613196979519881215, 613196979524075519, 613196979496812543, 613196979501006847, 613196979538755583, 613196979528269823, 613196979532464127, 613196978848792575, 613196978852986879, 613196978825723903, 613196978829918207, 613196978867666943, 613196978857181183, 613196978861375487, 613196979614253055, 613196979618447359, 613196979102547967, 613196979092062207, 613196979096256511, 613196979134005247, 613196979138199551, 613196977869422591, 613196977873616895, 613196974002274303, 613196973991788543, 613196973995982847, 613196974033731583, 613196974037925887, 613196978137858047, 613196978142052351, 613196978139955199, 613196974268612607, 613196974272806911, 613196980520222719, 613196980524417023, 613196980562165759, 613196980551679999, 613196980555874303, 613196980039974911, 613196980044169215, 613196979849134079, 613196979853328383, 613196979891077119, 613196979880591359, 613196979884785663, 613196980308410367, 613196980312604671, 613196980125958143, 613196980115472383, 613196980119666687, 613196980157415423, 613196980161609727, 613196980134346751, 613196980138541055, 613220567281041407, 613220567270555647, 613220567274749951, 613220567312498687, 613220567316692991, 613220567289430015, 613220567293624319, 613220567549476863, 613220567538991103, 613220567543185407, 613220567524311039, 613220567528505343, 613220567566254079, 613220567555768319, 613220567559962623, 613220565802549247, 613220565806743551, 613220565779480575, 613220565783674879, 613220565821423615, 613220565810937855, 613220565815132159, 613220566070984703, 613220566075179007, 613220566047916031, 613220566052110335, 613220566050013183, 613220566087761919, 613220566091956223, 613220568547721215, 613220568551915519, 613220568472223743, 613220568461737983, 613220568465932287, 613220568503681023, 613220568507875327, 613220567876632575, 613220567880826879, 613220567801135103, 613220567790649343, 613220567794843647, 613220567832592383, 613220567836786687, 613220568153456639, 613220568142970879, 613220568147165183, 613220568067473407, 613220568071667711, 613220568161845247, 613220568166039551, 613220524398477311, 613220524387991551, 613220524392185855, 613220524312494079, 613220524316688383, 613220524406865919, 613220524411060223, 613220524666912767, 613220524656427007, 613220524669009919, 613220524641746943, 613220524645941247, 613220524683689983, 613220524673204223, 613220524677398527, 613220522919985151, 613220522924179455, 613220522896916479, 613220522901110783, 613220522938859519, 613220522928373759, 613220522932568063, 613220523188420607, 613220523192614911, 613220523165351935, 613220523169546239, 613220523167449087, 613220523205197823, 613220523209392127, 613220523014356991, 613220523018551295, 613220525589659647, 613220525579173887, 613220525583368191, 613220525621116927, 613220525625311231, 613220525430276095, 613220525434470399, 613220524918571007, 613220524908085247, 613220524912279551, 613220524950028287, 613220524954222591, 613220525707100159, 613220525696614399, 613220525700808703, 613220525184909311, 613220525189103615, 613220573312450559, 613220573316644863, 613220573354393599, 613220573343907839, 613220573348102143, 613220541559472127, 613220541563666431, 613220573580886015, 613220573585080319, 613220573622829055, 613220573612343295, 613220573624926207, 613220573597663231, 613220573601857535, 613220540571713535, 613220540561227775, 613220540565422079, 613220540603170815, 613220540607365119, 613220540580102143, 613220540584296447, 613220539900624895, 613220539890139135, 613220539894333439, 613220539932082175, 613220539936276479, 613220539909013503, 613220539913207807, 613220539911110655, 613220540166963199, 613220540171157503, 613220540143894527, 613220540148088831, 613220540185837567, 613220540175351807, 613220540179546111, 613220542582882303, 613220542587076607, 613220542559813631, 613220542564007935, 613220542601756671, 613220542591270911, 613220542595465215, 613220542851317759, 613220542855512063, 613220542836637695, 613220542826151935, 613220542830346239, 613220542868094975, 613220542872289279, 613220461710409727, 613220461714604031, 613220461634912255, 613220461624426495, 613220461628620799, 613220461666369535, 613220461670563839, 613220461978845183, 613220461983039487, 613220461903347711, 613220461892861951, 613220461905444863, 613220461995622399, 613220461999816703, 613220214221307903, 613220214210822143, 613220214215016447, 613220214135324671, 613220214139518975, 613220214229696511, 613220214233890815, 613220213550219263, 613220213539733503, 613220213543927807, 613220213464236031, 613220213468430335, 613220213558607871, 613220213562802175, 613220213560705023, 613220213816557567, 613220213820751871, 613220213793488895, 613220213797683199, 613220213835431935, 613220213824946175, 613220213829140479, 613220216232476671, 613220216236670975, 613220216209407999, 613220216213602303, 613220216251351039, 613220216240865279, 613220216245059583, 613220216500912127, 613220476981870591, 613220216486232063, 613220216475746303, 613220216479940607, 613220216517689343, 613220216521883647, 613220479393595391, 613220479397789695, 613220478881890303, 613220478871404543, 613220478875598847, 613220478913347583, 613220478917541887, 613220478722506751, 613220478726701055, 613220479150325759, 613220479139839999, 613220479152422911, 613220478957387775, 613220478961582079, 613220478999330815, 613220478988845055, 613220478993039359, 613220231382302719, 613220231386497023, 613220231191461887, 613220231195656191, 613220231233404927, 613220231222919167, 613220231227113471, 613220230711214079, 613220230715408383, 613220231459897343, 613220231464091647, 613220231461994495, 613220231499743231, 613220231503937535, 613220231476674559, 613220231480868863, 613220631302897663, 613220631292411903, 613220631296606207, 613220631334354943, 613220631338549247, 613220631311286271, 613220631315480575, 613220631571333119, 613220631560847359, 613220631565041663, 613220631602790399, 613220631550361599, 613220631588110335, 613220631577624575, 613220631581818879, 613220633985155071, 613220633989349375, 613220633962086399, 613220633966280703, 613220634004029439, 613220633993543679, 613220633997737983, 613220633314066431, 613220633318260735, 613220633290997759, 613220633295192063, 613220633332940799, 613220633322455039, 613220633335037951, 613220633643319295, 613220633647513599, 613220633567821823, 613220633557336063, 613220633561530367, 613220633599279103, 613220633603473407, 613220600625758207, 613220600629952511, 613220600550260735, 613220600539774975, 613220600543969279, 613220600581718015, 613220600585912319, 613220600894193663, 613220600898387967, 613220600896290815, 613220600816599039, 613220600820793343, 613220600910970879, 613220600915165183, 613220588420333567, 613220588409847807, 613220588414042111, 613220588334350335, 613220588338544639, 613220588428722175, 613220588432916479, 613220588688769023, 613220588678283263, 613220588682477567, 613220588602785791, 613220588667797503, 613220588705546239, 613220588695060479, 613220588699254783, 613220591102590975, 613220591106785279, 613220591079522303, 613220591083716607, 613220591121465343, 613220591110979583, 613220591115173887, 613220590431502335, 613220590435696639, 613220590408433663, 613220590412627967, 613220590450376703, 613220590439890943, 613220590452473855, 613220591196962815, 613220591201157119, 613220590685257727, 613220590674771967, 613220590678966271, 613220590716715007, 613220590720909311, 613220589452132351, 613220589456326655, 613220617797238783, 613220617786753023, 613220617790947327, 613220617828696063, 613220617832890367, 613220589720567807, 613220589718470655, 613220589722664959, 613220618063577087, 613220618067771391, 613220606061576191, 613220606065770495, 613220606103519231, 613220606093033471, 613220606097227775, 613220605581328383, 613220605585522687, 613220605390487551, 613220605394681855, 613220605432430591, 613220605421944831, 613220605426139135, 613220605849763839, 613220605411459071, 613220605667311615, 613220605656825855, 613220605661020159, 613220605698768895, 613220605702963199, 613220605675700223, 613220605679894527, 613220608083230719, 613220608072744959, 613220608076939263, 613220608114687999, 613220608118882303, 613220608091619327, 613220608095813631, 613220608351666175, 613220608341180415, 613220608353763327, 613220608326500351, 613220608330694655, 613220608368443391, 613220608357957631, 613220608362151935, 613220606604738559, 613220606608932863, 613220606581669887, 613220606585864191, 613220606623612927, 613220606613127167, 613220606617321471, 613220606873174015, 613220606877368319, 613220606850105343, 613220606848008191, 613220606852202495, 613220606889951231, 613220606894145535, 613221654100705279, 613221654104899583, 613221654025207807, 613221654014722047, 613221654018916351, 613221654056665087, 613221654060859391, 613221653429616639, 613221653433810943, 613221653354119167, 613221653343633407, 613221653347827711, 613221653385576447, 613221653450588159, 613221653706440703, 613221653695954943, 613221653700149247, 613221653620457471, 613221653624651775, 613221653714829311, 613221653719023615, 613221656122359807, 613221656111874047, 613221656116068351, 613221656036376575, 613221656040570879, 613221656130748415, 613221656134942719, 613221656390795263, 613221656388698111, 613221656392892415, 613221656365629439, 613221656369823743, 613221656407572479, 613221656397086719, 613221656401281023, 613221654643867647, 613221654648061951, 613221654620798975, 613221654624993279, 613221654662742015, 613221654652256255, 613221654656450559, 613221654912303103, 613221654916497407, 613221654889234431, 613221654887137279, 613221654891331583, 613221654929080319, 613221654933274623, 613221654738239487, 613221654742433791, 613221671272185855, 613221671261700095, 613221671265894399, 613221671303643135, 613221671307837439, 613221671112802303, 613221671116996607, 613221670601097215, 613221670590611455, 613221670594805759, 613221670632554495, 613221671351877631, 613221671389626367, 613221671379140607, 613221671383334911, 613221670867435519, 613221670871629823, 613221669602852863, 613221669607047167, 613221669644795903, 613221669634310143, 613221669638504447, 613221673283354623, 613221673287548927, 613221669871288319, 613221669875482623, 613221669913231359, 613221669911134207, 613221669915328511, 613221669888065535, 613221669892259839, 613221672295596031, 613221672285110271, 613221672289304575, 613221672327053311, 613221672331247615, 613221672303984639, 613221672308178943, 613221671624507391, 613221671614021631, 613221671618215935, 613221671655964671, 613221671660158975, 613221671632895999, 613221671630798847, 613221671634993151, 613221671890845695, 613221671895039999, 613221671867777023, 613221671871971327, 613221671909720063, 613221671899234303, 613221671903428607, 613221559416389631, 613221559420583935, 613221559393320959, 613221559397515263, 613221559435263999, 613221559424778239, 613221559428972543, 613221559684825087, 613221559749836799, 613221559670145023, 613221559659659263, 613221559663853567, 613221559701602303, 613221559705796607, 613221558000812031, 613221558005006335, 613221557925314559, 613221557914828799, 613221557919023103, 613221557956771839, 613221557960966143, 613221558269247487, 613221558273441791, 613221558193750015, 613221558191652863, 613221558195847167, 613221558286024703, 613221558290219007, 613221560693555199, 613221560683069439, 613221560687263743, 613221560607571967, 613221560611766271, 613221560701943807, 613221560706138111, 613221560022466559, 613221560011980799, 613221560016175103, 613221559936483327, 613221559940677631, 613221560030855167, 613221560028758015, 613221560032952319, 613221560288804863, 613221560292999167, 613221560265736191, 613221560269930495, 613221560307679231, 613221560297193471, 613221560301387775, 613221576663367679, 613221576667561983, 613221576640299007, 613221576644493311, 613221576682242047, 613221576671756287, 613221576675950591, 613221580784271359, 613221580788465663, 613221576917123071, 613221576906637311, 613221576910831615, 613221576948580351, 613221576952774655, 613221575683997695, 613221575688191999, 613221575172292607, 613221575161806847, 613221575166001151, 613221575203749887, 613221575207944191, 613221575012909055, 613221575017103359, 613221575440728063, 613221575438630911, 613221575442825215, 613221575247790079, 613221575251984383, 613221575289733119, 613221575279247359, 613221575283441663, 613221577854550015, 613221577858744319, 613221577663709183, 613221577667903487, 613221577705652223, 613221577695166463, 613221577699360767, 613221577183461375, 613221577187655679, 613221577932144639, 613221577930047487, 613221577934241791, 613221577971990527, 613221577976184831, 613221577948921855, 613221577953116159, 613221735109492735, 613221735099006975, 613221735103201279, 613221735140950015, 613221735145144319, 613221735117881343, 613221735122075647, 613221735377928191, 613221735367442431, 613221735371636735, 613221735352762367, 613221735356956671, 613221735394705407, 613221735384219647, 613221735388413951, 613221730275557375, 613221730279751679, 613221730252488703, 613221730256683007, 613221730294431743, 613221730283945983, 613221730288140287, 613221729604468735, 613221729608663039, 613221729581400063, 613221729585594367, 613221729623343103, 613221729621245951, 613221729625440255, 613221729933721599, 613221729937915903, 613221729858224127, 613221729847738367, 613221729851932671, 613221729889681407, 613221729893875711, 613221732349640703, 613221732353835007, 613221732274143231, 613221732263657471, 613221732267851775, 613221732305600511, 613221732309794815, 613221732626464767, 613221732615979007, 613221732620173311, 613221732540481535, 613221732544675839, 613221732634853375, 613221732639047679, 613221692226928639, 613221692216442879, 613221692220637183, 613221692140945407, 613221692145139711, 613221692235317247, 613221692239511551, 613221692495364095, 613221692484878335, 613221692489072639, 613221692470198271, 613221692474392575, 613221692512141311, 613221692501655551, 613221692505849855, 613221687392993279, 613221687397187583, 613221687369924607, 613221687374118911, 613221687411867647, 613221687401381887, 613221687405576191, 613221686721904639, 613221686726098943, 613221686698835967, 613221686703030271, 613221686740779007, 613221686738681855, 613221686742876159, 613221687487365119, 613221687491559423, 613221686975660031, 613221686965174271, 613221686969368575, 613221687007117311, 613221687011311615, 613221693258727423, 613221693262921727, 613221689391579135, 613221689381093375, 613221689385287679, 613221689423036415, 613221689427230719, 613221693535551487, 613221693525065727, 613221693529260031, 613221689657917439, 613221689662111743, 613221709868171263, 613221709872365567, 613221709910114303, 613221709899628543, 613221709903822847, 613221709387923455, 613221709392117759, 613221709197082623, 613221709201276927, 613221709239025663, 613221709228539903, 613221709232734207, 613221709213859839, 613221709218054143, 613221709473906687, 613221709463420927, 613221709467615231, 613221709505363967, 613221709509558271, 613221709482295295, 613221709486489599, 613221704373633023, 613221704363147263, 613221704367341567, 613221704405090303, 613221704409284607, 613221704382021631, 613221704386215935, 613221704642068479, 613221704639971327, 613221704644165631, 613221704616902655, 613221704621096959, 613221704658845695, 613221704648359935, 613221704652554239, 613221710411333631, 613221710415527935, 613221710388264959, 613221710392459263, 613221710430207999, 613221710419722239, 613221710423916543, 613221710679769087, 613221710683963391, 613221710665089023, 613221710654603263, 613221710658797567, 613221710696546303, 613221710700740607, 613168113669636095, 613168113665441791, 613168113627693055, 613168113623498751, 613168113633984511, 613168113713676287, 613168113709481983, 613168113401200639, 613168113397006335, 613168113359257599, 613168113355063295, 613168113365549055, 613168113384423423, 613168113380229119, 613168114063900671, 613168114059706367, 613168114070192127, 613168114032443391, 613168114028249087, 613168114055512063, 613168114051317759, 613168111647981567, 613168111643787263, 613168111654273023, 613168111616524287, 613168111612329983, 613168111639592959, 613168111635398655, 613168111637495807, 613168111381643263, 613168111377448959, 613168111404711935, 613168111400517631, 613168111362768895, 613168111358574591, 613168111369060351, 613168113126473727, 613168113122279423, 613168113149542399, 613168113145348095, 613168113107599359, 613168113103405055, 613168113113890815, 613168112858038271, 613168112853843967, 613168112872718335, 613168112868524031, 613168112879009791, 613168112841261055, 613168112837066751, 613168113032101887, 613168113027907583, 613168096498155519, 613168096493961215, 613168096504446975, 613168096466698239, 613168096462503935, 613168096657539071, 613168096653344767, 613168096229720063, 613168096225525759, 613168096236011519, 613168096422658047, 613168096418463743, 613168096380715007, 613168096376520703, 613168096387006463, 613168096902905855, 613168096898711551, 613168098167488511, 613168098163294207, 613168098125545471, 613168098121351167, 613168098131836927, 613168094486986751, 613168094482792447, 613168097899053055, 613168097894858751, 613168097896955903, 613168097859207167, 613168097855012863, 613168097882275839, 613168097878081535, 613168095474745343, 613168095470551039, 613168095481036799, 613168095443288063, 613168095439093759, 613168095466356735, 613168095462162431, 613168095206309887, 613168095202115583, 613168095212601343, 613168095174852607, 613168095170658303, 613168095189532671, 613168095185338367, 613168095195824127, 613168095879495679, 613168095875301375, 613168095785123839, 613168095780929535, 613168095860621311, 613168095856427007, 613168095866912767, 613168208353951743, 613168208349757439, 613168208259579903, 613168208255385599, 613168208335077375, 613168208330883071, 613168208341368831, 613168208024698879, 613168208020504575, 613168207982755839, 613168207978561535, 613168207989047295, 613168208068739071, 613168208064544767, 613168209769529343, 613168209765335039, 613168209727586303, 613168209723391999, 613168209733877759, 613168209813569535, 613168209809375231, 613168209501093887, 613168209496899583, 613168209498996735, 613168209461247999, 613168209457053695, 613168209484316671, 613168209480122367, 613168207076786175, 613168207072591871, 613168207083077631, 613168207045328895, 613168207041134591, 613168207068397567, 613168207064203263, 613168206808350719, 613168206804156415, 613168206814642175, 613168206776893439, 613168206772699135, 613168206791573503, 613168206787379199, 613168206797864959, 613168207481536511, 613168207477342207, 613168207504605183, 613168207500410879, 613168207462662143, 613168207458467839, 613168207468953599, 613168191106973695, 613168191102779391, 613168191130042367, 613168191125848063, 613168191088099327, 613168191083905023, 613168191086002175, 613168159068782591, 613168159064588287, 613168190853218303, 613168190849023999, 613168190859509759, 613168190821761023, 613168190817566719, 613168192086343679, 613168192082149375, 613168192598048767, 613168192593854463, 613168192604340223, 613168192566591487, 613168192562397183, 613168191817908223, 613168191813713919, 613168191815811071, 613168192331710463, 613168192327516159, 613168192522551295, 613168192518356991, 613168192480608255, 613168192476413951, 613168192486899711, 613168189915791359, 613168189911597055, 613168190106632191, 613168190102437887, 613168190064689151, 613168190060494847, 613168190070980607, 613168189647355903, 613168189643161599, 613168189829808127, 613168189825613823, 613168189836099583, 613168189798350847, 613168189794156543, 613168189821419519, 613168189817225215, 613168202312056831, 613168202307862527, 613168202318348287, 613168202280599551, 613168202276405247, 613168202303668223, 613168202299473919, 613168202043621375, 613168202039427071, 613168202041524223, 613168201951346687, 613168201947152383, 613168202026844159, 613168202022649855, 613168202033135615, 613168037494783999, 613168037490589695, 613168037400412159, 613168037396217855, 613168037475909631, 613168037471715327, 613168037482201087, 613168037226348543, 613168037222154239, 613168037131976703, 613168037127782399, 613168037129879551, 613168037209571327, 613168037205377023, 613168037836619775, 613168037832425471, 613168037794676735, 613168037790482431, 613168037800968191, 613168037880659967, 613168037876465663, 613168035420700671, 613168035416506367, 613168035378757631, 613168035374563327, 613168035385049087, 613168035464740863, 613168035399729151, 613168035143876607, 613168035139682303, 613168035150168063, 613168035112419327, 613168035108225023, 613168035135487999, 613168035131293695, 613168047626125311, 613168047621931007, 613168047632416767, 613168047594668031, 613168047590473727, 613168047617736703, 613168047613542399, 613168047357689855, 613168047353495551, 613168047355592703, 613168047382855679, 613168047378661375, 613168047340912639, 613168047336718335, 613168047347204095, 613168020247805951, 613168020243611647, 613168020270874623, 613168020266680319, 613168020228931583, 613168020224737279, 613168020235223039, 613168019979370495, 613168019975176191, 613168020002439167, 613168019998244863, 613168020000342015, 613168019962593279, 613168019958398975, 613168020153434111, 613168020149239807, 613168020665139199, 613168020660944895, 613168020671430655, 613168020633681919, 613168020629487615, 613168032635682815, 613168032631488511, 613168018249220095, 613168018245025791, 613168018255511551, 613168018217762815, 613168032396607487, 613168032358858751, 613168032354664447, 613168032365150207, 613168017982881791, 613168017978687487, 613168029984882687, 613168029980688383, 613168029942939647, 613168029938745343, 613168029949231103, 613168030465130495, 613168030460936191, 613168029716447231, 613168029712252927, 613168029674504191, 613168029670309887, 613168029672407039, 613168029699670015, 613168029695475711, 613168030379147263, 613168030374952959, 613168030385438719, 613168030347689983, 613168030343495679, 613168030370758655, 613168030366564351, 613168063396708351, 613168063392514047, 613168063402999807, 613168063365251071, 613168063361056767, 613168063388319743, 613168063384125439, 613168063386222591, 613168063130370047, 613168063126175743, 613168063035998207, 613168063031803903, 613168063111495679, 613168063107301375, 613168063117787135, 613168831526862847, 613168831522668543, 613168831432491007, 613168831428296703, 613168831507988479, 613168831503794175, 613168831514279935, 613168831258427391, 613168831193415679, 613168831155666943, 613168831151472639, 613168831161958399, 613168831241650175, 613168831237455871, 613168828781690879, 613168828777496575, 613168828739747839, 613168828735553535, 613168828746039295, 613168828825731071, 613168828821536767, 613168828513255423, 613168828509061119, 613168828471312383, 613168828467118079, 613168828469215231, 613168828496478207, 613168828492283903, 613168829175955455, 613168829171761151, 613168829182246911, 613168829144498175, 613168829140303871, 613168829167566847, 613168829163372543, 613167015357579263, 613167015353384959, 613167015363870719, 613167015326121983, 613167015321927679, 613167015349190655, 613167015336607743, 613167015347093503, 613167015091240959, 613167015087046655, 613167015114309631, 613167015110115327, 613167015072366591, 613167015068172287, 613167015078658047, 613168814279884799, 613168814275690495, 613168814302953471, 613168814298759167, 613168814261010431, 613168814256816127, 613168814267301887, 613168814011449343, 613168813510230015, 613168814026129407, 613168814021935103, 613168814032420863, 613168813994672127, 613168813990477823, 613168814185512959, 613168814181318655, 613168811610210303, 613168811606015999, 613168811616501759, 613168811578753023, 613168811574558719, 613168811769593855, 613168811765399551, 613168811341774847, 613168811337580543, 613168811339677695, 613168811534712831, 613168811530518527, 613168811492769791, 613168811488575487, 613168811499061247, 613168812014960639, 613168812010766335, 613168813279543295, 613168813275348991, 613168813237600255, 613168813233405951, 613168813243891711, 613166998196584447, 613166998192390143, 613168813011107839, 613168812998524927, 613168813009010687, 613168812971261951, 613168812967067647, 613168812994330623, 613168812990136319, 613167078641238015, 613167078637043711, 613167078647529471, 613167078609780735, 613167078605586431, 613167078632849407, 613167078628655103, 613167078372802559, 613167078368608255, 613167078379094015, 613167078341345279, 613167078276333567, 613167078356025343, 613167078351831039, 613167078362316799, 613167079045988351, 613167079041794047, 613167078951616511, 613167078947422207, 613167079027113983, 613167079022919679, 613167079033405439, 613167076630069247, 613167076625874943, 613167076535697407, 613167076531503103, 613167076611194879, 613167076607000575, 613167076609097727, 613167076300816383, 613167076296622079, 613167076258873343, 613167076254679039, 613167076265164799, 613167076344856575, 613167076340662271, 613167078045646847, 613167078041452543, 613167078003703807, 613167077999509503, 613167078009995263, 613167078089687039, 613167078085492735, 613167077777211391, 613167077764628479, 613167077775114239, 613167077737365503, 613167077733171199, 613167077760434175, 613167077756239871, 613167061394259967, 613167061390065663, 613167061400551423, 613167061362802687, 613167061358608383, 613167061385871359, 613167061381677055, 613167061125824511, 613167061121630207, 613167061132115967, 613167061094367231, 613167061146796031, 613167061109047295, 613167061104852991, 613167061115338751, 613167061799010303, 613167061794815999, 613167061822078975, 613167061817884671, 613167061780135935, 613167061775941631, 613167061786427391, 613167059383091199, 613167059378896895, 613167059406159871, 613167059401965567, 613167059364216831, 613167059366313983, 613167059362119679, 613167055262187519, 613167055257993215, 613167059129335807, 613167059125141503, 613167059135627263, 613167059097878527, 613167059093684223, 613167060362461183, 613167060358266879, 613167060874166271, 613167060869971967, 613167060880457727, 613167060842708991, 613167060838514687, 613167060094025727, 613167060081442815, 613167060091928575, 613167060607827967, 613167060603633663, 613167060798668799, 613167060794474495, 613167060756725759, 613167060752531455, 613167060763017215, 613167104362807295, 613167104358612991, 613167104553648127, 613167104549453823, 613167104511705087, 613167104507510783, 613167104517996543, 613167104094371839, 613167104532676607, 613167104276824063, 613167104272629759, 613167104283115519, 613167104245366783, 613167104241172479, 613167104268435455, 613167104264241151, 613167098505461759, 613167098501267455, 613167098511753215, 613167098474004479, 613167098469810175, 613167098497073151, 613167098492878847, 613167098237026303, 613167098239123455, 613167098234929151, 613167098144751615, 613167098140557311, 613167098220249087, 613167098216054783, 613167098226540543, 613167103339397119, 613167103335202815, 613167103245025279, 613167103240830975, 613167103320522751, 613167103316328447, 613167103326814207, 613167103070961663, 613167103066767359, 613167102976589823, 613167102964006911, 613167102974492671, 613167103054184447, 613167103049990143, 613167103681232895, 613167103677038591, 613167103639289855, 613167103635095551, 613167103645581311, 613167103725273087, 613167103721078783, 613166949867716607, 613166949863522303, 613166949825773567, 613166949821579263, 613166949832065023, 613166949850939391, 613166949846745087, 613166949590892543, 613166949586698239, 613166949597183999, 613166949559435263, 613166949555240959, 613166949582503935, 613166949578309631, 613166943819530239, 613166943815335935, 613166943825821695, 613166943788072959, 613166943783878655, 613166943811141631, 613166943806947327, 613166943551094783, 613166943553191935, 613166943548997631, 613166943576260607, 613166943572066303, 613166943534317567, 613166943530123263, 613166943540609023, 613166948653465599, 613166948649271295, 613166948676534271, 613166948672339967, 613166948634591231, 613166948630396927, 613166948640882687, 613166948385030143, 613166948380835839, 613166948408098815, 613166948395515903, 613166948406001663, 613166948368252927, 613166948364058623, 613166948559093759, 613166948554899455, 613166949070798847, 613166949066604543, 613166949077090303, 613166949039341567, 613166949035147263, 613166928829087743, 613166928824893439, 613166932696236031, 613166932692041727, 613166932702527487, 613166928594206719, 613166928590012415, 613166928552263679, 613166928548069375, 613166928558555135, 613166932429897727, 613166932425703423, 613166926178287615, 613166926174093311, 613166926136344575, 613166926132150271, 613166926142636031, 613166926658535423, 613166926654341119, 613166925909852159, 613166925905657855, 613166925867909119, 613166925870006271, 613166925865811967, 613166925893074943, 613166925888880639, 613166926572552191, 613166926568357887, 613166926578843647, 613166926541094911, 613166926536900607, 613166926564163583, 613166926559969279, 613166931672825855, 613166931668631551, 613166931679117311, 613166931641368575, 613166931637174271, 613166931664437247, 613166931651854335, 613166931662340095, 613166931406487551, 613166931402293247, 613166931312115711, 613166931307921407, 613166931387613183, 613166931383418879, 613166931393904639, 613167727720267775, 613167727716073471, 613167727625895935, 613167727621701631, 613167727701393407, 613167727697199103, 613167727707684863, 613167727391014911, 613167727386820607, 613167727349071871, 613167727344877567, 613167727355363327, 613167727435055103, 613167727430860799, 613167724975095807, 613167724970901503] | ++----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ SELECT geohash(37.76938, -122.3889, 9); diff --git a/tests/cases/standalone/common/function/geo.sql b/tests/cases/standalone/common/function/geo.sql index cd9d403e6e..af2a16517d 100644 --- a/tests/cases/standalone/common/function/geo.sql +++ b/tests/cases/standalone/common/function/geo.sql @@ -26,18 +26,34 @@ SELECT h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64), h3_latlng_to_cell_stri SELECT h3_cell_to_string(h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64)) AS cell_str, h3_string_to_cell(h3_latlng_to_cell_string(37.76938, -122.3889, 8::UInt64)) AS cell_index; -SELECT h3_cell_center_lat(h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64)) AS cell_center_lat, h3_cell_center_lng(h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64)) AS cell_center_lng; +SELECT h3_cell_center_latlng(h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64)) AS cell_center; SELECT h3_cell_resolution(cell) AS resolution, h3_cell_base(cell) AS base, h3_cell_is_pentagon(cell) AS pentagon, h3_cell_parent(cell, 6::UInt64) AS parent, + h3_cell_to_children(cell, 10::UInt64) AS children, + h3_cell_to_children_size(cell, 10) AS children_count, + h3_cell_to_child_pos(cell, 6) AS child_pos, + h3_child_pos_to_cell(25, cell, 11) AS child FROM (SELECT h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64) AS cell); -SELECT h3_is_neighbour(cell1, cell2) -FROM (SELECT h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64) AS cell1, h3_latlng_to_cell(36.76938, -122.3889, 8::UInt64) AS cell2); +SELECT + h3_grid_disk(cell, 0) AS current_cell, + h3_grid_disk(cell, 3) AS grids, + h3_grid_disk_distances(cell, 3) AS all_grids, +FROM (SELECT h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64) AS cell); +SELECT + h3_grid_distance(cell1, cell2) AS distance, + h3_grid_path_cells(cell1, cell2) AS path_cells, +FROM + ( + SELECT + h3_latlng_to_cell(37.76938, -122.3889, 8::UInt64) AS cell1, + h3_latlng_to_cell(39.634, -104.999, 8::UInt64) AS cell2 + ); SELECT geohash(37.76938, -122.3889, 9); From 856c0280f53d3d70ee6f5b0e71568f549f6a5479 Mon Sep 17 00:00:00 2001 From: jeremyhi Date: Sat, 12 Oct 2024 17:04:22 +0800 Subject: [PATCH 13/36] feat: remove the distributed lock (#4825) * feat: remove the distributed lock as we do not need it any more * chore: delete todo comment * chore: remove unused error --- src/meta-client/examples/lock.rs | 129 -------------------- src/meta-client/src/client.rs | 35 ------ src/meta-client/src/client/lock.rs | 178 ---------------------------- src/meta-srv/src/bootstrap.rs | 22 +--- src/meta-srv/src/error.rs | 27 ----- src/meta-srv/src/lib.rs | 1 - src/meta-srv/src/lock.rs | 99 ---------------- src/meta-srv/src/lock/etcd.rs | 93 --------------- src/meta-srv/src/lock/memory.rs | 112 ----------------- src/meta-srv/src/metasrv.rs | 6 - src/meta-srv/src/metasrv/builder.rs | 12 -- src/meta-srv/src/service.rs | 1 - src/meta-srv/src/service/lock.rs | 51 -------- 13 files changed, 4 insertions(+), 762 deletions(-) delete mode 100644 src/meta-client/examples/lock.rs delete mode 100644 src/meta-client/src/client/lock.rs delete mode 100644 src/meta-srv/src/lock.rs delete mode 100644 src/meta-srv/src/lock/etcd.rs delete mode 100644 src/meta-srv/src/lock/memory.rs delete mode 100644 src/meta-srv/src/service/lock.rs diff --git a/src/meta-client/examples/lock.rs b/src/meta-client/examples/lock.rs deleted file mode 100644 index c8a8b61d60..0000000000 --- a/src/meta-client/examples/lock.rs +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2023 Greptime Team -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::sync::Arc; -use std::time::Duration; - -use api::v1::meta::Role; -use common_grpc::channel_manager::{ChannelConfig, ChannelManager}; -use common_meta::rpc::lock::{LockRequest, UnlockRequest}; -use meta_client::client::MetaClientBuilder; -use meta_client::MetaClientRef; -use tracing::{info, subscriber}; -use tracing_subscriber::FmtSubscriber; - -fn main() { - subscriber::set_global_default(FmtSubscriber::builder().finish()).unwrap(); - run(); -} - -#[tokio::main] -async fn run() { - let id = (1000u64, 2000u64); - let config = ChannelConfig::new() - .timeout(Duration::from_secs(30)) - .connect_timeout(Duration::from_secs(5)) - .tcp_nodelay(true); - let channel_manager = ChannelManager::with_config(config); - let mut meta_client = MetaClientBuilder::new(id.0, id.1, Role::Datanode) - .enable_lock() - .channel_manager(channel_manager) - .build(); - meta_client.start(&["127.0.0.1:3002"]).await.unwrap(); - let meta_client = Arc::new(meta_client); - - run_normal(meta_client.clone()).await; - - run_multi_thread(meta_client.clone()).await; - - run_multi_thread_with_one_timeout(meta_client).await; -} - -async fn run_normal(meta_client: MetaClientRef) { - let name = "lock_name".as_bytes().to_vec(); - let expire_secs = 60; - - let lock_req = LockRequest { name, expire_secs }; - - let lock_result = meta_client.lock(lock_req).await.unwrap(); - let key = lock_result.key; - info!( - "lock success! Returned key: {}", - String::from_utf8(key.clone()).unwrap() - ); - - // It is recommended that time of holding lock is less than the timeout of the grpc channel - info!("do some work, take 3 seconds"); - tokio::time::sleep(Duration::from_secs(3)).await; - - let unlock_req = UnlockRequest { key }; - - meta_client.unlock(unlock_req).await.unwrap(); - info!("unlock success!"); -} - -async fn run_multi_thread(meta_client: MetaClientRef) { - let meta_client_clone = meta_client.clone(); - let join1 = tokio::spawn(async move { - run_normal(meta_client_clone.clone()).await; - }); - - tokio::time::sleep(Duration::from_secs(1)).await; - - let join2 = tokio::spawn(async move { - run_normal(meta_client).await; - }); - - join1.await.unwrap(); - join2.await.unwrap(); -} - -async fn run_multi_thread_with_one_timeout(meta_client: MetaClientRef) { - let meta_client_clone = meta_client.clone(); - let join1 = tokio::spawn(async move { - run_with_timeout(meta_client_clone.clone()).await; - }); - - tokio::time::sleep(Duration::from_secs(1)).await; - - let join2 = tokio::spawn(async move { - run_normal(meta_client).await; - }); - - join1.await.unwrap(); - join2.await.unwrap(); -} - -async fn run_with_timeout(meta_client: MetaClientRef) { - let name = "lock_name".as_bytes().to_vec(); - let expire_secs = 5; - - let lock_req = LockRequest { name, expire_secs }; - - let lock_result = meta_client.lock(lock_req).await.unwrap(); - let key = lock_result.key; - info!( - "lock success! Returned key: {}", - String::from_utf8(key.clone()).unwrap() - ); - - // It is recommended that time of holding lock is less than the timeout of the grpc channel - info!("do some work, take 20 seconds"); - tokio::time::sleep(Duration::from_secs(20)).await; - - let unlock_req = UnlockRequest { key }; - - meta_client.unlock(unlock_req).await.unwrap(); - info!("unlock success!"); -} diff --git a/src/meta-client/src/client.rs b/src/meta-client/src/client.rs index 1c5b96a684..ed6fdf13fb 100644 --- a/src/meta-client/src/client.rs +++ b/src/meta-client/src/client.rs @@ -15,7 +15,6 @@ mod ask_leader; mod heartbeat; mod load_balance; -mod lock; mod procedure; mod cluster; @@ -33,7 +32,6 @@ use common_meta::datanode::{DatanodeStatKey, DatanodeStatValue, RegionStat}; use common_meta::ddl::{ExecutorContext, ProcedureExecutor}; use common_meta::error::{self as meta_error, Result as MetaResult}; use common_meta::rpc::ddl::{SubmitDdlTaskRequest, SubmitDdlTaskResponse}; -use common_meta::rpc::lock::{LockRequest, LockResponse, UnlockRequest}; use common_meta::rpc::procedure::{ MigrateRegionRequest, MigrateRegionResponse, ProcedureStateResponse, }; @@ -45,7 +43,6 @@ use common_meta::rpc::store::{ use common_meta::ClusterId; use common_telemetry::info; use heartbeat::Client as HeartbeatClient; -use lock::Client as LockClient; use procedure::Client as ProcedureClient; use snafu::{OptionExt, ResultExt}; use store::Client as StoreClient; @@ -67,7 +64,6 @@ pub struct MetaClientBuilder { role: Role, enable_heartbeat: bool, enable_store: bool, - enable_lock: bool, enable_procedure: bool, enable_access_cluster_info: bool, channel_manager: Option, @@ -123,13 +119,6 @@ impl MetaClientBuilder { } } - pub fn enable_lock(self) -> Self { - Self { - enable_lock: true, - ..self - } - } - pub fn enable_procedure(self) -> Self { Self { enable_procedure: true, @@ -188,10 +177,6 @@ impl MetaClientBuilder { client.store = Some(StoreClient::new(self.id, self.role, mgr.clone())); } - if self.enable_lock { - client.lock = Some(LockClient::new(self.id, self.role, mgr.clone())); - } - if self.enable_procedure { let mgr = self.ddl_channel_manager.unwrap_or(mgr.clone()); client.procedure = Some(ProcedureClient::new( @@ -221,7 +206,6 @@ pub struct MetaClient { channel_manager: ChannelManager, heartbeat: Option, store: Option, - lock: Option, procedure: Option, cluster: Option, } @@ -383,10 +367,6 @@ impl MetaClient { client.start(urls.clone()).await?; info!("Store client started"); } - if let Some(client) = &mut self.lock { - client.start(urls.clone()).await?; - info!("Lock client started"); - } if let Some(client) = &mut self.procedure { client.start(urls.clone()).await?; info!("DDL client started"); @@ -482,15 +462,6 @@ impl MetaClient { .context(ConvertMetaResponseSnafu) } - pub async fn lock(&self, req: LockRequest) -> Result { - self.lock_client()?.lock(req.into()).await.map(Into::into) - } - - pub async fn unlock(&self, req: UnlockRequest) -> Result<()> { - let _ = self.lock_client()?.unlock(req.into()).await?; - Ok(()) - } - /// Query the procedure state by its id. pub async fn query_procedure_state(&self, pid: &str) -> Result { self.procedure_client()?.query_procedure_state(pid).await @@ -538,12 +509,6 @@ impl MetaClient { }) } - pub fn lock_client(&self) -> Result { - self.lock.clone().context(NotStartedSnafu { - name: "lock_client", - }) - } - pub fn procedure_client(&self) -> Result { self.procedure.clone().context(NotStartedSnafu { name: "procedure_client", diff --git a/src/meta-client/src/client/lock.rs b/src/meta-client/src/client/lock.rs deleted file mode 100644 index 66fe077c22..0000000000 --- a/src/meta-client/src/client/lock.rs +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2023 Greptime Team -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::collections::HashSet; -use std::sync::Arc; - -use api::v1::meta::lock_client::LockClient; -use api::v1::meta::{LockRequest, LockResponse, Role, UnlockRequest, UnlockResponse}; -use common_grpc::channel_manager::ChannelManager; -use common_telemetry::tracing_context::TracingContext; -use snafu::{ensure, OptionExt, ResultExt}; -use tokio::sync::RwLock; -use tonic::transport::Channel; - -use crate::client::{load_balance, Id}; -use crate::error; -use crate::error::Result; - -#[derive(Clone, Debug)] -pub struct Client { - inner: Arc>, -} - -impl Client { - pub fn new(id: Id, role: Role, channel_manager: ChannelManager) -> Self { - let inner = Arc::new(RwLock::new(Inner { - id, - role, - channel_manager, - peers: vec![], - })); - - Self { inner } - } - - pub async fn start(&mut self, urls: A) -> Result<()> - where - U: AsRef, - A: AsRef<[U]>, - { - let mut inner = self.inner.write().await; - inner.start(urls).await - } - - pub async fn lock(&self, req: LockRequest) -> Result { - let inner = self.inner.read().await; - inner.lock(req).await - } - - pub async fn unlock(&self, req: UnlockRequest) -> Result { - let inner = self.inner.read().await; - inner.unlock(req).await - } -} - -#[derive(Debug)] -struct Inner { - id: Id, - role: Role, - channel_manager: ChannelManager, - peers: Vec, -} - -impl Inner { - async fn start(&mut self, urls: A) -> Result<()> - where - U: AsRef, - A: AsRef<[U]>, - { - ensure!( - !self.is_started(), - error::IllegalGrpcClientStateSnafu { - err_msg: "Lock client already started", - } - ); - - self.peers = urls - .as_ref() - .iter() - .map(|url| url.as_ref().to_string()) - .collect::>() - .drain() - .collect::>(); - - Ok(()) - } - - fn random_client(&self) -> Result> { - let len = self.peers.len(); - let peer = load_balance::random_get(len, |i| Some(&self.peers[i])).context( - error::IllegalGrpcClientStateSnafu { - err_msg: "Empty peers, lock client may not start yet", - }, - )?; - - self.make_client(peer) - } - - fn make_client(&self, addr: impl AsRef) -> Result> { - let channel = self - .channel_manager - .get(addr) - .context(error::CreateChannelSnafu)?; - - Ok(LockClient::new(channel)) - } - - #[inline] - fn is_started(&self) -> bool { - !self.peers.is_empty() - } - - async fn lock(&self, mut req: LockRequest) -> Result { - let mut client = self.random_client()?; - req.set_header( - self.id, - self.role, - TracingContext::from_current_span().to_w3c(), - ); - let res = client.lock(req).await.map_err(error::Error::from)?; - - Ok(res.into_inner()) - } - - async fn unlock(&self, mut req: UnlockRequest) -> Result { - let mut client = self.random_client()?; - req.set_header( - self.id, - self.role, - TracingContext::from_current_span().to_w3c(), - ); - let res = client.unlock(req).await.map_err(error::Error::from)?; - - Ok(res.into_inner()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[tokio::test] - async fn test_already_start() { - let mut client = Client::new((0, 0), Role::Datanode, ChannelManager::default()); - client - .start(&["127.0.0.1:1000", "127.0.0.1:1001"]) - .await - .unwrap(); - let res = client.start(&["127.0.0.1:1002"]).await; - assert!(res.is_err()); - assert!(matches!( - res.err(), - Some(error::Error::IllegalGrpcClientState { .. }) - )); - } - - #[tokio::test] - async fn test_start_with_duplicate_peers() { - let mut client = Client::new((0, 0), Role::Datanode, ChannelManager::default()); - client - .start(&["127.0.0.1:1000", "127.0.0.1:1000", "127.0.0.1:1000"]) - .await - .unwrap(); - - assert_eq!(1, client.inner.write().await.peers.len()); - } -} diff --git a/src/meta-srv/src/bootstrap.rs b/src/meta-srv/src/bootstrap.rs index dcfac253f3..d10b22c610 100644 --- a/src/meta-srv/src/bootstrap.rs +++ b/src/meta-srv/src/bootstrap.rs @@ -16,7 +16,6 @@ use std::sync::Arc; use api::v1::meta::cluster_server::ClusterServer; use api::v1::meta::heartbeat_server::HeartbeatServer; -use api::v1::meta::lock_server::LockServer; use api::v1::meta::procedure_service_server::ProcedureServiceServer; use api::v1::meta::store_server::StoreServer; use common_base::Plugins; @@ -48,8 +47,6 @@ use crate::election::etcd::EtcdElection; #[cfg(feature = "pg_kvbackend")] use crate::error::InvalidArgumentsSnafu; use crate::error::{InitExportMetricsTaskSnafu, TomlFormatSnafu}; -use crate::lock::etcd::EtcdLock; -use crate::lock::memory::MemLock; use crate::metasrv::builder::MetasrvBuilder; use crate::metasrv::{BackendImpl, Metasrv, MetasrvOptions, SelectorRef}; use crate::selector::lease_based::LeaseBasedSelector; @@ -183,7 +180,6 @@ pub fn router(metasrv: Metasrv) -> Router { .add_service(HeartbeatServer::new(metasrv.clone())) .add_service(StoreServer::new(metasrv.clone())) .add_service(ClusterServer::new(metasrv.clone())) - .add_service(LockServer::new(metasrv.clone())) .add_service(ProcedureServiceServer::new(metasrv.clone())) .add_service(admin::make_admin_service(metasrv)) } @@ -193,13 +189,9 @@ pub async fn metasrv_builder( plugins: Plugins, kv_backend: Option, ) -> Result { - let (kv_backend, election, lock) = match (kv_backend, &opts.backend) { - (Some(kv_backend), _) => (kv_backend, None, Some(Arc::new(MemLock::default()) as _)), - (None, BackendImpl::MemoryStore) => ( - Arc::new(MemoryKvBackend::new()) as _, - None, - Some(Arc::new(MemLock::default()) as _), - ), + let (kv_backend, election) = match (kv_backend, &opts.backend) { + (Some(kv_backend), _) => (kv_backend, None), + (None, BackendImpl::MemoryStore) => (Arc::new(MemoryKvBackend::new()) as _, None), (None, BackendImpl::EtcdStore) => { let etcd_client = create_etcd_client(opts).await?; let kv_backend = { @@ -224,18 +216,13 @@ pub async fn metasrv_builder( ) .await?, ), - Some(EtcdLock::with_etcd_client( - etcd_client, - opts.store_key_prefix.clone(), - )?), ) } #[cfg(feature = "pg_kvbackend")] (None, BackendImpl::PostgresStore) => { let pg_client = create_postgres_client(opts).await?; let kv_backend = PgStore::with_pg_client(pg_client).await.unwrap(); - // TODO: implement locking and leader election for pg backend. - (kv_backend, None, None) + (kv_backend, None) } }; @@ -253,7 +240,6 @@ pub async fn metasrv_builder( .in_memory(in_memory) .selector(selector) .election(election) - .lock(lock) .plugins(plugins)) } diff --git a/src/meta-srv/src/error.rs b/src/meta-srv/src/error.rs index 4c3d974c0a..6bcac5db2a 100644 --- a/src/meta-srv/src/error.rs +++ b/src/meta-srv/src/error.rs @@ -448,30 +448,6 @@ pub enum Error { location: Location, }, - #[snafu(display("Failed to lock based on etcd"))] - Lock { - #[snafu(source)] - error: etcd_client::Error, - #[snafu(implicit)] - location: Location, - }, - - #[snafu(display("Failed to unlock based on etcd"))] - Unlock { - #[snafu(source)] - error: etcd_client::Error, - #[snafu(implicit)] - location: Location, - }, - - #[snafu(display("Failed to grant lease"))] - LeaseGrant { - #[snafu(source)] - error: etcd_client::Error, - #[snafu(implicit)] - location: Location, - }, - #[snafu(display("Invalid utf-8 value"))] InvalidUtf8Value { #[snafu(source)] @@ -770,9 +746,6 @@ impl ErrorExt for Error { | Error::ResponseHeaderNotFound { .. } | Error::IsNotLeader { .. } | Error::InvalidHttpBody { .. } - | Error::Lock { .. } - | Error::Unlock { .. } - | Error::LeaseGrant { .. } | Error::ExceededRetryLimit { .. } | Error::SendShutdownSignal { .. } | Error::PusherNotFound { .. } diff --git a/src/meta-srv/src/lib.rs b/src/meta-srv/src/lib.rs index 01b48f1da0..a438f4255f 100644 --- a/src/meta-srv/src/lib.rs +++ b/src/meta-srv/src/lib.rs @@ -28,7 +28,6 @@ pub mod flow_meta_alloc; pub mod handler; pub mod key; pub mod lease; -pub mod lock; pub mod metasrv; mod metrics; #[cfg(feature = "mock")] diff --git a/src/meta-srv/src/lock.rs b/src/meta-srv/src/lock.rs deleted file mode 100644 index 53451591da..0000000000 --- a/src/meta-srv/src/lock.rs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2023 Greptime Team -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -pub mod etcd; -pub(crate) mod memory; - -use std::sync::Arc; - -use common_telemetry::error; - -use crate::error::Result; - -pub type Key = Vec; - -pub const DEFAULT_EXPIRE_TIME_SECS: u64 = 10; - -pub struct Opts { - // If the expiration time is exceeded and currently holds the lock, the lock is - // automatically released. - pub expire_secs: Option, -} - -impl Default for Opts { - fn default() -> Self { - Opts { - expire_secs: Some(DEFAULT_EXPIRE_TIME_SECS), - } - } -} - -#[async_trait::async_trait] -pub trait DistLock: Send + Sync { - // Lock acquires a distributed shared lock on a given named lock. On success, it - // will return a unique key that exists so long as the lock is held by the caller. - async fn lock(&self, name: Vec, opts: Opts) -> Result; - - // Unlock takes a key returned by Lock and releases the hold on lock. - async fn unlock(&self, key: Vec) -> Result<()>; -} - -pub type DistLockRef = Arc; - -pub struct DistLockGuard<'a> { - lock: &'a DistLockRef, - name: Vec, - key: Option, -} - -impl<'a> DistLockGuard<'a> { - pub fn new(lock: &'a DistLockRef, name: Vec) -> Self { - Self { - lock, - name, - key: None, - } - } - - pub async fn lock(&mut self) -> Result<()> { - if self.key.is_some() { - return Ok(()); - } - let key = self - .lock - .lock( - self.name.clone(), - Opts { - expire_secs: Some(2), - }, - ) - .await?; - self.key = Some(key); - Ok(()) - } -} - -impl Drop for DistLockGuard<'_> { - fn drop(&mut self) { - if let Some(key) = self.key.take() { - let lock = self.lock.clone(); - let name = self.name.clone(); - let _handle = common_runtime::spawn_global(async move { - if let Err(e) = lock.unlock(key).await { - error!(e; "Failed to unlock '{}'", String::from_utf8_lossy(&name)); - } - }); - } - } -} diff --git a/src/meta-srv/src/lock/etcd.rs b/src/meta-srv/src/lock/etcd.rs deleted file mode 100644 index 3f53b40e15..0000000000 --- a/src/meta-srv/src/lock/etcd.rs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2023 Greptime Team -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::sync::Arc; - -use etcd_client::{Client, LockOptions}; -use snafu::ResultExt; - -use super::{DistLock, DistLockRef, Opts, DEFAULT_EXPIRE_TIME_SECS}; -use crate::error; -use crate::error::Result; - -/// A implementation of distributed lock based on etcd. The Clone of EtcdLock is cheap. -#[derive(Clone)] -pub struct EtcdLock { - client: Client, - store_key_prefix: String, -} - -impl EtcdLock { - pub async fn with_endpoints(endpoints: S, store_key_prefix: String) -> Result - where - E: AsRef, - S: AsRef<[E]>, - { - let client = Client::connect(endpoints, None) - .await - .context(error::ConnectEtcdSnafu)?; - - Self::with_etcd_client(client, store_key_prefix) - } - - pub fn with_etcd_client(client: Client, store_key_prefix: String) -> Result { - Ok(Arc::new(EtcdLock { - client, - store_key_prefix, - })) - } - - fn lock_key(&self, key: Vec) -> Vec { - if self.store_key_prefix.is_empty() { - key - } else { - let mut prefix = self.store_key_prefix.as_bytes().to_vec(); - prefix.extend_from_slice(&key); - prefix - } - } -} - -#[async_trait::async_trait] -impl DistLock for EtcdLock { - async fn lock(&self, key: Vec, opts: Opts) -> Result> { - let expire = opts.expire_secs.unwrap_or(DEFAULT_EXPIRE_TIME_SECS) as i64; - - let mut client = self.client.clone(); - - let resp = client - .lease_grant(expire, None) - .await - .context(error::LeaseGrantSnafu)?; - - let lease_id = resp.id(); - let lock_opts = LockOptions::new().with_lease(lease_id); - - let resp = client - .lock(self.lock_key(key), Some(lock_opts)) - .await - .context(error::LockSnafu)?; - - Ok(resp.key().to_vec()) - } - - async fn unlock(&self, key: Vec) -> Result<()> { - let mut client = self.client.clone(); - let _ = client - .unlock(self.lock_key(key)) - .await - .context(error::UnlockSnafu)?; - Ok(()) - } -} diff --git a/src/meta-srv/src/lock/memory.rs b/src/meta-srv/src/lock/memory.rs deleted file mode 100644 index d312700d12..0000000000 --- a/src/meta-srv/src/lock/memory.rs +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2023 Greptime Team -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::sync::Arc; - -use async_trait::async_trait; -use dashmap::DashMap; -use tokio::sync::{Mutex, OwnedMutexGuard}; - -use crate::error::Result; -use crate::lock::{DistLock, Key, Opts}; - -#[derive(Default)] -pub(crate) struct MemLock { - mutexes: DashMap>>, - guards: DashMap>, -} - -#[async_trait] -impl DistLock for MemLock { - async fn lock(&self, key: Vec, _opts: Opts) -> Result { - let mutex = self - .mutexes - .entry(key.clone()) - .or_insert_with(|| Arc::new(Mutex::new(()))) - .clone(); - - let guard = mutex.lock_owned().await; - - let _ = self.guards.insert(key.clone(), guard); - Ok(key) - } - - async fn unlock(&self, key: Vec) -> Result<()> { - // drop the guard, so that the mutex can be unlocked, - // effectively make the `mutex.lock_owned` in `lock` method to proceed - let _ = self.guards.remove(&key); - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use std::collections::HashMap; - use std::sync::atomic::{AtomicU32, Ordering}; - - use rand::seq::SliceRandom; - - use super::*; - - #[tokio::test(flavor = "multi_thread")] - async fn test_mem_lock_concurrently() { - let lock = Arc::new(MemLock::default()); - - let keys = (0..10) - .map(|i| format!("my-lock-{i}").into_bytes()) - .collect::>(); - let counters: [(Key, AtomicU32); 10] = keys - .iter() - .map(|x| (x.clone(), AtomicU32::new(0))) - .collect::>() - .try_into() - .unwrap(); - let counters = Arc::new(HashMap::from(counters)); - - let tasks = (0..100) - .map(|_| { - let mut keys = keys.clone(); - keys.shuffle(&mut rand::thread_rng()); - - let lock_clone = lock.clone(); - let counters_clone = counters.clone(); - tokio::spawn(async move { - // every key counter will be added by 1 for 10 times - for i in 0..100 { - let key = &keys[i % keys.len()]; - assert!(lock_clone - .lock(key.clone(), Opts { expire_secs: None }) - .await - .is_ok()); - - // Intentionally create a critical section: - // if our MemLock is flawed, the resulting counter is wrong. - // - // Note that AtomicU32 is only used to enable the updates from multiple tasks, - // does not make any guarantee about the correctness of the result. - - let counter = counters_clone.get(key).unwrap(); - let v = counter.load(Ordering::Relaxed); - counter.store(v + 1, Ordering::Relaxed); - - lock_clone.unlock(key.clone()).await.unwrap(); - } - }) - }) - .collect::>(); - let _ = futures::future::join_all(tasks).await; - - assert!(counters.values().all(|x| x.load(Ordering::Relaxed) == 1000)); - } -} diff --git a/src/meta-srv/src/metasrv.rs b/src/meta-srv/src/metasrv.rs index 3cdb64e1e0..c43eec60d4 100644 --- a/src/meta-srv/src/metasrv.rs +++ b/src/meta-srv/src/metasrv.rs @@ -57,7 +57,6 @@ use crate::error::{ use crate::failure_detector::PhiAccrualFailureDetectorOptions; use crate::handler::HeartbeatHandlerGroupRef; use crate::lease::lookup_datanode_peer; -use crate::lock::DistLockRef; use crate::procedure::region_migration::manager::RegionMigrationManagerRef; use crate::procedure::ProcedureManagerListenerAdapter; use crate::pubsub::{PublisherRef, SubscriptionManagerRef}; @@ -356,7 +355,6 @@ pub struct Metasrv { flow_selector: SelectorRef, handler_group: HeartbeatHandlerGroupRef, election: Option, - lock: DistLockRef, procedure_manager: ProcedureManagerRef, mailbox: MailboxRef, procedure_executor: ProcedureExecutorRef, @@ -568,10 +566,6 @@ impl Metasrv { self.election.as_ref() } - pub fn lock(&self) -> &DistLockRef { - &self.lock - } - pub fn mailbox(&self) -> &MailboxRef { &self.mailbox } diff --git a/src/meta-srv/src/metasrv/builder.rs b/src/meta-srv/src/metasrv/builder.rs index 050f825174..db01b3ec9d 100644 --- a/src/meta-srv/src/metasrv/builder.rs +++ b/src/meta-srv/src/metasrv/builder.rs @@ -52,8 +52,6 @@ use crate::handler::{ HeartbeatHandlerGroup, HeartbeatHandlerGroupBuilder, HeartbeatMailbox, Pushers, }; use crate::lease::MetaPeerLookupService; -use crate::lock::memory::MemLock; -use crate::lock::DistLockRef; use crate::metasrv::{ ElectionRef, Metasrv, MetasrvInfo, MetasrvOptions, SelectorContext, SelectorRef, TABLE_ID_SEQ, }; @@ -79,7 +77,6 @@ pub struct MetasrvBuilder { handler_group: Option, election: Option, meta_peer_client: Option, - lock: Option, node_manager: Option, plugins: Option, table_metadata_allocator: Option, @@ -95,7 +92,6 @@ impl MetasrvBuilder { meta_peer_client: None, election: None, options: None, - lock: None, node_manager: None, plugins: None, table_metadata_allocator: None, @@ -137,11 +133,6 @@ impl MetasrvBuilder { self } - pub fn lock(mut self, lock: Option) -> Self { - self.lock = lock; - self - } - pub fn node_manager(mut self, node_manager: NodeManagerRef) -> Self { self.node_manager = Some(node_manager); self @@ -171,7 +162,6 @@ impl MetasrvBuilder { in_memory, selector, handler_group, - lock, node_manager, plugins, table_metadata_allocator, @@ -205,7 +195,6 @@ impl MetasrvBuilder { let flow_metadata_manager = Arc::new(FlowMetadataManager::new( leader_cached_kv_backend.clone() as _, )); - let lock = lock.unwrap_or_else(|| Arc::new(MemLock::default())); let selector_ctx = SelectorContext { server_addr: options.server_addr.clone(), datanode_lease_secs: distributed_time_constants::DATANODE_LEASE_SECS, @@ -384,7 +373,6 @@ impl MetasrvBuilder { flow_selector: Arc::new(RoundRobinSelector::new(SelectTarget::Flownode)), handler_group: Arc::new(handler_group), election, - lock, procedure_manager, mailbox, procedure_executor: ddl_manager, diff --git a/src/meta-srv/src/service.rs b/src/meta-srv/src/service.rs index c3e2e781e8..e260b8b980 100644 --- a/src/meta-srv/src/service.rs +++ b/src/meta-srv/src/service.rs @@ -20,7 +20,6 @@ use tonic::{Response, Status}; pub mod admin; pub mod cluster; mod heartbeat; -pub mod lock; pub mod mailbox; pub mod procedure; pub mod store; diff --git a/src/meta-srv/src/service/lock.rs b/src/meta-srv/src/service/lock.rs deleted file mode 100644 index 4334bdfc37..0000000000 --- a/src/meta-srv/src/service/lock.rs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2023 Greptime Team -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use api::v1::meta::{lock_server, LockRequest, LockResponse, UnlockRequest, UnlockResponse}; -use tonic::{Request, Response}; - -use super::GrpcResult; -use crate::lock::Opts; -use crate::metasrv::Metasrv; - -#[async_trait::async_trait] -impl lock_server::Lock for Metasrv { - async fn lock(&self, request: Request) -> GrpcResult { - let LockRequest { - name, expire_secs, .. - } = request.into_inner(); - let expire_secs = Some(expire_secs as u64); - - let key = self.lock().lock(name, Opts { expire_secs }).await?; - - let resp = LockResponse { - key, - ..Default::default() - }; - - Ok(Response::new(resp)) - } - - async fn unlock(&self, request: Request) -> GrpcResult { - let UnlockRequest { key, .. } = request.into_inner(); - - let _ = self.lock().unlock(key).await?; - - let resp = UnlockResponse { - ..Default::default() - }; - - Ok(Response::new(resp)) - } -} From 2f2b4b306cb480c1396f452f2c27dc2206705d38 Mon Sep 17 00:00:00 2001 From: Yingwen Date: Mon, 14 Oct 2024 11:09:03 +0800 Subject: [PATCH 14/36] feat!: implement interval type by multiple structs (#4772) * define structs and methods Signed-off-by: Ruihang Xia * feat: re-implement interval types in time crate * feat: use new * feat: interval value * feat: query crate interval * feat: pg and mysql interval * chore: remove unused imports * chore: remove commented codes * feat: make flow compile but may not work * feat: flow datetime * test: fix some tests * test: fix some flow tests(WIP) * chore: some fix test&docs * fix: change interval order * chore: remove unused codes * chore: fix cilppy * chore: now signature change * chore: remove todo * feat: update error message --------- Signed-off-by: Ruihang Xia Co-authored-by: Ruihang Xia Co-authored-by: discord9 --- src/api/src/helper.rs | 108 ++- .../function/src/scalars/date/date_add.rs | 126 +-- .../function/src/scalars/date/date_sub.rs | 128 +--- src/common/grpc/src/select.rs | 4 +- src/common/time/src/date.rs | 71 +- src/common/time/src/datetime.rs | 86 ++- src/common/time/src/interval.rs | 724 +++++++----------- src/common/time/src/lib.rs | 2 +- src/common/time/src/timestamp.rs | 98 ++- src/datatypes/src/interval.rs | 84 +- src/datatypes/src/types/interval_type.rs | 10 +- src/datatypes/src/types/primitive_type.rs | 14 +- src/datatypes/src/types/string_type.rs | 10 +- src/datatypes/src/value.rs | 199 +++-- src/datatypes/src/vectors/helper.rs | 7 +- src/flow/src/compute/render/reduce.rs | 41 +- src/flow/src/expr/df_func.rs | 19 +- src/flow/src/expr/func.rs | 171 +++-- src/flow/src/repr.rs | 10 +- src/flow/src/transform.rs | 18 +- src/flow/src/transform/aggr.rs | 120 ++- src/flow/src/transform/literal.rs | 21 +- src/mito2/src/row_converter.rs | 55 +- src/query/src/range_select/plan_rewrite.rs | 117 +-- src/servers/src/mysql/writer.rs | 6 +- src/servers/src/postgres/types.rs | 86 ++- src/servers/src/postgres/types/interval.rs | 50 +- src/sql/src/statements.rs | 4 +- .../standalone/common/range/interval.result | 27 +- .../standalone/common/range/interval.sql | 2 +- 30 files changed, 1190 insertions(+), 1228 deletions(-) diff --git a/src/api/src/helper.rs b/src/api/src/helper.rs index 101cae8802..4281201c42 100644 --- a/src/api/src/helper.rs +++ b/src/api/src/helper.rs @@ -17,10 +17,11 @@ use std::sync::Arc; use common_base::BitVec; use common_decimal::decimal128::{DECIMAL128_DEFAULT_SCALE, DECIMAL128_MAX_PRECISION}; use common_decimal::Decimal128; -use common_time::interval::IntervalUnit; use common_time::time::Time; use common_time::timestamp::TimeUnit; -use common_time::{Date, DateTime, Interval, Timestamp}; +use common_time::{ + Date, DateTime, IntervalDayTime, IntervalMonthDayNano, IntervalYearMonth, Timestamp, +}; use datatypes::prelude::{ConcreteDataType, ValueRef}; use datatypes::scalars::ScalarVector; use datatypes::types::{ @@ -456,13 +457,11 @@ pub fn push_vals(column: &mut Column, origin_count: usize, vector: VectorRef) { TimeUnit::Microsecond => values.time_microsecond_values.push(val.value()), TimeUnit::Nanosecond => values.time_nanosecond_values.push(val.value()), }, - Value::Interval(val) => match val.unit() { - IntervalUnit::YearMonth => values.interval_year_month_values.push(val.to_i32()), - IntervalUnit::DayTime => values.interval_day_time_values.push(val.to_i64()), - IntervalUnit::MonthDayNano => values - .interval_month_day_nano_values - .push(convert_i128_to_interval(val.to_i128())), - }, + Value::IntervalYearMonth(val) => values.interval_year_month_values.push(val.to_i32()), + Value::IntervalDayTime(val) => values.interval_day_time_values.push(val.to_i64()), + Value::IntervalMonthDayNano(val) => values + .interval_month_day_nano_values + .push(convert_month_day_nano_to_pb(val)), Value::Decimal128(val) => values.decimal128_values.push(convert_to_pb_decimal128(val)), Value::List(_) | Value::Duration(_) => unreachable!(), }); @@ -507,14 +506,12 @@ fn ddl_request_type(request: &DdlRequest) -> &'static str { } } -/// Converts an i128 value to google protobuf type [IntervalMonthDayNano]. -pub fn convert_i128_to_interval(v: i128) -> v1::IntervalMonthDayNano { - let interval = Interval::from_i128(v); - let (months, days, nanoseconds) = interval.to_month_day_nano(); +/// Converts an interval to google protobuf type [IntervalMonthDayNano]. +pub fn convert_month_day_nano_to_pb(v: IntervalMonthDayNano) -> v1::IntervalMonthDayNano { v1::IntervalMonthDayNano { - months, - days, - nanoseconds, + months: v.months, + days: v.days, + nanoseconds: v.nanoseconds, } } @@ -562,11 +559,15 @@ pub fn pb_value_to_value_ref<'a>( ValueData::TimeMillisecondValue(t) => ValueRef::Time(Time::new_millisecond(*t)), ValueData::TimeMicrosecondValue(t) => ValueRef::Time(Time::new_microsecond(*t)), ValueData::TimeNanosecondValue(t) => ValueRef::Time(Time::new_nanosecond(*t)), - ValueData::IntervalYearMonthValue(v) => ValueRef::Interval(Interval::from_i32(*v)), - ValueData::IntervalDayTimeValue(v) => ValueRef::Interval(Interval::from_i64(*v)), + ValueData::IntervalYearMonthValue(v) => { + ValueRef::IntervalYearMonth(IntervalYearMonth::from_i32(*v)) + } + ValueData::IntervalDayTimeValue(v) => { + ValueRef::IntervalDayTime(IntervalDayTime::from_i64(*v)) + } ValueData::IntervalMonthDayNanoValue(v) => { - let interval = Interval::from_month_day_nano(v.months, v.days, v.nanoseconds); - ValueRef::Interval(interval) + let interval = IntervalMonthDayNano::new(v.months, v.days, v.nanoseconds); + ValueRef::IntervalMonthDayNano(interval) } ValueData::Decimal128Value(v) => { // get precision and scale from datatype_extension @@ -657,7 +658,7 @@ pub fn pb_values_to_vector_ref(data_type: &ConcreteDataType, values: Values) -> IntervalType::MonthDayNano(_) => { Arc::new(IntervalMonthDayNanoVector::from_iter_values( values.interval_month_day_nano_values.iter().map(|x| { - Interval::from_month_day_nano(x.months, x.days, x.nanoseconds).to_i128() + IntervalMonthDayNano::new(x.months, x.days, x.nanoseconds).to_i128() }), )) } @@ -802,18 +803,18 @@ pub fn pb_values_to_values(data_type: &ConcreteDataType, values: Values) -> Vec< ConcreteDataType::Interval(IntervalType::YearMonth(_)) => values .interval_year_month_values .into_iter() - .map(|v| Value::Interval(Interval::from_i32(v))) + .map(|v| Value::IntervalYearMonth(IntervalYearMonth::from_i32(v))) .collect(), ConcreteDataType::Interval(IntervalType::DayTime(_)) => values .interval_day_time_values .into_iter() - .map(|v| Value::Interval(Interval::from_i64(v))) + .map(|v| Value::IntervalDayTime(IntervalDayTime::from_i64(v))) .collect(), ConcreteDataType::Interval(IntervalType::MonthDayNano(_)) => values .interval_month_day_nano_values .into_iter() .map(|v| { - Value::Interval(Interval::from_month_day_nano( + Value::IntervalMonthDayNano(IntervalMonthDayNano::new( v.months, v.days, v.nanoseconds, @@ -941,18 +942,16 @@ pub fn to_proto_value(value: Value) -> Option { value_data: Some(ValueData::TimeNanosecondValue(v.value())), }, }, - Value::Interval(v) => match v.unit() { - IntervalUnit::YearMonth => v1::Value { - value_data: Some(ValueData::IntervalYearMonthValue(v.to_i32())), - }, - IntervalUnit::DayTime => v1::Value { - value_data: Some(ValueData::IntervalDayTimeValue(v.to_i64())), - }, - IntervalUnit::MonthDayNano => v1::Value { - value_data: Some(ValueData::IntervalMonthDayNanoValue( - convert_i128_to_interval(v.to_i128()), - )), - }, + Value::IntervalYearMonth(v) => v1::Value { + value_data: Some(ValueData::IntervalYearMonthValue(v.to_i32())), + }, + Value::IntervalDayTime(v) => v1::Value { + value_data: Some(ValueData::IntervalDayTimeValue(v.to_i64())), + }, + Value::IntervalMonthDayNano(v) => v1::Value { + value_data: Some(ValueData::IntervalMonthDayNanoValue( + convert_month_day_nano_to_pb(v), + )), }, Value::Decimal128(v) => v1::Value { value_data: Some(ValueData::Decimal128Value(convert_to_pb_decimal128(v))), @@ -1044,13 +1043,11 @@ pub fn value_to_grpc_value(value: Value) -> GrpcValue { TimeUnit::Microsecond => ValueData::TimeMicrosecondValue(v.value()), TimeUnit::Nanosecond => ValueData::TimeNanosecondValue(v.value()), }), - Value::Interval(v) => Some(match v.unit() { - IntervalUnit::YearMonth => ValueData::IntervalYearMonthValue(v.to_i32()), - IntervalUnit::DayTime => ValueData::IntervalDayTimeValue(v.to_i64()), - IntervalUnit::MonthDayNano => { - ValueData::IntervalMonthDayNanoValue(convert_i128_to_interval(v.to_i128())) - } - }), + Value::IntervalYearMonth(v) => Some(ValueData::IntervalYearMonthValue(v.to_i32())), + Value::IntervalDayTime(v) => Some(ValueData::IntervalDayTimeValue(v.to_i64())), + Value::IntervalMonthDayNano(v) => Some(ValueData::IntervalMonthDayNanoValue( + convert_month_day_nano_to_pb(v), + )), Value::Decimal128(v) => Some(ValueData::Decimal128Value(convert_to_pb_decimal128(v))), Value::List(_) | Value::Duration(_) => unreachable!(), }, @@ -1061,6 +1058,7 @@ pub fn value_to_grpc_value(value: Value) -> GrpcValue { mod tests { use std::sync::Arc; + use common_time::interval::IntervalUnit; use datatypes::types::{ Int32Type, IntervalDayTimeType, IntervalMonthDayNanoType, IntervalYearMonthType, TimeMillisecondType, TimeSecondType, TimestampMillisecondType, TimestampSecondType, @@ -1506,11 +1504,11 @@ mod tests { #[test] fn test_convert_i128_to_interval() { - let i128_val = 3000; - let interval = convert_i128_to_interval(i128_val); + let i128_val = 3; + let interval = convert_month_day_nano_to_pb(IntervalMonthDayNano::from_i128(i128_val)); assert_eq!(interval.months, 0); assert_eq!(interval.days, 0); - assert_eq!(interval.nanoseconds, 3000); + assert_eq!(interval.nanoseconds, 3); } #[test] @@ -1590,9 +1588,9 @@ mod tests { }, ); let expect = vec![ - Value::Interval(Interval::from_year_month(1_i32)), - Value::Interval(Interval::from_year_month(2_i32)), - Value::Interval(Interval::from_year_month(3_i32)), + Value::IntervalYearMonth(IntervalYearMonth::new(1_i32)), + Value::IntervalYearMonth(IntervalYearMonth::new(2_i32)), + Value::IntervalYearMonth(IntervalYearMonth::new(3_i32)), ]; assert_eq!(expect, actual); @@ -1605,9 +1603,9 @@ mod tests { }, ); let expect = vec![ - Value::Interval(Interval::from_i64(1_i64)), - Value::Interval(Interval::from_i64(2_i64)), - Value::Interval(Interval::from_i64(3_i64)), + Value::IntervalDayTime(IntervalDayTime::from_i64(1_i64)), + Value::IntervalDayTime(IntervalDayTime::from_i64(2_i64)), + Value::IntervalDayTime(IntervalDayTime::from_i64(3_i64)), ]; assert_eq!(expect, actual); @@ -1636,9 +1634,9 @@ mod tests { }, ); let expect = vec![ - Value::Interval(Interval::from_month_day_nano(1, 2, 3)), - Value::Interval(Interval::from_month_day_nano(5, 6, 7)), - Value::Interval(Interval::from_month_day_nano(9, 10, 11)), + Value::IntervalMonthDayNano(IntervalMonthDayNano::new(1, 2, 3)), + Value::IntervalMonthDayNano(IntervalMonthDayNano::new(5, 6, 7)), + Value::IntervalMonthDayNano(IntervalMonthDayNano::new(9, 10, 11)), ]; assert_eq!(expect, actual); } diff --git a/src/common/function/src/scalars/date/date_add.rs b/src/common/function/src/scalars/date/date_add.rs index 1052acb868..2307d2caab 100644 --- a/src/common/function/src/scalars/date/date_add.rs +++ b/src/common/function/src/scalars/date/date_add.rs @@ -14,18 +14,19 @@ use std::fmt; -use common_query::error::{InvalidFuncArgsSnafu, Result, UnsupportedInputDataTypeSnafu}; +use common_query::error::{ArrowComputeSnafu, IntoVectorSnafu, InvalidFuncArgsSnafu, Result}; use common_query::prelude::Signature; -use datatypes::data_type::DataType; +use datatypes::arrow::compute::kernels::numeric; use datatypes::prelude::ConcreteDataType; -use datatypes::value::ValueRef; -use datatypes::vectors::VectorRef; -use snafu::ensure; +use datatypes::vectors::{Helper, VectorRef}; +use snafu::{ensure, ResultExt}; use crate::function::{Function, FunctionContext}; use crate::helper; -/// A function adds an interval value to Timestamp, Date or DateTime, and return the result. +/// A function adds an interval value to Timestamp, Date, and return the result. +/// The implementation of datetime type is based on Date64 which is incorrect so this function +/// doesn't support the datetime type. #[derive(Clone, Debug, Default)] pub struct DateAddFunction; @@ -44,7 +45,6 @@ impl Function for DateAddFunction { helper::one_of_sigs2( vec![ ConcreteDataType::date_datatype(), - ConcreteDataType::datetime_datatype(), ConcreteDataType::timestamp_second_datatype(), ConcreteDataType::timestamp_millisecond_datatype(), ConcreteDataType::timestamp_microsecond_datatype(), @@ -69,64 +69,14 @@ impl Function for DateAddFunction { } ); - let left = &columns[0]; - let right = &columns[1]; + let left = columns[0].to_arrow_array(); + let right = columns[1].to_arrow_array(); - let size = left.len(); - let left_datatype = columns[0].data_type(); - match left_datatype { - ConcreteDataType::Timestamp(_) => { - let mut result = left_datatype.create_mutable_vector(size); - for i in 0..size { - let ts = left.get(i).as_timestamp(); - let interval = right.get(i).as_interval(); - - let new_ts = match (ts, interval) { - (Some(ts), Some(interval)) => ts.add_interval(interval), - _ => ts, - }; - - result.push_value_ref(ValueRef::from(new_ts)); - } - - Ok(result.to_vector()) - } - ConcreteDataType::Date(_) => { - let mut result = left_datatype.create_mutable_vector(size); - for i in 0..size { - let date = left.get(i).as_date(); - let interval = right.get(i).as_interval(); - let new_date = match (date, interval) { - (Some(date), Some(interval)) => date.add_interval(interval), - _ => date, - }; - - result.push_value_ref(ValueRef::from(new_date)); - } - - Ok(result.to_vector()) - } - ConcreteDataType::DateTime(_) => { - let mut result = left_datatype.create_mutable_vector(size); - for i in 0..size { - let datetime = left.get(i).as_datetime(); - let interval = right.get(i).as_interval(); - let new_datetime = match (datetime, interval) { - (Some(datetime), Some(interval)) => datetime.add_interval(interval), - _ => datetime, - }; - - result.push_value_ref(ValueRef::from(new_datetime)); - } - - Ok(result.to_vector()) - } - _ => UnsupportedInputDataTypeSnafu { - function: NAME, - datatypes: columns.iter().map(|c| c.data_type()).collect::>(), - } - .fail(), - } + let result = numeric::add(&left, &right).context(ArrowComputeSnafu)?; + let arrow_type = result.data_type().clone(); + Helper::try_into_vector(result).context(IntoVectorSnafu { + data_type: arrow_type, + }) } } @@ -144,8 +94,7 @@ mod tests { use datatypes::prelude::ConcreteDataType; use datatypes::value::Value; use datatypes::vectors::{ - DateTimeVector, DateVector, IntervalDayTimeVector, IntervalYearMonthVector, - TimestampSecondVector, + DateVector, IntervalDayTimeVector, IntervalYearMonthVector, TimestampSecondVector, }; use super::{DateAddFunction, *}; @@ -168,16 +117,15 @@ mod tests { ConcreteDataType::date_datatype(), f.return_type(&[ConcreteDataType::date_datatype()]).unwrap() ); - assert_eq!( - ConcreteDataType::datetime_datatype(), - f.return_type(&[ConcreteDataType::datetime_datatype()]) - .unwrap() - ); - assert!(matches!(f.signature(), + assert!( + matches!(f.signature(), Signature { type_signature: TypeSignature::OneOf(sigs), volatility: Volatility::Immutable - } if sigs.len() == 18)); + } if sigs.len() == 15), + "{:?}", + f.signature() + ); } #[test] @@ -243,36 +191,4 @@ mod tests { } } } - - #[test] - fn test_datetime_date_add() { - let f = DateAddFunction; - - let dates = vec![Some(123), None, Some(42), None]; - // Intervals in months - let intervals = vec![1, 2, 3, 1]; - let results = [Some(2678400123), None, Some(7776000042), None]; - - let date_vector = DateTimeVector::from(dates.clone()); - let interval_vector = IntervalYearMonthVector::from_vec(intervals); - let args: Vec = vec![Arc::new(date_vector), Arc::new(interval_vector)]; - let vector = f.eval(FunctionContext::default(), &args).unwrap(); - - assert_eq!(4, vector.len()); - for (i, _t) in dates.iter().enumerate() { - let v = vector.get(i); - let result = results.get(i).unwrap(); - - if result.is_none() { - assert_eq!(Value::Null, v); - continue; - } - match v { - Value::DateTime(date) => { - assert_eq!(date.val(), result.unwrap()); - } - _ => unreachable!(), - } - } - } } diff --git a/src/common/function/src/scalars/date/date_sub.rs b/src/common/function/src/scalars/date/date_sub.rs index b1f87e880a..1e00db5331 100644 --- a/src/common/function/src/scalars/date/date_sub.rs +++ b/src/common/function/src/scalars/date/date_sub.rs @@ -14,18 +14,19 @@ use std::fmt; -use common_query::error::{InvalidFuncArgsSnafu, Result, UnsupportedInputDataTypeSnafu}; +use common_query::error::{ArrowComputeSnafu, IntoVectorSnafu, InvalidFuncArgsSnafu, Result}; use common_query::prelude::Signature; -use datatypes::data_type::DataType; +use datatypes::arrow::compute::kernels::numeric; use datatypes::prelude::ConcreteDataType; -use datatypes::value::ValueRef; -use datatypes::vectors::VectorRef; -use snafu::ensure; +use datatypes::vectors::{Helper, VectorRef}; +use snafu::{ensure, ResultExt}; use crate::function::{Function, FunctionContext}; use crate::helper; -/// A function subtracts an interval value to Timestamp, Date or DateTime, and return the result. +/// A function subtracts an interval value to Timestamp, Date, and return the result. +/// The implementation of datetime type is based on Date64 which is incorrect so this function +/// doesn't support the datetime type. #[derive(Clone, Debug, Default)] pub struct DateSubFunction; @@ -44,7 +45,6 @@ impl Function for DateSubFunction { helper::one_of_sigs2( vec![ ConcreteDataType::date_datatype(), - ConcreteDataType::datetime_datatype(), ConcreteDataType::timestamp_second_datatype(), ConcreteDataType::timestamp_millisecond_datatype(), ConcreteDataType::timestamp_microsecond_datatype(), @@ -69,65 +69,14 @@ impl Function for DateSubFunction { } ); - let left = &columns[0]; - let right = &columns[1]; + let left = columns[0].to_arrow_array(); + let right = columns[1].to_arrow_array(); - let size = left.len(); - let left_datatype = columns[0].data_type(); - - match left_datatype { - ConcreteDataType::Timestamp(_) => { - let mut result = left_datatype.create_mutable_vector(size); - for i in 0..size { - let ts = left.get(i).as_timestamp(); - let interval = right.get(i).as_interval(); - - let new_ts = match (ts, interval) { - (Some(ts), Some(interval)) => ts.sub_interval(interval), - _ => ts, - }; - - result.push_value_ref(ValueRef::from(new_ts)); - } - - Ok(result.to_vector()) - } - ConcreteDataType::Date(_) => { - let mut result = left_datatype.create_mutable_vector(size); - for i in 0..size { - let date = left.get(i).as_date(); - let interval = right.get(i).as_interval(); - let new_date = match (date, interval) { - (Some(date), Some(interval)) => date.sub_interval(interval), - _ => date, - }; - - result.push_value_ref(ValueRef::from(new_date)); - } - - Ok(result.to_vector()) - } - ConcreteDataType::DateTime(_) => { - let mut result = left_datatype.create_mutable_vector(size); - for i in 0..size { - let datetime = left.get(i).as_datetime(); - let interval = right.get(i).as_interval(); - let new_datetime = match (datetime, interval) { - (Some(datetime), Some(interval)) => datetime.sub_interval(interval), - _ => datetime, - }; - - result.push_value_ref(ValueRef::from(new_datetime)); - } - - Ok(result.to_vector()) - } - _ => UnsupportedInputDataTypeSnafu { - function: NAME, - datatypes: columns.iter().map(|c| c.data_type()).collect::>(), - } - .fail(), - } + let result = numeric::sub(&left, &right).context(ArrowComputeSnafu)?; + let arrow_type = result.data_type().clone(); + Helper::try_into_vector(result).context(IntoVectorSnafu { + data_type: arrow_type, + }) } } @@ -145,8 +94,7 @@ mod tests { use datatypes::prelude::ConcreteDataType; use datatypes::value::Value; use datatypes::vectors::{ - DateTimeVector, DateVector, IntervalDayTimeVector, IntervalYearMonthVector, - TimestampSecondVector, + DateVector, IntervalDayTimeVector, IntervalYearMonthVector, TimestampSecondVector, }; use super::{DateSubFunction, *}; @@ -174,11 +122,15 @@ mod tests { f.return_type(&[ConcreteDataType::datetime_datatype()]) .unwrap() ); - assert!(matches!(f.signature(), + assert!( + matches!(f.signature(), Signature { type_signature: TypeSignature::OneOf(sigs), volatility: Volatility::Immutable - } if sigs.len() == 18)); + } if sigs.len() == 15), + "{:?}", + f.signature() + ); } #[test] @@ -250,42 +202,4 @@ mod tests { } } } - - #[test] - fn test_datetime_date_sub() { - let f = DateSubFunction; - let millis_per_month = 3600 * 24 * 30 * 1000; - - let dates = vec![ - Some(123 * millis_per_month), - None, - Some(42 * millis_per_month), - None, - ]; - // Intervals in months - let intervals = vec![1, 2, 3, 1]; - let results = [Some(316137600000), None, Some(100915200000), None]; - - let date_vector = DateTimeVector::from(dates.clone()); - let interval_vector = IntervalYearMonthVector::from_vec(intervals); - let args: Vec = vec![Arc::new(date_vector), Arc::new(interval_vector)]; - let vector = f.eval(FunctionContext::default(), &args).unwrap(); - - assert_eq!(4, vector.len()); - for (i, _t) in dates.iter().enumerate() { - let v = vector.get(i); - let result = results.get(i).unwrap(); - - if result.is_none() { - assert_eq!(Value::Null, v); - continue; - } - match v { - Value::DateTime(date) => { - assert_eq!(date.val(), result.unwrap()); - } - _ => unreachable!(), - } - } - } } diff --git a/src/common/grpc/src/select.rs b/src/common/grpc/src/select.rs index ba13acf3b7..493893f49d 100644 --- a/src/common/grpc/src/select.rs +++ b/src/common/grpc/src/select.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use api::helper::{convert_i128_to_interval, convert_to_pb_decimal128}; +use api::helper::{convert_month_day_nano_to_pb, convert_to_pb_decimal128}; use api::v1::column::Values; use common_base::BitVec; use datatypes::types::{IntervalType, TimeType, TimestampType, WrapperType}; @@ -211,7 +211,7 @@ pub fn values(arrays: &[VectorRef]) -> Result { ConcreteDataType::Interval(IntervalType::MonthDayNano(_)), IntervalMonthDayNanoVector, interval_month_day_nano_values, - |x| { convert_i128_to_interval(x.into_native()) } + |x| { convert_month_day_nano_to_pb(x) } ), ( ConcreteDataType::Decimal128(_), diff --git a/src/common/time/src/date.rs b/src/common/time/src/date.rs index 86759d737d..4274913925 100644 --- a/src/common/time/src/date.rs +++ b/src/common/time/src/date.rs @@ -14,13 +14,13 @@ use std::fmt::{Display, Formatter, Write}; -use chrono::{Datelike, Days, LocalResult, Months, NaiveDate, NaiveTime, TimeZone}; +use chrono::{Datelike, Days, LocalResult, Months, NaiveDate, NaiveTime, TimeDelta, TimeZone}; use serde::{Deserialize, Serialize}; use serde_json::Value; use snafu::ResultExt; use crate::error::{InvalidDateStrSnafu, ParseDateStrSnafu, Result}; -use crate::interval::Interval; +use crate::interval::{IntervalDayTime, IntervalMonthDayNano, IntervalYearMonth}; use crate::timezone::get_timezone; use crate::util::datetime_to_utc; use crate::Timezone; @@ -134,29 +134,64 @@ impl Date { (self.0 as i64) * 24 * 3600 } - /// Adds given Interval to the current date. - /// Returns None if the resulting date would be out of range. - pub fn add_interval(&self, interval: Interval) -> Option { + // FIXME(yingwen): remove add/sub intervals later + /// Adds given [IntervalYearMonth] to the current date. + pub fn add_year_month(&self, interval: IntervalYearMonth) -> Option { let naive_date = self.to_chrono_date()?; - let (months, days, _) = interval.to_month_day_nano(); - naive_date - .checked_add_months(Months::new(months as u32))? - .checked_add_days(Days::new(days as u64)) + .checked_add_months(Months::new(interval.months as u32)) .map(Into::into) } - /// Subtracts given Interval to the current date. - /// Returns None if the resulting date would be out of range. - pub fn sub_interval(&self, interval: Interval) -> Option { + /// Adds given [IntervalDayTime] to the current date. + pub fn add_day_time(&self, interval: IntervalDayTime) -> Option { let naive_date = self.to_chrono_date()?; - let (months, days, _) = interval.to_month_day_nano(); + naive_date + .checked_add_days(Days::new(interval.days as u64))? + .checked_add_signed(TimeDelta::milliseconds(interval.milliseconds as i64)) + .map(Into::into) + } + + /// Adds given [IntervalMonthDayNano] to the current date. + pub fn add_month_day_nano(&self, interval: IntervalMonthDayNano) -> Option { + let naive_date = self.to_chrono_date()?; naive_date - .checked_sub_months(Months::new(months as u32))? - .checked_sub_days(Days::new(days as u64)) + .checked_add_months(Months::new(interval.months as u32))? + .checked_add_days(Days::new(interval.days as u64))? + .checked_add_signed(TimeDelta::nanoseconds(interval.nanoseconds)) + .map(Into::into) + } + + /// Subtracts given [IntervalYearMonth] to the current date. + pub fn sub_year_month(&self, interval: IntervalYearMonth) -> Option { + let naive_date = self.to_chrono_date()?; + + naive_date + .checked_sub_months(Months::new(interval.months as u32)) + .map(Into::into) + } + + /// Subtracts given [IntervalDayTime] to the current date. + pub fn sub_day_time(&self, interval: IntervalDayTime) -> Option { + let naive_date = self.to_chrono_date()?; + + naive_date + .checked_sub_days(Days::new(interval.days as u64))? + .checked_sub_signed(TimeDelta::milliseconds(interval.milliseconds as i64)) + .map(Into::into) + } + + /// Subtracts given [IntervalMonthDayNano] to the current date. + pub fn sub_month_day_nano(&self, interval: IntervalMonthDayNano) -> Option { + let naive_date = self.to_chrono_date()?; + + naive_date + .checked_sub_months(Months::new(interval.months as u32))? + .checked_sub_days(Days::new(interval.days as u64))? + .checked_sub_signed(TimeDelta::nanoseconds(interval.nanoseconds)) .map(Into::into) } @@ -246,12 +281,12 @@ mod tests { fn test_add_sub_interval() { let date = Date::new(1000); - let interval = Interval::from_year_month(3); + let interval = IntervalYearMonth::new(3); - let new_date = date.add_interval(interval).unwrap(); + let new_date = date.add_year_month(interval).unwrap(); assert_eq!(new_date.val(), 1091); - assert_eq!(date, new_date.sub_interval(interval).unwrap()); + assert_eq!(date, new_date.sub_year_month(interval).unwrap()); } #[test] diff --git a/src/common/time/src/datetime.rs b/src/common/time/src/datetime.rs index 4a60470aeb..abeae4908a 100644 --- a/src/common/time/src/datetime.rs +++ b/src/common/time/src/datetime.rs @@ -13,16 +13,18 @@ // limitations under the License. use std::fmt::{Display, Formatter, Write}; -use std::time::Duration; -use chrono::{Days, LocalResult, Months, NaiveDateTime, TimeZone as ChronoTimeZone, Utc}; +use chrono::{ + Days, LocalResult, Months, NaiveDateTime, TimeDelta, TimeZone as ChronoTimeZone, Utc, +}; use serde::{Deserialize, Serialize}; use snafu::ResultExt; use crate::error::{InvalidDateStrSnafu, Result}; +use crate::interval::{IntervalDayTime, IntervalMonthDayNano, IntervalYearMonth}; use crate::timezone::{get_timezone, Timezone}; use crate::util::{datetime_to_utc, format_utc_datetime}; -use crate::{Date, Interval}; +use crate::Date; const DATETIME_FORMAT: &str = "%F %H:%M:%S%.f"; const DATETIME_FORMAT_WITH_TZ: &str = "%F %H:%M:%S%.f%z"; @@ -160,32 +162,66 @@ impl DateTime { None => Utc.from_utc_datetime(&v).naive_local(), }) } - /// Adds given Interval to the current datetime. - /// Returns None if the resulting datetime would be out of range. - pub fn add_interval(&self, interval: Interval) -> Option { + + // FIXME(yingwen): remove add/sub intervals later + /// Adds given [IntervalYearMonth] to the current datetime. + pub fn add_year_month(&self, interval: IntervalYearMonth) -> Option { let naive_datetime = self.to_chrono_datetime()?; - let (months, days, nsecs) = interval.to_month_day_nano(); - let naive_datetime = naive_datetime - .checked_add_months(Months::new(months as u32))? - .checked_add_days(Days::new(days as u64))? - + Duration::from_nanos(nsecs as u64); - - Some(naive_datetime.into()) + naive_datetime + .checked_add_months(Months::new(interval.months as u32)) + .map(Into::into) } - /// Subtracts given Interval to the current datetime. - /// Returns None if the resulting datetime would be out of range. - pub fn sub_interval(&self, interval: Interval) -> Option { + /// Adds given [IntervalDayTime] to the current datetime. + pub fn add_day_time(&self, interval: IntervalDayTime) -> Option { let naive_datetime = self.to_chrono_datetime()?; - let (months, days, nsecs) = interval.to_month_day_nano(); - let naive_datetime = naive_datetime - .checked_sub_months(Months::new(months as u32))? - .checked_sub_days(Days::new(days as u64))? - - Duration::from_nanos(nsecs as u64); + naive_datetime + .checked_add_days(Days::new(interval.days as u64))? + .checked_add_signed(TimeDelta::milliseconds(interval.milliseconds as i64)) + .map(Into::into) + } - Some(naive_datetime.into()) + /// Adds given [IntervalMonthDayNano] to the current datetime. + pub fn add_month_day_nano(&self, interval: IntervalMonthDayNano) -> Option { + let naive_datetime = self.to_chrono_datetime()?; + + naive_datetime + .checked_add_months(Months::new(interval.months as u32))? + .checked_add_days(Days::new(interval.days as u64))? + .checked_add_signed(TimeDelta::nanoseconds(interval.nanoseconds)) + .map(Into::into) + } + + /// Subtracts given [IntervalYearMonth] to the current datetime. + pub fn sub_year_month(&self, interval: IntervalYearMonth) -> Option { + let naive_datetime = self.to_chrono_datetime()?; + + naive_datetime + .checked_sub_months(Months::new(interval.months as u32)) + .map(Into::into) + } + + /// Subtracts given [IntervalDayTime] to the current datetime. + pub fn sub_day_time(&self, interval: IntervalDayTime) -> Option { + let naive_datetime = self.to_chrono_datetime()?; + + naive_datetime + .checked_sub_days(Days::new(interval.days as u64))? + .checked_sub_signed(TimeDelta::milliseconds(interval.milliseconds as i64)) + .map(Into::into) + } + + /// Subtracts given [IntervalMonthDayNano] to the current datetime. + pub fn sub_month_day_nano(&self, interval: IntervalMonthDayNano) -> Option { + let naive_datetime = self.to_chrono_datetime()?; + + naive_datetime + .checked_sub_months(Months::new(interval.months as u32))? + .checked_sub_days(Days::new(interval.days as u64))? + .checked_sub_signed(TimeDelta::nanoseconds(interval.nanoseconds)) + .map(Into::into) } /// Convert to [common_time::date]. @@ -231,12 +267,12 @@ mod tests { fn test_add_sub_interval() { let datetime = DateTime::new(1000); - let interval = Interval::from_day_time(1, 200); + let interval = IntervalDayTime::new(1, 200); - let new_datetime = datetime.add_interval(interval).unwrap(); + let new_datetime = datetime.add_day_time(interval).unwrap(); assert_eq!(new_datetime.val(), 1000 + 3600 * 24 * 1000 + 200); - assert_eq!(datetime, new_datetime.sub_interval(interval).unwrap()); + assert_eq!(datetime, new_datetime.sub_day_time(interval).unwrap()); } #[test] diff --git a/src/common/time/src/interval.rs b/src/common/time/src/interval.rs index cd57028d29..0ca40f7d79 100644 --- a/src/common/time/src/interval.rs +++ b/src/common/time/src/interval.rs @@ -12,18 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::cmp::Ordering; -use std::default::Default; -use std::fmt::{self, Display, Formatter, Write}; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; use arrow::datatypes::IntervalUnit as ArrowIntervalUnit; use serde::{Deserialize, Serialize}; -use serde_json::Value; -use snafu::ResultExt; - -use crate::duration::Duration; -use crate::error::{Result, TimestampOverflowSnafu}; #[derive( Debug, Default, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, @@ -61,268 +53,269 @@ impl From for IntervalUnit { } } -/// Interval Type represents a period of time. -/// It is composed of months, days and nanoseconds. -/// 3 kinds of interval are supported: year-month, day-time and -/// month-day-nano, which will be stored in the following format. -/// Interval data format: -/// | months | days | nsecs | -/// | 4bytes | 4bytes | 8bytes | -#[derive(Debug, Clone, Default, Copy, Serialize, Deserialize)] -pub struct Interval { - months: i32, - days: i32, - nsecs: i64, - unit: IntervalUnit, +// The `Value` type requires Serialize, Deserialize. +#[derive( + Debug, Default, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, +)] +#[repr(C)] +pub struct IntervalYearMonth { + /// Number of months + pub months: i32, } -// Nanosecond convert to other time unit -pub const NANOS_PER_SEC: i64 = 1_000_000_000; -pub const NANOS_PER_MILLI: i64 = 1_000_000; -pub const NANOS_PER_MICRO: i64 = 1_000; -pub const NANOS_PER_HOUR: i64 = 60 * 60 * NANOS_PER_SEC; -pub const NANOS_PER_DAY: i64 = 24 * NANOS_PER_HOUR; -pub const NANOS_PER_MONTH: i64 = 30 * NANOS_PER_DAY; - -pub const DAYS_PER_MONTH: i64 = 30; - -impl Interval { - /// Creates a new interval from months, days and nanoseconds. - /// Precision is nanosecond. - pub fn from_month_day_nano(months: i32, days: i32, nsecs: i64) -> Self { - Interval { - months, - days, - nsecs, - unit: IntervalUnit::MonthDayNano, - } - } - - /// Creates a new interval from months. - pub fn from_year_month(months: i32) -> Self { - Interval { - months, - days: 0, - nsecs: 0, - unit: IntervalUnit::YearMonth, - } - } - - /// Creates a new interval from days and milliseconds. - pub fn from_day_time(days: i32, millis: i32) -> Self { - Interval { - months: 0, - days, - nsecs: (millis as i64) * NANOS_PER_MILLI, - unit: IntervalUnit::DayTime, - } - } - - pub fn to_duration(&self) -> Result { - Ok(Duration::new_nanosecond( - self.to_nanosecond() - .try_into() - .context(TimestampOverflowSnafu)?, - )) - } - - /// Return a tuple(months, days, nanoseconds) from the interval. - pub fn to_month_day_nano(&self) -> (i32, i32, i64) { - (self.months, self.days, self.nsecs) - } - - /// Converts the interval to nanoseconds. - pub fn to_nanosecond(&self) -> i128 { - let days = (self.days as i64) + DAYS_PER_MONTH * (self.months as i64); - (self.nsecs as i128) + (NANOS_PER_DAY as i128) * (days as i128) - } - - /// Smallest interval value. - pub const MIN: Self = Self { - months: i32::MIN, - days: i32::MIN, - nsecs: i64::MIN, - unit: IntervalUnit::MonthDayNano, - }; - - /// Largest interval value. - pub const MAX: Self = Self { - months: i32::MAX, - days: i32::MAX, - nsecs: i64::MAX, - unit: IntervalUnit::MonthDayNano, - }; - - /// Returns the justified interval. - /// allows you to adjust the interval of 30-day as one month and the interval of 24-hour as one day - pub fn justified_interval(&self) -> Self { - let mut result = *self; - let extra_months_d = self.days as i64 / DAYS_PER_MONTH; - let extra_months_nsecs = self.nsecs / NANOS_PER_MONTH; - result.days -= (extra_months_d * DAYS_PER_MONTH) as i32; - result.nsecs -= extra_months_nsecs * NANOS_PER_MONTH; - - let extra_days = self.nsecs / NANOS_PER_DAY; - result.nsecs -= extra_days * NANOS_PER_DAY; - - result.months += extra_months_d as i32 + extra_months_nsecs as i32; - result.days += extra_days as i32; - - result - } - - /// Convert Interval to nanoseconds, - /// to check whether Interval is positive - pub fn is_positive(&self) -> bool { - self.to_nanosecond() > 0 - } - - /// is_zero - pub fn is_zero(&self) -> bool { - self.months == 0 && self.days == 0 && self.nsecs == 0 - } - - /// get unit - pub fn unit(&self) -> IntervalUnit { - self.unit - } - - /// Multiple Interval by an integer with overflow check. - /// Returns justified Interval, or `None` if overflow occurred. - pub fn checked_mul_int(&self, rhs: I) -> Option - where - I: TryInto, - { - let rhs = rhs.try_into().ok()?; - let months = self.months.checked_mul(rhs)?; - let days = self.days.checked_mul(rhs)?; - let nsecs = self.nsecs.checked_mul(rhs as i64)?; - - Some( - Self { - months, - days, - nsecs, - unit: self.unit, - } - .justified_interval(), - ) - } - - /// Convert Interval to ISO 8601 string - pub fn to_iso8601_string(self) -> String { - IntervalFormat::from(self).to_iso8601_string() - } - - /// Convert Interval to postgres verbose string - pub fn to_postgres_string(self) -> String { - IntervalFormat::from(self).to_postgres_string() - } - - /// Convert Interval to sql_standard string - pub fn to_sql_standard_string(self) -> String { - IntervalFormat::from(self).to_sql_standard_string() - } - - /// Interval Type and i128 [IntervalUnit::MonthDayNano] Convert - /// v consists of months(i32) | days(i32) | nsecs(i64) - pub fn from_i128(v: i128) -> Self { - Interval { - nsecs: v as i64, - days: (v >> 64) as i32, - months: (v >> 96) as i32, - unit: IntervalUnit::MonthDayNano, - } - } - - /// `Interval` Type and i64 [IntervalUnit::DayTime] Convert - /// v consists of days(i32) | milliseconds(i32) - pub fn from_i64(v: i64) -> Self { - Interval { - nsecs: ((v as i32) as i64) * NANOS_PER_MILLI, - days: (v >> 32) as i32, - months: 0, - unit: IntervalUnit::DayTime, - } - } - - /// `Interval` Type and i32 [IntervalUnit::YearMonth] Convert - /// v consists of months(i32) - pub fn from_i32(v: i32) -> Self { - Interval { - nsecs: 0, - days: 0, - months: v, - unit: IntervalUnit::YearMonth, - } - } - - pub fn to_i128(&self) -> i128 { - // 128 96 64 0 - // +-------+-------+-------+-------+-------+-------+-------+-------+ - // | months | days | nanoseconds | - // +-------+-------+-------+-------+-------+-------+-------+-------+ - let months = (self.months as u128 & u32::MAX as u128) << 96; - let days = (self.days as u128 & u32::MAX as u128) << 64; - let nsecs = self.nsecs as u128 & u64::MAX as u128; - (months | days | nsecs) as i128 - } - - pub fn to_i64(&self) -> i64 { - // 64 32 0 - // +-------+-------+-------+-------+-------+-------+-------+-------+ - // | days | milliseconds | - // +-------+-------+-------+-------+-------+-------+-------+-------+ - let days = (self.days as u64 & u32::MAX as u64) << 32; - let milliseconds = (self.nsecs / NANOS_PER_MILLI) as u64 & u32::MAX as u64; - (days | milliseconds) as i64 +impl IntervalYearMonth { + pub fn new(months: i32) -> Self { + Self { months } } pub fn to_i32(&self) -> i32 { self.months } + pub fn from_i32(months: i32) -> Self { + Self { months } + } + pub fn negative(&self) -> Self { - Self { - months: -self.months, - days: -self.days, - nsecs: -self.nsecs, - unit: self.unit, + Self::new(-self.months) + } + + pub fn to_iso8601_string(&self) -> String { + IntervalFormat::from(*self).to_iso8601_string() + } +} + +impl From for IntervalFormat { + fn from(interval: IntervalYearMonth) -> Self { + IntervalFormat { + years: interval.months / 12, + months: interval.months % 12, + ..Default::default() } } } -impl From for Interval { +impl From for IntervalYearMonth { + fn from(v: i32) -> Self { + Self::from_i32(v) + } +} + +impl From for i32 { + fn from(v: IntervalYearMonth) -> Self { + v.to_i32() + } +} + +impl From for serde_json::Value { + fn from(v: IntervalYearMonth) -> Self { + serde_json::Value::from(v.to_i32()) + } +} + +#[derive( + Debug, Default, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, +)] +#[repr(C)] +pub struct IntervalDayTime { + /// Number of days + pub days: i32, + /// Number of milliseconds + pub milliseconds: i32, +} + +impl IntervalDayTime { + /// The additive identity i.e. `0`. + pub const ZERO: Self = Self::new(0, 0); + + /// The multiplicative inverse, i.e. `-1`. + pub const MINUS_ONE: Self = Self::new(-1, -1); + + /// The maximum value that can be represented + pub const MAX: Self = Self::new(i32::MAX, i32::MAX); + + /// The minimum value that can be represented + pub const MIN: Self = Self::new(i32::MIN, i32::MIN); + + pub const fn new(days: i32, milliseconds: i32) -> Self { + Self { days, milliseconds } + } + + pub fn to_i64(&self) -> i64 { + let d = (self.days as u64 & u32::MAX as u64) << 32; + let m = self.milliseconds as u64 & u32::MAX as u64; + (d | m) as i64 + } + + pub fn from_i64(value: i64) -> Self { + let days = (value >> 32) as i32; + let milliseconds = value as i32; + Self { days, milliseconds } + } + + pub fn negative(&self) -> Self { + Self::new(-self.days, -self.milliseconds) + } + + pub fn to_iso8601_string(&self) -> String { + IntervalFormat::from(*self).to_iso8601_string() + } + + pub fn as_millis(&self) -> i64 { + self.days as i64 * MS_PER_DAY + self.milliseconds as i64 + } +} + +impl From for IntervalDayTime { + fn from(v: i64) -> Self { + Self::from_i64(v) + } +} + +impl From for i64 { + fn from(v: IntervalDayTime) -> Self { + v.to_i64() + } +} + +impl From for serde_json::Value { + fn from(v: IntervalDayTime) -> Self { + serde_json::Value::from(v.to_i64()) + } +} + +// Millisecond convert to other time unit +pub const MS_PER_SEC: i64 = 1_000; +pub const MS_PER_MINUTE: i64 = 60 * MS_PER_SEC; +pub const MS_PER_HOUR: i64 = 60 * MS_PER_MINUTE; +pub const MS_PER_DAY: i64 = 24 * MS_PER_HOUR; +pub const NANOS_PER_MILLI: i64 = 1_000_000; + +impl From for IntervalFormat { + fn from(interval: IntervalDayTime) -> Self { + IntervalFormat { + days: interval.days, + hours: interval.milliseconds as i64 / MS_PER_HOUR, + minutes: (interval.milliseconds as i64 % MS_PER_HOUR) / MS_PER_MINUTE, + seconds: (interval.milliseconds as i64 % MS_PER_MINUTE) / MS_PER_SEC, + microseconds: (interval.milliseconds as i64 % MS_PER_SEC) * MS_PER_SEC, + ..Default::default() + } + } +} + +#[derive( + Debug, Default, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize, Deserialize, +)] +#[repr(C)] +pub struct IntervalMonthDayNano { + /// Number of months + pub months: i32, + /// Number of days + pub days: i32, + /// Number of nanoseconds + pub nanoseconds: i64, +} + +impl IntervalMonthDayNano { + /// The additive identity i.e. `0`. + pub const ZERO: Self = Self::new(0, 0, 0); + + /// The multiplicative inverse, i.e. `-1`. + pub const MINUS_ONE: Self = Self::new(-1, -1, -1); + + /// The maximum value that can be represented + pub const MAX: Self = Self::new(i32::MAX, i32::MAX, i64::MAX); + + /// The minimum value that can be represented + pub const MIN: Self = Self::new(i32::MIN, i32::MIN, i64::MIN); + + pub const fn new(months: i32, days: i32, nanoseconds: i64) -> Self { + Self { + months, + days, + nanoseconds, + } + } + + pub fn to_i128(&self) -> i128 { + let m = (self.months as u128 & u32::MAX as u128) << 96; + let d = (self.days as u128 & u32::MAX as u128) << 64; + let n = self.nanoseconds as u128 & u64::MAX as u128; + (m | d | n) as i128 + } + + pub fn from_i128(value: i128) -> Self { + let months = (value >> 96) as i32; + let days = (value >> 64) as i32; + let nanoseconds = value as i64; + Self { + months, + days, + nanoseconds, + } + } + + pub fn negative(&self) -> Self { + Self::new(-self.months, -self.days, -self.nanoseconds) + } + + pub fn to_iso8601_string(&self) -> String { + IntervalFormat::from(*self).to_iso8601_string() + } +} + +impl From for IntervalMonthDayNano { fn from(v: i128) -> Self { Self::from_i128(v) } } -impl From for i128 { - fn from(v: Interval) -> Self { +impl From for i128 { + fn from(v: IntervalMonthDayNano) -> Self { v.to_i128() } } -impl From for serde_json::Value { - fn from(v: Interval) -> Self { - Value::String(v.to_string()) +impl From for serde_json::Value { + fn from(v: IntervalMonthDayNano) -> Self { + serde_json::Value::from(v.to_i128().to_string()) } } -impl Display for Interval { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let mut s = String::new(); - if self.months != 0 { - write!(s, "{} months ", self.months)?; +// Nanosecond convert to other time unit +pub const NS_PER_SEC: i64 = 1_000_000_000; +pub const NS_PER_MINUTE: i64 = 60 * NS_PER_SEC; +pub const NS_PER_HOUR: i64 = 60 * NS_PER_MINUTE; +pub const NS_PER_DAY: i64 = 24 * NS_PER_HOUR; + +impl From for IntervalFormat { + fn from(interval: IntervalMonthDayNano) -> Self { + IntervalFormat { + years: interval.months / 12, + months: interval.months % 12, + days: interval.days, + hours: interval.nanoseconds / NS_PER_HOUR, + minutes: (interval.nanoseconds % NS_PER_HOUR) / NS_PER_MINUTE, + seconds: (interval.nanoseconds % NS_PER_MINUTE) / NS_PER_SEC, + microseconds: (interval.nanoseconds % NS_PER_SEC) / 1_000, } - if self.days != 0 { - write!(s, "{} days ", self.days)?; - } - if self.nsecs != 0 { - write!(s, "{} nsecs", self.nsecs)?; - } - write!(f, "{}", s.trim()) + } +} + +pub fn interval_year_month_to_month_day_nano(interval: IntervalYearMonth) -> IntervalMonthDayNano { + IntervalMonthDayNano { + months: interval.months, + days: 0, + nanoseconds: 0, + } +} + +pub fn interval_day_time_to_month_day_nano(interval: IntervalDayTime) -> IntervalMonthDayNano { + IntervalMonthDayNano { + months: 0, + days: interval.days, + nanoseconds: interval.milliseconds as i64 * NANOS_PER_MILLI, } } @@ -339,31 +332,6 @@ pub struct IntervalFormat { pub microseconds: i64, } -impl From for IntervalFormat { - fn from(val: Interval) -> IntervalFormat { - let months = val.months; - let days = val.days; - let microseconds = val.nsecs / NANOS_PER_MICRO; - let years = (months - (months % 12)) / 12; - let months = months - years * 12; - let hours = (microseconds - (microseconds % 3_600_000_000)) / 3_600_000_000; - let microseconds = microseconds - hours * 3_600_000_000; - let minutes = (microseconds - (microseconds % 60_000_000)) / 60_000_000; - let microseconds = microseconds - minutes * 60_000_000; - let seconds = (microseconds - (microseconds % 1_000_000)) / 1_000_000; - let microseconds = microseconds - seconds * 1_000_000; - IntervalFormat { - years, - months, - days, - hours, - minutes, - seconds, - microseconds, - } - } -} - impl IntervalFormat { /// All the field in the interval is 0 pub fn is_zero(&self) -> bool { @@ -540,117 +508,37 @@ fn get_time_part( interval } -/// IntervalCompare is used to compare two intervals -/// It makes interval into nanoseconds style. -#[derive(PartialEq, Eq, Hash, PartialOrd, Ord)] -struct IntervalCompare(i128); - -impl From for IntervalCompare { - fn from(interval: Interval) -> Self { - Self(interval.to_nanosecond()) - } -} - -impl Ord for Interval { - fn cmp(&self, other: &Self) -> Ordering { - IntervalCompare::from(*self).cmp(&IntervalCompare::from(*other)) - } -} - -impl PartialOrd for Interval { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Eq for Interval {} - -impl PartialEq for Interval { - fn eq(&self, other: &Self) -> bool { - self.cmp(other).is_eq() - } -} - -impl Hash for Interval { - fn hash(&self, state: &mut H) { - IntervalCompare::from(*self).hash(state) - } -} - #[cfg(test)] mod tests { - use std::collections::HashMap; - use super::*; - use crate::timestamp::TimeUnit; #[test] fn test_from_year_month() { - let interval = Interval::from_year_month(1); + let interval = IntervalYearMonth::new(1); assert_eq!(interval.months, 1); } #[test] fn test_from_date_time() { - let interval = Interval::from_day_time(1, 2); + let interval = IntervalDayTime::new(1, 2); assert_eq!(interval.days, 1); - assert_eq!(interval.nsecs, 2_000_000); + assert_eq!(interval.milliseconds, 2); } #[test] - fn test_to_duration() { - let interval = Interval::from_day_time(1, 2); - - let duration = interval.to_duration().unwrap(); - assert_eq!(86400002000000, duration.value()); - assert_eq!(TimeUnit::Nanosecond, duration.unit()); - - let interval = Interval::from_year_month(12); - - let duration = interval.to_duration().unwrap(); - assert_eq!(31104000000000000, duration.value()); - assert_eq!(TimeUnit::Nanosecond, duration.unit()); - } - - #[test] - fn test_interval_is_positive() { - let interval = Interval::from_year_month(1); - assert!(interval.is_positive()); - let interval = Interval::from_year_month(-1); - assert!(!interval.is_positive()); - - let interval = Interval::from_day_time(1, i32::MIN); - assert!(!interval.is_positive()); - } - - #[test] - fn test_to_nanosecond() { - let interval = Interval::from_year_month(1); - assert_eq!(interval.to_nanosecond(), 2592000000000000); - let interval = Interval::from_day_time(1, 2); - assert_eq!(interval.to_nanosecond(), 86400002000000); - - let max_interval = Interval::from_month_day_nano(i32::MAX, i32::MAX, i64::MAX); - assert_eq!(max_interval.to_nanosecond(), 5751829423496836854775807); - - let min_interval = Interval::from_month_day_nano(i32::MIN, i32::MIN, i64::MIN); - assert_eq!(min_interval.to_nanosecond(), -5751829426175236854775808); - } - - #[test] - fn test_interval_is_zero() { - let interval = Interval::from_month_day_nano(1, 1, 1); - assert!(!interval.is_zero()); - let interval = Interval::from_month_day_nano(0, 0, 0); - assert!(interval.is_zero()); + fn test_from_month_day_nano() { + let interval = IntervalMonthDayNano::new(1, 2, 3); + assert_eq!(interval.months, 1); + assert_eq!(interval.days, 2); + assert_eq!(interval.nanoseconds, 3); } #[test] fn test_interval_i128_convert() { let test_interval_eq = |month, day, nano| { - let interval = Interval::from_month_day_nano(month, day, nano); + let interval = IntervalMonthDayNano::new(month, day, nano); let interval_i128 = interval.to_i128(); - let interval2 = Interval::from_i128(interval_i128); + let interval2 = IntervalMonthDayNano::from_i128(interval_i128); assert_eq!(interval, interval2); }; @@ -666,11 +554,26 @@ mod tests { test_interval_eq(i32::MAX, i32::MIN, i64::MIN); test_interval_eq(i32::MIN, i32::MAX, i64::MIN); test_interval_eq(i32::MIN, i32::MIN, i64::MIN); + + let interval = IntervalMonthDayNano::from_i128(1); + assert_eq!(interval, IntervalMonthDayNano::new(0, 0, 1)); + assert_eq!(1, IntervalMonthDayNano::new(0, 0, 1).to_i128()); + } + + #[test] + fn test_interval_i64_convert() { + let interval = IntervalDayTime::from_i64(1); + assert_eq!(interval, IntervalDayTime::new(0, 1)); + assert_eq!(1, IntervalDayTime::new(0, 1).to_i64()); } #[test] fn test_convert_interval_format() { - let interval = Interval::from_month_day_nano(14, 160, 1000000); + let interval = IntervalMonthDayNano { + months: 14, + days: 160, + nanoseconds: 1000000, + }; let interval_format = IntervalFormat::from(interval); assert_eq!(interval_format.years, 1); assert_eq!(interval_format.months, 2); @@ -681,94 +584,34 @@ mod tests { assert_eq!(interval_format.microseconds, 1000); } - #[test] - fn test_interval_hash() { - let interval = Interval::from_month_day_nano(1, 31, 1); - let interval2 = Interval::from_month_day_nano(2, 1, 1); - let mut map = HashMap::new(); - map.insert(interval, 1); - assert_eq!(map.get(&interval2), Some(&1)); - } - - #[test] - fn test_interval_mul_int() { - let interval = Interval::from_month_day_nano(1, 1, 1); - let interval2 = interval.checked_mul_int(2).unwrap(); - assert_eq!(interval2.months, 2); - assert_eq!(interval2.days, 2); - assert_eq!(interval2.nsecs, 2); - - // test justified interval - let interval = Interval::from_month_day_nano(1, 31, 1); - let interval2 = interval.checked_mul_int(2).unwrap(); - assert_eq!(interval2.months, 4); - assert_eq!(interval2.days, 2); - assert_eq!(interval2.nsecs, 2); - - // test overflow situation - let interval = Interval::from_month_day_nano(i32::MAX, 1, 1); - let interval2 = interval.checked_mul_int(2); - assert!(interval2.is_none()); - } - - #[test] - fn test_display() { - let interval = Interval::from_month_day_nano(1, 1, 1); - assert_eq!(interval.to_string(), "1 months 1 days 1 nsecs"); - - let interval = Interval::from_month_day_nano(14, 31, 10000000000); - assert_eq!(interval.to_string(), "14 months 31 days 10000000000 nsecs"); - } - - #[test] - fn test_interval_justified() { - let interval = Interval::from_month_day_nano(1, 131, 1).justified_interval(); - let interval2 = Interval::from_month_day_nano(5, 11, 1); - assert_eq!(interval, interval2); - - let interval = Interval::from_month_day_nano(1, 1, NANOS_PER_MONTH + 2 * NANOS_PER_DAY) - .justified_interval(); - let interval2 = Interval::from_month_day_nano(2, 3, 0); - assert_eq!(interval, interval2); - } - - #[test] - fn test_serde_json() { - let interval = Interval::from_month_day_nano(1, 1, 1); - let json = serde_json::to_string(&interval).unwrap(); - assert_eq!( - json, - "{\"months\":1,\"days\":1,\"nsecs\":1,\"unit\":\"MonthDayNano\"}" - ); - let interval2: Interval = serde_json::from_str(&json).unwrap(); - assert_eq!(interval, interval2); - } - #[test] fn test_to_iso8601_string() { // Test interval zero - let interval = Interval::from_month_day_nano(0, 0, 0); + let interval = IntervalMonthDayNano::new(0, 0, 0); assert_eq!(interval.to_iso8601_string(), "PT0S"); - let interval = Interval::from_month_day_nano(1, 1, 1); + let interval = IntervalMonthDayNano::new(1, 1, 1); assert_eq!(interval.to_iso8601_string(), "P0Y1M1DT0H0M0S"); - let interval = Interval::from_month_day_nano(14, 31, 10000000000); + let interval = IntervalMonthDayNano::new(14, 31, 10000000000); assert_eq!(interval.to_iso8601_string(), "P1Y2M31DT0H0M10S"); - let interval = Interval::from_month_day_nano(14, 31, 23210200000000); + let interval = IntervalMonthDayNano::new(14, 31, 23210200000000); assert_eq!(interval.to_iso8601_string(), "P1Y2M31DT6H26M50.2S"); } #[test] fn test_to_postgres_string() { // Test interval zero - let interval = Interval::from_month_day_nano(0, 0, 0); - assert_eq!(interval.to_postgres_string(), "00:00:00"); - - let interval = Interval::from_month_day_nano(23, 100, 23210200000000); + let interval = IntervalMonthDayNano::new(0, 0, 0); assert_eq!( - interval.to_postgres_string(), + IntervalFormat::from(interval).to_postgres_string(), + "00:00:00" + ); + + let interval = IntervalMonthDayNano::new(23, 100, 23210200000000); + assert_eq!( + IntervalFormat::from(interval).to_postgres_string(), "1 year 11 mons 100 days 06:26:50.200000" ); } @@ -776,18 +619,21 @@ mod tests { #[test] fn test_to_sql_standard_string() { // Test zero interval - let interval = Interval::from_month_day_nano(0, 0, 0); - assert_eq!(interval.to_sql_standard_string(), "0"); + let interval = IntervalMonthDayNano::new(0, 0, 0); + assert_eq!(IntervalFormat::from(interval).to_sql_standard_string(), "0"); - let interval = Interval::from_month_day_nano(23, 100, 23210200000000); + let interval = IntervalMonthDayNano::new(23, 100, 23210200000000); assert_eq!( - interval.to_sql_standard_string(), + IntervalFormat::from(interval).to_sql_standard_string(), "+1-11 +100 +6:26:50.200000" ); // Test interval without year, month, day - let interval = Interval::from_month_day_nano(0, 0, 23210200000000); - assert_eq!(interval.to_sql_standard_string(), "6:26:50.200000"); + let interval = IntervalMonthDayNano::new(0, 0, 23210200000000); + assert_eq!( + IntervalFormat::from(interval).to_sql_standard_string(), + "6:26:50.200000" + ); } #[test] diff --git a/src/common/time/src/lib.rs b/src/common/time/src/lib.rs index 770057394c..fa025bf661 100644 --- a/src/common/time/src/lib.rs +++ b/src/common/time/src/lib.rs @@ -27,7 +27,7 @@ pub mod util; pub use date::Date; pub use datetime::DateTime; pub use duration::Duration; -pub use interval::Interval; +pub use interval::{IntervalDayTime, IntervalMonthDayNano, IntervalYearMonth}; pub use range::RangeMillis; pub use timestamp::Timestamp; pub use timestamp_millis::TimestampMillis; diff --git a/src/common/time/src/timestamp.rs b/src/common/time/src/timestamp.rs index 503c44cf99..258e9c1a96 100644 --- a/src/common/time/src/timestamp.rs +++ b/src/common/time/src/timestamp.rs @@ -20,16 +20,17 @@ use std::time::Duration; use arrow::datatypes::TimeUnit as ArrowTimeUnit; use chrono::{ - DateTime, Days, LocalResult, Months, NaiveDate, NaiveDateTime, NaiveTime, + DateTime, Days, LocalResult, Months, NaiveDate, NaiveDateTime, NaiveTime, TimeDelta, TimeZone as ChronoTimeZone, Utc, }; use serde::{Deserialize, Serialize}; use snafu::{OptionExt, ResultExt}; +use crate::error; use crate::error::{ArithmeticOverflowSnafu, ParseTimestampSnafu, Result, TimestampOverflowSnafu}; +use crate::interval::{IntervalDayTime, IntervalMonthDayNano, IntervalYearMonth}; use crate::timezone::{get_timezone, Timezone}; use crate::util::{datetime_to_utc, div_ceil}; -use crate::{error, Interval}; /// Timestamp represents the value of units(seconds/milliseconds/microseconds/nanoseconds) elapsed /// since UNIX epoch. The valid value range of [Timestamp] depends on it's unit (all in UTC timezone): @@ -140,40 +141,77 @@ impl Timestamp { }) } - /// Adds given Interval to the current timestamp. - /// Returns None if the resulting timestamp would be out of range. - pub fn add_interval(&self, interval: Interval) -> Option { + // FIXME(yingwen): remove add/sub intervals later + /// Adds given [IntervalYearMonth] to the current timestamp. + pub fn add_year_month(&self, interval: IntervalYearMonth) -> Option { let naive_datetime = self.to_chrono_datetime()?; - let (months, days, nsecs) = interval.to_month_day_nano(); - let naive_datetime = naive_datetime - .checked_add_months(Months::new(months as u32))? - .checked_add_days(Days::new(days as u64))? - + Duration::from_nanos(nsecs as u64); + let naive_datetime = + naive_datetime.checked_add_months(Months::new(interval.months as u32))?; - match Timestamp::from_chrono_datetime(naive_datetime) { - // Have to convert the new timestamp by the current unit. - Some(ts) => ts.convert_to(self.unit), - None => None, - } + // Have to convert the new timestamp by the current unit. + Timestamp::from_chrono_datetime(naive_datetime).and_then(|ts| ts.convert_to(self.unit)) } - /// Subtracts given Interval to the current timestamp. - /// Returns None if the resulting timestamp would be out of range. - pub fn sub_interval(&self, interval: Interval) -> Option { + /// Adds given [IntervalDayTime] to the current timestamp. + pub fn add_day_time(&self, interval: IntervalDayTime) -> Option { let naive_datetime = self.to_chrono_datetime()?; - let (months, days, nsecs) = interval.to_month_day_nano(); let naive_datetime = naive_datetime - .checked_sub_months(Months::new(months as u32))? - .checked_sub_days(Days::new(days as u64))? - - Duration::from_nanos(nsecs as u64); + .checked_add_days(Days::new(interval.days as u64))? + .checked_add_signed(TimeDelta::milliseconds(interval.milliseconds as i64))?; - match Timestamp::from_chrono_datetime(naive_datetime) { - // Have to convert the new timestamp by the current unit. - Some(ts) => ts.convert_to(self.unit), - None => None, - } + // Have to convert the new timestamp by the current unit. + Timestamp::from_chrono_datetime(naive_datetime).and_then(|ts| ts.convert_to(self.unit)) + } + + /// Adds given [IntervalMonthDayNano] to the current timestamp. + pub fn add_month_day_nano(&self, interval: IntervalMonthDayNano) -> Option { + let naive_datetime = self.to_chrono_datetime()?; + + let naive_datetime = naive_datetime + .checked_add_months(Months::new(interval.months as u32))? + .checked_add_days(Days::new(interval.days as u64))? + .checked_add_signed(TimeDelta::nanoseconds(interval.nanoseconds))?; + + // Have to convert the new timestamp by the current unit. + Timestamp::from_chrono_datetime(naive_datetime).and_then(|ts| ts.convert_to(self.unit)) + } + + /// Subtracts given [IntervalYearMonth] to the current timestamp. + pub fn sub_year_month(&self, interval: IntervalYearMonth) -> Option { + let naive_datetime = self.to_chrono_datetime()?; + + let naive_datetime = + naive_datetime.checked_sub_months(Months::new(interval.months as u32))?; + + // Have to convert the new timestamp by the current unit. + Timestamp::from_chrono_datetime(naive_datetime).and_then(|ts| ts.convert_to(self.unit)) + } + + /// Subtracts given [IntervalDayTime] to the current timestamp. + pub fn sub_day_time(&self, interval: IntervalDayTime) -> Option { + let naive_datetime = self.to_chrono_datetime()?; + + let naive_datetime = naive_datetime + .checked_sub_days(Days::new(interval.days as u64))? + .checked_sub_signed(TimeDelta::milliseconds(interval.milliseconds as i64))?; + + // Have to convert the new timestamp by the current unit. + Timestamp::from_chrono_datetime(naive_datetime).and_then(|ts| ts.convert_to(self.unit)) + } + + /// Subtracts given [IntervalMonthDayNano] to the current timestamp. + pub fn sub_month_day_nano(&self, interval: IntervalMonthDayNano) -> Option { + let naive_datetime = self.to_chrono_datetime()?; + + let naive_datetime = naive_datetime + .checked_sub_months(Months::new(interval.months as u32))? + .checked_sub_days(Days::new(interval.days as u64))? + .checked_sub_signed(TimeDelta::nanoseconds(interval.nanoseconds))?; + + // Have to convert the new timestamp by the current unit. + Timestamp::from_chrono_datetime(naive_datetime).and_then(|ts| ts.convert_to(self.unit)) } /// Subtracts current timestamp with another timestamp, yielding a duration. @@ -688,13 +726,13 @@ mod tests { fn test_add_sub_interval() { let ts = Timestamp::new(1000, TimeUnit::Millisecond); - let interval = Interval::from_day_time(1, 200); + let interval = IntervalDayTime::new(1, 200); - let new_ts = ts.add_interval(interval).unwrap(); + let new_ts = ts.add_day_time(interval).unwrap(); assert_eq!(new_ts.unit(), TimeUnit::Millisecond); assert_eq!(new_ts.value(), 1000 + 3600 * 24 * 1000 + 200); - assert_eq!(ts, new_ts.sub_interval(interval).unwrap()); + assert_eq!(ts, new_ts.sub_day_time(interval).unwrap()); } #[test] diff --git a/src/datatypes/src/interval.rs b/src/datatypes/src/interval.rs index c0969abc44..b724de8022 100644 --- a/src/datatypes/src/interval.rs +++ b/src/datatypes/src/interval.rs @@ -12,11 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use common_time::interval::Interval; +use common_time::{IntervalDayTime, IntervalMonthDayNano, IntervalYearMonth}; use paste::paste; -use serde::{Deserialize, Serialize}; -use crate::prelude::{Scalar, Value, ValueRef}; +use crate::prelude::Scalar; use crate::scalars::ScalarRef; use crate::types::{ IntervalDayTimeType, IntervalMonthDayNanoType, IntervalYearMonthType, WrapperType, @@ -26,39 +25,6 @@ use crate::vectors::{IntervalDayTimeVector, IntervalMonthDayNanoVector, Interval macro_rules! define_interval_with_unit { ($unit: ident, $native_ty: ty) => { paste! { - #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] - pub struct [](pub Interval); - - impl [] { - pub fn new(val: $native_ty) -> Self { - Self(Interval:: [](val)) - } - } - - impl Default for [] { - fn default() -> Self { - Self::new(0) - } - } - - impl From<[]> for Value { - fn from(t: []) -> Value { - Value::Interval(t.0) - } - } - - impl From<[]> for serde_json::Value { - fn from(t: []) -> Self { - t.0.into() - } - } - - impl From<[]> for ValueRef<'static> { - fn from(t: []) -> Self { - ValueRef::Interval(t.0) - } - } - impl Scalar for [] { type VectorType = []; type RefType<'a> = []; @@ -87,41 +53,11 @@ macro_rules! define_interval_with_unit { type Native = $native_ty; fn from_native(value: Self::Native) -> Self { - Self::new(value) + Self::[](value) } fn into_native(self) -> Self::Native { - self.0.[]() - } - } - - impl From<$native_ty> for [] { - fn from(val: $native_ty) -> Self { - []::from_native(val as $native_ty) - } - } - - impl From<[]> for $native_ty { - fn from(val: []) -> Self { - val.0.[]() - } - } - - impl TryFrom for Option<[]> { - type Error = $crate::error::Error; - - #[inline] - fn try_from(from: Value) -> std::result::Result { - match from { - Value::Interval(v) if v.unit() == common_time::interval::IntervalUnit::$unit => { - Ok(Some([](v))) - }, - Value::Null => Ok(None), - _ => $crate::error::TryFromValueSnafu { - reason: format!("{:?} is not a {}", from, stringify!([])), - } - .fail(), - } + self.[]() } } } @@ -138,17 +74,17 @@ mod tests { #[test] fn test_interval_scalar() { - let interval = IntervalYearMonth::new(1000); + let interval = IntervalYearMonth::from(1000); assert_eq!(interval, interval.as_scalar_ref()); assert_eq!(interval, interval.to_owned_scalar()); assert_eq!(1000, interval.into_native()); - let interval = IntervalDayTime::new(1000); + let interval = IntervalDayTime::from(1000); assert_eq!(interval, interval.as_scalar_ref()); assert_eq!(interval, interval.to_owned_scalar()); assert_eq!(1000, interval.into_native()); - let interval = IntervalMonthDayNano::new(1000); + let interval = IntervalMonthDayNano::from(1000); assert_eq!(interval, interval.as_scalar_ref()); assert_eq!(interval, interval.to_owned_scalar()); assert_eq!(1000, interval.into_native()); @@ -156,15 +92,15 @@ mod tests { #[test] fn test_interval_convert_to_native_type() { - let interval = IntervalMonthDayNano::new(1000); + let interval = IntervalMonthDayNano::from(1000); let native_value: i128 = interval.into(); assert_eq!(native_value, 1000); - let interval = IntervalDayTime::new(1000); + let interval = IntervalDayTime::from(1000); let native_interval: i64 = interval.into(); assert_eq!(native_interval, 1000); - let interval = IntervalYearMonth::new(1000); + let interval = IntervalYearMonth::from(1000); let native_interval: i32 = interval.into(); assert_eq!(native_interval, 1000); } diff --git a/src/datatypes/src/types/interval_type.rs b/src/datatypes/src/types/interval_type.rs index 7ee7964982..77f1b47d6d 100644 --- a/src/datatypes/src/types/interval_type.rs +++ b/src/datatypes/src/types/interval_type.rs @@ -17,8 +17,9 @@ use arrow::datatypes::{ IntervalMonthDayNanoType as ArrowIntervalMonthDayNanoType, IntervalUnit as ArrowIntervalUnit, IntervalYearMonthType as ArrowIntervalYearMonthType, }; -use common_time::interval::IntervalUnit; -use common_time::Interval; +use common_time::interval::{ + IntervalDayTime, IntervalMonthDayNano, IntervalUnit, IntervalYearMonth, +}; use enum_dispatch::enum_dispatch; use paste::paste; use serde::{Deserialize, Serialize}; @@ -26,7 +27,6 @@ use snafu::OptionExt; use crate::data_type::ConcreteDataType; use crate::error; -use crate::interval::{IntervalDayTime, IntervalMonthDayNano, IntervalYearMonth}; use crate::prelude::{ DataType, LogicalTypeId, MutableVector, ScalarVectorBuilder, Value, ValueRef, Vector, }; @@ -75,7 +75,7 @@ macro_rules! impl_data_type_for_interval { } fn default_value(&self) -> Value { - Value::Interval(Interval::from_i128(0)) + Value::[]([]::default()) } fn as_arrow_type(&self) -> ArrowDataType { @@ -124,7 +124,7 @@ macro_rules! impl_data_type_for_interval { fn cast_value_ref(value: ValueRef) -> crate::Result> { match value { ValueRef::Null => Ok(None), - ValueRef::Interval(t) => Ok(Some([](t))), + ValueRef::[](t) => Ok(Some(t)), other => error::CastTypeSnafu { msg: format!("Failed to cast value {:?} to {}", other, stringify!([])), } diff --git a/src/datatypes/src/types/primitive_type.rs b/src/datatypes/src/types/primitive_type.rs index cae71976fd..86972bd5ee 100644 --- a/src/datatypes/src/types/primitive_type.rs +++ b/src/datatypes/src/types/primitive_type.rs @@ -16,7 +16,6 @@ use std::cmp::Ordering; use std::fmt; use arrow::datatypes::{ArrowNativeType, ArrowPrimitiveType, DataType as ArrowDataType}; -use common_time::interval::IntervalUnit; use common_time::{Date, DateTime}; use serde::{Deserialize, Serialize}; use snafu::OptionExt; @@ -30,6 +29,7 @@ use crate::types::{DateTimeType, DateType}; use crate::value::{Value, ValueRef}; use crate::vectors::{MutableVector, PrimitiveVector, PrimitiveVectorBuilder, Vector}; +// TODO(yingwen): Can we remove `Into`? /// Represents the wrapper type that wraps a native type using the `newtype pattern`, /// such as [Date](`common_time::Date`) is a wrapper type for the underlying native /// type `i32`. @@ -364,11 +364,7 @@ impl DataType for Int64Type { Value::DateTime(v) => Some(Value::Int64(v.val())), Value::Timestamp(v) => Some(Value::Int64(v.value())), Value::Time(v) => Some(Value::Int64(v.value())), - Value::Interval(v) => match v.unit() { - IntervalUnit::DayTime => Some(Value::Int64(v.to_i64())), - IntervalUnit::YearMonth => None, - IntervalUnit::MonthDayNano => None, - }, + // We don't allow casting interval type to int. _ => None, } } @@ -410,11 +406,7 @@ impl DataType for Int32Type { Value::Float64(v) => num::cast::cast(v).map(Value::Int32), Value::String(v) => v.as_utf8().parse::().map(Value::Int32).ok(), Value::Date(v) => Some(Value::Int32(v.val())), - Value::Interval(v) => match v.unit() { - IntervalUnit::YearMonth => Some(Value::Int32(v.to_i32())), - IntervalUnit::DayTime => None, - IntervalUnit::MonthDayNano => None, - }, + // We don't allow casting interval type to int. _ => None, } } diff --git a/src/datatypes/src/types/string_type.rs b/src/datatypes/src/types/string_type.rs index 38045a600a..06a5e7c7f6 100644 --- a/src/datatypes/src/types/string_type.rs +++ b/src/datatypes/src/types/string_type.rs @@ -78,7 +78,15 @@ impl DataType for StringType { Value::DateTime(v) => Some(Value::String(StringBytes::from(v.to_string()))), Value::Timestamp(v) => Some(Value::String(StringBytes::from(v.to_iso8601_string()))), Value::Time(v) => Some(Value::String(StringBytes::from(v.to_iso8601_string()))), - Value::Interval(v) => Some(Value::String(StringBytes::from(v.to_iso8601_string()))), + Value::IntervalYearMonth(v) => { + Some(Value::String(StringBytes::from(v.to_iso8601_string()))) + } + Value::IntervalDayTime(v) => { + Some(Value::String(StringBytes::from(v.to_iso8601_string()))) + } + Value::IntervalMonthDayNano(v) => { + Some(Value::String(StringBytes::from(v.to_iso8601_string()))) + } Value::Duration(v) => Some(Value::String(StringBytes::from(v.to_string()))), Value::Decimal128(v) => Some(Value::String(StringBytes::from(v.to_string()))), diff --git a/src/datatypes/src/value.rs b/src/datatypes/src/value.rs index a8e59da513..b973a3156b 100644 --- a/src/datatypes/src/value.rs +++ b/src/datatypes/src/value.rs @@ -28,7 +28,7 @@ use common_time::datetime::DateTime; use common_time::interval::IntervalUnit; use common_time::time::Time; use common_time::timestamp::{TimeUnit, Timestamp}; -use common_time::{Duration, Interval, Timezone}; +use common_time::{Duration, IntervalDayTime, IntervalMonthDayNano, IntervalYearMonth, Timezone}; use datafusion_common::ScalarValue; use greptime_proto::v1::value::ValueData; pub use ordered_float::OrderedFloat; @@ -78,7 +78,10 @@ pub enum Value { Timestamp(Timestamp), Time(Time), Duration(Duration), - Interval(Interval), + // Interval types: + IntervalYearMonth(IntervalYearMonth), + IntervalDayTime(IntervalDayTime), + IntervalMonthDayNano(IntervalMonthDayNano), List(ListValue), } @@ -111,7 +114,15 @@ impl Display for Value { Value::DateTime(v) => write!(f, "{v}"), Value::Timestamp(v) => write!(f, "{}", v.to_iso8601_string()), Value::Time(t) => write!(f, "{}", t.to_iso8601_string()), - Value::Interval(v) => write!(f, "{}", v.to_iso8601_string()), + Value::IntervalYearMonth(v) => { + write!(f, "{}", v.to_iso8601_string()) + } + Value::IntervalDayTime(v) => { + write!(f, "{}", v.to_iso8601_string()) + } + Value::IntervalMonthDayNano(v) => { + write!(f, "{}", v.to_iso8601_string()) + } Value::Duration(d) => write!(f, "{d}"), Value::List(v) => { let items = v @@ -153,7 +164,15 @@ macro_rules! define_data_type_func { $struct::DateTime(_) => ConcreteDataType::datetime_datatype(), $struct::Time(t) => ConcreteDataType::time_datatype(*t.unit()), $struct::Timestamp(v) => ConcreteDataType::timestamp_datatype(v.unit()), - $struct::Interval(v) => ConcreteDataType::interval_datatype(v.unit()), + $struct::IntervalYearMonth(_) => { + ConcreteDataType::interval_datatype(IntervalUnit::YearMonth) + } + $struct::IntervalDayTime(_) => { + ConcreteDataType::interval_datatype(IntervalUnit::DayTime) + } + $struct::IntervalMonthDayNano(_) => { + ConcreteDataType::interval_datatype(IntervalUnit::MonthDayNano) + } $struct::List(list) => ConcreteDataType::list_datatype(list.datatype().clone()), $struct::Duration(d) => ConcreteDataType::duration_datatype(d.unit()), $struct::Decimal128(d) => { @@ -206,7 +225,9 @@ impl Value { Value::List(v) => ValueRef::List(ListValueRef::Ref { val: v }), Value::Timestamp(v) => ValueRef::Timestamp(*v), Value::Time(v) => ValueRef::Time(*v), - Value::Interval(v) => ValueRef::Interval(*v), + Value::IntervalYearMonth(v) => ValueRef::IntervalYearMonth(*v), + Value::IntervalDayTime(v) => ValueRef::IntervalDayTime(*v), + Value::IntervalMonthDayNano(v) => ValueRef::IntervalMonthDayNano(*v), Value::Duration(v) => ValueRef::Duration(*v), Value::Decimal128(v) => ValueRef::Decimal128(*v), } @@ -220,14 +241,6 @@ impl Value { } } - /// Cast Value to Interval. Return None if value is not a valid interval data type. - pub fn as_interval(&self) -> Option { - match self { - Value::Interval(i) => Some(*i), - _ => None, - } - } - /// Cast Value to utf8 String. Return None if value is not a valid string data type. pub fn as_string(&self) -> Option { match self { @@ -255,12 +268,35 @@ impl Value { /// Cast Value to [Time]. Return None if value is not a valid time data type. pub fn as_time(&self) -> Option