2013-05-24 10:49:19 +00:00
|
|
|
#include <DB/Interpreters/ExpressionAnalyzer.h>
|
|
|
|
#include <DB/Parsers/ParserSelectQuery.h>
|
|
|
|
#include <DB/Parsers/formatAST.h>
|
2015-04-11 03:30:54 +00:00
|
|
|
#include <DB/Parsers/parseQuery.h>
|
2013-06-17 13:35:05 +00:00
|
|
|
#include <DB/Parsers/ExpressionListParsers.h>
|
2015-05-28 03:49:28 +00:00
|
|
|
#include <DB/DataTypes/DataTypeFactory.h>
|
2013-05-24 10:49:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char ** argv)
|
|
|
|
{
|
2014-06-12 00:48:56 +00:00
|
|
|
using namespace DB;
|
|
|
|
|
2013-05-27 14:02:55 +00:00
|
|
|
try
|
|
|
|
{
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-24 10:49:19 +00:00
|
|
|
if (argc < 2)
|
|
|
|
{
|
|
|
|
std::cerr << "at least 1 argument expected" << std::endl;
|
|
|
|
return 1;
|
|
|
|
}
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-24 10:49:19 +00:00
|
|
|
Context context;
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-24 10:49:19 +00:00
|
|
|
NamesAndTypesList columns;
|
|
|
|
for (int i = 2; i + 1 < argc; i += 2)
|
|
|
|
{
|
|
|
|
NameAndTypePair col;
|
2014-07-10 00:31:17 +00:00
|
|
|
col.name = argv[i];
|
2015-05-28 03:49:28 +00:00
|
|
|
col.type = DataTypeFactory::instance().get(argv[i + 1]);
|
2013-05-24 10:49:19 +00:00
|
|
|
columns.push_back(col);
|
|
|
|
}
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-24 10:49:19 +00:00
|
|
|
ASTPtr root;
|
2014-03-10 14:49:36 +00:00
|
|
|
ParserPtr parsers[] = {ParserPtr(new ParserSelectQuery), ParserPtr(new ParserExpressionList)};
|
2013-06-17 13:35:05 +00:00
|
|
|
for (size_t i = 0; i < sizeof(parsers)/sizeof(parsers[0]); ++i)
|
2013-05-24 10:49:19 +00:00
|
|
|
{
|
2013-06-17 13:35:05 +00:00
|
|
|
IParser & parser = *parsers[i];
|
|
|
|
const char * pos = argv[1];
|
|
|
|
const char * end = argv[1] + strlen(argv[1]);
|
2015-04-11 03:30:54 +00:00
|
|
|
const char * max_parsed_pos = pos;
|
2014-06-12 00:48:56 +00:00
|
|
|
Expected expected = "";
|
2015-04-11 03:30:54 +00:00
|
|
|
if (parser.parse(pos, end, root, max_parsed_pos, expected))
|
2013-06-17 13:35:05 +00:00
|
|
|
break;
|
|
|
|
else
|
2014-04-08 07:31:51 +00:00
|
|
|
root = nullptr;
|
2013-06-17 13:35:05 +00:00
|
|
|
}
|
|
|
|
if (!root)
|
|
|
|
{
|
|
|
|
std::cerr << "invalid expression (should be select query or expression list)" << std::endl;
|
2013-05-24 10:49:19 +00:00
|
|
|
return 2;
|
|
|
|
}
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-24 10:49:19 +00:00
|
|
|
formatAST(*root, std::cout);
|
|
|
|
std::cout << std::endl;
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2015-07-15 02:56:12 +00:00
|
|
|
ExpressionAnalyzer analyzer(root, context, {}, columns);
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-30 16:52:21 +00:00
|
|
|
Names required = analyzer.getRequiredColumns();
|
|
|
|
std::cout << "required columns:\n";
|
|
|
|
for (size_t i = 0; i < required.size(); ++i)
|
|
|
|
{
|
|
|
|
std::cout << required[i] << "\n";
|
|
|
|
}
|
|
|
|
std::cout << "\n";
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-06-04 11:00:53 +00:00
|
|
|
std::cout << "only consts:\n\n" << analyzer.getConstActions()->dumpActions() << "\n";
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-24 10:49:19 +00:00
|
|
|
if (analyzer.hasAggregation())
|
|
|
|
{
|
|
|
|
Names key_names;
|
|
|
|
AggregateDescriptions aggregates;
|
|
|
|
analyzer.getAggregateInfo(key_names, aggregates);
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-24 10:49:19 +00:00
|
|
|
std::cout << "keys:\n";
|
|
|
|
for (size_t i = 0; i < key_names.size(); ++i)
|
|
|
|
std::cout << key_names[i] << "\n";
|
|
|
|
std::cout << "\n";
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-24 10:49:19 +00:00
|
|
|
std::cout << "aggregates:\n";
|
|
|
|
for (size_t i = 0; i < aggregates.size(); ++i)
|
|
|
|
{
|
|
|
|
AggregateDescription desc = aggregates[i];
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-24 10:49:19 +00:00
|
|
|
std::cout << desc.column_name << " = " << desc.function->getName() << " ( ";
|
|
|
|
for (size_t j = 0; j < desc.argument_names.size(); ++j)
|
|
|
|
std::cout << desc.argument_names[j] << " ";
|
|
|
|
std::cout << ")\n";
|
|
|
|
}
|
|
|
|
std::cout << "\n";
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-28 11:54:37 +00:00
|
|
|
ExpressionActionsChain before;
|
2014-03-28 20:32:38 +00:00
|
|
|
if (analyzer.appendWhere(before, false))
|
2013-05-28 14:24:20 +00:00
|
|
|
before.addStep();
|
2014-03-28 20:32:38 +00:00
|
|
|
analyzer.appendAggregateFunctionsArguments(before, false);
|
|
|
|
analyzer.appendGroupBy(before, false);
|
2013-05-28 14:24:20 +00:00
|
|
|
before.finalize();
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-28 11:54:37 +00:00
|
|
|
ExpressionActionsChain after;
|
2014-03-28 20:32:38 +00:00
|
|
|
if (analyzer.appendHaving(after, false))
|
2013-05-28 14:24:20 +00:00
|
|
|
after.addStep();
|
2014-03-28 20:32:38 +00:00
|
|
|
analyzer.appendSelect(after, false);
|
|
|
|
analyzer.appendOrderBy(after, false);
|
2013-05-28 14:24:20 +00:00
|
|
|
after.addStep();
|
2014-03-28 20:32:38 +00:00
|
|
|
analyzer.appendProjectResult(after, false);
|
2013-05-28 14:24:20 +00:00
|
|
|
after.finalize();
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-28 11:54:37 +00:00
|
|
|
std::cout << "before aggregation:\n\n";
|
2013-05-28 14:24:20 +00:00
|
|
|
for (size_t i = 0; i < before.steps.size(); ++i)
|
2013-05-28 11:54:37 +00:00
|
|
|
{
|
2013-05-28 14:24:20 +00:00
|
|
|
std::cout << before.steps[i].actions->dumpActions();
|
2013-05-28 11:54:37 +00:00
|
|
|
std::cout << std::endl;
|
|
|
|
}
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-28 11:54:37 +00:00
|
|
|
std::cout << "\nafter aggregation:\n\n";
|
2013-05-28 14:24:20 +00:00
|
|
|
for (size_t i = 0; i < after.steps.size(); ++i)
|
2013-05-28 11:54:37 +00:00
|
|
|
{
|
2013-05-28 14:24:20 +00:00
|
|
|
std::cout << after.steps[i].actions->dumpActions();
|
2013-05-28 11:54:37 +00:00
|
|
|
std::cout << std::endl;
|
|
|
|
}
|
2013-05-24 10:49:19 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-06-26 00:58:14 +00:00
|
|
|
if (typeid_cast<ASTSelectQuery *>(&*root))
|
2013-05-28 11:54:37 +00:00
|
|
|
{
|
|
|
|
ExpressionActionsChain chain;
|
2014-03-28 20:32:38 +00:00
|
|
|
if (analyzer.appendWhere(chain, false))
|
2013-05-28 14:24:20 +00:00
|
|
|
chain.addStep();
|
2014-03-28 20:32:38 +00:00
|
|
|
analyzer.appendSelect(chain, false);
|
|
|
|
analyzer.appendOrderBy(chain, false);
|
2013-05-28 14:24:20 +00:00
|
|
|
chain.addStep();
|
2014-03-28 20:32:38 +00:00
|
|
|
analyzer.appendProjectResult(chain, false);
|
2013-05-28 14:24:20 +00:00
|
|
|
chain.finalize();
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-28 14:24:20 +00:00
|
|
|
for (size_t i = 0; i < chain.steps.size(); ++i)
|
2013-05-28 11:54:37 +00:00
|
|
|
{
|
2013-05-28 14:24:20 +00:00
|
|
|
std::cout << chain.steps[i].actions->dumpActions();
|
2013-05-28 11:54:37 +00:00
|
|
|
std::cout << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-06-04 11:00:53 +00:00
|
|
|
std::cout << "unprojected actions:\n\n" << analyzer.getActions(false)->dumpActions() << "\n";
|
|
|
|
std::cout << "projected actions:\n\n" << analyzer.getActions(true)->dumpActions() << "\n";
|
2013-05-28 11:54:37 +00:00
|
|
|
}
|
2013-05-27 14:02:55 +00:00
|
|
|
}
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-27 14:02:55 +00:00
|
|
|
}
|
|
|
|
catch (Exception & e)
|
|
|
|
{
|
|
|
|
std::cerr << "Exception " << e.what() << ": " << e.displayText() << "\n" << e.getStackTrace().toString();
|
|
|
|
return 3;
|
2013-05-24 10:49:19 +00:00
|
|
|
}
|
2014-06-26 00:58:14 +00:00
|
|
|
|
2013-05-24 10:49:19 +00:00
|
|
|
return 0;
|
|
|
|
}
|