modified: frontend/src/components/SqlEditor.tsx

This commit is contained in:
2026-01-28 01:08:53 +03:00
parent fba8069b13
commit fd08e2c3e6

View File

@@ -96,24 +96,40 @@ function getFkSuggestions(
tablesInQuery: TableInfo[], tablesInQuery: TableInfo[],
schema: SchemaData, schema: SchemaData,
monaco: Monaco, monaco: Monaco,
range: any range: any,
sql: string
): any[] { ): any[] {
const suggestions: any[] = []; const suggestions: any[] = [];
const aliases = parseTableAliases(sql);
// Create reverse alias map: tableName -> alias (or tableName if no alias)
const tableToAlias = new Map<string, string>();
for (const [alias, tableName] of aliases) {
// Prefer shorter alias over table name
const existing = tableToAlias.get(tableName);
if (!existing || alias.length < existing.length) {
tableToAlias.set(tableName, alias);
}
}
for (const table of tablesInQuery) { for (const table of tablesInQuery) {
for (const fk of table.foreign_keys) { for (const fk of table.foreign_keys) {
// Find the referenced table // Find the referenced table
const refTable = schema.tables.find(t => t.name === fk.references_table); const refTable = schema.tables.find(t => t.name === fk.references_table);
if (refTable && tablesInQuery.some(t => t.name === refTable.name)) { if (refTable && tablesInQuery.some(t => t.name === refTable.name)) {
const joinCondition = `${table.name}.${fk.column} = ${refTable.name}.${fk.references_column}`; // Use alias if available, otherwise table name
const sourceAlias = tableToAlias.get(table.name) || table.name;
const targetAlias = tableToAlias.get(refTable.name) || refTable.name;
const joinCondition = `${sourceAlias}.${fk.column} = ${targetAlias}.${fk.references_column}`;
suggestions.push({ suggestions.push({
label: joinCondition, label: joinCondition,
kind: monaco.languages.CompletionItemKind.Snippet, kind: monaco.languages.CompletionItemKind.Snippet,
insertText: joinCondition, insertText: joinCondition,
detail: `FK: ${table.name}${refTable.name}`, detail: `FK: ${table.name}.${fk.column}${refTable.name}.${fk.references_column}`,
documentation: `Foreign key relationship`, documentation: `Foreign key relationship between ${table.name} and ${refTable.name}`,
range, range,
sortText: '0' + joinCondition, // Sort FK suggestions first sortText: '0' + joinCondition,
}); });
} }
} }
@@ -194,12 +210,16 @@ export default function SqlEditor({ value, onChange, databaseId, height }: SqlEd
} }
// Check if we're after ON keyword (FK suggestions) // Check if we're after ON keyword (FK suggestions)
const onMatch = textBeforeCursor.match(/\bON\s+$/i); // Match: "ON ", "ON ", "on ", after JOIN ... ON
const fullText = model.getValue();
const onMatch = textBeforeCursor.match(/\bON\s*$/i) || textUntilPosition.match(/\bJOIN\s+\w+\s+\w*\s+ON\s*$/i);
if (onMatch && currentSchema) { if (onMatch && currentSchema) {
const tablesInQuery = findTablesInQuery(textUntilPosition, currentSchema); const tablesInQuery = findTablesInQuery(fullText, currentSchema);
const fkSuggestions = getFkSuggestions(tablesInQuery, currentSchema, monaco, range); const fkSuggestions = getFkSuggestions(tablesInQuery, currentSchema, monaco, range, fullText);
// Add FK suggestions to the top, but also include other suggestions
if (fkSuggestions.length > 0) { if (fkSuggestions.length > 0) {
return { suggestions: fkSuggestions }; suggestions = [...fkSuggestions, ...suggestions];
return { suggestions };
} }
} }