should be it
This commit is contained in:
185
external/duckdb/extension/autocomplete/include/matcher.hpp
vendored
Normal file
185
external/duckdb/extension/autocomplete/include/matcher.hpp
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DuckDB
|
||||
//
|
||||
// matcher.hpp
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "duckdb/common/string_util.hpp"
|
||||
#include "duckdb/common/vector.hpp"
|
||||
#include "duckdb/common/reference_map.hpp"
|
||||
#include "transformer/parse_result.hpp"
|
||||
|
||||
namespace duckdb {
|
||||
class ParseResultAllocator;
|
||||
class Matcher;
|
||||
class MatcherAllocator;
|
||||
|
||||
enum class SuggestionState : uint8_t {
|
||||
SUGGEST_KEYWORD,
|
||||
SUGGEST_CATALOG_NAME,
|
||||
SUGGEST_SCHEMA_NAME,
|
||||
SUGGEST_TABLE_NAME,
|
||||
SUGGEST_TYPE_NAME,
|
||||
SUGGEST_COLUMN_NAME,
|
||||
SUGGEST_FILE_NAME,
|
||||
SUGGEST_VARIABLE,
|
||||
SUGGEST_SCALAR_FUNCTION_NAME,
|
||||
SUGGEST_TABLE_FUNCTION_NAME,
|
||||
SUGGEST_PRAGMA_NAME,
|
||||
SUGGEST_SETTING_NAME,
|
||||
SUGGEST_RESERVED_VARIABLE
|
||||
};
|
||||
|
||||
enum class CandidateType { KEYWORD, IDENTIFIER, LITERAL };
|
||||
|
||||
struct AutoCompleteCandidate {
|
||||
// NOLINTNEXTLINE: allow implicit conversion from string
|
||||
AutoCompleteCandidate(string candidate_p, int32_t score_bonus = 0,
|
||||
CandidateType candidate_type = CandidateType::IDENTIFIER)
|
||||
: candidate(std::move(candidate_p)), score_bonus(score_bonus), candidate_type(candidate_type) {
|
||||
}
|
||||
// NOLINTNEXTLINE: allow implicit conversion from const char*
|
||||
AutoCompleteCandidate(const char *candidate_p, int32_t score_bonus = 0,
|
||||
CandidateType candidate_type = CandidateType::IDENTIFIER)
|
||||
: AutoCompleteCandidate(string(candidate_p), score_bonus, candidate_type) {
|
||||
}
|
||||
|
||||
string candidate;
|
||||
//! The higher the score bonus, the more likely this candidate will be chosen
|
||||
int32_t score_bonus;
|
||||
//! The type of candidate we are suggesting - this modifies how we handle quoting/case sensitivity
|
||||
CandidateType candidate_type;
|
||||
//! Extra char to push at the back
|
||||
char extra_char = '\0';
|
||||
//! Suggestion position
|
||||
idx_t suggestion_pos = 0;
|
||||
};
|
||||
|
||||
struct AutoCompleteSuggestion {
|
||||
AutoCompleteSuggestion(string text_p, idx_t pos) : text(std::move(text_p)), pos(pos) {
|
||||
}
|
||||
|
||||
string text;
|
||||
idx_t pos;
|
||||
};
|
||||
|
||||
enum class MatchResultType { SUCCESS, FAIL };
|
||||
|
||||
enum class SuggestionType { OPTIONAL, MANDATORY };
|
||||
|
||||
enum class TokenType { WORD };
|
||||
|
||||
struct MatcherToken {
|
||||
// NOLINTNEXTLINE: allow implicit conversion from text
|
||||
MatcherToken(string text_p, idx_t offset_p) : text(std::move(text_p)), offset(offset_p) {
|
||||
length = text.length();
|
||||
}
|
||||
|
||||
TokenType type = TokenType::WORD;
|
||||
string text;
|
||||
idx_t offset = 0;
|
||||
idx_t length = 0;
|
||||
};
|
||||
|
||||
struct MatcherSuggestion {
|
||||
// NOLINTNEXTLINE: allow implicit conversion from auto-complete candidate
|
||||
MatcherSuggestion(AutoCompleteCandidate keyword_p)
|
||||
: keyword(std::move(keyword_p)), type(SuggestionState::SUGGEST_KEYWORD) {
|
||||
}
|
||||
// NOLINTNEXTLINE: allow implicit conversion from suggestion state
|
||||
MatcherSuggestion(SuggestionState type, char extra_char = '\0') : keyword(""), type(type), extra_char(extra_char) {
|
||||
}
|
||||
|
||||
//! Literal suggestion
|
||||
AutoCompleteCandidate keyword;
|
||||
SuggestionState type;
|
||||
char extra_char = '\0';
|
||||
};
|
||||
|
||||
struct MatchState {
|
||||
MatchState(vector<MatcherToken> &tokens, vector<MatcherSuggestion> &suggestions, ParseResultAllocator &allocator)
|
||||
: tokens(tokens), suggestions(suggestions), token_index(0), allocator(allocator) {
|
||||
}
|
||||
MatchState(MatchState &state)
|
||||
: tokens(state.tokens), suggestions(state.suggestions), token_index(state.token_index),
|
||||
allocator(state.allocator) {
|
||||
}
|
||||
|
||||
vector<MatcherToken> &tokens;
|
||||
vector<MatcherSuggestion> &suggestions;
|
||||
reference_set_t<const Matcher> added_suggestions;
|
||||
idx_t token_index;
|
||||
ParseResultAllocator &allocator;
|
||||
|
||||
void AddSuggestion(MatcherSuggestion suggestion);
|
||||
};
|
||||
|
||||
enum class MatcherType { KEYWORD, LIST, OPTIONAL, CHOICE, REPEAT, VARIABLE, STRING_LITERAL, NUMBER_LITERAL, OPERATOR };
|
||||
|
||||
class Matcher {
|
||||
public:
|
||||
explicit Matcher(MatcherType type) : type(type) {
|
||||
}
|
||||
virtual ~Matcher() = default;
|
||||
|
||||
//! Match
|
||||
virtual MatchResultType Match(MatchState &state) const = 0;
|
||||
virtual optional_ptr<ParseResult> MatchParseResult(MatchState &state) const = 0;
|
||||
virtual SuggestionType AddSuggestion(MatchState &state) const;
|
||||
virtual SuggestionType AddSuggestionInternal(MatchState &state) const = 0;
|
||||
virtual string ToString() const = 0;
|
||||
void Print() const;
|
||||
|
||||
static Matcher &RootMatcher(MatcherAllocator &allocator);
|
||||
|
||||
MatcherType Type() const {
|
||||
return type;
|
||||
}
|
||||
void SetName(string name_p) {
|
||||
name = std::move(name_p);
|
||||
}
|
||||
string GetName() const;
|
||||
|
||||
public:
|
||||
template <class TARGET>
|
||||
TARGET &Cast() {
|
||||
if (type != TARGET::TYPE) {
|
||||
throw InternalException("Failed to cast matcher to type - matcher type mismatch");
|
||||
}
|
||||
return reinterpret_cast<TARGET &>(*this);
|
||||
}
|
||||
|
||||
template <class TARGET>
|
||||
const TARGET &Cast() const {
|
||||
if (type != TARGET::TYPE) {
|
||||
throw InternalException("Failed to cast matcher to type - matcher type mismatch");
|
||||
}
|
||||
return reinterpret_cast<const TARGET &>(*this);
|
||||
}
|
||||
|
||||
protected:
|
||||
MatcherType type;
|
||||
string name;
|
||||
};
|
||||
|
||||
class MatcherAllocator {
|
||||
public:
|
||||
Matcher &Allocate(unique_ptr<Matcher> matcher);
|
||||
|
||||
private:
|
||||
vector<unique_ptr<Matcher>> matchers;
|
||||
};
|
||||
|
||||
class ParseResultAllocator {
|
||||
public:
|
||||
optional_ptr<ParseResult> Allocate(unique_ptr<ParseResult> parse_result);
|
||||
|
||||
private:
|
||||
vector<unique_ptr<ParseResult>> parse_results;
|
||||
};
|
||||
|
||||
} // namespace duckdb
|
||||
Reference in New Issue
Block a user