feat: sql with influxdb v1 result format (#2917)

* feat: sql with influxdb v1 result format

* chore: add unit tests

* feat: minor refactor

* chore: by comment

* chore; u128 to u64 since serde can't deser u128 in enum

* chore: by comment

* chore: apply suggestion

* chore: revert suggestion

* chore: try again

---------

Co-authored-by: dennis zhuang <killme2008@gmail.com>
This commit is contained in:
JeremyHi
2023-12-14 00:15:37 +08:00
committed by GitHub
parent d3da128d66
commit 99dda93f0e
6 changed files with 738 additions and 120 deletions
+78 -9
View File
@@ -20,6 +20,7 @@ use axum_test_helper::TestClient;
use common_error::status_code::StatusCode as ErrorCode;
use serde_json::json;
use servers::http::handler::HealthResponse;
use servers::http::influxdb_result_v1::InfluxdbOutput;
use servers::http::prometheus::{PrometheusJsonResponse, PrometheusResponse};
use servers::http::{JsonOutput, JsonResponse};
use tests_integration::test_util::{
@@ -123,6 +124,9 @@ pub async fn test_sql_api(store_type: StorageType) {
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert_eq!(body.code(), 1004);
assert_eq!(body.error().unwrap(), "sql parameter is required.");
let _ = body.execution_time_ms().unwrap();
@@ -134,10 +138,13 @@ pub async fn test_sql_api(store_type: StorageType) {
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert!(body.success());
let _ = body.execution_time_ms().unwrap();
let output = body.output().unwrap();
let output = body.output();
assert_eq!(output.len(), 1);
assert_eq!(
output[0],
@@ -146,6 +153,29 @@ pub async fn test_sql_api(store_type: StorageType) {
})).unwrap()
);
// test influxdb_v1 result format
let res = client
.get("/v1/sql?format=influxdb_v1&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();
let JsonResponse::InfluxdbV1(body) = body else {
unreachable!()
};
assert!(body.success());
let _ = body.execution_time_ms().unwrap();
let output = body.results();
assert_eq!(output.len(), 1);
assert_eq!(
output[0],
serde_json::from_value::<InfluxdbOutput>(json!({
"statement_id":0,"series":[{"name":"","columns":["number"],"values":[[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)")
@@ -161,9 +191,12 @@ pub async fn test_sql_api(store_type: StorageType) {
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert!(body.success());
let _ = body.execution_time_ms().unwrap();
let output = body.output().unwrap();
let output = body.output();
assert_eq!(output.len(), 1);
assert_eq!(
@@ -181,9 +214,12 @@ pub async fn test_sql_api(store_type: StorageType) {
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert!(body.success());
let _ = body.execution_time_ms().unwrap();
let output = body.output().unwrap();
let output = body.output();
assert_eq!(output.len(), 1);
assert_eq!(
@@ -201,9 +237,12 @@ pub async fn test_sql_api(store_type: StorageType) {
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert!(body.success());
let _ = body.execution_time_ms().unwrap();
let output = body.output().unwrap();
let output = body.output();
assert_eq!(output.len(), 1);
assert_eq!(
output[0],
@@ -220,9 +259,12 @@ pub async fn test_sql_api(store_type: StorageType) {
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert!(body.success());
let _ = body.execution_time_ms().unwrap();
let outputs = body.output().unwrap();
let outputs = body.output();
assert_eq!(outputs.len(), 2);
assert_eq!(
outputs[0],
@@ -246,6 +288,9 @@ pub async fn test_sql_api(store_type: StorageType) {
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert!(!body.success());
let _ = body.execution_time_ms().unwrap();
// TODO(shuiyisong): fix this when return source err msg to client side
@@ -259,9 +304,12 @@ pub async fn test_sql_api(store_type: StorageType) {
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert!(body.success());
let _ = body.execution_time_ms().unwrap();
let outputs = body.output().unwrap();
let outputs = body.output();
assert_eq!(outputs.len(), 1);
assert_eq!(
outputs[0],
@@ -277,6 +325,9 @@ pub async fn test_sql_api(store_type: StorageType) {
.await;
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert_eq!(body.code(), ErrorCode::DatabaseNotFound as u32);
// test catalog-schema given
@@ -287,9 +338,12 @@ pub async fn test_sql_api(store_type: StorageType) {
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert!(body.success());
let _ = body.execution_time_ms().unwrap();
let outputs = body.output().unwrap();
let outputs = body.output();
assert_eq!(outputs.len(), 1);
assert_eq!(
outputs[0],
@@ -305,6 +359,9 @@ pub async fn test_sql_api(store_type: StorageType) {
.await;
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert_eq!(body.code(), ErrorCode::DatabaseNotFound as u32);
// test invalid schema
@@ -314,6 +371,9 @@ pub async fn test_sql_api(store_type: StorageType) {
.await;
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert_eq!(body.code(), ErrorCode::DatabaseNotFound as u32);
guard.remove_all().await;
@@ -330,6 +390,9 @@ pub async fn test_prometheus_promql_api(store_type: StorageType) {
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert!(body.success());
let _ = body.execution_time_ms().unwrap();
@@ -543,8 +606,11 @@ def test(n) -> vector[f64]:
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert_eq!(body.code(), 0);
assert!(body.output().is_none());
assert!(body.output().is_empty());
// call script
let res = client
@@ -553,10 +619,13 @@ def test(n) -> vector[f64]:
.await;
assert_eq!(res.status(), StatusCode::OK);
let body = serde_json::from_str::<JsonResponse>(&res.text().await).unwrap();
let JsonResponse::GreptimedbV1(body) = body else {
unreachable!()
};
assert_eq!(body.code(), 0);
let _ = body.execution_time_ms().unwrap();
let output = body.output().unwrap();
let output = body.output();
assert_eq!(output.len(), 1);
assert_eq!(
output[0],