fix(oracle): restore alias completion and DIP visibility

This commit is contained in:
zipg authored and GitHub committed 2026-07-22 01:14:56 +08:00
1 parent 785c4098d1
commit 25e799c34b
18 files changed
+394 -61

No files matched your search

@@ -43,6 +43,7 @@ import { mergeSqlSemanticReferenceAnalysis, resolveSqlSemanticNavigationTarget }
import { buildElasticsearchCompletionItemsFromContext, getElasticsearchCompletionContext, getElasticsearchCompletionResultValidFor, shouldAutoOpenElasticsearchCompletion, type ElasticsearchCompletionItem } from "@/lib/elasticsearch/elasticsearchCompletion";
import { buildMongoCompletionItemsFromContext, getMongoCompletionContext, getMongoCompletionResultValidFor, mongoCompletionNeedsCollections, mongoCompletionNeedsFields, shouldAutoOpenMongoCompletion, type MongoCompletionItem } from "@/lib/mongo/mongoCompletion";
import { resolveSqlCompletionRoutineLookupTarget, resolveSqlCompletionTableLookupTarget } from "@/lib/sql/sqlCompletionLookupTarget";
import { usesOracleSessionCompletionColumns as shouldUseOracleSessionCompletionColumns } from "@/lib/sql/oracleCompletionSession";
import { extractIdentifierDetailsAt, isSqlKeyword, matchTable, mergeSqlObjectNavigationType, splitQualifiedIdentifier, sqlObjectHoverDetail, sqlObjectNavigationTarget, type SqlObjectNavigationTarget } from "@/lib/sql/sqlNavigation";
import { lineColumnToOffset, parseSqlErrorLocation } from "@/lib/sql/sqlDiagnostics";
import {
@@ -95,6 +96,8 @@ const props = defineProps<{
connectionId?: string;
database?: string;
schema?: string;
clientSessionId?: string;
completionContextVersion?: number;
databaseType?: DatabaseType;
dialect?: "mysql" | "postgres" | "sqlserver";
syntaxDialect?: "mysql" | "postgres" | "sqlserver";
@@ -350,6 +353,38 @@ const cachedInsertValueHintColumnsByTable = new Map<string, string[]>();
const cachedForeignKeysByTable = new Map<string, SqlCompletionForeignKey[]>();
const loadedColumnsByTable = new Set<string>();
function usesOracleSessionCompletionColumns(schema?: string | null): boolean {
return shouldUseOracleSessionCompletionColumns({
databaseType: props.databaseType,
selectedSchema: props.schema,
referenceSchema: schema,
clientSessionId: props.clientSessionId,
});
}
function completionColumnRequestContext() {
return {
clientSessionId: props.clientSessionId,
version: props.completionContextVersion,
};
}
async function listCompletionColumnsForEditor(connectionId: string, database: string, table: string, schema?: string) {
const requestedVersion = props.completionContextVersion;
const sessionScoped = usesOracleSessionCompletionColumns(schema);
const columns = await connectionStore.listCompletionColumns(connectionId, database, table, schema, completionColumnRequestContext());
if (sessionScoped && requestedVersion !== props.completionContextVersion) throw new Error("Stale Oracle completion context");
return columns;
}
async function refreshCompletionColumnsForEditor(connectionId: string, database: string, table: string, schema?: string) {
const requestedVersion = props.completionContextVersion;
const sessionScoped = usesOracleSessionCompletionColumns(schema);
const columns = await connectionStore.refreshCompletionColumns(connectionId, database, table, schema, completionColumnRequestContext());
if (sessionScoped && requestedVersion !== props.completionContextVersion) throw new Error("Stale Oracle completion context");
return columns;
}
const zoomCommitScheduler = createEditorZoomCommitScheduler((fontSize) => {
if (settingsStore.editorSettings.fontSize === fontSize) return;
settingsStore.updateEditorSettings({ fontSize });
@@ -1378,7 +1413,7 @@ function requestInsertValueHintTableColumns(table: string, schema?: string, data
cachedInsertValueHintColumnsByTable.set(cacheKey, insertValueHintColumnNames(databaseType, columns));
return;
}
const columns = await connectionStore.listCompletionColumns(connectionId, target.database, table, target.schema);
const columns = await listCompletionColumnsForEditor(connectionId, target.database, table, target.schema);
cachedColumnsByTable.set(cacheKey, columns);
};
void loadColumns()
@@ -1458,7 +1493,7 @@ async function ensureColumnsForTable(table: { name: string; schema?: string | nu
if (!props.connectionId || props.database == null) return false;
const target = completionMetadataTarget(table);
if (!target) return false;
const columns = await connectionStore.listCompletionColumns(props.connectionId, target.database, table.name, target.schema);
const columns = await listCompletionColumnsForEditor(props.connectionId, target.database, table.name, target.schema);
cachedColumnsByTable.set(cacheKey, columns);
loadedColumnsByTable.add(cacheKey.toLowerCase());
return true;
@@ -1782,6 +1817,10 @@ async function enrichSemanticDiagnosticTables(tables: SqlTableReference[]): Prom
enriched.push(table);
continue;
}
if (usesOracleSessionCompletionColumns(table.schema)) {
enriched.push(table);
continue;
}
try {
const match = await findExactSemanticDiagnosticTable(table);
if (!match) missingTables.add(tableReferenceKey(table));
@@ -2439,7 +2478,7 @@ function buildLocalSqlCompletionResult(completionContext: ReturnType<typeof getS
const columnsByTable = new Map<string, SqlCompletionColumn[]>();
if (completionContext.insertTable) {
const insertSchema = completionContext.insertSchema ?? props.schema;
const insertColumns = connectionStore.lookupLocalCompletionColumns(props.connectionId, props.database, completionContext.insertTable, insertSchema);
const insertColumns = usesOracleSessionCompletionColumns(insertSchema) ? [] : connectionStore.lookupLocalCompletionColumns(props.connectionId, props.database, completionContext.insertTable, insertSchema);
if (insertColumns.length > 0) {
columnsByTable.set(insertSchema ? `${insertSchema}.${completionContext.insertTable}` : completionContext.insertTable, insertColumns);
}
@@ -2453,7 +2492,7 @@ function buildLocalSqlCompletionResult(completionContext: ReturnType<typeof getS
columnsByTable.set(cacheKey, cached);
} else {
const target = completionMetadataTarget(qualifiedColumnTarget);
const localColumns = target ? connectionStore.lookupLocalCompletionColumns(props.connectionId, target.database, qualifiedColumnTarget.name, target.schema) : [];
const localColumns = target && !usesOracleSessionCompletionColumns(target.schema) ? connectionStore.lookupLocalCompletionColumns(props.connectionId, target.database, qualifiedColumnTarget.name, target.schema) : [];
if (localColumns.length > 0) {
columnsByTable.set(cacheKey, localColumns);
}
@@ -2482,7 +2521,7 @@ function buildLocalSqlCompletionResult(completionContext: ReturnType<typeof getS
continue;
}
const target = completionMetadataTarget(refTable);
const localColumns = target ? connectionStore.lookupLocalCompletionColumns(props.connectionId, target.database, refTable.name, target.schema) : [];
const localColumns = target && !usesOracleSessionCompletionColumns(target.schema) ? connectionStore.lookupLocalCompletionColumns(props.connectionId, target.database, refTable.name, target.schema) : [];
if (localColumns.length > 0) {
columnsByTable.set(cacheKey, localColumns);
}
@@ -2558,8 +2597,7 @@ function scheduleCompletionMetadataRefresh(completionContext: ReturnType<typeof
}
if (!onDemandOnlyColumns && completionContext.insertTable) {
const insertTable = completionContext.insertTable;
void connectionStore
.refreshCompletionColumns(connectionId, database, insertTable, completionContext.insertSchema ?? props.schema)
void refreshCompletionColumnsForEditor(connectionId, database, insertTable, completionContext.insertSchema ?? props.schema)
.then((columns) => {
const insertSchema = completionContext.insertSchema ?? props.schema;
cachedColumnsByTable.set(insertSchema ? `${insertSchema}.${insertTable}` : insertTable, columns);
@@ -2571,8 +2609,7 @@ function scheduleCompletionMetadataRefresh(completionContext: ReturnType<typeof
if (!onDemandOnlyColumns && qualifiedColumnTarget && qualifiedColumnCacheKey && !cachedColumnsByTable.has(qualifiedColumnCacheKey)) {
const target = completionMetadataTarget(qualifiedColumnTarget);
if (target) {
void connectionStore
.refreshCompletionColumns(connectionId, target.database, qualifiedColumnTarget.name, target.schema)
void refreshCompletionColumnsForEditor(connectionId, target.database, qualifiedColumnTarget.name, target.schema)
.then((columns) => {
if (columns.length > 0) cachedColumnsByTable.set(qualifiedColumnCacheKey, columns);
})
@@ -2588,8 +2625,7 @@ function scheduleCompletionMetadataRefresh(completionContext: ReturnType<typeof
if (cachedColumnsByTable.has(cacheKey)) continue;
const target = completionMetadataTarget(refTable);
if (!target) continue;
void connectionStore
.refreshCompletionColumns(connectionId, target.database, refTable.name, target.schema)
void refreshCompletionColumnsForEditor(connectionId, target.database, refTable.name, target.schema)
.then((columns) => {
if (columns.length > 0) cachedColumnsByTable.set(cacheKey, columns);
})
@@ -2692,7 +2728,7 @@ async function performAsyncCompletionWithResult(epoch: number, completionContext
let insertColumnsByTable = new Map<string, SqlCompletionColumn[]>();
if (completionContext.insertTable) {
try {
const insertCols = await connectionStore.listCompletionColumns(props.connectionId!, props.database!, completionContext.insertTable, completionContext.insertSchema ?? props.schema);
const insertCols = await listCompletionColumnsForEditor(props.connectionId!, props.database!, completionContext.insertTable, completionContext.insertSchema ?? props.schema);
if (epoch !== completionEpoch) return null;
if (insertCols.length > 0) {
const insertSchema = completionContext.insertSchema ?? props.schema;
@@ -2776,6 +2812,7 @@ async function performAsyncCompletionWithResult(epoch: number, completionContext
// Collect referenced tables — enrich with schema from filtered table lookup
let refs = completionContext.referencedTables.map((rt) => {
if (usesOracleSessionCompletionColumns(rt.schema)) return rt;
if (!rt.schema) {
const cached = tables.find((t) => t.name.toLowerCase() === rt.name.toLowerCase());
if (cached && cached.schema) {
@@ -2784,12 +2821,13 @@ async function performAsyncCompletionWithResult(epoch: number, completionContext
}
return rt;
});
const unresolvedRefs = refs.filter((rt) => !rt.schema && !rt.columns && !isVirtualCompletionTableReference(rt));
const unresolvedRefs = refs.filter((rt) => !usesOracleSessionCompletionColumns(rt.schema) && !rt.schema && !rt.columns && !isVirtualCompletionTableReference(rt));
if (!localOnlyMetadata && unresolvedRefs.length > 0) {
const lookupGroups = await Promise.all(unresolvedRefs.map((rt) => connectionStore.listCompletionTables(props.connectionId!, props.database!, rt.name, 20, props.schema, false, props.schema)));
if (epoch !== completionEpoch) return null;
const lookupTables = lookupGroups.flat();
refs = refs.map((rt) => {
if (usesOracleSessionCompletionColumns(rt.schema)) return rt;
if (rt.schema || rt.columns) return rt;
const matched = lookupTables.find((table) => table.name.toLowerCase() === rt.name.toLowerCase());
return matched?.schema ? { ...rt, schema: matched.schema } : rt;
@@ -2830,7 +2868,7 @@ async function performAsyncCompletionWithResult(epoch: number, completionContext
try {
const target = completionMetadataTarget(refTable);
if (!target) return;
const columns = await connectionStore.listCompletionColumns(props.connectionId!, target.database, refTable.name, target.schema);
const columns = await listCompletionColumnsForEditor(props.connectionId!, target.database, refTable.name, target.schema);
if (epoch !== completionEpoch) return;
if (columns.length === 0) return;
cachedColumnsByTable.set(cacheKey, columns);
@@ -3639,6 +3677,7 @@ onMounted(async () => {
let referencedTables: Array<SqlCompletionReferencedTable & Pick<SqlCompletionTable, "type">> = context.referencedTables;
// Enrich referenced tables with schema from cachedTables
referencedTables = referencedTables.map((rt) => {
if (usesOracleSessionCompletionColumns(rt.schema)) return rt;
const cached = cachedTables.find((ct) => ct.name.toLowerCase() === rt.name.toLowerCase() && (!rt.schema || !ct.schema || ct.schema.toLowerCase() === rt.schema.toLowerCase()));
if (!cached) return rt;
return {
@@ -3682,7 +3721,8 @@ onMounted(async () => {
let cols = cachedColumnsByTable.get(cacheKey);
if (!cols) {
try {
cols = await connectionStore.listCompletionColumns(props.connectionId!, props.database!, refTable.name, refTable.schema ?? props.schema);
const columnSchema = refTable.schema ?? props.schema;
cols = await listCompletionColumnsForEditor(props.connectionId!, props.database!, refTable.name, columnSchema);
cachedColumnsByTable.set(cacheKey, cols);
} catch {
continue;
@@ -3821,6 +3861,13 @@ watch(
},
);
watch([() => props.clientSessionId, () => props.completionContextVersion], () => {
completionEpoch++;
refreshCompletionCache();
setSemanticDiagnostics([]);
scheduleSemanticDiagnostics();
});
watch([() => props.databaseType, () => props.dialect, () => props.syntaxDialect], () => {
executableStatementRangeCache = null;
if (!view.value || !sqlLanguageComp || !buildSqlLanguageExtension || !sqlSemanticHighlightComp || !buildSqlSemanticHighlightExtension || !sqlSignatureComp || !buildSqlSignatureExtension) return;
@@ -814,6 +814,8 @@ defineExpose({ focusSearch, refreshData, refreshQueryEditorCompletionCache, hand
:connection-id="activeTab.connectionId"
:database="activeTab.database"
:schema="activeTab.schema"
:client-session-id="activeTab.id"
:completion-context-version="activeTab.completionContextVersion"
:database-type="activeEffectiveDatabaseType"
:dialect="editorDialect"
:syntax-dialect="editorSyntaxDialect"