fix(oracle): restore alias completion and DIP visibility
This commit is contained in:
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"
|
||||
|
||||
Reference in new issue
Block a user