aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/sql/v1/sql_group_by.h
blob: 83e602596c6b59504749ceaab21b98b90d727282 (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
61
62
63
64
65
66
67
68
69
70
71
72
73
#pragma once

#include "sql_translation.h"

namespace NSQLTranslationV1 {

using namespace NSQLv1Generated;

class TGroupByClause: public TSqlTranslation {
    enum class EGroupByFeatures {
        Begin,
        Ordinary = Begin,
        Expression,
        Rollup,
        Cube,
        GroupingSet,
        Empty,
        End,
    };
    typedef TEnumBitSet<EGroupByFeatures, static_cast<int>(EGroupByFeatures::Begin), static_cast<int>(EGroupByFeatures::End)> TGroupingSetFeatures;

    class TGroupByClauseCtx: public TSimpleRefCount<TGroupByClauseCtx> {
    public:
        typedef TIntrusivePtr<TGroupByClauseCtx> TPtr;

        TGroupingSetFeatures GroupFeatures;
        TMap<TString, TNodePtr> NodeAliases;
        size_t UnnamedCount = 0;
    };

public:
    TGroupByClause(TContext& ctx, NSQLTranslation::ESqlMode mode, TGroupByClauseCtx::TPtr groupSetContext = {})
        : TSqlTranslation(ctx, mode)
        , GroupSetContext(groupSetContext ? groupSetContext : TGroupByClauseCtx::TPtr(new TGroupByClauseCtx()))
        , CompactGroupBy(false)
    {}

    bool Build(const TRule_group_by_clause& node);
    bool ParseList(const TRule_grouping_element_list& groupingListNode, EGroupByFeatures featureContext);

    void SetFeatures(const TString& field) const;
    TVector<TNodePtr>& Content();
    TMap<TString, TNodePtr>& Aliases();
    TLegacyHoppingWindowSpecPtr GetLegacyHoppingWindow() const;
    bool IsCompactGroupBy() const;
    TString GetSuffix() const;

private:
    TMaybe<TVector<TNodePtr>> MultiplyGroupingSets(const TVector<TNodePtr>& lhs, const TVector<TNodePtr>& rhs) const;
    bool ResolveGroupByAndGrouping();
    bool GroupingElement(const TRule_grouping_element& node, EGroupByFeatures featureContext);
    void FeedCollection(const TNodePtr& elem, TVector<TNodePtr>& collection, bool& hasEmpty) const;
    bool OrdinaryGroupingSet(const TRule_ordinary_grouping_set& node, EGroupByFeatures featureContext);
    bool OrdinaryGroupingSetList(const TRule_ordinary_grouping_set_list& node, EGroupByFeatures featureContext);
    bool HoppingWindow(const TRule_hopping_window_specification& node);

    bool AllowUnnamed(TPosition pos, EGroupByFeatures featureContext);

    TGroupingSetFeatures& Features();
    const TGroupingSetFeatures& Features() const;
    bool AddAlias(const TString& label, const TNodePtr& node);
    TString GenerateGroupByExprName();
    bool IsAutogenerated(const TString* name) const;

    TVector<TNodePtr> GroupBySet;
    TGroupByClauseCtx::TPtr GroupSetContext;
    TLegacyHoppingWindowSpecPtr LegacyHoppingWindowSpec; // stream queries
    static const TString AutogenerateNamePrefix;
    bool CompactGroupBy;
    TString Suffix;
};

} // namespace NSQLTranslationV1