mirror of
https://github.com/t8y2/dbx.git
synced 2026-11-13 02:33:39 +08:00
fix(gaussdb): retrieve M-mode view DDL
This commit is contained in:
@@ -2652,9 +2652,9 @@ mod tests {
|
||||
dameng_object_statistics_rows_only_sql, dameng_object_statistics_user_segments_sql, deduplicate_column_infos,
|
||||
ephemeral_agent_metadata_session_id, external_driver_uses_mysql_ddl, filter_mongodb_agent_collections,
|
||||
filter_mysql_system_databases_for_config, filter_object_infos, filter_table_infos, filter_visible_schema_names,
|
||||
gbase8a_object_statistics_sql, is_agent_postgres_metadata_fallback_config, is_mysql_external_driver_config,
|
||||
is_retryable_metadata_error, metadata_error_action, metadata_name_or_comment_matches,
|
||||
mysql_external_driver_ddl_from_query_result, mysql_external_driver_ddl_sql,
|
||||
gaussdb_m_view_object_source_sql, gbase8a_object_statistics_sql, is_agent_postgres_metadata_fallback_config,
|
||||
is_mysql_external_driver_config, is_retryable_metadata_error, metadata_error_action,
|
||||
metadata_name_or_comment_matches, mysql_external_driver_ddl_from_query_result, mysql_external_driver_ddl_sql,
|
||||
mysql_object_source_ddl_column_index, mysql_object_source_sql, mysql_table_list_source_for_config,
|
||||
mysql_table_metadata_catalog, normalize_information_schema_table_type, oracle_columns_from_query_result,
|
||||
oracle_columns_sql, oracle_object_statistics_dba_segments_sql, oracle_object_statistics_from_query_result,
|
||||
@@ -2988,6 +2988,32 @@ mod tests {
|
||||
assert!(!external_driver_uses_mysql_ddl(&config));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gaussdb_m_view_object_source_sql_is_qualified_and_gated() {
|
||||
let mut config = test_connection_config(DatabaseType::Gaussdb);
|
||||
config.driver_profile = Some("gaussdb-m".to_string());
|
||||
|
||||
assert_eq!(
|
||||
gaussdb_m_view_object_source_sql(&config, "tenant`db", "active`users", &db::ObjectSourceKind::View)
|
||||
.as_deref(),
|
||||
Some("SHOW CREATE VIEW `tenant``db`.`active``users`")
|
||||
);
|
||||
assert_eq!(
|
||||
gaussdb_m_view_object_source_sql(&config, "", "active`users", &db::ObjectSourceKind::View).as_deref(),
|
||||
Some("SHOW CREATE VIEW `active``users`")
|
||||
);
|
||||
assert_eq!(
|
||||
gaussdb_m_view_object_source_sql(&config, "tenant_db", "refresh_users", &db::ObjectSourceKind::Function),
|
||||
None
|
||||
);
|
||||
|
||||
config.driver_profile = Some("gaussdb".to_string());
|
||||
assert_eq!(
|
||||
gaussdb_m_view_object_source_sql(&config, "tenant_db", "active_users", &db::ObjectSourceKind::View),
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mysql_external_driver_ddl_sql_uses_catalog_and_escaped_identifiers() {
|
||||
assert_eq!(
|
||||
@@ -3022,7 +3048,10 @@ mod tests {
|
||||
messages: Vec::new(),
|
||||
};
|
||||
|
||||
assert_eq!(mysql_external_driver_ddl_from_query_result(result).unwrap(), "CREATE TABLE `users` (`id` bigint);");
|
||||
assert_eq!(
|
||||
mysql_external_driver_ddl_from_query_result(result, "Create Table").unwrap(),
|
||||
"CREATE TABLE `users` (`id` bigint);"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -3044,11 +3073,66 @@ mod tests {
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
mysql_external_driver_ddl_from_query_result(result).unwrap(),
|
||||
mysql_external_driver_ddl_from_query_result(result, "Create Table").unwrap(),
|
||||
"CREATE TABLE `users` (`id` bigint);\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mysql_external_driver_view_ddl_reads_named_column_case_insensitively() {
|
||||
let result = db::QueryResult {
|
||||
columns: vec!["View".to_string(), "Extra".to_string(), "CREATE VIEW".to_string()],
|
||||
column_types: Vec::new(),
|
||||
column_sortables: Vec::new(),
|
||||
spatial_columns: vec![],
|
||||
spatial_values: vec![],
|
||||
rows: vec![vec![
|
||||
serde_json::json!("active_users"),
|
||||
serde_json::json!("ignored"),
|
||||
serde_json::json!("CREATE VIEW `active_users` AS SELECT 1"),
|
||||
]],
|
||||
affected_rows: 0,
|
||||
execution_time_ms: 0,
|
||||
truncated: false,
|
||||
session_id: None,
|
||||
has_more: false,
|
||||
elasticsearch_raw_body: None,
|
||||
messages: Vec::new(),
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
mysql_external_driver_ddl_from_query_result(result, "Create View").unwrap(),
|
||||
"CREATE VIEW `active_users` AS SELECT 1;"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mysql_external_driver_view_ddl_falls_back_to_second_column() {
|
||||
let result = db::QueryResult {
|
||||
columns: vec!["name".to_string(), "definition".to_string()],
|
||||
column_types: Vec::new(),
|
||||
column_sortables: Vec::new(),
|
||||
spatial_columns: vec![],
|
||||
spatial_values: vec![],
|
||||
rows: vec![vec![
|
||||
serde_json::json!("active_users"),
|
||||
serde_json::json!("CREATE VIEW `active_users` AS SELECT 1;\n"),
|
||||
]],
|
||||
affected_rows: 0,
|
||||
execution_time_ms: 0,
|
||||
truncated: false,
|
||||
session_id: None,
|
||||
has_more: false,
|
||||
elasticsearch_raw_body: None,
|
||||
messages: Vec::new(),
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
mysql_external_driver_ddl_from_query_result(result, "Create View").unwrap(),
|
||||
"CREATE VIEW `active_users` AS SELECT 1;\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mysql_object_source_sql_qualifies_cross_database_objects() {
|
||||
assert_eq!(
|
||||
@@ -6658,13 +6742,26 @@ fn external_driver_uses_mysql_ddl(config: &ConnectionConfig) -> bool {
|
||||
is_mysql_external_driver_config(config) || gaussdb_uses_m_jdbc_driver(config)
|
||||
}
|
||||
|
||||
fn gaussdb_m_view_object_source_sql(
|
||||
config: &ConnectionConfig,
|
||||
database: &str,
|
||||
name: &str,
|
||||
kind: &db::ObjectSourceKind,
|
||||
) -> Option<String> {
|
||||
(gaussdb_uses_m_jdbc_driver(config) && matches!(kind, db::ObjectSourceKind::View))
|
||||
.then(|| mysql_object_source_sql(database, name, kind))
|
||||
}
|
||||
|
||||
fn mysql_external_driver_ddl_sql(database: &str, schema: &str, table: &str) -> String {
|
||||
format!("SHOW CREATE TABLE {}", mysql_qualified_name(mysql_table_metadata_catalog(database, schema), table))
|
||||
}
|
||||
|
||||
fn mysql_external_driver_ddl_from_query_result(result: db::QueryResult) -> Result<String, String> {
|
||||
fn mysql_external_driver_ddl_from_query_result(
|
||||
result: db::QueryResult,
|
||||
named_ddl_column: &str,
|
||||
) -> Result<String, String> {
|
||||
let row = result.rows.first().ok_or_else(|| "DDL not found".to_string())?;
|
||||
let named_index = result.columns.iter().position(|column| column.trim().eq_ignore_ascii_case("Create Table"));
|
||||
let named_index = result.columns.iter().position(|column| column.trim().eq_ignore_ascii_case(named_ddl_column));
|
||||
let ddl = named_index
|
||||
.into_iter()
|
||||
.chain(std::iter::once(1))
|
||||
@@ -7287,6 +7384,29 @@ async fn get_object_source_once(
|
||||
let config = config.clone();
|
||||
let session = session.clone();
|
||||
drop(connections);
|
||||
if let Some(sql) = gaussdb_m_view_object_source_sql(config.as_ref(), database, name, &object_type) {
|
||||
let result: db::QueryResult = session
|
||||
.invoke_with_timeout(
|
||||
"executeQuery",
|
||||
serde_json::json!({
|
||||
"connection": config.as_ref(),
|
||||
"database": database,
|
||||
"schema": schema,
|
||||
"sql": sql,
|
||||
"maxRows": 1,
|
||||
}),
|
||||
agent_metadata_timeout(Some(config.as_ref())),
|
||||
)
|
||||
.await?;
|
||||
let source = mysql_external_driver_ddl_from_query_result(result, "Create View")?;
|
||||
return Ok(db::ObjectSource {
|
||||
name: name.to_string(),
|
||||
object_type,
|
||||
schema: if schema.is_empty() { None } else { Some(schema.to_string()) },
|
||||
source,
|
||||
editable: None,
|
||||
});
|
||||
}
|
||||
let result: db::ObjectSource = session
|
||||
.invoke_with_timeout(
|
||||
"getObjectSource",
|
||||
@@ -8814,7 +8934,7 @@ async fn external_driver_mysql_ddl(
|
||||
agent_metadata_timeout(Some(config)),
|
||||
)
|
||||
.await?;
|
||||
mysql_external_driver_ddl_from_query_result(result)
|
||||
mysql_external_driver_ddl_from_query_result(result, "Create Table")
|
||||
}
|
||||
|
||||
fn ensure_display_ddl_terminated(sql: String) -> String {
|
||||
|
||||
Reference in New Issue
Block a user