mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-21 08:13:34 +00:00
fix(gbase8s): omit owner qualifier in table admin SQL
This commit is contained in:
@@ -72,7 +72,7 @@ import type { ColumnInfo, ConnectionConfig, ConstraintInfo, ForeignKeyInfo, Inde
|
||||
import { sortTablesByFkDependency, type TableWithFk } from "@/lib/table/tableDependencySort";
|
||||
import { isSchemaAware, supportsTableVacuum, supportsTransfer } from "@/lib/database/databaseCapabilities";
|
||||
import { supportsAiAssistantContext, supportsSchemaDiagram, supportsTableImport, supportsTableStructureEditing, supportsTableTruncate } from "@/lib/database/databaseFeatureSupport";
|
||||
import { codeMirrorSqlDialect, connectionObjectTreeNodeSchema, connectionUsesDatabaseObjectTreeMode, effectiveDatabaseTypeForConnection, objectListSchemaForConnection, tableStructureDatabaseTypeForConnection } from "@/lib/database/jdbcDialect";
|
||||
import { codeMirrorSqlDialect, connectionObjectTreeNodeSchema, connectionTableSqlSchema, connectionUsesDatabaseObjectTreeMode, effectiveDatabaseTypeForConnection, objectListSchemaForConnection, tableStructureDatabaseTypeForConnection } from "@/lib/database/jdbcDialect";
|
||||
import { getTableMetadataCapabilities, type TableMetadataCapabilities } from "@/lib/table/tableMetadataCapabilities";
|
||||
import { constraintsForConstraintsTab } from "@/lib/table/constraintPresentation";
|
||||
import { buildTableSelectSql } from "@/lib/table/tableSelectSql";
|
||||
@@ -2531,7 +2531,7 @@ async function confirmPasteTable() {
|
||||
function tableAdminSqlOptions(row: ObjectBrowserRow, options?: { cascade?: boolean }): TableAdminSqlOptions {
|
||||
const result: TableAdminSqlOptions = {
|
||||
databaseType: effectiveDatabaseType.value,
|
||||
schema: row.schema || selectedSchema.value,
|
||||
schema: connectionTableSqlSchema(props.connection, row.schema || selectedSchema.value),
|
||||
tableName: row.name,
|
||||
// Cloud Spanner's dialect decides the quote; the static per-type mapping cannot.
|
||||
identifierQuote: connectionStore.connectionIdentifierQuote?.(props.connection.id),
|
||||
|
||||
@@ -162,7 +162,7 @@ import { buildViewDdl } from "@/lib/table/viewDdl";
|
||||
import { formatSqlForDisplay, sqlFormatDialectForDbType } from "@/lib/sql/sqlFormatter";
|
||||
import { omitDdlIdentifierQuotes } from "@/lib/sql/ddlDisplay";
|
||||
import { getTableStructureCapabilities } from "@/lib/table/tableStructureCapabilities";
|
||||
import { connectionObjectTreeNodeSchema, connectionObjectTreeQuerySchema, connectionUsesDatabaseObjectTreeMode, effectiveDatabaseTypeForConnection, tableStructureDatabaseTypeForConnection } from "@/lib/database/jdbcDialect";
|
||||
import { connectionObjectTreeNodeSchema, connectionObjectTreeQuerySchema, connectionTableSqlSchema, connectionUsesDatabaseObjectTreeMode, effectiveDatabaseTypeForConnection, tableStructureDatabaseTypeForConnection } from "@/lib/database/jdbcDialect";
|
||||
import { hasTreeNodeDatabaseContext } from "@/lib/sidebar/treeNodeContext";
|
||||
import {
|
||||
defaultPasteTableMode,
|
||||
@@ -2798,11 +2798,13 @@ function batchTruncateConfirmMessage(): string {
|
||||
|
||||
async function dropSqlForTreeNode(node: TreeNode, options?: { cascade?: boolean }): Promise<string | null> {
|
||||
if (node.type === "table" && node.connectionId && node.database) {
|
||||
const config = connectionStore.getConfig(node.connectionId);
|
||||
return buildDropTableSql({
|
||||
databaseType: databaseTypeForNode(node),
|
||||
schema: node.schema,
|
||||
schema: connectionTableSqlSchema(config, node.schema),
|
||||
tableName: node.label,
|
||||
cascade: options?.cascade && supportsDropTableCascade(databaseTypeForNode(node)),
|
||||
identifierQuote: connectionStore.connectionIdentifierQuote?.(node.connectionId),
|
||||
});
|
||||
}
|
||||
const objectOptions = dropObjectSqlOptionsForNode(node);
|
||||
|
||||
+13
-4
@@ -1,6 +1,6 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { shallowRef } from "vue";
|
||||
import type { TreeNode } from "@/types/database";
|
||||
import type { ConnectionConfig, DatabaseType, TreeNode } from "@/types/database";
|
||||
import { dropTableCascade, dropTablePreviewSql, emptyTablePreviewSql, sidebarDangerRunningCancel, sidebarDangerRunningExecutionId, sidebarDangerTarget, truncateTableCascade, truncateTablePreviewSql } from "@/components/sidebar/sidebarTreeDialogState";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
@@ -49,19 +49,20 @@ function tableNode(database: string | null | undefined): TreeNode {
|
||||
} as TreeNode;
|
||||
}
|
||||
|
||||
function runtime(database: string | null | undefined) {
|
||||
function runtime(database: string | null | undefined, config: Pick<ConnectionConfig, "db_type"> & Partial<Pick<ConnectionConfig, "driver_profile">> = { db_type: "saphana" }, databaseType: DatabaseType = "saphana") {
|
||||
const node = tableNode(database);
|
||||
const activeNode = shallowRef(node);
|
||||
const connectionStore = {
|
||||
ensureConnected: mocks.ensureConnected,
|
||||
getConfig: () => config,
|
||||
removeTreeNode: mocks.removeTreeNode,
|
||||
} as any;
|
||||
const feature = useSidebarTableMutationRuntime({
|
||||
activeNode,
|
||||
releaseActiveNodeReference: mocks.releaseActiveNodeReference,
|
||||
connectionStore,
|
||||
currentDatabaseType: () => "saphana",
|
||||
databaseTypeForNode: () => "saphana",
|
||||
currentDatabaseType: () => databaseType,
|
||||
databaseTypeForNode: () => databaseType,
|
||||
executeWithProductionGuard: mocks.executeWithProductionGuard,
|
||||
closeDroppedTableObjectTabsForNode: mocks.closeDroppedTableObjectTabsForNode,
|
||||
refreshMutatedTableDataTabsForNode: mocks.refreshMutatedTableDataTabsForNode,
|
||||
@@ -121,6 +122,14 @@ describe("useSidebarTableMutationRuntime SAP HANA schema-scoped actions", () =>
|
||||
expect(mocks.releaseActiveNodeReference).toHaveBeenCalledWith([node.id]);
|
||||
});
|
||||
|
||||
it("omits the GBase 8s metadata owner from generated table SQL", async () => {
|
||||
const { feature } = runtime("tenant", { db_type: "gbase", driver_profile: "gbase8s" }, "informix");
|
||||
|
||||
await feature.confirmDropTable();
|
||||
|
||||
expect(mocks.buildDropTableSql).toHaveBeenCalledWith(expect.objectContaining({ databaseType: "informix", schema: undefined, tableName: "ORDERS" }));
|
||||
});
|
||||
|
||||
it.each(["confirmEmptyTable", "confirmTruncateTable"] as const)("refreshes data tabs after %s", async (action) => {
|
||||
const { feature, node } = runtime("");
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
type VacuumTableSqlOptions,
|
||||
} from "@/lib/database/dbAdminSql";
|
||||
import { isSqlServerLinkedNode } from "@/lib/database/sqlServerLinkedServers";
|
||||
import { connectionTableSqlSchema } from "@/lib/database/jdbcDialect";
|
||||
import { isQueryTimeoutErrorMessage } from "@/lib/sql/queryError";
|
||||
import { uuid } from "@/lib/common/utils";
|
||||
import * as api from "@/lib/backend/api";
|
||||
@@ -74,9 +75,10 @@ export function useSidebarTableMutationRuntime(options: SidebarTableMutationRunt
|
||||
const supportsMysqlAutoIncrement = computed(() => activeNode.value.type === "table" && supportsNativeMysqlAutoIncrement(activeNode.value.connectionId ? connectionStore.getConfig(activeNode.value.connectionId) : undefined));
|
||||
|
||||
function tableAdminSqlOptions(optionsOverride?: { cascade?: boolean }): TableAdminSqlOptions {
|
||||
const config = activeNode.value.connectionId ? connectionStore.getConfig(activeNode.value.connectionId) : undefined;
|
||||
const result: TableAdminSqlOptions = {
|
||||
databaseType: currentDatabaseType(),
|
||||
schema: activeNode.value.schema,
|
||||
schema: connectionTableSqlSchema(config, activeNode.value.schema),
|
||||
tableName: activeNode.value.label,
|
||||
// Cloud Spanner's two dialects quote differently, so admin SQL needs the quote the connected
|
||||
// agent reported rather than the static per-type mapping.
|
||||
@@ -87,9 +89,10 @@ export function useSidebarTableMutationRuntime(options: SidebarTableMutationRunt
|
||||
}
|
||||
|
||||
function tableAdminSqlOptionsForNode(node: TreeNode, optionsOverride?: { cascade?: boolean }): TableAdminSqlOptions {
|
||||
const config = node.connectionId ? connectionStore.getConfig(node.connectionId) : undefined;
|
||||
const result: TableAdminSqlOptions = {
|
||||
databaseType: databaseTypeForNode(node),
|
||||
schema: node.schema,
|
||||
schema: connectionTableSqlSchema(config, node.schema),
|
||||
tableName: node.label,
|
||||
identifierQuote: connectionStore.connectionIdentifierQuote?.(node.connectionId),
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
connectionQueryExecutionSchema,
|
||||
connectionShouldDiscoverJdbcSchemas,
|
||||
connectionShouldLoadIdentifierQuote,
|
||||
connectionTableSqlSchema,
|
||||
connectionUsesConnectionRootSchemaMode,
|
||||
connectionUsesDatabaseObjectTreeMode,
|
||||
effectiveDatabaseTypeForConnection,
|
||||
@@ -176,6 +177,12 @@ describe("jdbc dialect inference", () => {
|
||||
expect(connectionShouldDiscoverJdbcSchemas({ db_type: "gbase", driver_profile: "gbase8a" })).toBe(false);
|
||||
});
|
||||
|
||||
it("omits the metadata owner from GBase 8s table SQL", () => {
|
||||
expect(connectionTableSqlSchema({ db_type: "gbase", driver_profile: "gbase8s" }, "gbasedbt")).toBeUndefined();
|
||||
expect(connectionTableSqlSchema({ db_type: "gbase", driver_profile: "gbase8a" }, "analytics")).toBe("analytics");
|
||||
expect(connectionTableSqlSchema({ db_type: "informix", driver_profile: "informix" }, "informix")).toBe("informix");
|
||||
});
|
||||
|
||||
it("recognizes GaussDB reached through PostgreSQL-compatible JDBC drivers", () => {
|
||||
const connection = {
|
||||
db_type: "jdbc" as const,
|
||||
|
||||
@@ -312,6 +312,12 @@ export function connectionObjectTreeNodeSchema(connection: JdbcDialectConnection
|
||||
return isSchemaAware(type) ? schema || database : undefined;
|
||||
}
|
||||
|
||||
/** GBase 8s reports the table owner as a schema, but does not accept it in table DML/DDL names. */
|
||||
export function connectionTableSqlSchema(connection: JdbcDialectConnection | undefined, schema?: string): string | undefined {
|
||||
if (connection?.db_type === "gbase" && isGbase8sProfile(connection.driver_profile)) return undefined;
|
||||
return schema;
|
||||
}
|
||||
|
||||
/** Maps a database type to the corresponding CodeMirror SQL dialect name used by QueryEditor and DdlViewDialog. */
|
||||
export function codeMirrorSqlDialect(dbType: DatabaseType | undefined): "mysql" | "postgres" | "sqlserver" {
|
||||
if (dbType === "postgres" || dbType === "gaussdb" || dbType === "kwdb" || dbType === "opengauss") return "postgres";
|
||||
|
||||
Reference in New Issue
Block a user