| 163 | } |
| 164 | |
| 165 | BlockIO ClickHouseDictionarySource::createStreamForQuery(const String & query) |
| 166 | { |
| 167 | BlockIO io; |
| 168 | |
| 169 | /// Sample block should not contain first row default values |
| 170 | auto empty_sample_block = std::make_shared<const Block>(sample_block.cloneEmpty()); |
| 171 | |
| 172 | /// Copy context because results of scalar subqueries potentially could be cached |
| 173 | auto context_copy = Context::createCopy(context); |
| 174 | context_copy->makeQueryContext(); |
| 175 | |
| 176 | const char * query_begin = query.data(); |
| 177 | const char * query_end = query.data() + query.size(); |
| 178 | ParserQuery parser(query_end); |
| 179 | ASTPtr ast = parseQuery(parser, query_begin, query_end, "Query for ClickHouse dictionary", 0, DBMS_DEFAULT_MAX_PARSER_DEPTH, DBMS_DEFAULT_MAX_PARSER_BACKTRACKS); |
| 180 | |
| 181 | if (!ast || ast->getQueryKind() != IAST::QueryKind::Select) |
| 182 | throw Exception(ErrorCodes::INCORRECT_QUERY, "Only SELECT query can be used as a dictionary source"); |
| 183 | |
| 184 | if (configuration.is_local) |
| 185 | { |
| 186 | context_copy->setCurrentQueryId({}); |
| 187 | |
| 188 | if (!CurrentThread::getGroup()) |
| 189 | io.query_scope = QueryScope::create(context_copy); |
| 190 | |
| 191 | io = executeQuery(query, context_copy, QueryFlags{ .internal = true }).second; |
| 192 | |
| 193 | io.pipeline.convertStructureTo(empty_sample_block->getColumnsWithTypeAndName(), context_copy); |
| 194 | } |
| 195 | else |
| 196 | { |
| 197 | io.pipeline = QueryPipeline(std::make_shared<RemoteSource>( |
| 198 | std::make_shared<RemoteQueryExecutor>(pool, query, empty_sample_block, std::move(context_copy)), false, false, false)); |
| 199 | } |
| 200 | |
| 201 | return io; |
| 202 | } |
| 203 | |
| 204 | std::string ClickHouseDictionarySource::doInvalidateQuery(const std::string & request) const |
| 205 | { |
nothing calls this directly
no test coverage detected