1#include <Storages/IStorage.h>
2#include <DataStreams/OneBlockInputStream.h>
3#include <DataStreams/BlockIO.h>
4#include <DataTypes/DataTypeString.h>
5#include <Parsers/queryToString.h>
6#include <Common/typeid_cast.h>
7#include <TableFunctions/ITableFunction.h>
8#include <TableFunctions/TableFunctionFactory.h>
9#include <Interpreters/InterpreterSelectWithUnionQuery.h>
10#include <Interpreters/Context.h>
11#include <Interpreters/InterpreterDescribeQuery.h>
12#include <Interpreters/IdentifierSemantic.h>
13#include <Parsers/ASTIdentifier.h>
14#include <Parsers/ASTFunction.h>
15#include <Parsers/ASTTablesInSelectQuery.h>
16#include <Parsers/TablePropertiesQueriesASTs.h>
17
18
19namespace DB
20{
21
22BlockIO InterpreterDescribeQuery::execute()
23{
24 BlockIO res;
25 res.in = executeImpl();
26 return res;
27}
28
29
30Block InterpreterDescribeQuery::getSampleBlock()
31{
32 Block block;
33
34 ColumnWithTypeAndName col;
35 col.name = "name";
36 col.type = std::make_shared<DataTypeString>();
37 col.column = col.type->createColumn();
38 block.insert(col);
39
40 col.name = "type";
41 block.insert(col);
42
43 col.name = "default_type";
44 block.insert(col);
45
46 col.name = "default_expression";
47 block.insert(col);
48
49 col.name = "comment";
50 block.insert(col);
51
52 col.name = "codec_expression";
53 block.insert(col);
54
55 col.name = "ttl_expression";
56 block.insert(col);
57
58 return block;
59}
60
61
62BlockInputStreamPtr InterpreterDescribeQuery::executeImpl()
63{
64 ColumnsDescription columns;
65
66 const auto & ast = query_ptr->as<ASTDescribeQuery &>();
67 const auto & table_expression = ast.table_expression->as<ASTTableExpression &>();
68 if (table_expression.subquery)
69 {
70 auto names_and_types = InterpreterSelectWithUnionQuery::getSampleBlock(
71 table_expression.subquery->children.at(0), context).getNamesAndTypesList();
72 columns = ColumnsDescription(std::move(names_and_types));
73 }
74 else
75 {
76 StoragePtr table;
77 if (table_expression.table_function)
78 {
79 const auto & table_function = table_expression.table_function->as<ASTFunction &>();
80 TableFunctionPtr table_function_ptr = TableFunctionFactory::instance().get(table_function.name, context);
81 /// Run the table function and remember the result
82 table = table_function_ptr->execute(table_expression.table_function, context, table_function_ptr->getName());
83 }
84 else
85 {
86 const auto & identifier = table_expression.database_and_table_name->as<ASTIdentifier &>();
87
88 String database_name;
89 String table_name;
90 std::tie(database_name, table_name) = IdentifierSemantic::extractDatabaseAndTable(identifier);
91
92 table = context.getTable(database_name, table_name);
93 }
94
95 auto table_lock = table->lockStructureForShare(false, context.getInitialQueryId());
96 columns = table->getColumns();
97 }
98
99 Block sample_block = getSampleBlock();
100 MutableColumns res_columns = sample_block.cloneEmptyColumns();
101
102 for (const auto & column : columns)
103 {
104 if (column.is_virtual)
105 continue;
106
107 res_columns[0]->insert(column.name);
108 res_columns[1]->insert(column.type->getName());
109
110 if (column.default_desc.expression)
111 {
112 res_columns[2]->insert(toString(column.default_desc.kind));
113 res_columns[3]->insert(queryToString(column.default_desc.expression));
114 }
115 else
116 {
117 res_columns[2]->insertDefault();
118 res_columns[3]->insertDefault();
119 }
120
121 res_columns[4]->insert(column.comment);
122
123 if (column.codec)
124 res_columns[5]->insert(column.codec->getCodecDesc());
125 else
126 res_columns[5]->insertDefault();
127
128 if (column.ttl)
129 res_columns[6]->insert(queryToString(column.ttl));
130 else
131 res_columns[6]->insertDefault();
132 }
133
134 return std::make_shared<OneBlockInputStream>(sample_block.cloneWithColumns(std::move(res_columns)));
135}
136
137}
138