MCPcopy Create free account
hub / github.com/bytebase/bytebase / Completion

Function Completion

backend/plugin/parser/tidb/completion.go:52–112  ·  view source on GitHub ↗

Completion provides auto-complete candidates for TiDB statements using the omni TiDB completion engine, replacing the previous mysql ANTLR completer.

(ctx context.Context, cCtx base.CompletionContext, statement string, caretLine int, caretOffset int)

Source from the content-addressed store, hash-verified

50// Completion provides auto-complete candidates for TiDB statements using the
51// omni TiDB completion engine, replacing the previous mysql ANTLR completer.
52func Completion(ctx context.Context, cCtx base.CompletionContext, statement string, caretLine int, caretOffset int) ([]base.Candidate, error) {
53 // Limit completion to the statement containing the caret so table refs from
54 // earlier statements in the buffer don't leak into the candidate set.
55 stmt, pos := currentStatement(statement, lineOffsetToBytePos(statement, caretLine, caretOffset))
56
57 cat := buildCatalog(ctx, cCtx, stmt)
58 caretInBacktick := caretInsideBacktickIdentifier(stmt, pos)
59 candidateMap := make(map[string]base.Candidate)
60 for _, c := range omnicompletion.Complete(stmt, pos, cat) {
61 t := omniCandidateTypeToBase(c.Type)
62 text := c.Text
63 switch {
64 case isObjectIdentifierCandidate(t):
65 text = quoteIdentifierIfNeeded(c.Text, caretInBacktick)
66 case t == base.CandidateTypeFunction:
67 text = c.Text + "()"
68 default:
69 // Keywords and value-like candidates pass through unchanged.
70 }
71 candidateMap[string(t)+":"+text] = base.Candidate{
72 Type: t,
73 Text: text,
74 Definition: c.Definition,
75 Comment: c.Comment,
76 }
77 }
78
79 // In the read-only query scene, drop keywords that *initiate* writes
80 // (DML/DDL/transaction/admin statements) so the editor doesn't offer to start
81 // a write statement. This only applies at a statement-start position: the same
82 // keywords are valid sub-keywords inside read statements (e.g. CREATE in SHOW
83 // CREATE TABLE, UPDATE in SELECT ... FOR UPDATE) and must be preserved there.
84 if cCtx.Scene == base.SceneTypeQuery && caretAtStatementStart(stmt, pos) {
85 for key, c := range candidateMap {
86 if c.Type == base.CandidateTypeKeyword && writeStatementKeywords[strings.ToUpper(c.Text)] {
87 delete(candidateMap, key)
88 }
89 }
90 }
91
92 result := make([]base.Candidate, 0, len(candidateMap))
93 for _, c := range candidateMap {
94 result = append(result, c)
95 }
96 slices.SortFunc(result, func(a, b base.Candidate) int {
97 if a.Type != b.Type {
98 if a.Type < b.Type {
99 return -1
100 }
101 return 1
102 }
103 if a.Text < b.Text {
104 return -1
105 }
106 if a.Text > b.Text {
107 return 1
108 }
109 return 0

Calls 8

currentStatementFunction · 0.85
quoteIdentifierIfNeededFunction · 0.85
caretAtStatementStartFunction · 0.85
lineOffsetToBytePosFunction · 0.70
buildCatalogFunction · 0.70
omniCandidateTypeToBaseFunction · 0.70