Skip to content

Commit

Permalink
conver all table name to lowercase except select with quote.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rachelint committed Dec 5, 2022
1 parent 61b03dc commit 6463f3b
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 16 deletions.
59 changes: 57 additions & 2 deletions server/src/grpc/storage_service/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

//! Route handler
use ceresdbproto::storage::{RouteRequest, RouteResponse};
use std::collections::HashMap;

use ceresdbproto::storage::{Route, RouteRequest, RouteResponse};
use error::ErrNoCause;
use http::StatusCode;
use snafu::OptionExt;

use crate::grpc::storage_service::{
error::{self, Result},
Expand All @@ -13,11 +18,61 @@ pub async fn handle_route<Q>(
ctx: &HandlerContext<'_, Q>,
req: RouteRequest,
) -> Result<RouteResponse> {
// TODO: the case sensitive mode with quoted is not supported now, all table
// name will be converted to lowercase.

// Get normalized metrics to original one's mapping.
let normalized_to_origin: HashMap<_, _> = req
.metrics
.iter()
.enumerate()
.map(|(idx, metric)| (metric.to_ascii_lowercase(), idx))
.collect();
let mut origins = req.metrics;

// Route using normalized metrics.
let normalized_metrics: Vec<_> = normalized_to_origin
.iter()
.map(|(k, _)| k.clone())
.collect();
let req = RouteRequest {
metrics: normalized_metrics,
};

// Replace the normalized metrics in response to origin ones to avoiding
// exposing this behavior to client.
let routes = ctx.router.route(ctx.tenant(), req).await?;
let mut routes_with_origins = Vec::with_capacity(routes.len());
let origins_len = origins.len();
for route in routes {
let idx = normalized_to_origin
.get(&route.metric)
.with_context(|| ErrNoCause {
code: StatusCode::INTERNAL_SERVER_ERROR,
msg: format!(
"unknown normalized metric name while finding its origin, metric:{}",
route.metric
),
})?;

let origin = origins.get_mut(*idx).with_context(|| ErrNoCause {
code: StatusCode::INTERNAL_SERVER_ERROR,
msg: format!(
"impossible to find nothing through idx, idx:{}, origins len:{}",
idx, origins_len
),
})?;

routes_with_origins.push(Route {
metric: std::mem::take(origin),
endpoint: route.endpoint,
ext: route.ext,
});
}

let resp = RouteResponse {
header: Some(error::build_ok_header()),
routes,
routes: routes_with_origins,
};

Ok(resp)
Expand Down
8 changes: 4 additions & 4 deletions server/src/grpc/storage_service/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,15 @@ async fn write_request_to_insert_plan<Q: QueryExecutor + 'static>(
let mut plan_vec = Vec::with_capacity(write_request.metrics.len());

for write_metric in write_request.metrics {
let table_name = &write_metric.metric;
let mut table = try_get_table(ctx, table_name)?;
let normalized_table_name = &write_metric.metric.to_ascii_lowercase();
let mut table = try_get_table(ctx, normalized_table_name)?;

if table.is_none() {
if let Some(config) = ctx.schema_config {
if config.auto_create_tables {
create_table(ctx, &write_metric, request_id).await?;
// try to get table again
table = try_get_table(ctx, table_name)?;
table = try_get_table(ctx, normalized_table_name)?;
}
}
}
Expand All @@ -139,7 +139,7 @@ async fn write_request_to_insert_plan<Q: QueryExecutor + 'static>(
msg: format!(
"Table not found, tenant:{}, table:{}",
ctx.tenant(),
table_name
normalized_table_name
),
}
.fail();
Expand Down
12 changes: 2 additions & 10 deletions sql/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! SQL statement
use sqlparser::ast::{
ColumnDef, Ident, ObjectName, SqlOption, Statement as SqlStatement, TableConstraint,
ColumnDef, ObjectName, SqlOption, Statement as SqlStatement, TableConstraint,
};

/// Statement representations
Expand Down Expand Up @@ -33,22 +33,14 @@ impl TableName {
pub fn is_empty(&self) -> bool {
self.0 .0.is_empty()
}

// Normalize an identifer to a lowercase string unless the identifier is quoted.
fn normalize_ident(id: &Ident) -> String {
match id.quote_style {
Some(_) => id.value.clone(),
None => id.value.to_ascii_lowercase(),
}
}
}

impl ToString for TableName {
fn to_string(&self) -> String {
self.0
.0
.iter()
.map(Self::normalize_ident)
.map(|id| id.value.to_ascii_lowercase())
.collect::<Vec<_>>()
.join(".")
}
Expand Down

0 comments on commit 6463f3b

Please sign in to comment.