添加 Manticore Search 支持 (#1145)

* 添加 Manticore Search 支持

* 更新 Manticore Search 文档
This commit is contained in:
Vergil Lai authored and GitHub committed 2026-06-13 20:23:36 +08:00
1 parent 6c57169162
commit 799d20a2cf
34 files changed
+258 -49

No files matched your search

+1 -1
View File
@@ -358,7 +358,7 @@ impl AppState {
.await?;
PoolKind::Mysql(pool, mode)
}
DatabaseType::Doris | DatabaseType::StarRocks | DatabaseType::Databend => {
DatabaseType::Doris | DatabaseType::StarRocks | DatabaseType::ManticoreSearch | DatabaseType::Databend => {
let pool = if database.is_none() {
connect_bare_metadata_pool(&db_config, &host, port, connect_timeout, mysql_pool_max_connections)
.await?
+6 -2
View File
@@ -29,8 +29,12 @@ impl MySqlQueryDialect {
pub fn for_connection(db_type: DatabaseType, driver_profile: Option<&str>) -> Self {
let profile = driver_profile.map(str::to_ascii_lowercase);
Self {
supports_admin_show_results: matches!(db_type, DatabaseType::Doris | DatabaseType::StarRocks)
|| profile.as_deref().is_some_and(|profile| matches!(profile, "doris" | "selectdb" | "starrocks")),
supports_admin_show_results: matches!(
db_type,
DatabaseType::Doris | DatabaseType::StarRocks | DatabaseType::ManticoreSearch
) || profile
.as_deref()
.is_some_and(|profile| matches!(profile, "doris" | "selectdb" | "starrocks" | "manticoresearch")),
}
}
}
+17 -9
View File
@@ -240,6 +240,8 @@ pub enum DatabaseType {
Doris,
#[serde(rename = "starrocks")]
StarRocks,
#[serde(rename = "manticoresearch")]
ManticoreSearch,
Databend,
Redshift,
Dameng,
@@ -593,12 +595,10 @@ impl ConnectionConfig {
}
pub fn needs_bare_mysql(&self) -> bool {
matches!(self.db_type, DatabaseType::Doris | DatabaseType::StarRocks)
|| self
.driver_profile
.as_deref()
.map(|p| p.to_lowercase())
.is_some_and(|p| matches!(p.as_str(), "doris" | "starrocks" | "selectdb" | "oceanbase"))
matches!(self.db_type, DatabaseType::Doris | DatabaseType::StarRocks | DatabaseType::ManticoreSearch)
|| self.driver_profile.as_deref().map(|p| p.to_lowercase()).is_some_and(|p| {
matches!(p.as_str(), "doris" | "starrocks" | "manticoresearch" | "selectdb" | "oceanbase")
})
}
pub fn canonicalized(&self) -> Self {
@@ -656,7 +656,11 @@ impl ConnectionConfig {
let fragment = self.redis_tls_insecure_fragment();
format!("{scheme}://{host}:{port}/{fragment}")
}
DatabaseType::Mysql | DatabaseType::Doris | DatabaseType::StarRocks | DatabaseType::Databend => {
DatabaseType::Mysql
| DatabaseType::Doris
| DatabaseType::StarRocks
| DatabaseType::ManticoreSearch
| DatabaseType::Databend => {
let suffix = if params.is_empty() { String::new() } else { format!("?{params}") };
format!("mysql://{host}:{port}{db_part}{suffix}")
}
@@ -777,7 +781,11 @@ impl ConnectionConfig {
format!("{scheme}://{username}:{password}@{host}:{port}/{fragment}")
}
}
DatabaseType::Mysql | DatabaseType::Doris | DatabaseType::StarRocks | DatabaseType::Databend => {
DatabaseType::Mysql
| DatabaseType::Doris
| DatabaseType::StarRocks
| DatabaseType::ManticoreSearch
| DatabaseType::Databend => {
let suffix = if params.is_empty() { String::new() } else { format!("?{params}") };
format!("mysql://{}:{}@{host}:{port}{db_part}{suffix}", username, password)
}
@@ -958,7 +966,7 @@ impl ConnectionConfig {
DatabaseType::Mysql => {
normalize_mysql_url_params(value, self.mysql_uses_tls(), self.ca_cert_path.trim().is_empty())
}
DatabaseType::Doris | DatabaseType::StarRocks | DatabaseType::Databend => {
DatabaseType::Doris | DatabaseType::StarRocks | DatabaseType::ManticoreSearch | DatabaseType::Databend => {
normalize_bare_mysql_url_params(value)
}
DatabaseType::Postgres | DatabaseType::Redshift => normalize_postgres_url_params(value, self.ssl),
+60 -5
View File
@@ -319,7 +319,9 @@ async fn list_databases_once(state: &AppState, connection_id: &str) -> Result<Ve
match pool {
PoolKind::Mysql(p, _) if db_config.as_ref().is_some_and(is_doris_family_config) => {
db::mysql::list_databases_show(p).await
db::mysql::list_databases_show(p)
.await
.map(|databases| filter_mysql_system_databases_for_config(databases, db_config.as_ref()))
}
PoolKind::Mysql(p, mode) => dispatch_mysql!(p, mode, db::mysql::list_databases, db::ob_oracle::list_databases),
PoolKind::Postgres(p) => db::postgres::list_databases(p).await,
@@ -599,8 +601,8 @@ fn filter_table_infos(
#[cfg(test)]
mod tests {
use super::{
clickhouse_metadata_database, deduplicate_column_infos, filter_table_infos,
is_agent_postgres_metadata_fallback_config,
clickhouse_metadata_database, deduplicate_column_infos, filter_mysql_system_databases_for_config,
filter_table_infos, is_agent_postgres_metadata_fallback_config,
};
#[cfg(feature = "duckdb-bundled")]
use super::{duckdb_attach_database, duckdb_list_databases, duckdb_query_tables_in_database};
@@ -675,6 +677,39 @@ mod tests {
}
}
fn test_database_info(name: &str) -> super::db::DatabaseInfo {
super::db::DatabaseInfo { name: name.to_string() }
}
#[test]
fn manticoresearch_database_list_filters_mysql_system_databases() {
let databases = vec![
test_database_info("Manticore"),
test_database_info("information_schema"),
test_database_info("mysql"),
test_database_info("performance_schema"),
test_database_info("sys"),
];
let config = test_connection_config(DatabaseType::ManticoreSearch);
let filtered = filter_mysql_system_databases_for_config(databases, Some(&config));
assert_eq!(filtered.into_iter().map(|database| database.name).collect::<Vec<_>>(), vec!["Manticore"]);
}
#[test]
fn doris_database_list_keeps_system_databases() {
let databases = vec![test_database_info("information_schema"), test_database_info("analytics")];
let config = test_connection_config(DatabaseType::Doris);
let filtered = filter_mysql_system_databases_for_config(databases, Some(&config));
assert_eq!(
filtered.into_iter().map(|database| database.name).collect::<Vec<_>>(),
vec!["information_schema", "analytics"]
);
}
#[test]
fn filter_table_infos_applies_filter_offset_and_limit() {
let tables = vec![
@@ -1469,8 +1504,28 @@ fn is_opengauss_family_config(config: &ConnectionConfig) -> bool {
}
fn is_doris_family_config(config: &ConnectionConfig) -> bool {
matches!(config.db_type, DatabaseType::Doris | DatabaseType::StarRocks)
|| matches!(config.driver_profile.as_deref(), Some("doris" | "selectdb" | "starrocks"))
matches!(config.db_type, DatabaseType::Doris | DatabaseType::StarRocks | DatabaseType::ManticoreSearch)
|| matches!(config.driver_profile.as_deref(), Some("doris" | "selectdb" | "starrocks" | "manticoresearch"))
}
fn is_manticoresearch_config(config: &ConnectionConfig) -> bool {
matches!(config.db_type, DatabaseType::ManticoreSearch)
|| matches!(config.driver_profile.as_deref(), Some("manticoresearch"))
}
fn filter_mysql_system_databases_for_config(
databases: Vec<db::DatabaseInfo>,
config: Option<&ConnectionConfig>,
) -> Vec<db::DatabaseInfo> {
if !config.is_some_and(is_manticoresearch_config) {
return databases;
}
databases.into_iter().filter(|database| !is_mysql_system_database(&database.name)).collect()
}
fn is_mysql_system_database(name: &str) -> bool {
matches!(name.to_ascii_lowercase().as_str(), "information_schema" | "mysql" | "performance_schema" | "sys")
}
fn sql_string(value: &str) -> String {
+25 -3
View File
@@ -7,7 +7,9 @@ pub(in crate::schema) async fn list_databases(
config: Option<&ConnectionConfig>,
) -> Result<Vec<db::DatabaseInfo>, String> {
match pool {
PoolKind::Mysql(p, _) if config.is_some_and(is_doris_family_config) => db::mysql::list_databases_show(p).await,
PoolKind::Mysql(p, _) if config.is_some_and(is_doris_family_config) => db::mysql::list_databases_show(p)
.await
.map(|databases| filter_mysql_system_databases_for_config(databases, config)),
PoolKind::Mysql(p, mode) if *mode == MysqlMode::OceanBaseOracle => db::ob_oracle::list_databases(p).await,
PoolKind::Mysql(p, _) => db::mysql::list_databases(p).await,
PoolKind::Postgres(p) => db::postgres::list_databases(p).await,
@@ -262,6 +264,26 @@ fn is_opengauss_family_config(config: &ConnectionConfig) -> bool {
}
fn is_doris_family_config(config: &ConnectionConfig) -> bool {
matches!(config.db_type, DatabaseType::Doris | DatabaseType::StarRocks)
|| matches!(config.driver_profile.as_deref(), Some("doris" | "selectdb" | "starrocks"))
matches!(config.db_type, DatabaseType::Doris | DatabaseType::StarRocks | DatabaseType::ManticoreSearch)
|| matches!(config.driver_profile.as_deref(), Some("doris" | "selectdb" | "starrocks" | "manticoresearch"))
}
fn is_manticoresearch_config(config: &ConnectionConfig) -> bool {
matches!(config.db_type, DatabaseType::ManticoreSearch)
|| matches!(config.driver_profile.as_deref(), Some("manticoresearch"))
}
fn filter_mysql_system_databases_for_config(
databases: Vec<db::DatabaseInfo>,
config: Option<&ConnectionConfig>,
) -> Vec<db::DatabaseInfo> {
if !config.is_some_and(is_manticoresearch_config) {
return databases;
}
databases.into_iter().filter(|database| !is_mysql_system_database(&database.name)).collect()
}
fn is_mysql_system_database(name: &str) -> bool {
matches!(name.to_ascii_lowercase().as_str(), "information_schema" | "mysql" | "performance_schema" | "sys")
}
+26 -8
View File
@@ -64,7 +64,11 @@ impl SqlParsingOptions {
Self {
supports_hash_line_comments: matches!(
db_type,
DatabaseType::Mysql | DatabaseType::Doris | DatabaseType::StarRocks | DatabaseType::Goldendb
DatabaseType::Mysql
| DatabaseType::Doris
| DatabaseType::StarRocks
| DatabaseType::ManticoreSearch
| DatabaseType::Goldendb
),
supports_oracle_plsql_blocks: matches!(
db_type,
@@ -1203,13 +1207,27 @@ fn executable_sql_keyword_matches(token: &str, keyword: &str) -> bool {
}
fn is_mysql_compatible_import_target(db_type: &DatabaseType, driver_profile: Option<&str>) -> bool {
matches!(db_type, DatabaseType::Mysql | DatabaseType::Doris | DatabaseType::StarRocks | DatabaseType::Goldendb)
|| driver_profile.map(|profile| profile.to_ascii_lowercase()).is_some_and(|profile| {
matches!(
profile.as_str(),
"mariadb" | "tidb" | "oceanbase" | "custom_mysql" | "doris" | "starrocks" | "selectdb" | "goldendb"
)
})
matches!(
db_type,
DatabaseType::Mysql
| DatabaseType::Doris
| DatabaseType::StarRocks
| DatabaseType::ManticoreSearch
| DatabaseType::Goldendb
) || driver_profile.map(|profile| profile.to_ascii_lowercase()).is_some_and(|profile| {
matches!(
profile.as_str(),
"mariadb"
| "tidb"
| "oceanbase"
| "custom_mysql"
| "doris"
| "starrocks"
| "manticoresearch"
| "selectdb"
| "goldendb"
)
})
}
fn mysql_executable_comment_body(statement: &str) -> Option<&str> {
+1 -1
View File
@@ -91,7 +91,7 @@ fn starts_with_duckdb_parser_gap_sql(sql: &str) -> bool {
fn normalize_dialect(dialect: Option<&str>) -> String {
match dialect.unwrap_or("generic").to_ascii_lowercase().as_str() {
"postgres" | "postgresql" | "redshift" | "opengauss" | "gaussdb" | "highgo" => "postgres".to_string(),
"mysql" | "mariadb" | "doris" | "starrocks" | "oceanbase" => "mysql".to_string(),
"mysql" | "mariadb" | "doris" | "starrocks" | "manticoresearch" | "oceanbase" => "mysql".to_string(),
"sqlite" => "sqlite".to_string(),
"sqlserver" | "mssql" => "sqlserver".to_string(),
"clickhouse" => "clickhouse".to_string(),
@@ -36,6 +36,7 @@ pub fn quote_table_identifier(database_type: Option<DatabaseType>, name: &str) -
DatabaseType::Mysql
| DatabaseType::Goldendb
| DatabaseType::StarRocks
| DatabaseType::ManticoreSearch
| DatabaseType::Hive
| DatabaseType::Databend
| DatabaseType::Tdengine
+1 -1
View File
@@ -34,7 +34,7 @@ impl std::fmt::Display for SqlRisk {
fn normalize_dialect(dialect: &str) -> &'static str {
match dialect.to_ascii_lowercase().as_str() {
"postgres" | "postgresql" | "redshift" | "opengauss" | "gaussdb" | "highgo" => "postgres",
"mysql" | "mariadb" | "doris" | "starrocks" | "oceanbase" => "mysql",
"mysql" | "mariadb" | "doris" | "starrocks" | "manticoresearch" | "oceanbase" => "mysql",
"sqlite" => "sqlite",
"sqlserver" | "mssql" => "sqlserver",
"clickhouse" => "clickhouse",