| 341 | } |
| 342 | |
| 343 | WindowTransform::WindowTransform(const Block & input_header_, |
| 344 | const Block & output_header_, |
| 345 | const WindowDescription & window_description_, |
| 346 | const std::vector<WindowFunctionDescription> & functions, |
| 347 | DialectType dialect_type_) |
| 348 | : IProcessor({input_header_}, {output_header_}) |
| 349 | , input(inputs.front()) |
| 350 | , output(outputs.front()) |
| 351 | , input_header(input_header_) |
| 352 | , window_description(window_description_) |
| 353 | , dt(dialect_type_) |
| 354 | { |
| 355 | // Materialize all columns in header, because we materialize all columns |
| 356 | // in chunks and it's convenient if they match. |
| 357 | auto input_columns = input_header.getColumns(); |
| 358 | for (auto & column : input_columns) |
| 359 | { |
| 360 | column = std::move(column)->convertToFullColumnIfConst(); |
| 361 | } |
| 362 | input_header.setColumns(input_columns); |
| 363 | |
| 364 | // Initialize window function workspaces. |
| 365 | workspaces.reserve(functions.size()); |
| 366 | for (const auto & f : functions) |
| 367 | { |
| 368 | WindowFunctionWorkspace workspace; |
| 369 | workspace.aggregate_function = f.aggregate_function; |
| 370 | const auto & aggregate_function = workspace.aggregate_function; |
| 371 | if (!arena && aggregate_function->allocatesMemoryInArena()) |
| 372 | { |
| 373 | arena = std::make_unique<Arena>(); |
| 374 | } |
| 375 | |
| 376 | workspace.argument_column_indices.reserve(f.argument_names.size()); |
| 377 | for (const auto & argument_name : f.argument_names) |
| 378 | { |
| 379 | workspace.argument_column_indices.push_back( |
| 380 | input_header.getPositionByName(argument_name)); |
| 381 | } |
| 382 | workspace.argument_columns.assign(f.argument_names.size(), nullptr); |
| 383 | |
| 384 | /// Currently we have slightly wrong mixup of the interfaces of Window and Aggregate functions. |
| 385 | workspace.window_function_impl = dynamic_cast<IWindowFunction *>(const_cast<IAggregateFunction *>(aggregate_function.get())); |
| 386 | |
| 387 | workspace.aggregate_function_state.reset( |
| 388 | aggregate_function->sizeOfData(), |
| 389 | aggregate_function->alignOfData()); |
| 390 | aggregate_function->create(workspace.aggregate_function_state.data()); |
| 391 | |
| 392 | if (workspace.window_function_impl && workspace.window_function_impl->hasSecondStage()) |
| 393 | { |
| 394 | has_two_stage_exection = true; |
| 395 | } |
| 396 | |
| 397 | workspaces.push_back(std::move(workspace)); |
| 398 | } |
| 399 | |
| 400 | partition_by_indices.reserve(window_description.partition_by.size()); |
nothing calls this directly
no test coverage detected