fix(sql): support Oracle system value completion

This commit is contained in:
zipg authored and GitHub committed 2026-07-20 23:29:18 +08:00
1 parent f4ce0dc435
commit 79f8c7284a
3 files changed
+117 -1

No files matched your search

@@ -1,5 +1,5 @@
import type { SqlCompletionColumn, SqlCompletionTable } from "@/lib/sql/sqlCompletion";
import { getSqlCompletionContext } from "@/lib/sql/sqlCompletion";
import { getSqlCompletionContext, isOracleSystemValueName } from "@/lib/sql/sqlCompletion";
import { executableStatementRanges, isOraclePlSqlStatement, type SqlTextRange } from "@/lib/sql/sqlStatementRanges";
import type { DatabaseType, SqlColumnReference, SqlReferenceAnalysis, SqlReferenceScope, SqlTableReference, SqlTextSpan } from "@/types/database";
@@ -63,6 +63,7 @@ export function buildSqlSemanticDiagnostics(analysis: SqlReferenceAnalysis, sche
}
for (const column of analysis.columns) {
if (isUnquotedOracleSystemValueReference(column, schema)) continue;
const table = resolveColumnTable(column, tables, knownTables, schema.sql, scopesById);
if (!table) continue;
if (schema.missingTables?.has(tableReferenceKey(table))) continue;
@@ -84,6 +85,16 @@ export function buildSqlSemanticDiagnostics(analysis: SqlReferenceAnalysis, sche
return diagnostics;
}
function isUnquotedOracleSystemValueReference(column: SqlColumnReference, schema: SqlSemanticDiagnosticSchema): boolean {
if (column.qualifier || !isOracleSystemValueName(column.name, schema.databaseType)) return false;
if (!schema.sql) return false;
const range = sqlTextSpanToOffsetRange(schema.sql, column.span);
if (!range) return false;
const firstCharacter = schema.sql.slice(range.from, range.to).trimStart()[0];
return firstCharacter !== '"' && firstCharacter !== "'" && firstCharacter !== "`" && firstCharacter !== "[";
}
export function isSqlVirtualTableReference(table: { name: string; schema?: string | null }, databaseType?: DatabaseType): boolean {
return databaseType === "mysql" && !table.schema && normalizeName(table.name) === "dual";
}
+24
View File
@@ -509,6 +509,14 @@ const ORACLE_SQL_TYPES = [
"XMLTYPE",
];
const ORACLE_SYSTEM_VALUE_NAMES = ["SYSDATE", "SYSTIMESTAMP", "CURRENT_DATE", "CURRENT_TIMESTAMP", "LOCALTIMESTAMP", "SESSIONTIMEZONE", "DBTIMEZONE", "USER", "UID"] as const;
const ORACLE_SYSTEM_VALUE_NAME_SET = new Set<string>(ORACLE_SYSTEM_VALUE_NAMES);
export function isOracleSystemValueName(name: string, databaseType?: DatabaseType): boolean {
return isOracleLikeDatabase(databaseType) && ORACLE_SYSTEM_VALUE_NAME_SET.has(name.toUpperCase());
}
const NON_ORACLE_COMPLETION_WORDS = new Set(["BIGSERIAL", "BOOLEAN", "ELSEIF", "LIMIT", "LOCALTIME", "SERIAL", "STRING", "TEXT", "TIME", "USE"]);
const ORACLE_SQL_KEYWORDS = Array.from(
@@ -1350,6 +1358,9 @@ class SqlCompletionProvider {
if (!preferReferencedColumns || context.suggestRoutines) {
const functionItems = buildFunctionSnippetItems(context.prefix, getFunctionDescriptions(this.t), this.databaseType);
this.items.push(...(preferReferencedColumns ? functionItems.filter((item) => item.label.toLowerCase().startsWith(context.prefix.toLowerCase())) : functionItems));
if (isOracleLikeDatabase(this.databaseType)) {
this.items.push(...buildOracleSystemValueItems(context.prefix, this.input.keywordCase));
}
}
}
@@ -4025,6 +4036,19 @@ function buildFunctionSnippetItems(prefix: string, functionDescriptions: Map<str
return items;
}
function buildOracleSystemValueItems(prefix: string, keywordCase?: SqlKeywordCase): SqlCompletionItem[] {
return ORACLE_SYSTEM_VALUE_NAMES.filter((name) => matchesPrefix(name, prefix)).map((name) => {
const label = applySqlKeywordCase(name, keywordCase);
return {
label,
type: "function" as const,
detail: "Oracle system value",
apply: label,
boost: computeBoost(name, prefix) + 300,
};
});
}
function mongoCompletionItemToSqlCompletionItem(item: MongoCompletionItem): SqlCompletionItem {
return {
label: item.label,