2018-08-16 02:55:52 +00:00
|
|
|
#include <Interpreters/InterpreterSelectQuery.h>
|
2018-02-25 06:34:20 +00:00
|
|
|
#include <Interpreters/InterpreterSelectWithUnionQuery.h>
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Parsers/ASTCreateQuery.h>
|
2018-08-16 02:55:52 +00:00
|
|
|
#include <Parsers/ASTSubquery.h>
|
2013-11-08 17:43:03 +00:00
|
|
|
|
2017-04-01 09:19:00 +00:00
|
|
|
#include <Storages/StorageView.h>
|
2017-12-30 00:36:06 +00:00
|
|
|
#include <Storages/StorageFactory.h>
|
2013-11-08 17:43:03 +00:00
|
|
|
|
2018-02-28 19:47:33 +00:00
|
|
|
#include <DataStreams/MaterializingBlockInputStream.h>
|
|
|
|
|
2018-08-16 02:55:52 +00:00
|
|
|
#include <Common/typeid_cast.h>
|
2018-09-12 05:41:09 +00:00
|
|
|
#include <Interpreters/PredicateExpressionsOptimizer.h>
|
|
|
|
#include <Parsers/ASTAsterisk.h>
|
|
|
|
#include <iostream>
|
|
|
|
#include <Parsers/queryToString.h>
|
2013-10-30 13:52:02 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2016-01-11 21:46:36 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
2017-09-19 19:18:34 +00:00
|
|
|
extern const int INCORRECT_QUERY;
|
2018-08-16 02:55:52 +00:00
|
|
|
extern const int LOGICAL_ERROR;
|
2016-01-11 21:46:36 +00:00
|
|
|
}
|
|
|
|
|
2013-10-30 13:52:02 +00:00
|
|
|
|
2014-09-30 03:08:47 +00:00
|
|
|
StorageView::StorageView(
|
2017-04-01 07:20:54 +00:00
|
|
|
const String & table_name_,
|
2017-09-17 18:49:43 +00:00
|
|
|
const ASTCreateQuery & query,
|
2018-03-06 20:18:34 +00:00
|
|
|
const ColumnsDescription & columns_)
|
|
|
|
: IStorage{columns_}, table_name(table_name_)
|
2013-11-08 17:43:03 +00:00
|
|
|
{
|
2017-09-19 19:18:34 +00:00
|
|
|
if (!query.select)
|
|
|
|
throw Exception("SELECT query is not specified for " + getName(), ErrorCodes::INCORRECT_QUERY);
|
|
|
|
|
2017-09-17 18:49:43 +00:00
|
|
|
inner_query = query.select->ptr();
|
2013-11-08 17:43:03 +00:00
|
|
|
}
|
|
|
|
|
2014-06-12 23:21:38 +00:00
|
|
|
|
2013-11-08 17:43:03 +00:00
|
|
|
BlockInputStreams StorageView::read(
|
2017-04-01 07:20:54 +00:00
|
|
|
const Names & column_names,
|
2018-08-16 02:55:52 +00:00
|
|
|
const SelectQueryInfo & query_info,
|
2017-04-01 07:20:54 +00:00
|
|
|
const Context & context,
|
2018-09-08 11:29:23 +00:00
|
|
|
QueryProcessingStage::Enum /*processed_stage*/,
|
2017-12-01 21:13:25 +00:00
|
|
|
const size_t /*max_block_size*/,
|
|
|
|
const unsigned /*num_streams*/)
|
2013-10-30 13:52:02 +00:00
|
|
|
{
|
2018-08-16 02:55:52 +00:00
|
|
|
BlockInputStreams res;
|
|
|
|
|
2018-09-17 15:30:15 +00:00
|
|
|
ASTPtr current_inner_query = inner_query;
|
2018-09-12 05:41:09 +00:00
|
|
|
|
2018-08-16 02:55:52 +00:00
|
|
|
if (context.getSettings().enable_optimize_predicate_expression)
|
|
|
|
{
|
2018-09-12 05:41:09 +00:00
|
|
|
auto new_inner_query = inner_query->clone();
|
|
|
|
auto new_outer_query = query_info.query->clone();
|
|
|
|
auto new_outer_select = typeid_cast<ASTSelectQuery *>(new_outer_query.get());
|
|
|
|
|
|
|
|
replaceTableNameWithSubquery(new_outer_select, new_inner_query);
|
2018-08-16 02:55:52 +00:00
|
|
|
|
2018-09-12 05:41:09 +00:00
|
|
|
if (PredicateExpressionsOptimizer(new_outer_select, context.getSettings(), context).optimize())
|
|
|
|
current_inner_query = new_inner_query;
|
2018-08-16 02:55:52 +00:00
|
|
|
}
|
|
|
|
|
2018-09-12 05:41:09 +00:00
|
|
|
res = InterpreterSelectWithUnionQuery(current_inner_query, context, column_names).executeWithMultipleStreams();
|
2018-02-28 19:47:33 +00:00
|
|
|
|
|
|
|
/// It's expected that the columns read from storage are not constant.
|
|
|
|
/// Because method 'getSampleBlockForColumns' is used to obtain a structure of result in InterpreterSelectQuery.
|
|
|
|
for (auto & stream : res)
|
|
|
|
stream = std::make_shared<MaterializingBlockInputStream>(stream);
|
|
|
|
|
|
|
|
return res;
|
2013-11-08 17:43:03 +00:00
|
|
|
}
|
|
|
|
|
2018-08-16 02:55:52 +00:00
|
|
|
void StorageView::replaceTableNameWithSubquery(ASTSelectQuery * select_query, ASTPtr & subquery)
|
|
|
|
{
|
|
|
|
ASTTablesInSelectQueryElement * select_element = static_cast<ASTTablesInSelectQueryElement *>(select_query->tables->children[0].get());
|
|
|
|
|
|
|
|
if (!select_element->table_expression)
|
|
|
|
throw Exception("Logical error: incorrect table expression", ErrorCodes::LOGICAL_ERROR);
|
|
|
|
|
|
|
|
ASTTableExpression * table_expression = static_cast<ASTTableExpression *>(select_element->table_expression.get());
|
|
|
|
|
|
|
|
if (!table_expression->database_and_table_name)
|
|
|
|
throw Exception("Logical error: incorrect table expression", ErrorCodes::LOGICAL_ERROR);
|
|
|
|
|
2018-09-12 05:41:09 +00:00
|
|
|
const auto alias = table_expression->database_and_table_name->tryGetAlias();
|
2018-08-16 02:55:52 +00:00
|
|
|
table_expression->database_and_table_name = {};
|
|
|
|
table_expression->subquery = std::make_shared<ASTSubquery>();
|
2018-09-12 05:41:09 +00:00
|
|
|
table_expression->subquery->children.push_back(subquery);
|
|
|
|
if (!alias.empty())
|
|
|
|
table_expression->subquery->setAlias(alias);
|
2018-08-16 02:55:52 +00:00
|
|
|
}
|
|
|
|
|
2017-12-30 00:36:06 +00:00
|
|
|
|
|
|
|
void registerStorageView(StorageFactory & factory)
|
|
|
|
{
|
|
|
|
factory.registerStorage("View", [](const StorageFactory::Arguments & args)
|
|
|
|
{
|
|
|
|
if (args.query.storage)
|
|
|
|
throw Exception("Specifying ENGINE is not allowed for a View", ErrorCodes::INCORRECT_QUERY);
|
|
|
|
|
2018-03-01 04:23:32 +00:00
|
|
|
return StorageView::create(args.table_name, args.query, args.columns);
|
2017-12-30 00:36:06 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-10-30 13:52:02 +00:00
|
|
|
}
|