fix(postgresql): show trigger source details

This commit is contained in:
zipg authored and GitHub committed 2026-07-23 21:16:43 +08:00
1 parent 6115771b34
commit 6b2f55e4de
13 files changed
+137 -19

No files matched your search

+3
View File
@@ -1851,6 +1851,7 @@ pub async fn export_database_sql_core(
view_name,
crate::db::ObjectSourceKind::View,
None,
None,
)
.await
{
@@ -1901,6 +1902,7 @@ pub async fn export_database_sql_core(
proc_name,
crate::db::ObjectSourceKind::Procedure,
procedure.signature.as_deref(),
None,
)
.await
{
@@ -1955,6 +1957,7 @@ pub async fn export_database_sql_core(
func_name,
crate::db::ObjectSourceKind::Function,
function.signature.as_deref(),
None,
)
.await
{
+88 -7
View File
@@ -5373,9 +5373,17 @@ pub async fn get_table_ddl_core(
return Err("DDL is not supported for SQL Server linked server tables".to_string());
}
if matches!(object_type, Some(db::ObjectSourceKind::View)) {
let source =
get_object_source_core(state, connection_id, database, schema, table, db::ObjectSourceKind::View, None)
.await?;
let source = get_object_source_core(
state,
connection_id,
database,
schema,
table,
db::ObjectSourceKind::View,
None,
None,
)
.await?;
let database_type = connection_config(state, connection_id).await.map(|config| config.db_type);
return Ok(crate::object_source_sql::build_view_ddl_sql(crate::object_source_sql::BuildViewDdlInput {
database_type,
@@ -5393,6 +5401,7 @@ pub async fn get_table_ddl_core(
table,
db::ObjectSourceKind::MaterializedView,
None,
None,
)
.await?;
return Ok(source.source);
@@ -5675,6 +5684,24 @@ pub fn postgres_object_source_sql(
postgres_object_source_sql_inner(schema, name, kind, signature, true, false)
}
fn postgres_trigger_object_source_sql(schema: &str, name: &str, relation_name: Option<&str>) -> String {
let relation_filter = relation_name
.filter(|value| !value.trim().is_empty())
.map(|value| format!(" AND c.relname = {}", sql_string(value)))
.unwrap_or_default();
format!(
"SELECT pg_catalog.pg_get_triggerdef(t.oid, true) \
FROM pg_catalog.pg_trigger t \
JOIN pg_catalog.pg_class c ON c.oid = t.tgrelid \
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace \
WHERE n.nspname = {} AND t.tgname = {} AND NOT t.tgisinternal{} \
ORDER BY t.oid LIMIT 1",
sql_string(schema),
sql_string(name),
relation_filter
)
}
fn opengauss_object_source_sql(
schema: &str,
name: &str,
@@ -5929,9 +5956,19 @@ pub async fn get_object_source_core(
name: &str,
object_type: db::ObjectSourceKind,
signature: Option<&str>,
relation_name: Option<&str>,
) -> Result<db::ObjectSource, String> {
retry_metadata_connection(state, connection_id, Some(database), || {
get_object_source_once(state, connection_id, database, schema, name, object_type.clone(), signature)
get_object_source_once(
state,
connection_id,
database,
schema,
name,
object_type.clone(),
signature,
relation_name,
)
})
.await
}
@@ -5944,6 +5981,7 @@ async fn get_object_source_once(
name: &str,
object_type: db::ObjectSourceKind,
signature: Option<&str>,
relation_name: Option<&str>,
) -> Result<db::ObjectSource, String> {
let pool_key = state.get_or_create_pool(connection_id, Some(database)).await?;
let db_config = connection_config(state, connection_id).await;
@@ -6015,7 +6053,16 @@ async fn get_object_source_once(
}
PoolKind::Postgres(pool) => {
let unwrap_opengauss_record = db_config.as_ref().is_some_and(is_opengauss_family_config);
postgres_object_source(pool, schema, name, &object_type, signature, unwrap_opengauss_record).await?
postgres_object_source(
pool,
schema,
name,
&object_type,
signature,
relation_name,
unwrap_opengauss_record,
)
.await?
}
PoolKind::Sqlite(pool) => first_string_cell(
db::sqlite::execute_query(pool, &sqlite_object_source_sql(schema, name, &object_type)).await?,
@@ -6062,12 +6109,32 @@ async fn get_object_source_once(
}
};
let editable = if matches!(object_type, db::ObjectSourceKind::Trigger)
&& db_config.as_ref().is_some_and(|config| {
matches!(
config.db_type,
DatabaseType::Postgres
| DatabaseType::Redshift
| DatabaseType::Gaussdb
| DatabaseType::Kwdb
| DatabaseType::OpenGauss
| DatabaseType::Questdb
| DatabaseType::Kingbase
| DatabaseType::Highgo
| DatabaseType::Vastbase
)
}) {
Some(false)
} else {
None
};
Ok(db::ObjectSource {
name: name.to_string(),
object_type,
schema: if schema.is_empty() { None } else { Some(schema.to_string()) },
source,
editable: None,
editable,
})
}
@@ -6370,9 +6437,12 @@ async fn postgres_object_source(
name: &str,
object_type: &db::ObjectSourceKind,
signature: Option<&str>,
relation_name: Option<&str>,
unwrap_opengauss_record: bool,
) -> Result<String, String> {
let sql = if unwrap_opengauss_record {
let sql = if matches!(object_type, db::ObjectSourceKind::Trigger) {
postgres_trigger_object_source_sql(schema, name, relation_name)
} else if unwrap_opengauss_record {
opengauss_object_source_sql(schema, name, object_type, signature)
} else {
postgres_object_source_sql(schema, name, object_type, signature)
@@ -6475,6 +6545,17 @@ mod object_source_tests {
);
}
#[test]
fn builds_postgres_object_source_sql_for_table_trigger() {
let sql = postgres_trigger_object_source_sql("audit", "trg_orders_update", Some("orders"));
assert!(sql.contains("pg_get_triggerdef(t.oid, true)"));
assert!(sql.contains("n.nspname = 'audit'"));
assert!(sql.contains("c.relname = 'orders'"));
assert!(sql.contains("t.tgname = 'trg_orders_update'"));
assert!(sql.contains("NOT t.tgisinternal"));
}
#[test]
fn builds_postgres_object_source_sql_without_relispopulated_for_legacy_catalogs() {
let sql = postgres_object_source_sql_without_relispopulated(