From 44f49253d74a96eecd5f33efcdf86007220beb60 Mon Sep 17 00:00:00 2001 From: Elias <45232878+mapan0424@users.noreply.github.com> Date: Thu, 30 Jul 2026 18:18:43 +0800 Subject: [PATCH] fix(xugu): support synonym object source requests --- agents/drivers/xugu/main.go | 1 + agents/drivers/xugu/main_test.go | 3 +++ crates/dbx-core/src/object_source_sql.rs | 4 ++++ crates/dbx-core/src/schema.rs | 6 ++++++ crates/dbx-core/src/transfer.rs | 7 ++++--- crates/dbx-core/src/types.rs | 11 ++++++++++- 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/agents/drivers/xugu/main.go b/agents/drivers/xugu/main.go index 984394bf4..a3d7810d6 100644 --- a/agents/drivers/xugu/main.go +++ b/agents/drivers/xugu/main.go @@ -2285,6 +2285,7 @@ func (s *server) getSynonymSource(schema, name string) (map[string]any, error) { "object_type": "SYNONYM", "schema": synonym.Schema, "source": builder.String(), + "editable": false, }, nil } diff --git a/agents/drivers/xugu/main_test.go b/agents/drivers/xugu/main_test.go index e4023621c..c8282f281 100644 --- a/agents/drivers/xugu/main_test.go +++ b/agents/drivers/xugu/main_test.go @@ -851,6 +851,9 @@ func TestGetSynonymSourceReconstructsPrivateQuotedDDL(t *testing.T) { if source["schema"] != "SYSDBA" || source["name"] != "dbxSynonymReplayCase" { t.Fatalf("synonym source must preserve catalog spelling: %#v", source) } + if source["editable"] != false { + t.Fatalf("synonym source must be read-only: %#v", source) + } ddl, _ := source["source"].(string) want := "CREATE SYNONYM \"SYSDBA\".\"dbxSynonymReplayCase\"\nFOR \"AppSchema\".\"tbUserProfile\";" diff --git a/crates/dbx-core/src/object_source_sql.rs b/crates/dbx-core/src/object_source_sql.rs index fadc4adbd..3e7b9b63e 100644 --- a/crates/dbx-core/src/object_source_sql.rs +++ b/crates/dbx-core/src/object_source_sql.rs @@ -327,6 +327,7 @@ fn object_type_keyword(object_type: &ObjectSourceKind) -> &'static str { ObjectSourceKind::Function => "FUNCTION", ObjectSourceKind::Trigger => "TRIGGER", ObjectSourceKind::Sequence => "SEQUENCE", + ObjectSourceKind::Synonym => "SYNONYM", ObjectSourceKind::Package => "PACKAGE", ObjectSourceKind::PackageBody => "PACKAGE BODY", ObjectSourceKind::Type => "TYPE", @@ -894,6 +895,8 @@ fn parse_object_source_kind(value: &str) -> Option { Some(ObjectSourceKind::Trigger) } else if value.eq_ignore_ascii_case("SEQUENCE") { Some(ObjectSourceKind::Sequence) + } else if value.eq_ignore_ascii_case("SYNONYM") { + Some(ObjectSourceKind::Synonym) } else if value.eq_ignore_ascii_case("PACKAGE") { Some(ObjectSourceKind::Package) } else if value.eq_ignore_ascii_case("PACKAGE BODY") || value.eq_ignore_ascii_case("PACKAGE_BODY") { @@ -1535,6 +1538,7 @@ mod tests { #[test] fn parses_programmable_metadata_object_kinds() { assert_eq!(parse_object_source_kind("TRIGGER"), Some(ObjectSourceKind::Trigger)); + assert_eq!(parse_object_source_kind("SYNONYM"), Some(ObjectSourceKind::Synonym)); assert_eq!(parse_object_source_kind("TYPE"), Some(ObjectSourceKind::Type)); assert_eq!(parse_object_source_kind("TYPE_BODY"), Some(ObjectSourceKind::TypeBody)); assert_eq!(parse_object_source_kind("PACKAGE BODY"), Some(ObjectSourceKind::PackageBody)); diff --git a/crates/dbx-core/src/schema.rs b/crates/dbx-core/src/schema.rs index 4af48cce1..80892f651 100644 --- a/crates/dbx-core/src/schema.rs +++ b/crates/dbx-core/src/schema.rs @@ -5285,6 +5285,7 @@ fn sqlite_object_type(kind: &db::ObjectSourceKind) -> &'static str { | db::ObjectSourceKind::Function | db::ObjectSourceKind::Trigger | db::ObjectSourceKind::Sequence + | db::ObjectSourceKind::Synonym | db::ObjectSourceKind::Package | db::ObjectSourceKind::PackageBody | db::ObjectSourceKind::Type @@ -5299,6 +5300,7 @@ fn sqlserver_object_type_filter(kind: &db::ObjectSourceKind) -> &'static str { db::ObjectSourceKind::Function => "'FN','IF','TF','FS','FT'", db::ObjectSourceKind::Trigger => "'TR'", db::ObjectSourceKind::Sequence + | db::ObjectSourceKind::Synonym | db::ObjectSourceKind::Package | db::ObjectSourceKind::PackageBody | db::ObjectSourceKind::Type @@ -5535,6 +5537,7 @@ fn postgres_object_source_sql_inner( ) } db::ObjectSourceKind::Trigger + | db::ObjectSourceKind::Synonym | db::ObjectSourceKind::Package | db::ObjectSourceKind::PackageBody | db::ObjectSourceKind::Type @@ -5550,6 +5553,7 @@ pub fn oracle_object_source_sql(schema: &str, name: &str, kind: &db::ObjectSourc db::ObjectSourceKind::Function => "FUNCTION", db::ObjectSourceKind::Trigger => "TRIGGER", db::ObjectSourceKind::Sequence => "SEQUENCE", + db::ObjectSourceKind::Synonym => "SYNONYM", db::ObjectSourceKind::Package => "PACKAGE", db::ObjectSourceKind::PackageBody => "PACKAGE_BODY", db::ObjectSourceKind::Type => "TYPE", @@ -5605,6 +5609,7 @@ pub fn mysql_object_source_sql(database: &str, name: &str, kind: &db::ObjectSour db::ObjectSourceKind::Function => format!("SHOW CREATE FUNCTION {qualified_name}"), db::ObjectSourceKind::Trigger | db::ObjectSourceKind::Sequence + | db::ObjectSourceKind::Synonym | db::ObjectSourceKind::Package | db::ObjectSourceKind::PackageBody | db::ObjectSourceKind::Type @@ -5638,6 +5643,7 @@ pub(crate) fn mysql_object_source_ddl_column_index(kind: &db::ObjectSourceKind) | db::ObjectSourceKind::Function | db::ObjectSourceKind::Trigger | db::ObjectSourceKind::Sequence + | db::ObjectSourceKind::Synonym | db::ObjectSourceKind::Package | db::ObjectSourceKind::PackageBody | db::ObjectSourceKind::Type diff --git a/crates/dbx-core/src/transfer.rs b/crates/dbx-core/src/transfer.rs index 1cfe91c74..0ce087693 100644 --- a/crates/dbx-core/src/transfer.rs +++ b/crates/dbx-core/src/transfer.rs @@ -4979,9 +4979,10 @@ where rewrite_postgres_routine_schema(&object.source, &request.source_schema, &request.target_schema) .unwrap_or_else(|| object.source.clone()) } - db::ObjectSourceKind::Sequence | db::ObjectSourceKind::Package | db::ObjectSourceKind::PackageBody => { - object.source.clone() - } + db::ObjectSourceKind::Sequence + | db::ObjectSourceKind::Synonym + | db::ObjectSourceKind::Package + | db::ObjectSourceKind::PackageBody => object.source.clone(), db::ObjectSourceKind::Trigger | db::ObjectSourceKind::Type | db::ObjectSourceKind::TypeBody => { object.source.clone() } diff --git a/crates/dbx-core/src/types.rs b/crates/dbx-core/src/types.rs index 96c599612..dcee7a951 100644 --- a/crates/dbx-core/src/types.rs +++ b/crates/dbx-core/src/types.rs @@ -103,6 +103,7 @@ pub enum ObjectSourceKind { Function, Trigger, Sequence, + Synonym, Package, PackageBody, Type, @@ -383,7 +384,7 @@ pub struct OwnerInfo { #[cfg(test)] mod tests { - use super::ObjectInfo; + use super::{ObjectInfo, ObjectSourceKind}; #[test] fn list_objects_payload_preserves_optional_validity() { @@ -394,4 +395,12 @@ mod tests { assert_eq!(objects[0].valid, Some(false)); assert_eq!(objects[0].object_type, "TRIGGER"); } + + #[test] + fn object_source_kind_accepts_synonym_wire_value() { + let kind: ObjectSourceKind = serde_json::from_str("\"SYNONYM\"").unwrap(); + + assert_eq!(kind, ObjectSourceKind::Synonym); + assert_eq!(serde_json::to_string(&kind).unwrap(), "\"SYNONYM\""); + } }