1#include <Common/typeid_cast.h>
2#include <IO/WriteHelpers.h>
3
4#include <Storages/IStorage.h>
5
6#include <Parsers/ASTFunction.h>
7#include <Parsers/ASTIdentifier.h>
8#include <Parsers/ASTSelectQuery.h>
9#include <Parsers/ASTSelectWithUnionQuery.h>
10#include <Parsers/ASTSubquery.h>
11
12#include <Interpreters/interpretSubquery.h>
13#include <Interpreters/DatabaseAndTableWithAlias.h>
14
15namespace DB
16{
17
18std::shared_ptr<InterpreterSelectWithUnionQuery> interpretSubquery(
19 const ASTPtr & table_expression, const Context & context, size_t subquery_depth, const Names & required_source_columns)
20{
21 if (auto * expr = table_expression->as<ASTTableExpression>())
22 {
23 ASTPtr table;
24 if (expr->subquery)
25 table = expr->subquery;
26 else if (expr->table_function)
27 table = expr->table_function;
28 else if (expr->database_and_table_name)
29 table = expr->database_and_table_name;
30
31 return interpretSubquery(table, context, subquery_depth, required_source_columns);
32 }
33
34 /// Subquery or table name. The name of the table is similar to the subquery `SELECT * FROM t`.
35 const auto * subquery = table_expression->as<ASTSubquery>();
36 const auto * function = table_expression->as<ASTFunction>();
37 const auto * table = table_expression->as<ASTIdentifier>();
38
39 if (!subquery && !table && !function)
40 throw Exception("Table expression is undefined, Method: ExpressionAnalyzer::interpretSubquery." , ErrorCodes::LOGICAL_ERROR);
41
42 /** The subquery in the IN / JOIN section does not have any restrictions on the maximum size of the result.
43 * Because the result of this query is not the result of the entire query.
44 * Constraints work instead
45 * max_rows_in_set, max_bytes_in_set, set_overflow_mode,
46 * max_rows_in_join, max_bytes_in_join, join_overflow_mode,
47 * which are checked separately (in the Set, Join objects).
48 */
49 Context subquery_context = context;
50 Settings subquery_settings = context.getSettings();
51 subquery_settings.max_result_rows = 0;
52 subquery_settings.max_result_bytes = 0;
53 /// 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).
54 subquery_settings.extremes = 0;
55 subquery_context.setSettings(subquery_settings);
56
57 auto subquery_options = SelectQueryOptions(QueryProcessingStage::Complete, subquery_depth).subquery();
58
59 ASTPtr query;
60 if (table || function)
61 {
62 /// create ASTSelectQuery for "SELECT * FROM table" as if written by hand
63 const auto select_with_union_query = std::make_shared<ASTSelectWithUnionQuery>();
64 query = select_with_union_query;
65
66 select_with_union_query->list_of_selects = std::make_shared<ASTExpressionList>();
67
68 const auto select_query = std::make_shared<ASTSelectQuery>();
69 select_with_union_query->list_of_selects->children.push_back(select_query);
70
71 select_query->setExpression(ASTSelectQuery::Expression::SELECT, std::make_shared<ASTExpressionList>());
72 const auto select_expression_list = select_query->select();
73
74 NamesAndTypesList columns;
75
76 /// get columns list for target table
77 if (function)
78 {
79 auto query_context = const_cast<Context *>(&context.getQueryContext());
80 const auto & storage = query_context->executeTableFunction(table_expression);
81 columns = storage->getColumns().getOrdinary();
82 select_query->addTableFunction(*const_cast<ASTPtr *>(&table_expression)); // XXX: const_cast should be avoided!
83 }
84 else
85 {
86 DatabaseAndTableWithAlias database_table(*table);
87 const auto & storage = context.getTable(database_table.database, database_table.table);
88 columns = storage->getColumns().getOrdinary();
89 select_query->replaceDatabaseAndTable(database_table.database, database_table.table);
90 }
91
92 select_expression_list->children.reserve(columns.size());
93 /// manually substitute column names in place of asterisk
94 for (const auto & column : columns)
95 select_expression_list->children.emplace_back(std::make_shared<ASTIdentifier>(column.name));
96 }
97 else
98 {
99 query = subquery->children.at(0);
100 subquery_options.removeDuplicates();
101 }
102
103 return std::make_shared<InterpreterSelectWithUnionQuery>(query, subquery_context, subquery_options, required_source_columns);
104}
105
106}
107