fix(completion): replace partially quoted identifiers
This commit is contained in:
4 files changed
+126
-7
No files matched your search
@@ -259,11 +259,13 @@ function semanticMutationTarget(model: SqlSemanticModel): SqlSemanticRowSource |
|
||||
}
|
||||
|
||||
export function sqlCompletionContextFromSemantic(model: SqlSemanticModel, base: SqlCompletionContext): SqlCompletionContext {
|
||||
if (model.cursorIntent.confidence === "low" || model.cursorIntent.kind === "suppressed") {
|
||||
if (model.cursorIntent.kind === "suppressed") {
|
||||
return base;
|
||||
}
|
||||
const replacementRange = model.cursorIntent.replacementRange;
|
||||
if (model.cursorIntent.confidence === "low") return { ...base, replacementRange };
|
||||
if ((base.suggestTables || base.exclusiveTableSuggestions) && model.cursorIntent.kind !== "table" && model.cursorIntent.kind !== "schema" && model.cursorIntent.kind !== "catalog" && model.cursorIntent.kind !== "delete_target") {
|
||||
return base;
|
||||
return { ...base, replacementRange };
|
||||
}
|
||||
|
||||
const scope = sqlSemanticCompletionScope(model);
|
||||
@@ -284,6 +286,7 @@ export function sqlCompletionContextFromSemantic(model: SqlSemanticModel, base:
|
||||
|
||||
return {
|
||||
...base,
|
||||
replacementRange,
|
||||
prefix,
|
||||
qualifier,
|
||||
qualifierParts,
|
||||
|
||||
@@ -1275,6 +1275,8 @@ export interface SqlCompletionForeignKey {
|
||||
ref_column: string;
|
||||
}
|
||||
|
||||
export type SqlCompletionClosingQuote = '"' | "'" | "`" | "]";
|
||||
|
||||
export interface SqlCompletionItem {
|
||||
label: string;
|
||||
filterText?: string;
|
||||
@@ -1282,7 +1284,7 @@ export interface SqlCompletionItem {
|
||||
detail?: string;
|
||||
info?: string | ((completion: Completion) => CompletionInfo | Promise<CompletionInfo>);
|
||||
apply?: string;
|
||||
replaceClosingQuote?: '"' | "'";
|
||||
replaceClosingQuote?: SqlCompletionClosingQuote;
|
||||
boost: number;
|
||||
exactMatch?: boolean;
|
||||
dedupeKey?: string;
|
||||
@@ -1332,6 +1334,7 @@ export type SqlCompletionContextKind = "table" | "schema" | "catalog" | "routine
|
||||
|
||||
export interface SqlCompletionContext {
|
||||
prefix: string;
|
||||
replacementRange?: { start: number; end: number };
|
||||
qualifier?: string;
|
||||
qualifierParts?: string[];
|
||||
suggestTables: boolean;
|
||||
@@ -1367,6 +1370,33 @@ export interface SqlCompletionContext {
|
||||
dataTypeContext: boolean;
|
||||
}
|
||||
|
||||
const SQL_COMPLETION_CLOSING_QUOTES: Readonly<Record<string, SqlCompletionClosingQuote>> = {
|
||||
'"': '"',
|
||||
"'": "'",
|
||||
"`": "`",
|
||||
"[": "]",
|
||||
};
|
||||
|
||||
export function prepareSqlCompletionReplacement(sql: string, cursor: number, context: Pick<SqlCompletionContext, "prefix" | "qualifier" | "replacementRange">, items: SqlCompletionItem[]): { from: number; items: SqlCompletionItem[] } {
|
||||
const range = context.replacementRange;
|
||||
const from = range && range.start >= 0 && range.start <= cursor && range.end === cursor ? range.start : cursor - context.prefix.length;
|
||||
const closingQuote = from < cursor ? SQL_COMPLETION_CLOSING_QUOTES[sql[from] ?? ""] : undefined;
|
||||
if (!closingQuote) return { from, items };
|
||||
const replaceClosingQuote = sql[cursor] === closingQuote ? closingQuote : undefined;
|
||||
return {
|
||||
from,
|
||||
items: items.map((item) => {
|
||||
let prepared = item;
|
||||
const apply = item.apply ?? item.label;
|
||||
if (item.type === "column" && !(apply.startsWith(sql[from] ?? "") && apply.endsWith(closingQuote)) && (context.qualifier || !apply.includes("."))) {
|
||||
const escaped = apply.replaceAll(closingQuote, closingQuote + closingQuote);
|
||||
prepared = { ...prepared, apply: `${sql[from]}${escaped}${closingQuote}` };
|
||||
}
|
||||
return replaceClosingQuote && !prepared.replaceClosingQuote ? { ...prepared, replaceClosingQuote } : prepared;
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
export interface PostgresSequenceLiteralCompletionContext {
|
||||
from: number;
|
||||
prefix: string;
|
||||
|
||||
Reference in new issue
Block a user