#pragma once #include #include #include #include #include #include #include #include #include #include namespace DB { /** Вернуть названия и типы столбцов указанной таблицы. */ class InterpreterDescribeQuery { public: InterpreterDescribeQuery(ASTPtr query_ptr_, Context & context_) : query_ptr(query_ptr_), context(context_) {} BlockIO execute() { BlockIO res; res.in = executeImpl(); res.in_sample = getSampleBlock(); return res; } BlockInputStreamPtr executeAndFormat(WriteBuffer & buf) { Block sample = getSampleBlock(); ASTPtr format_ast = dynamic_cast(*query_ptr).format; String format_name = format_ast ? dynamic_cast(*format_ast).name : context.getDefaultFormat(); BlockInputStreamPtr in = executeImpl(); BlockOutputStreamPtr out = context.getFormatFactory().getOutput(format_name, buf, sample); copyData(*in, *out); return in; } private: ASTPtr query_ptr; Context context; Block getSampleBlock() { Block block; ColumnWithNameAndType col; col.name = "name"; col.type = new DataTypeString; col.column = col.type->createColumn(); block.insert(col); col.name = "type"; block.insert(col); return block; } BlockInputStreamPtr executeImpl() { const ASTDescribeQuery & ast = dynamic_cast(*query_ptr); NamesAndTypesList columns; { Poco::ScopedLock lock(context.getMutex()); if (!context.isTableExist(ast.database, ast.table)) throw Exception("Table " + (ast.database.empty() ? "" : ast.database + ".") + ast.table + " doesn't exist", ErrorCodes::UNKNOWN_TABLE); columns = context.getTable(ast.database, ast.table)->getColumnsList(); } ColumnString * name_column = new ColumnString; ColumnString * type_column = new ColumnString; Block block; block.insert(ColumnWithNameAndType(name_column, new DataTypeString, "name")); block.insert(ColumnWithNameAndType(type_column, new DataTypeString, "type")); for (NamesAndTypesList::iterator it = columns.begin(); it != columns.end(); ++it) { name_column->insert(it->first); type_column->insert(it->second->getName()); } return new OneBlockInputStream(block); } }; }