From 868502326c7d993d646d87f4b2509c5f8ae90de5 Mon Sep 17 00:00:00 2001 From: zipg Date: Sat, 15 Aug 2026 21:55:37 +0800 Subject: [PATCH] feat(kyuubi): add native connection support --- agents/drivers/hive-go/connector.go | 6 +- agents/drivers/hive-go/connector_test.go | 9 ++ agents/drivers/hive-go/main.go | 6 +- agents/drivers/hive-go/metadata.go | 26 +++++- agents/drivers/hive-go/metadata_test.go | 72 +++++++++++++++ apps/desktop/public/icons/database/kyuubi.png | Bin 0 -> 13227 bytes .../connection/ConnectionDialog.vue | 13 +-- .../src/components/icons/DatabaseIcon.spec.ts | 11 +++ .../src/components/icons/DatabaseIcon.vue | 1 + .../connectionAttemptTimeout.spec.ts | 4 + .../connection/connectionPassword.spec.ts | 11 +++ .../__tests__/table/tableSelectSql.spec.ts | 4 + .../__tests__/agentDriverInstallHint.spec.ts | 4 +- .../lib/connection/agentDriverInstallHint.ts | 2 +- .../connection/connectionAttemptTimeout.ts | 1 + .../src/lib/connection/connectionPassword.ts | 8 +- .../__tests__/transferObjectKinds.spec.ts | 2 +- .../lib/database/databaseCapabilitySets.ts | 1 + .../lib/database/databaseNamespaceCreation.ts | 1 + .../database/databaseObjectCapabilities.ts | 1 + .../lib/database/databasePropertyEditing.ts | 1 + .../database/databaseTableDataCapabilities.ts | 11 +++ apps/desktop/src/lib/database/jdbcDialect.ts | 2 +- apps/desktop/src/lib/table/tableSelectSql.ts | 14 ++- apps/desktop/src/stores/connectionStore.ts | 1 + apps/desktop/src/types/database.ts | 1 + .../assets/database-drivers.manifest.json | 30 +++++++ crates/dbx-core/src/agent_catalog.rs | 13 +++ crates/dbx-core/src/connection.rs | 1 + crates/dbx-core/src/db_admin_sql.rs | 46 +++++++--- crates/dbx-core/src/models/connection.rs | 33 +++++++ .../dbx-core/src/sql_dialect/capabilities.rs | 1 + .../dbx-core/src/sql_dialect/ddl_profile.rs | 6 +- .../dbx-core/src/sql_dialect/identifiers.rs | 2 + .../dbx-core/src/sql_dialect/table_select.rs | 2 +- crates/dbx-core/src/table_import.rs | 6 +- crates/dbx-core/src/transfer.rs | 82 +++++++++++++----- .../dbx-core/tests/database_capabilities.rs | 21 +++++ 38 files changed, 402 insertions(+), 54 deletions(-) create mode 100644 apps/desktop/public/icons/database/kyuubi.png diff --git a/agents/drivers/hive-go/connector.go b/agents/drivers/hive-go/connector.go index c232d08df8..ce745c1827 100644 --- a/agents/drivers/hive-go/connector.go +++ b/agents/drivers/hive-go/connector.go @@ -89,7 +89,7 @@ func newDiscoveryConnector(config connectionConfig) *discoveryConnector { BrowserResponsePort: config.BrowserResponsePort, BrowserResponseTimeout: config.BrowserResponseTimeout, BrowserDisableSSLCheck: config.BrowserDisableSSLCheck, - WaitForNonQueryCompletion: strings.EqualFold(config.DatabaseType, "impala"), + WaitForNonQueryCompletion: waitsForNonQueryCompletion(config.DatabaseType), }) }, driver: &gohive.Driver{}, @@ -98,6 +98,10 @@ func newDiscoveryConnector(config connectionConfig) *discoveryConnector { } } +func waitsForNonQueryCompletion(databaseType string) bool { + return strings.EqualFold(databaseType, "impala") || strings.EqualFold(databaseType, "kyuubi") +} + func gssapiOptionsFromKerberos(config kerberosConfig) gosasl.GSSAPIOptions { return gosasl.GSSAPIOptions{ ConfigPath: config.ConfigPath, diff --git a/agents/drivers/hive-go/connector_test.go b/agents/drivers/hive-go/connector_test.go index 89a2d35310..af9678152a 100644 --- a/agents/drivers/hive-go/connector_test.go +++ b/agents/drivers/hive-go/connector_test.go @@ -114,6 +114,15 @@ func TestNormalizeHiveAuth(t *testing.T) { } } +func TestWaitsForKyuubiAndImpalaNonQueryCompletion(t *testing.T) { + if !waitsForNonQueryCompletion("kyuubi") || !waitsForNonQueryCompletion("KYUUBI") || !waitsForNonQueryCompletion("impala") { + t.Fatal("Kyuubi and Impala must wait for asynchronous non-query operations") + } + if waitsForNonQueryCompletion("hive") { + t.Fatal("Hive must retain its existing non-query behavior") + } +} + func TestKerberosServiceForEndpoint(t *testing.T) { target := endpoint{Host: "hs2.example.com", Port: 10000, Principal: "hive/hs2.example.com@EXAMPLE.COM"} discovered := connectionConfig{Kerberos: kerberosConfig{Service: "hive"}} diff --git a/agents/drivers/hive-go/main.go b/agents/drivers/hive-go/main.go index 7ad269e491..6af04f087c 100644 --- a/agents/drivers/hive-go/main.go +++ b/agents/drivers/hive-go/main.go @@ -431,7 +431,11 @@ func (server *server) dispatch(method string, params map[string]json.RawMessage) case "list_constraints", "list_partitions", "list_subpartitions": return []any{}, false, nil case "get_object_source": - result, err := server.getTableDDL(stringParam(params, "schema"), firstNonEmpty(stringParam(params, "name"), stringParam(params, "table"))) + result, err := server.getObjectSource( + stringParam(params, "schema"), + firstNonEmpty(stringParam(params, "name"), stringParam(params, "table")), + stringParam(params, "object_type"), + ) return result, false, err case "get_table_ddl": result, err := server.getTableDDL(stringParam(params, "schema"), stringParam(params, "table")) diff --git a/agents/drivers/hive-go/metadata.go b/agents/drivers/hive-go/metadata.go index 8fb1ff97a9..bc0dcf1c1b 100644 --- a/agents/drivers/hive-go/metadata.go +++ b/agents/drivers/hive-go/metadata.go @@ -40,6 +40,13 @@ type objectInfo struct { Valid *bool `json:"valid,omitempty"` } +type objectSource struct { + Name string `json:"name"` + ObjectType string `json:"object_type"` + Schema *string `json:"schema"` + Source string `json:"source"` +} + type columnInfo struct { Name string `json:"name"` DataType string `json:"data_type"` @@ -200,7 +207,11 @@ func (server *server) connectionInfo() (map[string]any, error) { productName := "Apache Hive" compatibilityMode := "hive" driverName := "DBX Hive Go Agent" - if strings.EqualFold(server.params.DatabaseType, "impala") || strings.Contains(strings.ToLower(version), "impalad version") { + if strings.EqualFold(server.params.DatabaseType, "kyuubi") { + productName = "Apache Kyuubi" + compatibilityMode = "kyuubi" + driverName = "DBX Kyuubi Go Agent" + } else if strings.EqualFold(server.params.DatabaseType, "impala") || strings.Contains(strings.ToLower(version), "impalad version") { productName = "Apache Impala" compatibilityMode = "impala" driverName = "DBX Impala Go Agent" @@ -573,6 +584,19 @@ func (server *server) getTableDDL(schema, table string) (string, error) { return strings.Join(lines, "\n") + "\n", nil } +func (server *server) getObjectSource(schema, name, objectType string) (objectSource, error) { + source, err := server.getTableDDL(schema, name) + if err != nil { + return objectSource{}, err + } + return objectSource{ + Name: name, + ObjectType: strings.ToUpper(objectType), + Schema: optionalString(schema), + Source: source, + }, nil +} + func (server *server) getExplainInfo(sqlText string) (string, error) { sqlText = trimStatementSQL(sqlText) if sqlText == "" { diff --git a/agents/drivers/hive-go/metadata_test.go b/agents/drivers/hive-go/metadata_test.go index c9bba860b9..a6c114de1c 100644 --- a/agents/drivers/hive-go/metadata_test.go +++ b/agents/drivers/hive-go/metadata_test.go @@ -3,6 +3,7 @@ package main import ( "context" "database/sql/driver" + "encoding/json" "errors" "reflect" "strings" @@ -20,6 +21,77 @@ func TestShowTablesRowName(t *testing.T) { } } +func TestKyuubiConnectionInfoReportsNativeIdentity(t *testing.T) { + behavior := &scriptedBehavior{ + query: func(ctx context.Context, query string) (driver.Rows, error) { + switch query { + case "SELECT VERSION()": + return newScriptedRows(ctx, []string{"version"}, []string{"STRING"}, [][]driver.Value{{"3.5.8"}}), nil + case "SELECT CURRENT_USER()": + return newScriptedRows(ctx, []string{"current_user"}, []string{"STRING"}, [][]driver.Value{{"dbx"}}), nil + default: + return nil, errors.New("unexpected query: " + query) + } + }, + } + server := newScriptedServer(t, behavior) + server.params.DatabaseType = "kyuubi" + server.config.Username = "fallback" + + info, err := server.connectionInfo() + if err != nil { + t.Fatal(err) + } + if info["compatibilityMode"] != "kyuubi" || info["username"] != "dbx" || info["version"] != "3.5.8" { + t.Fatalf("unexpected Kyuubi connection info: %#v", info) + } + databaseInfo, ok := info["databaseInfo"].(map[string]string) + if !ok || databaseInfo["productName"] != "Apache Kyuubi" || databaseInfo["driverName"] != "DBX Kyuubi Go Agent" { + t.Fatalf("unexpected Kyuubi database identity: %#v", info["databaseInfo"]) + } +} + +func TestGetObjectSourceReturnsProtocolObject(t *testing.T) { + behavior := &scriptedBehavior{ + query: func(ctx context.Context, query string) (driver.Rows, error) { + if query != "SHOW CREATE TABLE `dbx_kyuubi_demo`.`high_value_orders`" { + t.Fatalf("unexpected query: %q", query) + } + return newScriptedRows( + ctx, + []string{"createtab_stmt"}, + []string{"STRING"}, + [][]driver.Value{ + {"CREATE VIEW dbx_kyuubi_demo.high_value_orders"}, + {"AS SELECT id, customer, amount FROM dbx_kyuubi_demo.orders WHERE amount >= 50"}, + }, + ), nil + }, + } + server := newScriptedServer(t, behavior) + defer server.disconnect() + + result, _, err := server.dispatch("get_object_source", map[string]json.RawMessage{ + "schema": json.RawMessage(`"dbx_kyuubi_demo"`), + "name": json.RawMessage(`"high_value_orders"`), + "object_type": json.RawMessage(`"VIEW"`), + }) + if err != nil { + t.Fatal(err) + } + source, ok := result.(objectSource) + if !ok { + t.Fatalf("get_object_source returned %T instead of objectSource", result) + } + if source.Name != "high_value_orders" || source.ObjectType != "VIEW" || source.Schema == nil || *source.Schema != "dbx_kyuubi_demo" { + t.Fatalf("unexpected object source metadata: %#v", source) + } + expected := "CREATE VIEW dbx_kyuubi_demo.high_value_orders\nAS SELECT id, customer, amount FROM dbx_kyuubi_demo.orders WHERE amount >= 50\n" + if source.Source != expected { + t.Fatalf("unexpected object source DDL: %q", source.Source) + } +} + func TestListDatabasesUsesShowDatabasesBeforeHiveServerMetadata(t *testing.T) { behavior := &scriptedBehavior{ query: func(ctx context.Context, sql string) (driver.Rows, error) { diff --git a/apps/desktop/public/icons/database/kyuubi.png b/apps/desktop/public/icons/database/kyuubi.png new file mode 100644 index 0000000000000000000000000000000000000000..36c5b798c04bb1337dbcdd83750284a9a79e5023 GIT binary patch literal 13227 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 D^&*Ag literal 0 HcmV?d00001 diff --git a/apps/desktop/src/components/connection/ConnectionDialog.vue b/apps/desktop/src/components/connection/ConnectionDialog.vue index 6bb617f370..1ff7ba37a3 100644 --- a/apps/desktop/src/components/connection/ConnectionDialog.vue +++ b/apps/desktop/src/components/connection/ConnectionDialog.vue @@ -1162,6 +1162,7 @@ const driverProfiles: Record< trino: { type: "trino", port: 8080, user: "", label: "Trino", icon: "trino" }, prestosql: { type: "prestosql", port: 8080, user: "", label: "PrestoSQL", icon: "presto" }, hive: { type: "hive", port: 10000, user: "", label: "Apache Hive", icon: "hive" }, + kyuubi: { type: "kyuubi", port: 10009, user: "", label: "Apache Kyuubi", icon: "kyuubi", urlParams: "auth=NONE" }, impala: { type: "impala", port: 21050, user: "", label: "Apache Impala", icon: "impala", urlParams: "auth=noSasl" }, spark: { type: "spark", port: 10015, user: "", label: "Apache Spark", icon: "spark" }, db2: { type: "db2", port: 50000, user: "db2inst1", label: "IBM DB2", icon: "db2" }, @@ -2416,7 +2417,7 @@ function applyProfile(val: string, preserveConnectionFields = false) { form.value.connection_string = undefined; form.value.url_params = ""; } - resetHiveKerberosFields(profile.type === "hive" || profile.type === "impala" ? form.value : undefined); + resetHiveKerberosFields(profile.type === "hive" || profile.type === "kyuubi" || profile.type === "impala" ? form.value : undefined); } } @@ -2542,7 +2543,7 @@ watch( resetVictoriaMetricsFields(); } resetElasticsearchProxyFields(config.db_type === "elasticsearch" ? config.external_config : undefined); - resetHiveKerberosFields(config.db_type === "hive" || config.db_type === "impala" ? config : undefined); + resetHiveKerberosFields(config.db_type === "hive" || config.db_type === "kyuubi" || config.db_type === "impala" ? config : undefined); resetDamengJvmOptions(config.db_type === "dameng" ? config : undefined); h2ConnectionMode.value = h2ConnectionModeForConfig(config); customColorInput.value = config.color || ""; @@ -2797,6 +2798,7 @@ const iconTypeMap: Record = { trino: "trino", prestosql: "prestosql", hive: "hive", + kyuubi: "kyuubi", impala: "impala", spark: "spark", db2: "db2", @@ -2879,6 +2881,7 @@ const dbOptions: DbOption[] = [ { value: "trino", label: "Trino" }, { value: "prestosql", label: "PrestoSQL" }, { value: "hive", label: "Hive" }, + { value: "kyuubi", label: "Apache Kyuubi" }, { value: "impala", label: "Apache Impala" }, { value: "spark", label: "Apache Spark" }, { value: "db2", label: "DB2" }, @@ -2925,7 +2928,7 @@ const dbCategoryDefinitions: Array<{ { key: "analytics", titleKey: "connection.databaseCategoryAnalytics", - optionValues: ["cloudberry", "clickhouse", "doris", "starrocks", "databend", "selectdb", "databricks", "saphana", "teradata", "vertica", "exasol", "redshift", "snowflake", "trino", "prestosql", "hive", "impala", "spark", "bigquery", "kylin", "dremio"], + optionValues: ["cloudberry", "clickhouse", "doris", "starrocks", "databend", "selectdb", "databricks", "saphana", "teradata", "vertica", "exasol", "redshift", "snowflake", "trino", "prestosql", "hive", "kyuubi", "impala", "spark", "bigquery", "kylin", "dremio"], }, { key: "domestic", @@ -3767,7 +3770,7 @@ function connectionConfigForSubmit(id: string, generatedName = ""): ConnectionCo config.ssl = !!config.ssl || damengSsl.enabled; config.url_params = applyDamengSslUrlParams(config.url_params, config.ssl, damengSsl.sslFilesPath, damengSsl.sslKeystorePassword, damengSsl.sslProtocol); } - if (config.db_type === "hive" || config.db_type === "impala") { + if (config.db_type === "hive" || config.db_type === "kyuubi" || config.db_type === "impala") { if (hiveAuthMode.value === "kerberos" && !hivePrincipal.value.trim()) { throw new Error(t("connection.hiveKerberosPrincipalRequired")); } @@ -7039,7 +7042,7 @@ function openExternalUrl(url: string) {

{{ t("connection.oracleTnsPathHint") }}

-