2018-10-12 15:41:28 +00:00
# include <Common/typeid_cast.h>
# include <IO/WriteHelpers.h>
# include <Storages/IStorage.h>
# include <Parsers/ASTFunction.h>
# include <Parsers/ASTIdentifier.h>
# include <Parsers/ASTSelectQuery.h>
# include <Parsers/ASTSelectWithUnionQuery.h>
# include <Parsers/ASTSubquery.h>
# include <Interpreters/interpretSubquery.h>
2018-10-30 16:31:21 +00:00
# include <Interpreters/DatabaseAndTableWithAlias.h>
2018-10-12 15:41:28 +00:00
namespace DB
{
std : : shared_ptr < InterpreterSelectWithUnionQuery > interpretSubquery (
const ASTPtr & table_expression , const Context & context , size_t subquery_depth , const Names & required_source_columns )
{
/// Subquery or table name. The name of the table is similar to the subquery `SELECT * FROM t`.
2019-03-11 13:22:51 +00:00
const auto * subquery = table_expression - > as < ASTSubquery > ( ) ;
const auto * function = table_expression - > as < ASTFunction > ( ) ;
const auto * table = table_expression - > as < ASTIdentifier > ( ) ;
2018-10-12 15:41:28 +00:00
if ( ! subquery & & ! table & & ! function )
throw Exception ( " Table expression is undefined, Method: ExpressionAnalyzer::interpretSubquery. " , ErrorCodes : : LOGICAL_ERROR ) ;
/** The subquery in the IN / JOIN section does not have any restrictions on the maximum size of the result.
* Because the result of this query is not the result of the entire query .
* Constraints work instead
* max_rows_in_set , max_bytes_in_set , set_overflow_mode ,
* max_rows_in_join , max_bytes_in_join , join_overflow_mode ,
* which are checked separately ( in the Set , Join objects ) .
*/
Context subquery_context = context ;
Settings subquery_settings = context . getSettings ( ) ;
subquery_settings . max_result_rows = 0 ;
subquery_settings . max_result_bytes = 0 ;
/// The calculation of `extremes` does not make sense and is not necessary (if you do it, then the `extremes` of the subquery can be taken instead of the whole query).
subquery_settings . extremes = 0 ;
subquery_context . setSettings ( subquery_settings ) ;
2019-03-18 14:56:33 +00:00
auto subquery_options = SelectQueryOptions ( QueryProcessingStage : : Complete , subquery_depth ) . subquery ( ) ;
2018-10-12 15:41:28 +00:00
ASTPtr query ;
if ( table | | function )
{
/// create ASTSelectQuery for "SELECT * FROM table" as if written by hand
const auto select_with_union_query = std : : make_shared < ASTSelectWithUnionQuery > ( ) ;
query = select_with_union_query ;
select_with_union_query - > list_of_selects = std : : make_shared < ASTExpressionList > ( ) ;
const auto select_query = std : : make_shared < ASTSelectQuery > ( ) ;
select_with_union_query - > list_of_selects - > children . push_back ( select_query ) ;
2019-04-09 14:59:06 +00:00
select_query - > setExpression ( ASTSelectQuery : : Expression : : SELECT , std : : make_shared < ASTExpressionList > ( ) ) ;
const auto select_expression_list = select_query - > select ( ) ;
2018-10-12 15:41:28 +00:00
NamesAndTypesList columns ;
/// get columns list for target table
if ( function )
{
auto query_context = const_cast < Context * > ( & context . getQueryContext ( ) ) ;
const auto & storage = query_context - > executeTableFunction ( table_expression ) ;
2019-03-14 15:20:51 +00:00
columns = storage - > getColumns ( ) . getOrdinary ( ) ;
2019-03-11 12:49:39 +00:00
select_query - > addTableFunction ( * const_cast < ASTPtr * > ( & table_expression ) ) ; // XXX: const_cast should be avoided!
2018-10-12 15:41:28 +00:00
}
else
{
2018-10-30 16:31:21 +00:00
DatabaseAndTableWithAlias database_table ( * table ) ;
const auto & storage = context . getTable ( database_table . database , database_table . table ) ;
2019-03-14 15:20:51 +00:00
columns = storage - > getColumns ( ) . getOrdinary ( ) ;
2018-10-30 16:31:21 +00:00
select_query - > replaceDatabaseAndTable ( database_table . database , database_table . table ) ;
2018-10-12 15:41:28 +00:00
}
select_expression_list - > children . reserve ( columns . size ( ) ) ;
/// manually substitute column names in place of asterisk
for ( const auto & column : columns )
select_expression_list - > children . emplace_back ( std : : make_shared < ASTIdentifier > ( column . name ) ) ;
}
else
{
query = subquery - > children . at ( 0 ) ;
2019-03-18 14:56:33 +00:00
subquery_options . removeDuplicates ( ) ;
2018-10-12 15:41:28 +00:00
}
2019-03-18 14:56:33 +00:00
return std : : make_shared < InterpreterSelectWithUnionQuery > ( query , subquery_context , subquery_options , required_source_columns ) ;
2018-10-12 15:41:28 +00:00
}
}