Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(query): show create table support display inverted index #15169

Merged
merged 3 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/common/exception/src/exception_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@ build_exceptions! {
UnknownIndex(2722),
DropIndexWithDropTime(2723),
GetIndexWithDropTime(2724),
DuplicatedIndexColumnId(2725),
IndexColumnIdNotFound(2726),

// Stream error codes.
UnknownStream(2730),
Expand Down
32 changes: 12 additions & 20 deletions src/meta/api/src/schema_api_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ use databend_common_meta_app::app_error::DatabaseAlreadyExists;
use databend_common_meta_app::app_error::DropDbWithDropTime;
use databend_common_meta_app::app_error::DropIndexWithDropTime;
use databend_common_meta_app::app_error::DropTableWithDropTime;
use databend_common_meta_app::app_error::DuplicatedIndexColumnId;
use databend_common_meta_app::app_error::DuplicatedUpsertFiles;
use databend_common_meta_app::app_error::GetIndexWithDropTime;
use databend_common_meta_app::app_error::IndexAlreadyExists;
use databend_common_meta_app::app_error::IndexColumnIdNotFound;
use databend_common_meta_app::app_error::MultiStmtTxnCommitFailed;
use databend_common_meta_app::app_error::ShareHasNoGrantedPrivilege;
use databend_common_meta_app::app_error::StreamAlreadyExists;
Expand Down Expand Up @@ -1085,7 +1087,7 @@ impl<KV: kvapi::KVApi<Error = MetaError> + ?Sized> SchemaApi for KV {

// get an index with drop time
if index_meta.dropped_on.is_some() {
return Err(KVAppError::AppError(AppError::GetIndexWithDropTIme(
return Err(KVAppError::AppError(AppError::GetIndexWithDropTime(
GetIndexWithDropTime::new(&tenant_index.index_name),
)));
}
Expand Down Expand Up @@ -3215,33 +3217,23 @@ impl<KV: kvapi::KVApi<Error = MetaError> + ?Sized> SchemaApi for KV {
// check the index column id exists
for column_id in &req.column_ids {
if table_meta.schema.is_column_deleted(*column_id) {
return Err(KVAppError::AppError(AppError::UnknownIndex(
UnknownIndex::new(
&req.name,
format!("table index column id {} is not exist", column_id),
),
return Err(KVAppError::AppError(AppError::IndexColumnIdNotFound(
IndexColumnIdNotFound::new(*column_id, &req.name),
)));
}
}

let mut other_column_ids = HashSet::new();
// column_id can not be duplicated
for (name, index) in indexes.iter() {
if *name == req.name {
continue;
}
for column_id in &index.column_ids {
other_column_ids.insert(column_id);
}
}
// column_id can not be duplicated
for column_id in &req.column_ids {
if other_column_ids.contains(column_id) {
return Err(KVAppError::AppError(AppError::IndexAlreadyExists(
IndexAlreadyExists::new(
&req.name,
format!("column {} already exist in other indexes", column_id),
),
)));
for column_id in &req.column_ids {
if index.column_ids.contains(column_id) {
return Err(KVAppError::AppError(AppError::DuplicatedIndexColumnId(
DuplicatedIndexColumnId::new(*column_id, &req.name),
)));
}
}
}

Expand Down
67 changes: 64 additions & 3 deletions src/meta/app/src/app_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ impl IndexAlreadyExists {
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, thiserror::Error)]
#[error("CreateIndexWithDropTime: create {index_name} with drop time")]
#[error("UnknownIndex: `{index_name}` while `{context}`")]
pub struct UnknownIndex {
index_name: String,
context: String,
Expand Down Expand Up @@ -873,6 +873,38 @@ impl GetIndexWithDropTime {
}
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, thiserror::Error)]
#[error("DuplicatedIndexColumnId: {column_id} is duplicated with index {index_name}")]
pub struct DuplicatedIndexColumnId {
column_id: u32,
index_name: String,
}

impl DuplicatedIndexColumnId {
pub fn new(column_id: u32, index_name: impl Into<String>) -> Self {
Self {
column_id,
index_name: index_name.into(),
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, thiserror::Error)]
#[error("IndexColumnIdNotFound: index {index_name} column id {column_id} is not found")]
pub struct IndexColumnIdNotFound {
column_id: u32,
index_name: String,
}

impl IndexColumnIdNotFound {
pub fn new(column_id: u32, index_name: impl Into<String>) -> Self {
Self {
column_id,
index_name: index_name.into(),
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, thiserror::Error)]
#[error("VirtualColumnAlreadyExists: `{table_id}` while `{context}`")]
pub struct VirtualColumnAlreadyExists {
Expand Down Expand Up @@ -1035,7 +1067,13 @@ pub enum AppError {
DropIndexWithDropTime(#[from] DropIndexWithDropTime),

#[error(transparent)]
GetIndexWithDropTIme(#[from] GetIndexWithDropTime),
GetIndexWithDropTime(#[from] GetIndexWithDropTime),

#[error(transparent)]
DuplicatedIndexColumnId(#[from] DuplicatedIndexColumnId),

#[error(transparent)]
IndexColumnIdNotFound(#[from] IndexColumnIdNotFound),

#[error(transparent)]
DatamaskAlreadyExists(#[from] DatamaskAlreadyExists),
Expand Down Expand Up @@ -1361,6 +1399,24 @@ impl AppErrorMessage for GetIndexWithDropTime {
}
}

impl AppErrorMessage for DuplicatedIndexColumnId {
fn message(&self) -> String {
format!(
"{} is duplicated with index '{}'",
self.column_id, self.index_name
)
}
}

impl AppErrorMessage for IndexColumnIdNotFound {
fn message(&self) -> String {
format!(
"index '{}' column id {} is not found",
self.index_name, self.column_id
)
}
}

impl AppErrorMessage for DatamaskAlreadyExists {
fn message(&self) -> String {
format!("Datamask '{}' already exists", self.name)
Expand Down Expand Up @@ -1483,7 +1539,12 @@ impl From<AppError> for ErrorCode {
AppError::IndexAlreadyExists(err) => ErrorCode::IndexAlreadyExists(err.message()),
AppError::UnknownIndex(err) => ErrorCode::UnknownIndex(err.message()),
AppError::DropIndexWithDropTime(err) => ErrorCode::DropIndexWithDropTime(err.message()),
AppError::GetIndexWithDropTIme(err) => ErrorCode::GetIndexWithDropTime(err.message()),
AppError::GetIndexWithDropTime(err) => ErrorCode::GetIndexWithDropTime(err.message()),
AppError::DuplicatedIndexColumnId(err) => {
ErrorCode::DuplicatedIndexColumnId(err.message())
}
AppError::IndexColumnIdNotFound(err) => ErrorCode::IndexColumnIdNotFound(err.message()),

AppError::DatamaskAlreadyExists(err) => ErrorCode::DatamaskAlreadyExists(err.message()),
AppError::UnknownDatamask(err) => ErrorCode::UnknownDatamask(err.message()),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,11 @@ impl ShowCreateTableInterpreter {
)
}

// Append columns.
let table_info = table.get_table_info();

// Append columns and indexes.
{
let mut columns = vec![];
let mut create_defs = vec![];
for (idx, field) in schema.fields().iter().enumerate() {
let nullable = if field.is_nullable() {
" NULL".to_string()
Expand Down Expand Up @@ -140,7 +142,7 @@ impl ShowCreateTableInterpreter {
} else {
"".to_string()
};
let column = format!(
let column_str = format!(
" {} {}{}{}{}{}",
format_name(field.name(), quoted_ident_case_sensitive, sql_dialect),
field.data_type().remove_recursive_nullable().sql_name(),
Expand All @@ -150,21 +152,51 @@ impl ShowCreateTableInterpreter {
comment
);

columns.push(column);
create_defs.push(column_str);
}

for index_field in table_info.meta.indexes.values() {
let sync = if index_field.sync_creation {
"SYNC"
} else {
"ASYNC"
};
let mut column_names = Vec::with_capacity(index_field.column_ids.len());
for column_id in index_field.column_ids.iter() {
let field = schema.field_of_column_id(*column_id)?;
column_names.push(field.name().to_string());
}
let column_names_str = column_names.join(", ").to_string();
let mut options = Vec::with_capacity(index_field.options.len());
for (key, value) in index_field.options.iter() {
let option = format!("{} = '{}'", key, value);
options.push(option);
}
let mut index_str = format!(
" {} INVERTED INDEX {} ({})",
sync,
format_name(&index_field.name, quoted_ident_case_sensitive, sql_dialect),
column_names_str
);
if !options.is_empty() {
let options_str = options.join(", ").to_string();
index_str.push(' ');
index_str.push_str(&options_str);
}
create_defs.push(index_str);
}

// Format is:
// (
// x,
// y
// )
let columns_str = format!("{}\n", columns.join(",\n"));
table_create_sql.push_str(&columns_str);
let create_defs_str = format!("{}\n", create_defs.join(",\n"));
table_create_sql.push_str(&create_defs_str);
}

let table_engine = format!(") ENGINE={}", engine);
table_create_sql.push_str(table_engine.as_str());

let table_info = table.get_table_info();
if let Some((_, cluster_keys_str)) = table_info.meta.cluster_key() {
table_create_sql.push_str(format!(" CLUSTER BY {}", cluster_keys_str).as_str());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ INSERT INTO t VALUES
statement ok
CREATE INVERTED INDEX IF NOT EXISTS idx1 ON t(content) tokenizer = 'chinese'

query TT
SHOW CREATE TABLE t
----
t CREATE TABLE t ( id INT NULL, content VARCHAR NULL, SYNC INVERTED INDEX idx1 (content) tokenizer = 'chinese' ) ENGINE=FUSE

statement ok
REFRESH INVERTED INDEX idx1 ON t

Expand Down Expand Up @@ -173,3 +178,4 @@ use default

statement ok
drop database test_index

Loading