feat(sql): add Doris/SelectDB completion and semantic diagnostics

This commit is contained in:
zipg authored and GitHub committed 2026-09-12 17:36:58 +08:00
1 parent 20f6092cf2
commit f8ce8ab353
10 files changed
+6273 -17

No files matched your search

+15 -4
View File
@@ -18,6 +18,7 @@ import { identifierMatchScore, matchesIdentifierSearch } from "@/lib/sql/identif
import { containsHan, orderedSubsequenceSpan, pinyinFirstLetters } from "@/lib/common/pinyin";
import { quoteTableIdentifier } from "@/lib/table/tableSelectSql";
import { driverProfileCompletionObjects, driverProfileCompletionTableMetadata, driverProfileCompletionTables, driverProfileRoutineSignatures } from "@/lib/database/driverProfileExtensions";
import { DORIS_FUNCTION_DOCS, DORIS_FUNCTION_SIGNATURES } from "@/lib/sql/doris/functions";
export { DEFAULT_SQL_SNIPPETS, resolveSqlSnippetBodyForDatabase } from "@/lib/sql/sqlSnippetTemplates";
@@ -585,8 +586,8 @@ const DATABASE_SQL_KEYWORDS: Partial<Record<DatabaseType, string[]>> = {
manticoresearch: MANTICORESEARCH_SQL_KEYWORDS,
duckdb: ["COMMENT"],
clickhouse: ["COMMENT"],
doris: ["COMMENT", "MATERIALIZED", "MATERIALIZED VIEW"],
starrocks: ["COMMENT", "MATERIALIZED", "MATERIALIZED VIEW"],
doris: ["COMMENT", "MATERIALIZED", "MATERIALIZED VIEW", "DISTRIBUTED BY HASH", "DUPLICATE KEY", "AGGREGATE KEY", "UNIQUE KEY", "PRIMARY KEY", "PROPERTIES", "PARTITION BY", "BUCKETS", "LATERAL VIEW", "EXPLODE", "ARRAY", "MAP", "STRUCT", "BITMAP", "HLL"],
starrocks: ["COMMENT", "MATERIALIZED", "MATERIALIZED VIEW", "DISTRIBUTED BY HASH", "DUPLICATE KEY", "PROPERTIES", "PARTITION BY", "BUCKETS", "LATERAL VIEW"],
dameng: ["COMMENT"],
kingbase: ["COMMENT"],
vastbase: ["COMMENT"],
@@ -648,7 +649,8 @@ const EXACT_LABEL_MATCH_BOOST = 10000;
const EXACT_CUSTOM_SNIPPET_TRIGGER_BOOST = 40000;
function isTableTriggerKeyword(keyword: string, options: SqlSemanticBuildOptions): boolean {
return TABLE_TRIGGER_KEYWORDS.has(keyword) || (keyword === "desc" && resolveSqlDialectId(options) === "mysql");
const dialectId = resolveSqlDialectId(options);
return TABLE_TRIGGER_KEYWORDS.has(keyword) || (keyword === "desc" && (dialectId === "mysql" || dialectId === "doris"));
}
// Keywords that only make sense in DDL / statement-start contexts (not inside SELECT/INSERT/UPDATE/DELETE)
@@ -1131,6 +1133,8 @@ const DATABASE_FUNCTION_SIGNATURES: Partial<Record<DatabaseType, Map<string, str
"cloudflare-d1": CLOUDFLARE_D1_FUNCTION_SIGNATURES,
sqlserver: SQLSERVER_FUNCTION_SIGNATURES,
manticoresearch: MANTICORESEARCH_FUNCTION_SIGNATURES,
doris: DORIS_FUNCTION_SIGNATURES,
starrocks: DORIS_FUNCTION_SIGNATURES,
};
const MYSQL_FUNCTION_APPLY_TEMPLATES = new Map<string, string>([
@@ -5039,6 +5043,13 @@ function activeFunctionSignatures(databaseType?: DatabaseType): Map<string, stri
return signatures;
}
const DORIS_FUNCTION_DESCRIPTIONS = new Map(DORIS_FUNCTION_DOCS);
const EMPTY_FUNCTION_DESCRIPTIONS = new Map<string, string>();
function activeFunctionDescriptions(databaseType?: DatabaseType): Map<string, string> {
return databaseType === "doris" || databaseType === "starrocks" ? DORIS_FUNCTION_DESCRIPTIONS : EMPTY_FUNCTION_DESCRIPTIONS;
}
function formatFunctionSignatureApply(definition: ClickHouseFunctionDefinition, omitOpeningParen: boolean): string {
if (omitOpeningParen) return definition.name;
const signature = definition.signatures[definition.preferredSignature ?? 0];
@@ -5089,7 +5100,7 @@ function buildFunctionSnippetItems(prefix: string, functionDescriptions: Map<str
items.push({
label: functionName,
type: "function" as const,
detail: functionDescriptions.get(name) ?? "function",
detail: activeFunctionDescriptions(databaseType).get(name) ?? functionDescriptions.get(name) ?? "function",
apply: mysqlApply ? `${functionName}${applyGeneratedSqlTemplateKeywordCase(mysqlApply.slice(name.length), keywordCase)}` : `${functionName}(${paramStr})`,
boost: computeBoost(name, prefix) + 300,
});