1#pragma once
2
3#include <Core/Block.h>
4#include <Core/NamesAndTypes.h>
5#include <Interpreters/Aliases.h>
6#include <Interpreters/SelectQueryOptions.h>
7#include <Storages/IStorage_fwd.h>
8
9namespace DB
10{
11
12class ASTFunction;
13class AnalyzedJoin;
14class Context;
15struct SelectQueryOptions;
16using Scalars = std::map<String, Block>;
17
18struct SyntaxAnalyzerResult
19{
20 StoragePtr storage;
21 std::shared_ptr<AnalyzedJoin> analyzed_join;
22
23 NamesAndTypesList source_columns;
24 /// Set of columns that are enough to read from the table to evaluate the expression. It does not include joined columns.
25 NamesAndTypesList required_source_columns;
26
27 Aliases aliases;
28 std::vector<const ASTFunction *> aggregates;
29
30 /// Which column is needed to be ARRAY-JOIN'ed to get the specified.
31 /// For example, for `SELECT s.v ... ARRAY JOIN a AS s` will get "s.v" -> "a.v".
32 NameToNameMap array_join_result_to_source;
33
34 /// For the ARRAY JOIN section, mapping from the alias to the full column name.
35 /// For example, for `ARRAY JOIN [1,2] AS b` "b" -> "array(1,2)" will enter here.
36 /// Note: not used further.
37 NameToNameMap array_join_alias_to_name;
38
39 /// The backward mapping for array_join_alias_to_name.
40 /// Note: not used further.
41 NameToNameMap array_join_name_to_alias;
42
43 /// Predicate optimizer overrides the sub queries
44 bool rewrite_subqueries = false;
45
46 /// Results of scalar sub queries
47 Scalars scalars;
48
49 bool maybe_optimize_trivial_count = false;
50
51 void collectUsedColumns(const ASTPtr & query, const NamesAndTypesList & additional_source_columns);
52 Names requiredSourceColumns() const { return required_source_columns.getNames(); }
53 const Scalars & getScalars() const { return scalars; }
54};
55
56using SyntaxAnalyzerResultPtr = std::shared_ptr<const SyntaxAnalyzerResult>;
57
58/// AST syntax analysis.
59/// Optimises AST tree and collect information for further expression analysis.
60/// Result AST has the following invariants:
61/// * all aliases are substituted
62/// * qualified names are translated
63/// * scalar subqueries are executed replaced with constants
64/// * unneeded columns are removed from SELECT clause
65/// * duplicated columns are removed from ORDER BY, LIMIT BY, USING(...).
66/// Motivation:
67/// * group most of the AST-changing operations in single place
68/// * avoid AST rewriting in ExpressionAnalyzer
69/// * decompose ExpressionAnalyzer
70class SyntaxAnalyzer
71{
72public:
73 SyntaxAnalyzer(const Context & context_, const SelectQueryOptions & select_options = {})
74 : context(context_)
75 , subquery_depth(select_options.subquery_depth)
76 , remove_duplicates(select_options.remove_duplicates)
77 {}
78
79 SyntaxAnalyzerResultPtr analyze(
80 ASTPtr & query,
81 const NamesAndTypesList & source_columns_,
82 const Names & required_result_columns = {},
83 StoragePtr storage = {},
84 const NamesAndTypesList & additional_source_columns = {}) const;
85
86private:
87 const Context & context;
88 size_t subquery_depth;
89 bool remove_duplicates;
90};
91
92}
93