| 480 | } |
| 481 | |
| 482 | void PushingToViewsBlockOutputStream::process(const Block & block, ViewInfo & view) |
| 483 | { |
| 484 | Stopwatch watch; |
| 485 | |
| 486 | try |
| 487 | { |
| 488 | BlockInputStreamPtr in; |
| 489 | |
| 490 | /// We need keep InterpreterSelectQuery, until the processing will be finished, since: |
| 491 | /// |
| 492 | /// - We copy Context inside InterpreterSelectQuery to support |
| 493 | /// modification of context (Settings) for subqueries |
| 494 | /// - InterpreterSelectQuery lives shorter than query pipeline. |
| 495 | /// It's used just to build the query pipeline and no longer needed |
| 496 | /// - ExpressionAnalyzer and then, Functions, that created in InterpreterSelectQuery, |
| 497 | /// **can** take a reference to Context from InterpreterSelectQuery |
| 498 | /// (the problem raises only when function uses context from the |
| 499 | /// execute*() method, like FunctionDictGet do) |
| 500 | /// - These objects live inside query pipeline (DataStreams) and the reference become dangling. |
| 501 | |
| 502 | if (view.query) |
| 503 | { |
| 504 | /// We create a table with the same name as original table and the same alias columns, |
| 505 | /// but it will contain single block (that is INSERT-ed into main table). |
| 506 | /// InterpreterSelectQuery will do processing of alias columns. |
| 507 | |
| 508 | auto local_context = Context::createCopy(select_context); |
| 509 | local_context->addViewSource( |
| 510 | StorageValues::create(storage->getStorageID(), metadata_snapshot->getColumns(), block, storage->getVirtuals())); |
| 511 | |
| 512 | #if USE_RDKAFKA |
| 513 | /// Set the limits for Kafka specially as Kafka stream may need long time to write a block with many map keys; |
| 514 | /// If write data timeout, throw exception to trigger re-consumption |
| 515 | if (auto * kafka = dynamic_cast<StorageCloudKafka *>(storage.get())) |
| 516 | { |
| 517 | auto settings = local_context->getSettingsRef(); |
| 518 | settings.max_execution_time = kafka->getSettings().max_write_execution_second; |
| 519 | settings.timeout_overflow_mode = OverflowMode::THROW; |
| 520 | local_context->setSettings(settings); |
| 521 | LOG_TRACE(log, "Set max execution limit for reading from {} to write view with {} s", |
| 522 | storage->getStorageID().getNameForLogs(), local_context->getSettings().max_execution_time.totalSeconds()); |
| 523 | } |
| 524 | #endif |
| 525 | |
| 526 | if (auto * select = view.query->as<ASTSelectWithUnionQuery>()) |
| 527 | { |
| 528 | InterpreterSelectWithUnionQuery interepter_select(view.query, local_context, SelectQueryOptions()); |
| 529 | in = std::make_shared<MaterializingBlockInputStream>(interepter_select.execute().getInputStream()); |
| 530 | } |
| 531 | else |
| 532 | { |
| 533 | InterpreterSelectQuery interepter_select(view.query, local_context, SelectQueryOptions()); |
| 534 | in = std::make_shared<MaterializingBlockInputStream>(interepter_select.execute().getInputStream()); |
| 535 | } |
| 536 | |
| 537 | /// Squashing is needed here because the materialized view query can generate a lot of blocks |
| 538 | /// even when only one block is inserted into the parent table (e.g. if the query is a GROUP BY |
| 539 | /// and two-level aggregation is triggered). |
no test coverage detected