| 1257 | } |
| 1258 | |
| 1259 | ReadFromMerge::ChildPlan ReadFromMerge::createPlanForTable( |
| 1260 | const StorageSnapshotPtr & storage_snapshot_, |
| 1261 | SelectQueryInfo & modified_query_info, |
| 1262 | QueryProcessingStage::Enum processed_stage, |
| 1263 | UInt64 max_block_size, |
| 1264 | const StorageWithLockAndName & storage_with_lock, |
| 1265 | const Names & real_column_names_read_from_the_source_table, |
| 1266 | bool & is_smallest_column_requested, |
| 1267 | const RowPolicyDataOpt & row_policy_data_opt, |
| 1268 | ContextMutablePtr modified_context, |
| 1269 | size_t streams_num) const |
| 1270 | { |
| 1271 | const auto & [database_name, storage, _, table_name] = storage_with_lock; |
| 1272 | auto & modified_select = modified_query_info.query->as<ASTSelectQuery &>(); |
| 1273 | |
| 1274 | if (!InterpreterSelectQuery::isQueryWithFinal(modified_query_info) && storage->needRewriteQueryWithFinal(real_column_names_read_from_the_source_table)) |
| 1275 | { |
| 1276 | /// NOTE: It may not work correctly in some cases, because query was analyzed without final. |
| 1277 | /// However, it's needed for Materialized...SQL and it's unlikely that someone will use it with Merge tables. |
| 1278 | modified_select.setFinal(); |
| 1279 | } |
| 1280 | |
| 1281 | bool use_analyzer = modified_context->getSettingsRef()[Setting::allow_experimental_analyzer]; |
| 1282 | |
| 1283 | auto storage_stage = storage->getQueryProcessingStage(modified_context, |
| 1284 | processed_stage, |
| 1285 | storage_snapshot_, |
| 1286 | modified_query_info); |
| 1287 | |
| 1288 | QueryPlan plan; |
| 1289 | |
| 1290 | bool must_return_interpreter_select_query_plan |
| 1291 | = use_analyzer && processed_stage > QueryProcessingStage::FetchColumns && dynamic_cast<StorageMerge *>(storage.get()); |
| 1292 | if (processed_stage <= storage_stage && !must_return_interpreter_select_query_plan) |
| 1293 | { |
| 1294 | /// If there are only virtual columns in query, we must request at least one other column. |
| 1295 | Names real_column_names = real_column_names_read_from_the_source_table; |
| 1296 | if (real_column_names.empty()) |
| 1297 | { |
| 1298 | real_column_names.push_back(ExpressionActions::getSmallestColumn(storage_snapshot_->metadata->getColumns().getAllPhysical()).name); |
| 1299 | is_smallest_column_requested = true; |
| 1300 | } |
| 1301 | |
| 1302 | storage->read(plan, |
| 1303 | real_column_names, |
| 1304 | storage_snapshot_, |
| 1305 | modified_query_info, |
| 1306 | modified_context, |
| 1307 | processed_stage, |
| 1308 | max_block_size, |
| 1309 | UInt32(streams_num)); |
| 1310 | |
| 1311 | if (!plan.isInitialized()) |
| 1312 | return {}; |
| 1313 | |
| 1314 | if (row_policy_data_opt) |
| 1315 | { |
| 1316 | if (auto * source_step_with_filter = dynamic_cast<SourceStepWithFilter *>((plan.getRootNode()->step.get()))) |
nothing calls this directly
no test coverage detected