feat(dolt): improve system tables and SQL completion
This commit is contained in:
1 parent
c5eea21821
commit
a574459f8b
30 files changed
+789
-70
No files matched your search
@@ -13,7 +13,7 @@ import { requiresMysqlIdentifierQuote, requiresPostgresIdentifierQuote } from "@
|
||||
import { identifierMatchScore, matchesIdentifierSearch } from "@/lib/sql/identifierSearch";
|
||||
import { containsHan, orderedSubsequenceSpan, pinyinFirstLetters } from "@/lib/common/pinyin";
|
||||
import { quoteTableIdentifier } from "@/lib/table/tableSelectSql";
|
||||
import { DOLT_SQL_ROUTINES, doltSqlRoutineSignatures, isDoltDriverProfile } from "@/lib/database/doltProfile";
|
||||
import { driverProfileCompletionObjects, driverProfileCompletionTableMetadata, driverProfileCompletionTables, driverProfileRoutineSignatures } from "@/lib/database/driverProfileExtensions";
|
||||
|
||||
export { DEFAULT_SQL_SNIPPETS, resolveSqlSnippetBodyForDatabase } from "@/lib/sql/sqlSnippetTemplates";
|
||||
|
||||
@@ -1373,6 +1373,18 @@ class SqlCompletionProvider {
|
||||
build(): SqlCompletionItem[] {
|
||||
const { context } = this;
|
||||
const pendingJoinKeyword = isPendingJoinKeywordContext(context);
|
||||
const completionTables = [
|
||||
...this.input.tables.map((table) => {
|
||||
const metadata = driverProfileCompletionTableMetadata(this.input.driverProfile, table.name);
|
||||
if (!metadata) return table;
|
||||
return {
|
||||
...table,
|
||||
detail: table.detail ?? metadata.detail,
|
||||
boost: (table.boost ?? 0) + (metadata.boost ?? 0),
|
||||
};
|
||||
}),
|
||||
...driverProfileCompletionTables(this.input.driverProfile, context),
|
||||
];
|
||||
|
||||
if (this.databaseType === "mongodb") {
|
||||
return dedupeAndSort(buildMongoCompletionItemsFromContext({ mode: "root", prefix: context.prefix, from: 0 }).map(mongoCompletionItemToSqlCompletionItem));
|
||||
@@ -1385,7 +1397,7 @@ class SqlCompletionProvider {
|
||||
this.items.push(...buildSnippetItems(context.prefix, snippets, this.input.keywordCase, this.databaseType));
|
||||
}
|
||||
if (!preferReferencedColumns || context.suggestRoutines) {
|
||||
const functionItems = context.dataTypeContext ? [] : buildFunctionSnippetItems(context.prefix, getFunctionDescriptions(this.t), this.databaseType, this.input.driverProfile, context.openingParenAfterCursor, this.input.keywordCase, this.input.functionCase);
|
||||
const functionItems = context.dataTypeContext ? [] : buildFunctionSnippetItems(context.prefix, getFunctionDescriptions(this.t), this.databaseType, context.openingParenAfterCursor, this.input.keywordCase, this.input.functionCase);
|
||||
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));
|
||||
@@ -1443,8 +1455,8 @@ class SqlCompletionProvider {
|
||||
}
|
||||
|
||||
if (!context.exclusiveColumnSuggestions && context.suggestTables) {
|
||||
this.items.push(...buildForeignKeyRelatedTableItems(context, this.input.tables, this.input.foreignKeysByTable, this.dialect, !!this.input.autoAliasTables && context.autoAliasTableCompletions, this.databaseType, this.input.keywordCase, this.input.currentSchema));
|
||||
this.items.push(...buildTableItems(context, this.input.tables, this.dialect, !!this.input.autoAliasTables && context.autoAliasTableCompletions, context.referencedTables, this.databaseType, this.input.currentSchema, this.input.keywordCase));
|
||||
this.items.push(...buildForeignKeyRelatedTableItems(context, completionTables, this.input.foreignKeysByTable, this.dialect, !!this.input.autoAliasTables && context.autoAliasTableCompletions, this.databaseType, this.input.keywordCase, this.input.currentSchema));
|
||||
this.items.push(...buildTableItems(context, completionTables, this.dialect, !!this.input.autoAliasTables && context.autoAliasTableCompletions, context.referencedTables, this.databaseType, this.input.currentSchema, this.input.keywordCase));
|
||||
if (this.databaseType === "clickhouse") {
|
||||
this.items.push(...buildClickHouseFunctionItems(context.prefix, context.openingParenAfterCursor, "table"));
|
||||
}
|
||||
@@ -1457,7 +1469,7 @@ class SqlCompletionProvider {
|
||||
}
|
||||
|
||||
if (context.suggestRoutines || context.exclusiveRoutineSuggestions || context.oracleTableFunctionContext) {
|
||||
const profileObjects = isDoltDriverProfile(this.input.driverProfile) ? DOLT_SQL_ROUTINES : [];
|
||||
const profileObjects = driverProfileCompletionObjects(this.input.driverProfile, context);
|
||||
this.items.push(...buildObjectItems(context, [...(this.input.objects ?? []), ...profileObjects], this.dialect, this.databaseType, this.input.currentSchema));
|
||||
}
|
||||
|
||||
@@ -1889,7 +1901,7 @@ export function getSqlFunctionSignatureHelp(sql: string, cursor: number, databas
|
||||
const observedParameter = countTopLevelCommas(call.groupText);
|
||||
if (databaseType !== "clickhouse") {
|
||||
const lookupName = call.name.toUpperCase();
|
||||
const parameters = activeFunctionSignatures(databaseType, driverProfile).get(lookupName);
|
||||
const parameters = activeFunctionSignatures(databaseType).get(lookupName) ?? driverProfileRoutineSignatures(driverProfile).get(lookupName);
|
||||
if (!parameters) return null;
|
||||
const activeParameter = Math.min(observedParameter, Math.max(0, parameters.length - 1));
|
||||
const signature = `${lookupName}(${parameters.join(", ")})`;
|
||||
@@ -4455,14 +4467,13 @@ function buildSnippetItems(prefix: string, snippets: SqlSnippet[], keywordCase?:
|
||||
});
|
||||
}
|
||||
|
||||
function activeFunctionSignatures(databaseType?: DatabaseType, driverProfile?: string): Map<string, string[]> {
|
||||
function activeFunctionSignatures(databaseType?: DatabaseType): Map<string, string[]> {
|
||||
const commonFunctionNames = databaseType === "cloudflare-d1" ? CLOUDFLARE_D1_COMMON_FUNCTION_NAMES : COMMON_SQL_FUNCTION_NAMES;
|
||||
const signatures = databaseType ? new Map(Array.from(SQL_FUNCTION_SIGNATURES.entries()).filter(([name]) => commonFunctionNames.has(name))) : new Map(SQL_FUNCTION_SIGNATURES);
|
||||
const databaseSignatures = databaseType ? DATABASE_FUNCTION_SIGNATURES[databaseType] : undefined;
|
||||
if (databaseSignatures) {
|
||||
for (const [name, parameters] of databaseSignatures) signatures.set(name, parameters);
|
||||
}
|
||||
for (const [name, parameters] of doltSqlRoutineSignatures(driverProfile)) signatures.set(name, parameters);
|
||||
return signatures;
|
||||
}
|
||||
|
||||
@@ -4504,11 +4515,11 @@ function buildClickHouseFunctionItems(prefix: string, omitOpeningParen: boolean,
|
||||
});
|
||||
}
|
||||
|
||||
function buildFunctionSnippetItems(prefix: string, functionDescriptions: Map<string, string>, databaseType?: DatabaseType, driverProfile?: string, omitOpeningParen = false, keywordCase?: SqlKeywordCase, functionCase?: SqlKeywordCase): SqlCompletionItem[] {
|
||||
function buildFunctionSnippetItems(prefix: string, functionDescriptions: Map<string, string>, databaseType?: DatabaseType, omitOpeningParen = false, keywordCase?: SqlKeywordCase, functionCase?: SqlKeywordCase): SqlCompletionItem[] {
|
||||
if (databaseType === "clickhouse") return buildClickHouseFunctionItems(prefix, omitOpeningParen);
|
||||
const items: SqlCompletionItem[] = [];
|
||||
|
||||
for (const [name, parameters] of activeFunctionSignatures(databaseType, driverProfile).entries()) {
|
||||
for (const [name, parameters] of activeFunctionSignatures(databaseType).entries()) {
|
||||
if (!matchesPrefix(name, prefix)) continue;
|
||||
const functionName = applySqlFunctionCase(name, functionCase);
|
||||
const paramStr = parameters.length > 0 ? parameters.map((p) => `\${${applyGeneratedSqlTemplateKeywordCase(p, keywordCase)}}`).join(", ") : "";
|
||||
@@ -4516,7 +4527,7 @@ function buildFunctionSnippetItems(prefix: string, functionDescriptions: Map<str
|
||||
items.push({
|
||||
label: functionName,
|
||||
type: "function" as const,
|
||||
detail: functionDescriptions.get(name) ?? (isDoltDriverProfile(driverProfile) && name.startsWith("DOLT_") ? "Dolt routine" : "function"),
|
||||
detail: functionDescriptions.get(name) ?? "function",
|
||||
apply: mysqlApply ? `${functionName}${applyGeneratedSqlTemplateKeywordCase(mysqlApply.slice(name.length), keywordCase)}` : `${functionName}(${paramStr})`,
|
||||
boost: computeBoost(name, prefix) + 300,
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user