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>
2020-02-10 15:50:12 +00:00
# include <Parsers/ASTTablesInSelectQuery.h>
2018-10-12 15:41:28 +00:00
2020-05-20 20:16:32 +00:00
# include <Interpreters/Context.h>
2024-03-19 16:04:29 +00:00
# include <Interpreters/DatabaseAndTableWithAlias.h>
# include <Interpreters/DatabaseCatalog.h>
# include <Interpreters/interpretSubquery.h>
2018-10-12 15:41:28 +00:00
namespace DB
{
2020-02-25 18:10:48 +00:00
namespace ErrorCodes
{
extern const int LOGICAL_ERROR ;
}
2018-10-12 15:41:28 +00:00
std : : shared_ptr < InterpreterSelectWithUnionQuery > interpretSubquery (
2021-04-10 23:33:54 +00:00
const ASTPtr & table_expression , ContextPtr context , size_t subquery_depth , const Names & required_source_columns )
2020-02-20 02:56:20 +00:00
{
auto subquery_options = SelectQueryOptions ( QueryProcessingStage : : Complete , subquery_depth ) ;
return interpretSubquery ( table_expression , context , required_source_columns , subquery_options ) ;
}
std : : shared_ptr < InterpreterSelectWithUnionQuery > interpretSubquery (
2021-04-10 23:33:54 +00:00
const ASTPtr & table_expression , ContextPtr context , const Names & required_source_columns , const SelectQueryOptions & options )
2018-10-12 15:41:28 +00:00
{
2019-09-04 16:20:02 +00:00
if ( auto * expr = table_expression - > as < ASTTableExpression > ( ) )
{
ASTPtr table ;
if ( expr - > subquery )
table = expr - > subquery ;
else if ( expr - > table_function )
table = expr - > table_function ;
else if ( expr - > database_and_table_name )
table = expr - > database_and_table_name ;
2020-02-20 02:56:20 +00:00
return interpretSubquery ( table , context , required_source_columns , options ) ;
2019-09-04 16:20:02 +00:00
}
2018-10-12 15:41:28 +00:00
/// 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 > ( ) ;
2020-10-26 15:49:00 +00:00
const auto * table = table_expression - > as < ASTTableIdentifier > ( ) ;
2018-10-12 15:41:28 +00:00
if ( ! subquery & & ! table & & ! function )
2023-01-23 21:13:58 +00:00
throw Exception ( ErrorCodes : : LOGICAL_ERROR , " Table expression is undefined, Method: ExpressionAnalyzer::interpretSubquery. " ) ;
2018-10-12 15:41:28 +00:00
/** 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 ) .
*/
2021-04-10 23:33:54 +00:00
auto subquery_context = Context : : createCopy ( context ) ;
Settings subquery_settings = context - > getSettings ( ) ;
2018-10-12 15:41:28 +00:00
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).
2020-03-09 00:28:05 +00:00
subquery_settings . extremes = false ;
2021-04-10 23:33:54 +00:00
subquery_context - > setSettings ( subquery_settings ) ;
2018-10-12 15:41:28 +00:00
2020-02-20 02:56:20 +00:00
auto subquery_options = options . subquery ( ) ;
2019-03-18 14:56:33 +00:00
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 )
{
2021-04-10 23:33:54 +00:00
auto query_context = context - > getQueryContext ( ) ;
2018-10-12 15:41:28 +00:00
const auto & storage = query_context - > executeTableFunction ( table_expression ) ;
2020-06-17 16:39:58 +00:00
columns = storage - > getInMemoryMetadataPtr ( ) - > 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
{
2021-04-10 23:33:54 +00:00
auto table_id = context - > resolveStorageID ( table_expression ) ;
2020-05-28 23:01:18 +00:00
const auto & storage = DatabaseCatalog : : instance ( ) . getTable ( table_id , context ) ;
2020-06-17 16:39:58 +00:00
columns = storage - > getInMemoryMetadataPtr ( ) - > getColumns ( ) . getOrdinary ( ) ;
2020-03-12 18:04:29 +00:00
select_query - > replaceDatabaseAndTable ( table_id ) ;
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
}
}