fix(postgres): preserve overloaded routine signatures
This commit is contained in:
parent
4b2a6c971a
commit
727290fa32
|
|
@ -1653,7 +1653,7 @@ async function handleQuickOpenSelect(item: any) {
|
|||
|
||||
const schema = item.schema || item.database;
|
||||
try {
|
||||
const result = await api.getObjectSource(item.connectionId, item.database, schema, item.objectName || item.tableName, objectType);
|
||||
const result = await api.getObjectSource(item.connectionId, item.database, schema, item.objectName || item.tableName, objectType, item.signature);
|
||||
const tabId = queryStore.createTab(item.connectionId, item.database, `Source - ${item.objectName || item.tableName}`);
|
||||
queryStore.updateSql(tabId, result.source);
|
||||
if (item.type !== "sequence" && item.type !== "trigger" && item.type !== "type" && item.type !== "type-body") {
|
||||
|
|
@ -1661,6 +1661,7 @@ async function handleQuickOpenSelect(item: any) {
|
|||
schema,
|
||||
name: item.objectName || item.tableName,
|
||||
objectType,
|
||||
signature: item.signature,
|
||||
});
|
||||
}
|
||||
queryStore.markTabClean(queryStore.tabs.find((tab) => tab.id === tabId));
|
||||
|
|
|
|||
|
|
@ -527,24 +527,24 @@ async function handleSelectObject(obj: SchemaDiffObject) {
|
|||
try {
|
||||
// For "create" objects: source has it, target doesn't → fetch source DDL
|
||||
if (obj.operationType === "create" && !obj.sourceDdl) {
|
||||
const result = await api.getObjectSource(sourceConnectionId.value, sourceDatabase.value, sourceSchema.value, obj.name, objectType);
|
||||
const result = await api.getObjectSource(sourceConnectionId.value, sourceDatabase.value, sourceSchema.value, obj.name, objectType, obj.arguments);
|
||||
if (result?.source) obj.sourceDdl = result.source;
|
||||
}
|
||||
|
||||
// For "delete" objects: target has it, source doesn't → fetch target DDL
|
||||
if (obj.operationType === "delete" && !obj.targetDdl) {
|
||||
const result = await api.getObjectSource(targetConnectionId.value, targetDatabase.value, targetSchema.value, obj.name, objectType);
|
||||
const result = await api.getObjectSource(targetConnectionId.value, targetDatabase.value, targetSchema.value, obj.name, objectType, obj.arguments);
|
||||
if (result?.source) obj.targetDdl = result.source;
|
||||
}
|
||||
|
||||
// For "modify" objects: fetch whichever side is missing
|
||||
if (obj.operationType === "modify") {
|
||||
if (!obj.sourceDdl) {
|
||||
const result = await api.getObjectSource(sourceConnectionId.value, sourceDatabase.value, sourceSchema.value, obj.name, objectType);
|
||||
const result = await api.getObjectSource(sourceConnectionId.value, sourceDatabase.value, sourceSchema.value, obj.name, objectType, obj.arguments);
|
||||
if (result?.source) obj.sourceDdl = result.source;
|
||||
}
|
||||
if (!obj.targetDdl) {
|
||||
const result = await api.getObjectSource(targetConnectionId.value, targetDatabase.value, targetSchema.value, obj.name, objectType);
|
||||
const result = await api.getObjectSource(targetConnectionId.value, targetDatabase.value, targetSchema.value, obj.name, objectType, obj.arguments);
|
||||
if (result?.source) obj.targetDdl = result.source;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1031,7 +1031,7 @@ async function openSource(row: ObjectBrowserRow) {
|
|||
const database = props.database;
|
||||
const schema = row.schema || selectedSchema.value || database;
|
||||
try {
|
||||
const result = await api.getObjectSource(connectionId, database, schema, row.name, row.type as ObjectSourceKind);
|
||||
const result = await api.getObjectSource(connectionId, database, schema, row.name, row.type as ObjectSourceKind, row.signature ?? undefined);
|
||||
if (sidePanelGuard.isStale(epoch)) return;
|
||||
sourceCanEdit.value = result.editable !== false && !["SEQUENCE", "TRIGGER", "TYPE", "TYPE_BODY"].includes(row.type);
|
||||
const editable = sourceCanEdit.value
|
||||
|
|
@ -1154,7 +1154,7 @@ async function confirmRename() {
|
|||
try {
|
||||
const schema = row.schema || selectedSchema.value || props.database;
|
||||
if (supportsSourceBackedRoutineRename(effectiveDatabaseType.value, row.type as ObjectSourceKind)) {
|
||||
const source = await api.getObjectSource(props.connection.id, props.database, schema, row.name, row.type as ObjectSourceKind);
|
||||
const source = await api.getObjectSource(props.connection.id, props.database, schema, row.name, row.type as ObjectSourceKind, row.signature ?? undefined);
|
||||
const statements = await buildRoutineRenameObjectSourceStatements({
|
||||
databaseType: effectiveDatabaseType.value,
|
||||
objectType: row.type as ObjectSourceKind,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { appendTableTreeLoadMoreNode, buildSimpleObjectTreeNodes, buildTableTreeNodes, mergeTableTreePageChildren, tablePartitionGroups, withoutTableTreeLoadMoreNodes } from "@/lib/table/tableTree";
|
||||
import { appendTableTreeLoadMoreNode, buildGroupedObjectTreeNodes, buildSimpleObjectTreeNodes, buildTableTreeNodes, mergeTableTreePageChildren, tablePartitionGroups, withoutTableTreeLoadMoreNodes } from "@/lib/table/tableTree";
|
||||
import type { ObjectInfo, TableInfo, TreeNode } from "@/types/database";
|
||||
|
||||
const context = {
|
||||
|
|
@ -27,6 +27,24 @@ describe("PostgreSQL overloaded routines", () => {
|
|||
);
|
||||
expect(new Set(nodes.map((node) => node.id)).size).toBe(3);
|
||||
});
|
||||
|
||||
it("keeps grouped routine nodes distinct by identity arguments", () => {
|
||||
const objects: ObjectInfo[] = [
|
||||
{ name: "calc", object_type: "FUNCTION", schema: "public", signature: "integer" },
|
||||
{ name: "calc", object_type: "FUNCTION", schema: "public", signature: "integer, integer" },
|
||||
{ name: "calc", object_type: "FUNCTION", schema: "public", signature: "numeric" },
|
||||
];
|
||||
|
||||
const groups = buildGroupedObjectTreeNodes({ ...context, schema: "public", objects });
|
||||
const functionGroup = groups.find((node) => node.type === "group-functions");
|
||||
|
||||
expect(functionGroup?.children?.map((node) => ({ label: node.label, objectName: node.objectName, signature: node.signature }))).toEqual([
|
||||
{ label: "calc(integer)", objectName: "calc", signature: "integer" },
|
||||
{ label: "calc(integer, integer)", objectName: "calc", signature: "integer, integer" },
|
||||
{ label: "calc(numeric)", objectName: "calc", signature: "numeric" },
|
||||
]);
|
||||
expect(new Set(functionGroup?.children?.map((node) => node.id) ?? []).size).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe("programmable database objects", () => {
|
||||
|
|
|
|||
|
|
@ -668,7 +668,8 @@ export function buildGroupedObjectTreeNodes({ nodeId, connectionId, database, sc
|
|||
if (!name) continue;
|
||||
const t = normalizeObjectType(obj.object_type);
|
||||
const objectSchema = obj.schema ? normalizeDatabaseObjectName(obj.schema) : schema || "";
|
||||
const key = `${t}\0${objectSchema.toLowerCase()}\0${name.toLowerCase()}`;
|
||||
const signature = (obj.signature ?? "").trim();
|
||||
const key = `${t}\0${objectSchema.toLowerCase()}\0${name.toLowerCase()}\0${signature.toLowerCase()}`;
|
||||
if (seen.has(key)) continue;
|
||||
seen.add(key);
|
||||
const arr = buckets.get(t) ?? [];
|
||||
|
|
@ -695,10 +696,14 @@ export function buildGroupedObjectTreeNodes({ nodeId, connectionId, database, sc
|
|||
const objectType = normalizeObjectType(obj.object_type);
|
||||
const childType = typeof def.childType === "function" ? def.childType(objectType) : def.childType;
|
||||
const objectTypeSuffix = objectType === "PACKAGE" || objectType === "PACKAGE_BODY" || objectType === "TYPE" || objectType === "TYPE_BODY" ? `:${objectType}` : "";
|
||||
const signature = obj.signature?.trim() || "";
|
||||
const signatureIdPart = signature && (objectType === "FUNCTION" || objectType === "PROCEDURE") ? `:${signature}` : "";
|
||||
return {
|
||||
id: `${nodeId}:${def.key}:${childSchema ? `${childSchema}:` : ""}${obj.name}${objectTypeSuffix}`,
|
||||
label: obj.name,
|
||||
id: `${nodeId}:${def.key}:${childSchema ? `${childSchema}:` : ""}${obj.name}${signatureIdPart}${objectTypeSuffix}`,
|
||||
label: signature && (objectType === "FUNCTION" || objectType === "PROCEDURE") ? `${obj.name}(${signature})` : obj.name,
|
||||
type: childType,
|
||||
objectName: obj.name,
|
||||
signature: signature || undefined,
|
||||
comment: obj.comment,
|
||||
valid: obj.valid ?? undefined,
|
||||
connectionId,
|
||||
|
|
|
|||
|
|
@ -847,6 +847,7 @@ export interface QueryTab {
|
|||
schema?: string;
|
||||
name: string;
|
||||
objectType: ObjectSourceKind;
|
||||
signature?: string;
|
||||
};
|
||||
tableMeta?: {
|
||||
schema?: string;
|
||||
|
|
|
|||
Loading…
Reference in New Issue