fix(dameng): keep object tab schema across reloads

Closes #8301
This commit is contained in:
t8y2 committed 2026-09-08 12:07:49 +08:00
1 parent ab5fa637e0
commit 9392a68832
4 files changed
+111 -4

No files matched your search

@@ -20,6 +20,7 @@ import {
gaussdbTargetServerType,
inferJdbcDialect,
metadataSchemaForConnection,
objectListSchemaForConnection,
setGaussdbConnectionMode,
setGaussdbCountQueryDop,
setGaussdbIdentifierQuoteStyle,
@@ -488,3 +489,28 @@ describe("object tree node schema", () => {
expect(connectionDatabaseMetadataSchema({ db_type: "spanner" }, "projects/p/instances/i/databases/db", "public")).toBe("public");
});
});
describe("object list schema", () => {
it("falls back to the uppercased Dameng connection username when no schema is selected", () => {
// Dameng's object SQL filters on a fixed WHERE o.OWNER = ?, so a blank schema
// matches nothing and the object tab renders empty (#8301).
expect(objectListSchemaForConnection({ db_type: "dameng", username: "sales_app" })).toBe("SALES_APP");
});
it("applies the Dameng fallback to generic jdbc:dm connections", () => {
expect(objectListSchemaForConnection({ db_type: "jdbc", connection_string: "jdbc:dm://localhost:5236", username: "sysdba" })).toBe("SYSDBA");
});
it("keeps an explicitly selected schema for Dameng", () => {
expect(objectListSchemaForConnection({ db_type: "dameng", username: "sales_app" }, "OTHER_SCHEMA")).toBe("OTHER_SCHEMA");
});
it("returns a blank schema for Dameng when the connection has no usable username", () => {
expect(objectListSchemaForConnection({ db_type: "dameng" })).toBe("");
expect(objectListSchemaForConnection({ db_type: "dameng", username: " " })).toBe("");
});
it.each(["oracle", "oceanbase-oracle", "postgres", "mysql"] as const)("does not fall back to the username for %s", (dbType) => {
expect(objectListSchemaForConnection({ db_type: dbType, username: "app_user" })).toBe("");
});
});
+16 -1
View File
@@ -2,7 +2,7 @@ import type { ConnectionConfig, DatabaseType } from "@/types/database";
import { isSchemaAware, spannerObjectTreeSchema, usesDatabaseObjectTreeMode, usesTreeSchemaMode } from "@/lib/database/databaseFeatureSupport";
import type { CodeMirrorSqlDialectName } from "@/lib/editor/codemirrorSqlDialect";
type JdbcDialectConnection = Partial<Pick<ConnectionConfig, "db_type" | "driver_profile" | "driver_label" | "connection_string" | "url_params" | "jdbc_driver_class" | "jdbc_driver_paths" | "database_info" | "external_config">>;
type JdbcDialectConnection = Partial<Pick<ConnectionConfig, "db_type" | "driver_profile" | "driver_label" | "connection_string" | "url_params" | "jdbc_driver_class" | "jdbc_driver_paths" | "database_info" | "external_config" | "username">>;
export type GaussdbIdentifierQuoteStyle = "auto" | "double" | "backtick";
export type GaussdbConnectionMode = "native" | "m-jdbc";
@@ -264,6 +264,21 @@ export function connectionObjectTreeQuerySchema(connection: JdbcDialectConnectio
return schema || database;
}
/**
* Schema sent with object-list (listObjects) requests. Dameng's object SQL
* filters on a fixed `WHERE o.OWNER = ?`, so a blank schema matches nothing and
* the object tab renders empty when the schema could not be resolved (#8301).
* Mirror the completion path (connectionStore.listCompletionColumns) and fall
* back to the connection username — uppercased, the Oracle-family storage
* convention for unquoted Dameng users. Other Oracle-family types keep the
* blank schema so the backend resolves the current schema itself.
*/
export function objectListSchemaForConnection(connection: JdbcDialectConnection | undefined, schema?: string): string {
if (schema) return schema;
if (effectiveDatabaseTypeForConnection(connection) !== "dameng") return "";
return connection?.username?.trim().toUpperCase() || "";
}
/**
* Metadata schema for query paths that treat the database name as the schema when a
* connection exposes no schema level (MySQL, HBase, and the other flat engines).