| 674 | } |
| 675 | |
| 676 | ColumnPtr FunctionArrayElement::executeTuple(const ColumnsWithTypeAndName & arguments, size_t input_rows_count) const |
| 677 | { |
| 678 | const ColumnArray * col_array = typeid_cast<const ColumnArray *>(arguments[0].column.get()); |
| 679 | |
| 680 | if (!col_array) |
| 681 | return nullptr; |
| 682 | |
| 683 | const ColumnTuple * col_nested = typeid_cast<const ColumnTuple *>(&col_array->getData()); |
| 684 | |
| 685 | if (!col_nested) |
| 686 | return nullptr; |
| 687 | |
| 688 | if (is_mysql_dialect) |
| 689 | throw Exception(ErrorCodes::NOT_IMPLEMENTED, "arrayElement(col, idx) where col is Array(Tuple(T)) is not supported under MySQL."); |
| 690 | |
| 691 | const auto & tuple_columns = col_nested->getColumns(); |
| 692 | size_t tuple_size = tuple_columns.size(); |
| 693 | |
| 694 | const DataTypes & tuple_types = typeid_cast<const DataTypeTuple &>( |
| 695 | *typeid_cast<const DataTypeArray &>(*arguments[0].type).getNestedType()).getElements(); |
| 696 | |
| 697 | /** We will calculate the function for the tuple of the internals of the array. |
| 698 | * To do this, create a temporary columns. |
| 699 | * It will consist of the following columns |
| 700 | * - the index of the array to be taken; |
| 701 | * - an array of the first elements of the tuples; |
| 702 | * - the result of taking the elements by the index for an array of the first elements of the tuples; |
| 703 | * - array of the second elements of the tuples; |
| 704 | * - result of taking elements by index for an array of second elements of tuples; |
| 705 | * ... |
| 706 | */ |
| 707 | ColumnsWithTypeAndName temporary_results(2); |
| 708 | temporary_results[1] = arguments[1]; |
| 709 | |
| 710 | /// results of taking elements by index for arrays from each element of the tuples; |
| 711 | Columns result_tuple_columns(tuple_size); |
| 712 | |
| 713 | for (size_t i = 0; i < tuple_size; ++i) |
| 714 | { |
| 715 | ColumnWithTypeAndName array_of_tuple_section; |
| 716 | array_of_tuple_section.column = ColumnArray::create(tuple_columns[i], col_array->getOffsetsPtr()); |
| 717 | array_of_tuple_section.type = std::make_shared<DataTypeArray>(tuple_types[i]); |
| 718 | temporary_results[0] = array_of_tuple_section; |
| 719 | |
| 720 | auto type = getReturnTypeImpl(temporary_results); |
| 721 | auto col = executeImpl(temporary_results, type, input_rows_count); |
| 722 | result_tuple_columns[i] = std::move(col); |
| 723 | } |
| 724 | |
| 725 | return ColumnTuple::create(result_tuple_columns); |
| 726 | } |
| 727 | |
| 728 | namespace |
| 729 | { |
nothing calls this directly
no test coverage detected