()
| 187 | } |
| 188 | |
| 189 | func (c *Completer) completion() ([]base.Candidate, error) { |
| 190 | // Check if the caret token is quoted. |
| 191 | if c.caretTokenIndex < len(c.tokens) { |
| 192 | tok := c.tokens[c.caretTokenIndex] |
| 193 | if tok.Type == pgparser.IDENT && tok.Loc < len(c.sql) && c.sql[tok.Loc] == '"' { |
| 194 | c.caretTokenIsQuoted = true |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | caretIndex := c.caretTokenIndex |
| 199 | if caretIndex > 0 && !isNoSeparatorRequired(c.tokens[caretIndex-1].Type) { |
| 200 | caretIndex-- |
| 201 | } |
| 202 | c.referencesStack = append([][]base.TableReference{{}}, c.referencesStack...) |
| 203 | |
| 204 | // Use omni parser to collect grammar candidates instead of C3. |
| 205 | completionOffset := c.cursorByteOffset |
| 206 | candidates := pgparser.Collect(c.sql, completionOffset) |
| 207 | |
| 208 | // If Collect returned no rule candidates and the cursor is at the end of a |
| 209 | // partial identifier token (prefix), retry Collect at the start of that |
| 210 | // token. This enables completion for "SELECT * FROM t|" style inputs |
| 211 | // where the parser sees a complete token and doesn't know what grammar |
| 212 | // rule to suggest. |
| 213 | if len(candidates.Rules) == 0 { |
| 214 | if prefixTok, ok := c.prefixToken(); ok { |
| 215 | completionOffset = prefixTok.Loc |
| 216 | candidates = pgparser.Collect(c.sql, completionOffset) |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | for _, rc := range candidates.Rules { |
| 221 | if rc.Rule == "columnref" { |
| 222 | completionContext := pgparser.CollectCompletion(c.sql, completionOffset) |
| 223 | c.collectLeadingTableReferences(caretIndex) |
| 224 | c.takeReferencesSnapshot() |
| 225 | c.collectRemainingTableReferences() |
| 226 | c.takeReferencesSnapshot() |
| 227 | c.collectCompletionScopeReferences(completionContext) |
| 228 | break |
| 229 | } |
| 230 | } |
| 231 | |
| 232 | return c.convertCandidates(candidates) |
| 233 | } |
| 234 | |
| 235 | // prefixToken returns the token immediately before (or containing) the cursor |
| 236 | // position when that token is an identifier-like token that the user is still |
no test coverage detected