2018-10-19 15:33:40 +00:00
|
|
|
#include <DataTypes/DataTypesNumber.h>
|
|
|
|
|
|
|
|
#include <Storages/System/StorageSystemOne.h>
|
|
|
|
#include <Storages/System/StorageSystemNumbers.h>
|
|
|
|
#include <Databases/DatabaseMemory.h>
|
|
|
|
|
|
|
|
#include <Parsers/ParserSelectQuery.h>
|
|
|
|
#include <Parsers/parseQuery.h>
|
|
|
|
|
|
|
|
#include <Interpreters/Context.h>
|
2018-11-07 12:55:19 +00:00
|
|
|
#include <Interpreters/SyntaxAnalyzer.h>
|
2018-10-19 15:33:40 +00:00
|
|
|
|
|
|
|
#include <IO/WriteBufferFromFileDescriptor.h>
|
|
|
|
#include <IO/ReadBufferFromFileDescriptor.h>
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
|
|
|
|
using namespace DB;
|
|
|
|
|
2018-11-22 21:19:58 +00:00
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int SYNTAX_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-19 15:33:40 +00:00
|
|
|
struct TestEntry
|
|
|
|
{
|
|
|
|
String query;
|
|
|
|
std::unordered_map<String, String> expected_aliases; /// alias -> AST.getID()
|
|
|
|
NamesAndTypesList source_columns = {};
|
|
|
|
|
|
|
|
bool check(const Context & context)
|
|
|
|
{
|
|
|
|
ASTPtr ast = parse(query);
|
|
|
|
|
2020-02-28 10:38:46 +00:00
|
|
|
auto res = SyntaxAnalyzer(context).analyze(ast, source_columns);
|
2018-11-12 15:40:33 +00:00
|
|
|
return checkAliases(*res);
|
2018-10-19 15:33:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2018-11-07 12:55:19 +00:00
|
|
|
bool checkAliases(const SyntaxAnalyzerResult & res)
|
2018-10-19 15:33:40 +00:00
|
|
|
{
|
2018-11-07 12:55:19 +00:00
|
|
|
for (const auto & alias : res.aliases)
|
2018-10-19 15:33:40 +00:00
|
|
|
{
|
|
|
|
const String & alias_name = alias.first;
|
|
|
|
if (expected_aliases.count(alias_name) == 0 ||
|
|
|
|
expected_aliases[alias_name] != alias.second->getID())
|
|
|
|
{
|
|
|
|
std::cout << "unexpected alias: " << alias_name << ' ' << alias.second->getID() << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
expected_aliases.erase(alias_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!expected_aliases.empty())
|
|
|
|
{
|
|
|
|
std::cout << "missing aliases: " << expected_aliases.size() << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static ASTPtr parse(const std::string & query)
|
|
|
|
{
|
|
|
|
ParserSelectQuery parser;
|
|
|
|
std::string message;
|
|
|
|
auto text = query.data();
|
|
|
|
if (ASTPtr ast = tryParseQuery(parser, text, text + query.size(), message, false, "", false, 0))
|
|
|
|
return ast;
|
2018-11-22 21:19:58 +00:00
|
|
|
throw Exception(message, ErrorCodes::SYNTAX_ERROR);
|
2018-10-19 15:33:40 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
std::vector<TestEntry> queries =
|
|
|
|
{
|
|
|
|
{
|
|
|
|
"SELECT number AS n FROM system.numbers LIMIT 0",
|
|
|
|
{{"n", "Identifier_number"}},
|
|
|
|
{ NameAndTypePair("number", std::make_shared<DataTypeUInt64>()) }
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"SELECT number AS n FROM system.numbers LIMIT 0",
|
|
|
|
{{"n", "Identifier_number"}}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Context context = Context::createGlobal();
|
2019-07-08 02:14:32 +00:00
|
|
|
context.makeGlobalContext();
|
2018-10-19 15:33:40 +00:00
|
|
|
|
|
|
|
auto system_database = std::make_shared<DatabaseMemory>("system");
|
2020-02-10 13:10:17 +00:00
|
|
|
DatabaseCatalog::instance().attachDatabase("system", system_database);
|
2018-10-19 15:33:40 +00:00
|
|
|
//context.setCurrentDatabase("system");
|
|
|
|
system_database->attachTable("one", StorageSystemOne::create("one"));
|
2020-03-10 19:36:17 +00:00
|
|
|
system_database->attachTable("numbers", StorageSystemNumbers::create(StorageID("system", "numbers"), false));
|
2018-10-19 15:33:40 +00:00
|
|
|
|
|
|
|
size_t success = 0;
|
|
|
|
for (auto & entry : queries)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (entry.check(context))
|
|
|
|
{
|
|
|
|
++success;
|
|
|
|
std::cout << "[OK] " << entry.query << std::endl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
std::cout << "[Failed] " << entry.query << std::endl;
|
|
|
|
}
|
|
|
|
catch (Exception & e)
|
|
|
|
{
|
|
|
|
std::cout << "[Error] " << entry.query << std::endl << e.displayText() << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return success != queries.size();
|
|
|
|
}
|