aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Parsers/Kusto/ParserKQLSort.cpp
blob: ef4b84b17c78cacd1fa2ced302dede766b05e3fa (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <Parsers/ASTLiteral.h>
#include <Parsers/IParserBase.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/ASTOrderByElement.h>
#include <Parsers/Kusto/ParserKQLQuery.h>
#include <Parsers/Kusto/ParserKQLSort.h>

namespace DB
{

bool ParserKQLSort :: parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
{
    bool has_dir = false;
    std::vector <bool> has_directions;
    ParserOrderByExpressionList order_list;
    ASTPtr order_expression_list;

    auto expr = getExprFromToken(pos);

    Tokens tokens(expr.c_str(), expr.c_str() + expr.size());
    IParser::Pos new_pos(tokens, pos.max_depth);

    auto pos_backup = new_pos;
    if (!order_list.parse(pos_backup, order_expression_list, expected))
        return false;

    while (!new_pos->isEnd() && new_pos->type != TokenType::PipeMark && new_pos->type != TokenType::Semicolon)
    {
        String tmp(new_pos->begin, new_pos->end);
        if (tmp == "desc" || tmp == "asc")
            has_dir = true;

        if (new_pos->type == TokenType::Comma)
        {
            has_directions.push_back(has_dir);
            has_dir = false;
        }
        ++new_pos;
    }
    has_directions.push_back(has_dir);

    for (uint64_t i = 0; i < order_expression_list->children.size(); ++i)
    {
        if (!has_directions[i])
        {
            auto *order_expr =  order_expression_list->children[i]->as<ASTOrderByElement>();
            order_expr->direction = -1; // default desc
            if (!order_expr->nulls_direction_was_explicitly_specified)
                order_expr->nulls_direction = -1;
            else
                order_expr->nulls_direction = order_expr->nulls_direction == 1 ? -1 : 1;
        }
    }

    node->as<ASTSelectQuery>()->setExpression(ASTSelectQuery::Expression::ORDER_BY, std::move(order_expression_list));

    return true;
}

}