SuggestKeyword uses Levenshtein distance to suggest the closest SQL keyword matching the given input token. The suggestion is only returned when the edit distance is within half the length of the input (minimum threshold of 2), which prevents semantically unrelated tokens from being suggested. Resu
(input string)
| 41 | // Returns the matching keyword in uppercase, or an empty string if no sufficiently |
| 42 | // close match is found. |
| 43 | func SuggestKeyword(input string) string { |
| 44 | input = strings.ToUpper(input) |
| 45 | if input == "" { |
| 46 | return "" |
| 47 | } |
| 48 | |
| 49 | // Check cache first |
| 50 | if cached, ok := suggestionCache.get(input); ok { |
| 51 | return cached |
| 52 | } |
| 53 | |
| 54 | minDistance := len(input) + 1 |
| 55 | var bestMatch string |
| 56 | |
| 57 | for _, keyword := range commonKeywords { |
| 58 | distance := levenshteinDistance(input, keyword) |
| 59 | if distance < minDistance { |
| 60 | minDistance = distance |
| 61 | bestMatch = keyword |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | // Only suggest if the distance is small relative to input length |
| 66 | // (avoid suggesting "SELECT" for completely unrelated words) |
| 67 | threshold := len(input) / 2 |
| 68 | if threshold < 2 { |
| 69 | threshold = 2 |
| 70 | } |
| 71 | |
| 72 | var result string |
| 73 | if minDistance <= threshold { |
| 74 | result = bestMatch |
| 75 | } |
| 76 | |
| 77 | // Cache the result |
| 78 | suggestionCache.set(input, result) |
| 79 | |
| 80 | return result |
| 81 | } |
| 82 | |
| 83 | // levenshteinDistance calculates the edit distance between two strings |
| 84 | func levenshteinDistance(s1, s2 string) int { |