1#include <DataTypes/DataTypesNumber.h>
2
3#include <Storages/System/StorageSystemOne.h>
4#include <Storages/System/StorageSystemNumbers.h>
5#include <Databases/DatabaseMemory.h>
6
7#include <Parsers/ParserSelectQuery.h>
8#include <Parsers/parseQuery.h>
9
10#include <Interpreters/Context.h>
11#include <Interpreters/SyntaxAnalyzer.h>
12
13#include <IO/WriteBufferFromFileDescriptor.h>
14#include <IO/ReadBufferFromFileDescriptor.h>
15
16#include <vector>
17#include <unordered_map>
18#include <iostream>
19
20
21using namespace DB;
22
23namespace DB
24{
25 namespace ErrorCodes
26 {
27 extern const int SYNTAX_ERROR;
28 }
29}
30
31struct TestEntry
32{
33 String query;
34 std::unordered_map<String, String> expected_aliases; /// alias -> AST.getID()
35 NamesAndTypesList source_columns = {};
36 Names required_result_columns = {};
37
38 bool check(const Context & context)
39 {
40 ASTPtr ast = parse(query);
41
42 auto res = SyntaxAnalyzer(context, {}).analyze(ast, source_columns, required_result_columns);
43 return checkAliases(*res);
44 }
45
46private:
47 bool checkAliases(const SyntaxAnalyzerResult & res)
48 {
49 for (const auto & alias : res.aliases)
50 {
51 const String & alias_name = alias.first;
52 if (expected_aliases.count(alias_name) == 0 ||
53 expected_aliases[alias_name] != alias.second->getID())
54 {
55 std::cout << "unexpected alias: " << alias_name << ' ' << alias.second->getID() << std::endl;
56 return false;
57 }
58 else
59 expected_aliases.erase(alias_name);
60 }
61
62 if (!expected_aliases.empty())
63 {
64 std::cout << "missing aliases: " << expected_aliases.size() << std::endl;
65 return false;
66 }
67
68 return true;
69 }
70
71 static ASTPtr parse(const std::string & query)
72 {
73 ParserSelectQuery parser;
74 std::string message;
75 auto text = query.data();
76 if (ASTPtr ast = tryParseQuery(parser, text, text + query.size(), message, false, "", false, 0))
77 return ast;
78 throw Exception(message, ErrorCodes::SYNTAX_ERROR);
79 }
80};
81
82
83int main()
84{
85 std::vector<TestEntry> queries =
86 {
87 {
88 "SELECT number AS n FROM system.numbers LIMIT 0",
89 {{"n", "Identifier_number"}},
90 { NameAndTypePair("number", std::make_shared<DataTypeUInt64>()) }
91 },
92
93 {
94 "SELECT number AS n FROM system.numbers LIMIT 0",
95 {{"n", "Identifier_number"}}
96 }
97 };
98
99 Context context = Context::createGlobal();
100 context.makeGlobalContext();
101
102 auto system_database = std::make_shared<DatabaseMemory>("system");
103 context.addDatabase("system", system_database);
104 //context.setCurrentDatabase("system");
105 system_database->attachTable("one", StorageSystemOne::create("one"));
106 system_database->attachTable("numbers", StorageSystemNumbers::create("numbers", false));
107
108 size_t success = 0;
109 for (auto & entry : queries)
110 {
111 try
112 {
113 if (entry.check(context))
114 {
115 ++success;
116 std::cout << "[OK] " << entry.query << std::endl;
117 }
118 else
119 std::cout << "[Failed] " << entry.query << std::endl;
120 }
121 catch (Exception & e)
122 {
123 std::cout << "[Error] " << entry.query << std::endl << e.displayText() << std::endl;
124 }
125 }
126
127 return success != queries.size();
128}
129