session/
table_name.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use snafu::ensure;
16use sql::ast::ObjectName;
17use sql::error::{InvalidSqlSnafu, PermissionDeniedSnafu, Result};
18use sql::parser::ParserContext;
19
20use crate::QueryContextRef;
21
22/// Parse table name into `(catalog, schema, table)` with query context and validates
23/// if catalog matches current catalog in query context.
24pub fn table_name_to_full_name(
25    name: &str,
26    query_ctx: &QueryContextRef,
27) -> Result<(String, String, String)> {
28    let obj_name = ParserContext::parse_table_name(name, query_ctx.sql_dialect())?;
29
30    let (catalog, schema, table) = table_idents_to_full_name(&obj_name, query_ctx)?;
31    // todo(hl): also check if schema matches when rbac is ready. https://github.com/GreptimeTeam/greptimedb/pull/3988/files#r1608687652
32    ensure!(
33        catalog == query_ctx.current_catalog(),
34        PermissionDeniedSnafu {
35            target: catalog,
36            current: query_ctx.current_catalog(),
37        }
38    );
39    Ok((catalog, schema, table))
40}
41
42/// Converts maybe fully-qualified table name (`<catalog>.<schema>.<table>`) to tuple.
43pub fn table_idents_to_full_name(
44    obj_name: &ObjectName,
45    query_ctx: &QueryContextRef,
46) -> Result<(String, String, String)> {
47    match &obj_name.0[..] {
48        [table] => Ok((
49            query_ctx.current_catalog().to_string(),
50            query_ctx.current_schema().to_string(),
51            table.value.clone(),
52        )),
53        [schema, table] => Ok((
54            query_ctx.current_catalog().to_string(),
55            schema.value.clone(),
56            table.value.clone(),
57        )),
58        [catalog, schema, table] => Ok((
59            catalog.value.clone(),
60            schema.value.clone(),
61            table.value.clone(),
62        )),
63        _ => InvalidSqlSnafu {
64            msg: format!(
65                "expect table name to be <catalog>.<schema>.<table>, <schema>.<table> or <table>, actual: {obj_name}",
66            ),
67        }.fail(),
68    }
69}