mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-01-04 04:12:55 +00:00
* chore: kick off. change datafusion/arrow/parquet to target version
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* chore: replace one last datafusion dep
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* feat: arrow_array switch to arrow
* chore: update dep of binary vector
* chore: fix wrong merge commit
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* feat: Switch to datatypes2
* feat: Make recordbatch compile
* chore: sort Cargo.toml
* feat: Fix common::recordbatch compiler errors
* feat: Fix recordbatch test compiling issue
* fix: api crate (#708)
* fix: rename ConcreteDataType::timestamp_millis_type to ConcreteDataType::timestamp_millisecond_type. fix other warnings regarding timestamp
* fix: revert changes in datatypes2
* fix: helper
* chore: delete datatypes based on arrow2
* feat: Fix some compiler errors in common::query (#710)
* feat: Fix some compiler errors in common::query
* feat: test_collect use vectors api
* fix: common-query subcrate (#712)
* fix: record batch adapter
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix error enum
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix: Fix common::query compiler errors (#713)
* feat: Move conversion to ScalarValue to value.rs
* fix: Fix common::query compiler errors
This commit also make InnerError pub(crate)
* feat: Implements diff accumulator using WrapperType (#715)
* feat: Remove usage of opaque error from common::recordbatch
* feat: Remove opaque error from common::query
* feat: Fix diff compiler errors
Now common_function just use common_query's Error and Result. Adds
a LargestType associated type to LogicalPrimitiveType to get the largest
type a logical primitive type can cast to.
* feat: Remove LargestType from NativeType trait
* chore: Update comments
* feat: Restrict Scalar::RefType of WrapperType to itself
Add trait bound `for<'a> Scalar<RefType<'a> = Self>` to WrapperType
* chore: Address CR comments
* chore: Format codes
* fix: fix compile error for mean/polyval/pow/interp ops
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* Revert "fix: fix compile error for mean/polyval/pow/interp ops"
This reverts commit fb0b4eb826.
* fix: Fix compiler errors in argmax/rate/median/norm_cdf (#716)
* fix: Fix compiler errors in argmax/rate/median/norm_cdf
* chore: Address CR comments
* fix: fix compile error for mean/polyval/pow/interp ops (#717)
* fix: fix compile error for mean/polyval/pow/interp ops
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* simplify type bounds
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix: fix argmin/percentile/clip/interp/scipy_stats_norm_pdf errors (#718)
fix: fix argmin/percentile/clip/interp/scipy_stats_norm_pdf compiler errors
* fix: fix other compile error in common-function (#719)
* further fixing
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix all compile errors in common function
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix: Fix tests and clippy for common-function subcrate (#726)
* further fixing
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix all compile errors in common function
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix tests
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix clippy
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* revert test changes
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix: row group pruning (#725)
* fix: row group pruning
* chore: use macro to simplify stats implemetation
* fxi: CR comments
* fix: row group metadata length mismatch
* fix: simplify code
* fix: Fix common::grpc compiler errors (#722)
* fix: Fix common::grpc compiler errors
This commit refactors RecordBatch and holds vectors in the RecordBatch
struct, so we don't need to cast the array to vector when doing
serialization or iterating the batch.
Now we use the vector API instead of the arrow API in grpc crate.
* chore: Address CR comments
* fix common record batch
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix: Fix compile error in server subcrate (#727)
* fix: Fix compile error in server subcrate
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* remove unused type alias
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* explicitly panic
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* Update src/storage/src/sst/parquet.rs
Co-authored-by: Yingwen <realevenyag@gmail.com>
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Co-authored-by: Yingwen <realevenyag@gmail.com>
* fix: Fix common grpc expr (#730)
* fix compile errors
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* rename fn names
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix styles
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix wranings in common-time
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix: pre-cast to avoid tremendous match arms (#734)
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* feat: upgrade storage crate to arrow and parquet offcial impl (#738)
* fix: compile erros
* fix: parquet reader and writer
* fix: parquet reader and writer
* fix: WriteBatch IPC encode/decode
* fix: clippy errors in storage subcrate
* chore: remove suspicious unwrap
* fix: some cr comments
* fix: CR comments
* fix: CR comments
* fix: Fix compiler errors in catalog and mito crates (#742)
* fix: Fix compiler errors in mito
* fix: Fix compiler errors in catalog crate
* style: Fix clippy
* chore: Fix use
* Merge pull request #745
* fix nyc-taxi and util
* Merge branch 'replace-arrow2' into fix-others
* fix substrait
* fix warnings and error in test
* fix: Fix imports in optimizer.rs
* fix: errors in optimzer
* fix: remove unwrap
* fix: Fix compiler errors in query crate (#746)
* fix: Fix compiler errors in state.rs
* fix: fix compiler errors in state
* feat: upgrade sqlparser to 0.26
* fix: fix datafusion engine compiler errors
* fix: Fix some tests in query crate
* fix: Fix all warnings in tests
* feat: Remove `Type` from timestamp's type name
* fix: fix query tests
Now datafusion already supports median, so this commit also remove the
median function
* style: Fix clippy
* feat: Remove RecordBatch::pretty_print
* chore: Address CR comments
* Update src/query/src/query_engine/state.rs
Co-authored-by: Ruihang Xia <waynestxia@gmail.com>
* fix: frontend compile errors (#747)
fix: fix compile errors in frontend
* fix: Fix compiler errors in script crate (#749)
* fix: Fix compiler errors in state.rs
* fix: fix compiler errors in state
* feat: upgrade sqlparser to 0.26
* fix: fix datafusion engine compiler errors
* fix: Fix some tests in query crate
* fix: Fix all warnings in tests
* feat: Remove `Type` from timestamp's type name
* fix: fix query tests
Now datafusion already supports median, so this commit also remove the
median function
* style: Fix clippy
* feat: Remove RecordBatch::pretty_print
* chore: Address CR comments
* feat: Add column_by_name to RecordBatch
* feat: modify select_from_rb
* feat: Fix some compiler errors in vector.rs
* feat: Fix more compiler errors in vector.rs
* fix: fix table.rs
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix: Fix compiler errors in coprocessor
* fix: Fix some compiler errors
* fix: Fix compiler errors in script
* chore: Remove unused imports and format code
* test: disable interval tests
* test: Fix test_compile_execute test
* style: Fix clippy
* feat: Support interval
* feat: Add RecordBatch::columns and fix clippy
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Co-authored-by: Ruihang Xia <waynestxia@gmail.com>
* fix: Fix All The Tests! (#752)
* fix: Fix several tests compile errors
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix: some compile errors in tests
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* fix: compile errors in frontend tests
* fix: compile errors in frontend tests
* test: Fix tests in api and common-query
* test: Fix test in sql crate
* fix: resolve substrait error
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* chore: add more test
* test: Fix tests in servers
* fix instance_test
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
* test: Fix tests in tests-integration
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Co-authored-by: Lei, HUANG <mrsatangel@gmail.com>
Co-authored-by: evenyag <realevenyag@gmail.com>
* fix: clippy errors
Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
Co-authored-by: Ruihang Xia <waynestxia@gmail.com>
Co-authored-by: evenyag <realevenyag@gmail.com>
255 lines
9.4 KiB
Rust
255 lines
9.4 KiB
Rust
// Copyright 2022 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::StatusCode;
|
|
use axum_test_helper::TestClient;
|
|
use serde_json::json;
|
|
use servers::http::handler::HealthResponse;
|
|
use servers::http::{JsonOutput, JsonResponse};
|
|
use tests_integration::test_util::{setup_test_app, setup_test_app_with_frontend, StorageType};
|
|
|
|
#[macro_export]
|
|
macro_rules! http_test {
|
|
($service:ident, $($(#[$meta:meta])* $test:ident),*,) => {
|
|
paste::item! {
|
|
mod [<integration_http_ $service:lower _test>] {
|
|
$(
|
|
#[tokio::test(flavor = "multi_thread")]
|
|
$(
|
|
#[$meta]
|
|
)*
|
|
async fn [< $test >]() {
|
|
let store_type = tests_integration::test_util::StorageType::$service;
|
|
if store_type.test_on() {
|
|
let _ = $crate::http::$test(store_type).await;
|
|
}
|
|
}
|
|
)*
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! http_tests {
|
|
($($service:ident),*) => {
|
|
$(
|
|
http_test!(
|
|
$service,
|
|
|
|
test_sql_api,
|
|
test_metrics_api,
|
|
test_scripts_api,
|
|
test_health_api,
|
|
);
|
|
)*
|
|
};
|
|
}
|
|
|
|
pub async fn test_sql_api(store_type: StorageType) {
|
|
common_telemetry::init_default_ut_logging();
|
|
let (app, mut guard) = setup_test_app(store_type, "sql_api").await;
|
|
let client = TestClient::new(app);
|
|
let res = client.get("/v1/sql").send().await;
|
|
assert_eq!(res.status(), StatusCode::OK);
|
|
|
|
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
|
|
// body json: r#"{"code":1004,"error":"sql parameter is required."}"#
|
|
assert_eq!(body.code(), 1004);
|
|
assert_eq!(body.error().unwrap(), "sql parameter is required.");
|
|
assert!(body.execution_time_ms().is_some());
|
|
|
|
let res = client
|
|
.get("/v1/sql?sql=select * from numbers limit 10")
|
|
.send()
|
|
.await;
|
|
assert_eq!(res.status(), StatusCode::OK);
|
|
|
|
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
|
|
// body json:
|
|
// r#"{"code":0,"output":[{"records":{"schema":{"column_schemas":[{"name":"number","data_type":"UInt32"}]},"rows":[[0],[1],[2],[3],[4],[5],[6],[7],[8],[9]]}}]}"#
|
|
|
|
assert!(body.success());
|
|
assert!(body.execution_time_ms().is_some());
|
|
|
|
let output = body.output().unwrap();
|
|
assert_eq!(output.len(), 1);
|
|
assert_eq!(
|
|
output[0],
|
|
serde_json::from_value::<JsonOutput>(json!({
|
|
"records" :{"schema":{"column_schemas":[{"name":"number","data_type":"UInt32"}]},"rows":[[0],[1],[2],[3],[4],[5],[6],[7],[8],[9]]}
|
|
})).unwrap()
|
|
);
|
|
|
|
// test insert and select
|
|
let res = client
|
|
.get("/v1/sql?sql=insert into demo values('host', 66.6, 1024, 0)")
|
|
.send()
|
|
.await;
|
|
assert_eq!(res.status(), StatusCode::OK);
|
|
|
|
// select *
|
|
let res = client
|
|
.get("/v1/sql?sql=select * from demo limit 10")
|
|
.send()
|
|
.await;
|
|
assert_eq!(res.status(), StatusCode::OK);
|
|
|
|
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
|
|
// body json: r#"{"code":0,"output":[{"records":{"schema":{"column_schemas":[{"name":"host","data_type":"String"},{"name":"cpu","data_type":"Float64"},{"name":"memory","data_type":"Float64"},{"name":"ts","data_type":"Timestamp"}]},"rows":[["host",66.6,1024.0,0]]}}]}"#
|
|
assert!(body.success());
|
|
assert!(body.execution_time_ms().is_some());
|
|
let output = body.output().unwrap();
|
|
assert_eq!(output.len(), 1);
|
|
|
|
assert_eq!(
|
|
output[0],
|
|
serde_json::from_value::<JsonOutput>(json!({
|
|
"records":{"schema":{"column_schemas":[{"name":"host","data_type":"String"},{"name":"cpu","data_type":"Float64"},{"name":"memory","data_type":"Float64"},{"name":"ts","data_type":"TimestampMillisecond"}]},"rows":[["host",66.6,1024.0,0]]}
|
|
})).unwrap()
|
|
);
|
|
|
|
// select with projections
|
|
let res = client
|
|
.get("/v1/sql?sql=select cpu, ts from demo limit 10")
|
|
.send()
|
|
.await;
|
|
assert_eq!(res.status(), StatusCode::OK);
|
|
|
|
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
|
|
// body json:
|
|
// r#"{"code":0,"output":[{"records":{"schema":{"column_schemas":[{"name":"cpu","data_type":"Float64"},{"name":"ts","data_type":"Timestamp"}]},"rows":[[66.6,0]]}}]}"#
|
|
assert!(body.success());
|
|
assert!(body.execution_time_ms().is_some());
|
|
let output = body.output().unwrap();
|
|
assert_eq!(output.len(), 1);
|
|
|
|
assert_eq!(
|
|
output[0],
|
|
serde_json::from_value::<JsonOutput>(json!({
|
|
"records":{"schema":{"column_schemas":[{"name":"cpu","data_type":"Float64"},{"name":"ts","data_type":"TimestampMillisecond"}]},"rows":[[66.6,0]]}
|
|
})).unwrap()
|
|
);
|
|
|
|
// select with column alias
|
|
let res = client
|
|
.get("/v1/sql?sql=select cpu as c, ts as time from demo limit 10")
|
|
.send()
|
|
.await;
|
|
assert_eq!(res.status(), StatusCode::OK);
|
|
|
|
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
|
|
// body json:
|
|
// r#"{"code":0,"output":[{"records":{"schema":{"column_schemas":[{"name":"c","data_type":"Float64"},{"name":"time","data_type":"Timestamp"}]},"rows":[[66.6,0]]}}]}"#
|
|
assert!(body.success());
|
|
assert!(body.execution_time_ms().is_some());
|
|
let output = body.output().unwrap();
|
|
assert_eq!(output.len(), 1);
|
|
assert_eq!(
|
|
output[0],
|
|
serde_json::from_value::<JsonOutput>(json!({
|
|
"records":{"schema":{"column_schemas":[{"name":"c","data_type":"Float64"},{"name":"time","data_type":"TimestampMillisecond"}]},"rows":[[66.6,0]]}
|
|
})).unwrap()
|
|
);
|
|
|
|
guard.remove_all().await;
|
|
}
|
|
|
|
pub async fn test_metrics_api(store_type: StorageType) {
|
|
common_telemetry::init_default_ut_logging();
|
|
common_telemetry::init_default_metrics_recorder();
|
|
let (app, mut guard) = setup_test_app(store_type, "metrics_api").await;
|
|
let client = TestClient::new(app);
|
|
|
|
// Send a sql
|
|
let res = client
|
|
.get("/v1/sql?sql=select * from numbers limit 10")
|
|
.send()
|
|
.await;
|
|
assert_eq!(res.status(), StatusCode::OK);
|
|
|
|
// Call metrics api
|
|
let res = client.get("/metrics").send().await;
|
|
assert_eq!(res.status(), StatusCode::OK);
|
|
let body = res.text().await;
|
|
assert!(body.contains("datanode_handle_sql_elapsed"));
|
|
guard.remove_all().await;
|
|
}
|
|
|
|
pub async fn test_scripts_api(store_type: StorageType) {
|
|
common_telemetry::init_default_ut_logging();
|
|
let (app, mut guard) = setup_test_app_with_frontend(store_type, "script_api").await;
|
|
let client = TestClient::new(app);
|
|
|
|
let res = client
|
|
.post("/v1/scripts?name=test")
|
|
.body(
|
|
r#"
|
|
@copr(sql='select number from numbers limit 10', args=['number'], returns=['n'])
|
|
def test(n):
|
|
return n + 1;
|
|
"#,
|
|
)
|
|
.send()
|
|
.await;
|
|
assert_eq!(res.status(), StatusCode::OK);
|
|
|
|
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
|
|
// body json: r#"{"code":0}"#
|
|
assert_eq!(body.code(), 0);
|
|
assert!(body.output().is_none());
|
|
|
|
// call script
|
|
let res = client.post("/v1/run-script?name=test").send().await;
|
|
assert_eq!(res.status(), StatusCode::OK);
|
|
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
|
|
|
|
// body json:
|
|
// r#"{"code":0,"output":[{"records":{"schema":{"column_schemas":[{"name":"n","data_type":"Float64"}]},"rows":[[1.0],[2.0],[3.0],[4.0],[5.0],[6.0],[7.0],[8.0],[9.0],[10.0]]}}]}"#
|
|
assert_eq!(body.code(), 0);
|
|
assert!(body.execution_time_ms().is_some());
|
|
let output = body.output().unwrap();
|
|
assert_eq!(output.len(), 1);
|
|
assert_eq!(
|
|
output[0],
|
|
serde_json::from_value::<JsonOutput>(json!({
|
|
"records":{"schema":{"column_schemas":[{"name":"n","data_type":"Float64"}]},"rows":[[1.0],[2.0],[3.0],[4.0],[5.0],[6.0],[7.0],[8.0],[9.0],[10.0]]}
|
|
})).unwrap()
|
|
);
|
|
|
|
guard.remove_all().await;
|
|
}
|
|
|
|
pub async fn test_health_api(store_type: StorageType) {
|
|
common_telemetry::init_default_ut_logging();
|
|
let (app, _guard) = setup_test_app_with_frontend(store_type, "health_api").await;
|
|
let client = TestClient::new(app);
|
|
|
|
// we can call health api with both `GET` and `POST` method.
|
|
let res_post = client.post("/health").send().await;
|
|
assert_eq!(res_post.status(), StatusCode::OK);
|
|
let res_get = client.get("/health").send().await;
|
|
assert_eq!(res_get.status(), StatusCode::OK);
|
|
|
|
// both `GET` and `POST` method return same result
|
|
let body_text = res_post.text().await;
|
|
assert_eq!(body_text, res_get.text().await);
|
|
|
|
// currently health api simply returns an empty json `{}`, which can be deserialized to an empty `HealthResponse`
|
|
assert_eq!(body_text, "{}");
|
|
|
|
let body = serde_json::from_str::<HealthResponse>(&body_text).unwrap();
|
|
assert_eq!(body, HealthResponse {});
|
|
}
|