mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-19 16:16:45 +00:00
fix(oracle): support sequence and pseudo-column completion
This commit is contained in:
@@ -2004,7 +2004,7 @@ func completionRequestHasTableLikeKind(kinds []string) bool {
|
||||
func completionRequestHasRoutineKind(kinds []string) bool {
|
||||
for _, kind := range kinds {
|
||||
switch strings.ToLower(strings.TrimSpace(kind)) {
|
||||
case "routine", "procedure", "function":
|
||||
case "routine", "procedure", "function", "sequence":
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -2450,13 +2450,54 @@ func oracleCompletionSynonymTargetsQuery(targets []oracleCompletionSynonymTarget
|
||||
}
|
||||
}
|
||||
|
||||
func oracleCompletionRoutineObjectTypes(kinds []string) []string {
|
||||
if len(kinds) == 0 {
|
||||
return []string{"'FUNCTION'", "'PROCEDURE'", "'PACKAGE'", "'SEQUENCE'"}
|
||||
}
|
||||
hasRoutine := false
|
||||
hasProc := false
|
||||
hasFunc := false
|
||||
hasSeq := false
|
||||
for _, kind := range kinds {
|
||||
switch strings.ToLower(strings.TrimSpace(kind)) {
|
||||
case "routine":
|
||||
hasRoutine = true
|
||||
case "procedure":
|
||||
hasProc = true
|
||||
case "function":
|
||||
hasFunc = true
|
||||
case "sequence":
|
||||
hasSeq = true
|
||||
}
|
||||
}
|
||||
types := make([]string, 0, 4)
|
||||
if hasRoutine {
|
||||
types = append(types, "'FUNCTION'", "'PROCEDURE'", "'PACKAGE'")
|
||||
} else {
|
||||
if hasProc {
|
||||
types = append(types, "'PROCEDURE'")
|
||||
}
|
||||
if hasFunc {
|
||||
types = append(types, "'FUNCTION'")
|
||||
}
|
||||
}
|
||||
if hasSeq {
|
||||
types = append(types, "'SEQUENCE'")
|
||||
}
|
||||
if len(types) == 0 {
|
||||
return []string{"'FUNCTION'", "'PROCEDURE'", "'PACKAGE'"}
|
||||
}
|
||||
return types
|
||||
}
|
||||
|
||||
func oracleCompletionRoutinesQuery(request completionAssistantRequest, preferredSchema string, limit int) oracleMetadataListQuery {
|
||||
pattern := oracleCompletionLikePattern(request.Mask, request.MatchMode)
|
||||
args := make([]any, 0, 5)
|
||||
baseSQL := `
|
||||
objectTypes := oracleCompletionRoutineObjectTypes(request.ObjectKinds)
|
||||
baseSQL := fmt.Sprintf(`
|
||||
SELECT o.OWNER, o.OBJECT_NAME, o.OBJECT_TYPE, CAST(NULL AS VARCHAR2(128)) AS PARENT_NAME
|
||||
FROM ALL_OBJECTS o
|
||||
WHERE o.OBJECT_TYPE IN ('FUNCTION', 'PROCEDURE', 'PACKAGE')`
|
||||
WHERE o.OBJECT_TYPE IN (%s)`, strings.Join(objectTypes, ", "))
|
||||
args = append(args, pattern)
|
||||
nameParam := len(args)
|
||||
|
||||
|
||||
@@ -2347,6 +2347,30 @@ func TestOracleCompletionRoutinesQueryUsesPublicPackageMetadata(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestOracleCompletionRoutinesQueryIncludesSequences(t *testing.T) {
|
||||
query := oracleCompletionRoutinesQuery(completionAssistantRequest{
|
||||
Schema: "HR",
|
||||
ObjectKinds: []string{"routine", "sequence"},
|
||||
Mask: "SEQ",
|
||||
GlobalSearch: false,
|
||||
}, "HR", 100)
|
||||
sqlText := strings.ToUpper(query.SQL)
|
||||
if !strings.Contains(sqlText, "'SEQUENCE'") {
|
||||
t.Fatalf("routines query should include SEQUENCE when requested: %s", query.SQL)
|
||||
}
|
||||
|
||||
seqOnlyQuery := oracleCompletionRoutinesQuery(completionAssistantRequest{
|
||||
Schema: "HR",
|
||||
ObjectKinds: []string{"sequence"},
|
||||
Mask: "SEQ",
|
||||
GlobalSearch: false,
|
||||
}, "HR", 100)
|
||||
seqSQL := strings.ToUpper(seqOnlyQuery.SQL)
|
||||
if !strings.Contains(seqSQL, "IN ('SEQUENCE')") {
|
||||
t.Fatalf("sequence-only query should only include SEQUENCE: %s", seqOnlyQuery.SQL)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOracleCompletionPackageCandidatesPreserveOverloadsAndReturnTypes(t *testing.T) {
|
||||
rows := []oraclePackageRoutineRow{
|
||||
{
|
||||
|
||||
@@ -1411,6 +1411,12 @@ export function useQueryEditorCompletion(options: QueryEditorCompletionOptions)
|
||||
|
||||
function completionObjectKindsForContext(completionContext: ReturnType<typeof getSqlCompletionContext>): CompletionAssistantObjectKind[] {
|
||||
if (completionContext.contextKind === "exec") return ["procedure"];
|
||||
if (isOracleCompletionDatabase(props.databaseType)) {
|
||||
if (completionContext.suggestColumns && completionContext.referencedTables.length > 0 && !completionContext.qualifier) {
|
||||
return ["function", "sequence"];
|
||||
}
|
||||
return ["routine", "sequence"];
|
||||
}
|
||||
if (completionContext.suggestColumns && completionContext.referencedTables.length > 0 && !completionContext.qualifier) return ["function"];
|
||||
return ["routine"];
|
||||
}
|
||||
|
||||
@@ -484,6 +484,163 @@ describe("PostgreSQL sequence literal completion", () => {
|
||||
expect(items.some((item) => item.label === "order_seq")).toBe(false);
|
||||
});
|
||||
|
||||
it("suggests Oracle sequences in SQL expressions and select lists", () => {
|
||||
const sql = "SELECT ord";
|
||||
const unqualifiedItems = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map(),
|
||||
databaseType: "oracle",
|
||||
dialect: "oracle",
|
||||
currentSchema: "APP",
|
||||
});
|
||||
|
||||
expect(unqualifiedItems).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "ORDER_SEQ",
|
||||
type: "variable",
|
||||
detail: "sequence in APP",
|
||||
apply: "ORDER_SEQ",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
const qualifiedItems = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map(),
|
||||
databaseType: "oracle",
|
||||
dialect: "oracle",
|
||||
});
|
||||
|
||||
expect(qualifiedItems).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "ORDER_SEQ",
|
||||
type: "variable",
|
||||
detail: "sequence in APP",
|
||||
apply: "APP.ORDER_SEQ",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("suggests Oracle sequences under schema qualifier", () => {
|
||||
const sql = "SELECT app.ord";
|
||||
const items = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map(),
|
||||
databaseType: "oracle",
|
||||
dialect: "oracle",
|
||||
});
|
||||
|
||||
expect(items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "ORDER_SEQ",
|
||||
type: "variable",
|
||||
apply: "ORDER_SEQ",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("suggests NEXTVAL and CURRVAL pseudo-columns for Oracle sequences", () => {
|
||||
const sql = "SELECT ORDER_SEQ.";
|
||||
const items = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map(),
|
||||
databaseType: "oracle",
|
||||
dialect: "oracle",
|
||||
});
|
||||
|
||||
expect(items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "NEXTVAL",
|
||||
type: "column",
|
||||
detail: "sequence pseudo-column",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
label: "CURRVAL",
|
||||
type: "column",
|
||||
detail: "sequence pseudo-column",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("suggests NEXTVAL and CURRVAL pseudo-columns for schema-qualified Oracle sequences", () => {
|
||||
const sql = "SELECT APP.ORDER_SEQ.";
|
||||
const items = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map(),
|
||||
databaseType: "oracle",
|
||||
dialect: "oracle",
|
||||
});
|
||||
|
||||
expect(items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "NEXTVAL",
|
||||
type: "column",
|
||||
detail: "sequence pseudo-column",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
label: "CURRVAL",
|
||||
type: "column",
|
||||
detail: "sequence pseudo-column",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("respects keyword case for Oracle sequence pseudo-columns", () => {
|
||||
const sql = "SELECT ORDER_SEQ.n";
|
||||
const items = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map(),
|
||||
databaseType: "oracle",
|
||||
dialect: "oracle",
|
||||
keywordCase: "lower",
|
||||
});
|
||||
|
||||
expect(items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "nextval",
|
||||
apply: "nextval",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("suggests Oracle sequence pseudo-columns in INSERT VALUES clause", () => {
|
||||
const sql = "INSERT INTO orders (id, name) VALUES (ORDER_SEQ.";
|
||||
const items = buildSqlCompletionItems(sql, sql.length, {
|
||||
tables: [{ name: "orders", schema: "APP" }],
|
||||
objects: [{ name: "ORDER_SEQ", schema: "APP", type: "sequence" }],
|
||||
columnsByTable: new Map([["APP.orders", [{ name: "id" }, { name: "name" }]]]),
|
||||
databaseType: "oracle",
|
||||
dialect: "oracle",
|
||||
});
|
||||
|
||||
expect(items).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
label: "NEXTVAL",
|
||||
type: "column",
|
||||
detail: "sequence pseudo-column",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it.each([
|
||||
["SELECT 'order_", "postgres"],
|
||||
["SELECT nextval('order_", "mysql"],
|
||||
|
||||
@@ -1832,6 +1832,14 @@ class SqlCompletionProvider {
|
||||
this.items.push(...buildColumnItems(context, this.input.columnsByTable, this.dialect, this.databaseType, this.input.quoteIdentifiers));
|
||||
this.items.push(...buildSelectAllColumnItems(context, this.input.columnsByTable, this.t, this.dialect, this.databaseType));
|
||||
this.items.push(...buildInsertAllColumnItems(context, this.input.columnsByTable, this.t, this.dialect, this.input.keywordCase));
|
||||
if (isOracleLikeDatabase(this.databaseType) && context.qualifier && !completionQualifierIsReferencedTable(context)) {
|
||||
const profileObjects = driverProfileCompletionObjects(this.input.driverProfile, context);
|
||||
const allObjects = [...(this.input.objects ?? []), ...profileObjects];
|
||||
const hasKnownSequence = allObjects.some((object) => sequenceMatchesQualifier(object, context));
|
||||
if (hasKnownSequence || (!completionQualifierIsKnownTableOrSchema(context, completionTables, this.input.schemas) && (matchesPrefix("NEXTVAL", context.prefix) || matchesPrefix("CURRVAL", context.prefix)))) {
|
||||
this.items.push(...buildOracleSequencePseudoColumnItems(context.prefix, this.input.keywordCase, hasKnownSequence));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const emptyTableNameCompletion = !context.prefix && (context.suggestTables || context.exclusiveTableSuggestions);
|
||||
@@ -4453,8 +4461,14 @@ function buildObjectItems(context: SqlCompletionContext, objects: SqlCompletionO
|
||||
const onlyProcedures = context.contextKind === "exec";
|
||||
const onlyFunctions = context.suggestColumns && context.referencedTables.length > 0 && !context.qualifier;
|
||||
const prioritizeOracleFunctions = isOracleCompletionDatabase(databaseType) && context.statementKind === "select";
|
||||
const allowOracleSequences = isOracleCompletionDatabase(databaseType) && !onlyProcedures;
|
||||
return objects
|
||||
.filter((object) => object.type !== "sequence" && (!onlyProcedures || object.type === "procedure") && (!onlyFunctions || (object.type === "function" && object.name.toLowerCase().startsWith(context.prefix.toLowerCase()))) && objectMatchesCompletionContext(object, context))
|
||||
.filter((object) => {
|
||||
if (object.type === "sequence") {
|
||||
return allowOracleSequences && objectMatchesCompletionContext(object, context);
|
||||
}
|
||||
return (!onlyProcedures || object.type === "procedure") && (!onlyFunctions || (object.type === "function" && object.name.toLowerCase().startsWith(context.prefix.toLowerCase()))) && objectMatchesCompletionContext(object, context);
|
||||
})
|
||||
.map((object) => {
|
||||
const qualifiedByContext = objectIsQualifiedByContext(object, context);
|
||||
const objectInCurrentSchema = !!currentSchema && !!object.schema && normalizeIdentifierPart(object.schema) === normalizeIdentifierPart(currentSchema);
|
||||
@@ -4471,10 +4485,10 @@ function buildObjectItems(context: SqlCompletionContext, objects: SqlCompletionO
|
||||
const baseDedupeKey = object.applyName || (isOracleCompletionDatabase(databaseType) && object.schema) ? applyName : undefined;
|
||||
return {
|
||||
label: object.name,
|
||||
type: "function" as const,
|
||||
type: object.type === "sequence" ? ("variable" as const) : ("function" as const),
|
||||
detail,
|
||||
info: buildRoutineInfo(object),
|
||||
apply: object.type === "trigger" || object.type === "package" ? applyName : buildRoutineApply(applyName, object.signature, includeParams),
|
||||
apply: object.type === "trigger" || object.type === "package" || object.type === "sequence" ? applyName : buildRoutineApply(applyName, object.signature, includeParams),
|
||||
boost: computeBoost(object.name, context.prefix) + typeBoost + schemaBoost,
|
||||
dedupeKey: signature ? `${baseDedupeKey ?? object.name}(${signature})` : baseDedupeKey,
|
||||
// Preserve exact routine matches before the capped candidate list is truncated.
|
||||
@@ -4539,6 +4553,7 @@ function buildRoutineInfo(object: SqlCompletionObject): string | undefined {
|
||||
|
||||
function routineTypeBoost(type: SqlCompletionObject["type"], prioritizeFunctions: boolean): number {
|
||||
if (type === "package") return 1600;
|
||||
if (type === "sequence") return 1500;
|
||||
if (type === "function") return prioritizeFunctions ? 1800 : 900;
|
||||
return prioritizeFunctions ? 900 : 1800;
|
||||
}
|
||||
@@ -4551,6 +4566,55 @@ function completionQualifierIsReferencedTable(context: SqlCompletionContext): bo
|
||||
return context.referencedTables.some((table) => referencedTableMatchesColumnQualifier(table, qualifier, qualifierLower, qualifiedTarget));
|
||||
}
|
||||
|
||||
function sequenceMatchesQualifier(object: SqlCompletionObject, context: SqlCompletionContext): boolean {
|
||||
if (object.type !== "sequence") return false;
|
||||
if (!context.qualifier) return false;
|
||||
const parts = context.qualifierParts?.length ? context.qualifierParts : context.qualifier.split(".").filter(Boolean);
|
||||
if (parts.length === 1) {
|
||||
return normalizeIdentifierPart(object.name) === normalizeIdentifierPart(parts[0]);
|
||||
}
|
||||
if (parts.length === 2) {
|
||||
const [schema, name] = parts;
|
||||
const schemaMatches = !object.schema || normalizeIdentifierPart(object.schema) === normalizeIdentifierPart(schema);
|
||||
return schemaMatches && normalizeIdentifierPart(object.name) === normalizeIdentifierPart(name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function completionQualifierIsKnownTableOrSchema(context: SqlCompletionContext, tables: SqlCompletionTable[], schemas?: string[]): boolean {
|
||||
if (!context.qualifier) return false;
|
||||
const parts = context.qualifierParts?.length ? context.qualifierParts : context.qualifier.split(".").filter(Boolean);
|
||||
if (parts.length === 1) {
|
||||
const name = normalizeIdentifierPart(parts[0]);
|
||||
if (schemas?.some((s) => normalizeIdentifierPart(s) === name)) return true;
|
||||
if (tables.some((t) => normalizeIdentifierPart(t.name) === name)) return true;
|
||||
return false;
|
||||
}
|
||||
if (parts.length === 2) {
|
||||
const [schema, table] = parts;
|
||||
if (tables.some((t) => normalizeIdentifierPart(t.name) === normalizeIdentifierPart(table) && (!t.schema || normalizeIdentifierPart(t.schema) === normalizeIdentifierPart(schema)))) return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function buildOracleSequencePseudoColumnItems(prefix: string, keywordCase?: SqlKeywordCase, hasKnownSequence = false): SqlCompletionItem[] {
|
||||
const pseudoColumns = ["NEXTVAL", "CURRVAL"] as const;
|
||||
return pseudoColumns
|
||||
.filter((col) => matchesPrefix(col, prefix))
|
||||
.map((col) => {
|
||||
const label = applySqlKeywordCase(col, keywordCase);
|
||||
const isNextVal = col === "NEXTVAL";
|
||||
return {
|
||||
label,
|
||||
type: "column" as const,
|
||||
detail: "sequence pseudo-column",
|
||||
apply: label,
|
||||
boost: computeBoost(col, prefix) + (hasKnownSequence ? (isNextVal ? 2200 : 2100) : isNextVal ? 1200 : 1100),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function objectIsQualifiedByContext(object: SqlCompletionObject, context: SqlCompletionContext): boolean {
|
||||
if (!context.qualifier || !object.parentName) return false;
|
||||
const qualifier = context.qualifier.toLowerCase();
|
||||
@@ -4562,6 +4626,13 @@ function objectIsQualifiedByContext(object: SqlCompletionObject, context: SqlCom
|
||||
|
||||
function objectMatchesCompletionContext(object: SqlCompletionObject, context: SqlCompletionContext): boolean {
|
||||
if (context.oracleTableFunctionContext && object.type !== "function") return false;
|
||||
if (object.type === "sequence") {
|
||||
if (context.qualifier) {
|
||||
const qualifier = context.qualifier.toLowerCase();
|
||||
return !!object.schema && object.schema.toLowerCase() === qualifier && matchesPrefix(object.name, context.prefix);
|
||||
}
|
||||
return matchesPrefix(object.name, context.prefix);
|
||||
}
|
||||
if (context.qualifier) {
|
||||
const qualifier = context.qualifier.toLowerCase();
|
||||
const qualifierParts = qualifier.split(".").filter(Boolean);
|
||||
|
||||
@@ -1625,6 +1625,51 @@ describe("connectionStore completion assistant", () => {
|
||||
expect(objects).toEqual([expect.objectContaining({ name: "CALCULATE_BONUS", schema: "HR", type: "function", parentSchema: "HR", parentName: "PAYROLL", dataType: undefined, applyName: "HR.CALCULATE_BONUS", boost: 0 })]);
|
||||
});
|
||||
|
||||
it("maps Oracle sequence objects from completion assistant", async () => {
|
||||
const completionAssistantSearch = vi.fn().mockResolvedValue({
|
||||
candidates: [{ name: "ORDER_SEQ", kind: "sequence", schema: "HR", data_type: "SEQUENCE" }],
|
||||
incomplete: false,
|
||||
fallback_used: false,
|
||||
});
|
||||
|
||||
vi.doMock("@/lib/backend/tauriRuntime", () => ({ isTauriRuntime: () => false }));
|
||||
vi.doMock("@/lib/backend/api", () => ({
|
||||
checkConnectionHealth: vi.fn().mockResolvedValue(undefined),
|
||||
completionAssistantSearch,
|
||||
listObjects: vi.fn().mockResolvedValue([]),
|
||||
}));
|
||||
|
||||
const { useConnectionStore } = await import("@/stores/connectionStore");
|
||||
const store = useConnectionStore();
|
||||
store.connections = [oracleConnection()];
|
||||
store.connectedIds.add("oracle-1");
|
||||
|
||||
const objects = await store.listCompletionObjects("oracle-1", "ORCL", "ORDER", 20, "HR", undefined, false, "APP", ["routine", "sequence"]);
|
||||
|
||||
expect(completionAssistantSearch).toHaveBeenCalledWith(expect.objectContaining({ object_kinds: ["routine", "sequence"], mask: "ORDER", schema: "APP" }));
|
||||
expect(objects).toEqual([expect.objectContaining({ name: "ORDER_SEQ", schema: "HR", type: "sequence", dataType: undefined, applyName: "HR.ORDER_SEQ" })]);
|
||||
});
|
||||
|
||||
it("maps Oracle sequence objects from listObjects in fallback path", async () => {
|
||||
const listCompletionObjects = vi.fn().mockResolvedValue([{ name: "ORDER_SEQ", object_type: "SEQUENCE", schema: "HR" }]);
|
||||
|
||||
vi.doMock("@/lib/backend/tauriRuntime", () => ({ isTauriRuntime: () => false }));
|
||||
vi.doMock("@/lib/backend/api", () => ({
|
||||
checkConnectionHealth: vi.fn().mockResolvedValue(undefined),
|
||||
completionAssistantSearch: vi.fn().mockRejectedValue(new Error("assistant disabled")),
|
||||
listCompletionObjects,
|
||||
}));
|
||||
|
||||
const { useConnectionStore } = await import("@/stores/connectionStore");
|
||||
const store = useConnectionStore();
|
||||
store.connections = [oracleConnection()];
|
||||
store.connectedIds.add("oracle-1");
|
||||
|
||||
const objects = await store.listCompletionObjects("oracle-1", "ORCL", "ORDER", 20, "HR", undefined, false, "APP", ["routine", "sequence"]);
|
||||
|
||||
expect(objects).toEqual([expect.objectContaining({ name: "ORDER_SEQ", schema: "HR", type: "sequence" })]);
|
||||
});
|
||||
|
||||
it("loads PostgreSQL routines by prefix and preserves return metadata", async () => {
|
||||
const completionAssistantSearch = vi.fn().mockResolvedValue({
|
||||
candidates: [{ name: "st_area", kind: "function", schema: "public", data_type: "double precision", comment: "Returns an area" }],
|
||||
|
||||
@@ -8263,7 +8263,7 @@ export const useConnectionStore = defineStore("connection", () => {
|
||||
const candidateType = candidate.data_type?.toUpperCase();
|
||||
const type = candidate.kind === "procedure" ? "procedure" : candidate.kind === "function" ? "function" : candidate.kind === "sequence" ? "sequence" : candidate.kind === "object" && candidateType === "PACKAGE" ? "package" : null;
|
||||
if (!type) return null;
|
||||
const dataType = candidate.data_type && !["FUNCTION", "PROCEDURE", "PACKAGE"].includes(candidateType ?? "") ? candidate.data_type : undefined;
|
||||
const dataType = candidate.data_type && !["FUNCTION", "PROCEDURE", "PACKAGE", "SEQUENCE"].includes(candidateType ?? "") ? candidate.data_type : undefined;
|
||||
return {
|
||||
name: candidate.name,
|
||||
schema: candidate.schema ?? undefined,
|
||||
@@ -9204,7 +9204,7 @@ export const useConnectionStore = defineStore("connection", () => {
|
||||
|
||||
function toSqlCompletionObject(object: ObjectInfo): SqlCompletionObject | null {
|
||||
const objectType = object.object_type.toUpperCase();
|
||||
const type = objectType.includes("PROCEDURE") ? "procedure" : objectType.includes("FUNCTION") ? "function" : objectType.includes("TRIGGER") ? "trigger" : objectType.includes("PACKAGE") ? "package" : null;
|
||||
const type = objectType.includes("PROCEDURE") ? "procedure" : objectType.includes("FUNCTION") ? "function" : objectType.includes("TRIGGER") ? "trigger" : objectType.includes("PACKAGE") ? "package" : objectType.includes("SEQUENCE") ? "sequence" : null;
|
||||
if (!type) return null;
|
||||
return {
|
||||
name: object.name,
|
||||
|
||||
Reference in New Issue
Block a user