diff options
| author | vitalyisaev <[email protected]> | 2023-11-14 09:58:56 +0300 | 
|---|---|---|
| committer | vitalyisaev <[email protected]> | 2023-11-14 10:20:20 +0300 | 
| commit | c2b2dfd9827a400a8495e172a56343462e3ceb82 (patch) | |
| tree | cd4e4f597d01bede4c82dffeb2d780d0a9046bd0 /contrib/clickhouse/src/Databases/MySQL/tryQuoteUnrecognizedTokens.cpp | |
| parent | d4ae8f119e67808cb0cf776ba6e0cf95296f2df7 (diff) | |
YQ Connector: move tests from yql to ydb (OSS)
Перенос папки с тестами на Коннектор из папки yql в папку ydb (синхронизируется с github).
Diffstat (limited to 'contrib/clickhouse/src/Databases/MySQL/tryQuoteUnrecognizedTokens.cpp')
| -rw-r--r-- | contrib/clickhouse/src/Databases/MySQL/tryQuoteUnrecognizedTokens.cpp | 96 | 
1 files changed, 96 insertions, 0 deletions
| diff --git a/contrib/clickhouse/src/Databases/MySQL/tryQuoteUnrecognizedTokens.cpp b/contrib/clickhouse/src/Databases/MySQL/tryQuoteUnrecognizedTokens.cpp new file mode 100644 index 00000000000..cd4603ddaec --- /dev/null +++ b/contrib/clickhouse/src/Databases/MySQL/tryQuoteUnrecognizedTokens.cpp @@ -0,0 +1,96 @@ +#include <Databases/MySQL/tryQuoteUnrecognizedTokens.h> +#include <Parsers/CommonParsers.h> +#include <Common/quoteString.h> + +namespace DB +{ + +/// Checks if there are no any tokens (like whitespaces) between current and previous pos +static bool noWhitespaces(const char * to, const char * from) +{ +    return static_cast<size_t>(from - to) == 0; +} + +/// Checks if the token should be quoted too together with unrecognized +static bool isWordOrNumber(TokenType type) +{ +    return type == TokenType::BareWord || type == TokenType::Number; +} + +static void quoteLiteral( +    IParser::Pos & pos, +    IParser::Pos & pos_prev, +    const char *& pos_unrecognized, +    const char *& copy_from, +    String & rewritten_query) +{ +    /// Copy also whitespaces if any +    const auto * end = +        isWordOrNumber(pos->type) && noWhitespaces(pos_prev->end, pos->begin) +        ? pos->end +        : pos_prev->end; +    String literal(pos_unrecognized, static_cast<size_t>(end - pos_unrecognized)); +    rewritten_query.append(copy_from, pos_unrecognized - copy_from).append(backQuoteMySQL(literal)); +    copy_from = end; +} + +bool tryQuoteUnrecognizedTokens(const String & query, String & res) +{ +    Tokens tokens(query.data(), query.data() + query.size()); +    IParser::Pos pos(tokens, 0); +    Expected expected; +    String rewritten_query; +    const char * copy_from = query.data(); +    auto pos_prev = pos; +    const char * pos_unrecognized = nullptr; +    for (;pos->type != TokenType::EndOfStream; ++pos) +    { +        /// Commit quotes if any whitespaces found or the token is not a word +        bool commit = !noWhitespaces(pos_prev->end, pos->begin) || (pos->type != TokenType::Error && !isWordOrNumber(pos->type)); +        if (pos_unrecognized && commit) +        { +            quoteLiteral( +                pos, +                pos_prev, +                pos_unrecognized, +                copy_from, +                rewritten_query); +            pos_unrecognized = nullptr; +        } +        if (pos->type == TokenType::Error) +        { +            /// Find first appearance of the error token +            if (!pos_unrecognized) +            { +                pos_unrecognized = +                    isWordOrNumber(pos_prev->type) && noWhitespaces(pos_prev->end, pos->begin) +                    ? pos_prev->begin +                    : pos->begin; +            } +        } +        pos_prev = pos; +    } + +    /// There was EndOfStream but not committed unrecognized token +    if (pos_unrecognized) +    { +        quoteLiteral( +            pos, +            pos_prev, +            pos_unrecognized, +            copy_from, +            rewritten_query); +        pos_unrecognized = nullptr; +    } + +    /// If no Errors found +    if (copy_from == query.data()) +        return false; + +    auto size = static_cast<size_t>(pos->end - copy_from); +    rewritten_query.append(copy_from, size); +    res = rewritten_query; +    return true; +} + +} | 
