17
17
#include < DataTypes/DataTypeFunction.h>
18
18
#include < DataTypes/DataTypeLowCardinality.h>
19
19
#include < DataTypes/DataTypeMap.h>
20
+ #include < DataTypes/DataTypeTuple.h>
20
21
#include < DataTypes/DataTypesNumber.h>
21
22
22
23
#include < Functions/FunctionHelpers.h>
@@ -115,6 +116,7 @@ class FunctionArrayMapped : public IFunction
115
116
throw Exception (ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
116
117
" Function {} needs one argument with data" , getName ());
117
118
119
+ size_t tuple_argument_size = 0 ;
118
120
size_t nested_types_count = is_argument_type_map ? (arguments.size () - 1 ) * 2 : (arguments.size () - 1 );
119
121
DataTypes nested_types (nested_types_count);
120
122
for (size_t i = 0 ; i < arguments.size () - 1 ; ++i)
@@ -128,6 +130,10 @@ class FunctionArrayMapped : public IFunction
128
130
getName (),
129
131
argument_type_name,
130
132
arguments[i + 1 ]->getName ());
133
+
134
+ if (const auto * tuple_type = checkAndGetDataType<DataTypeTuple>(array_type->getNestedType ().get ()))
135
+ tuple_argument_size = tuple_type->getElements ().size ();
136
+
131
137
if constexpr (is_argument_type_map)
132
138
{
133
139
nested_types[2 * i] = recursiveRemoveLowCardinality (array_type->getKeyType ());
@@ -137,14 +143,41 @@ class FunctionArrayMapped : public IFunction
137
143
{
138
144
nested_types[i] = recursiveRemoveLowCardinality (array_type->getNestedType ());
139
145
}
146
+
140
147
}
141
148
142
149
const DataTypeFunction * function_type = checkAndGetDataType<DataTypeFunction>(arguments[0 ].get ());
143
- if (!function_type || function_type->getArgumentTypes ().size () != nested_types.size ())
150
+ if (!function_type)
151
+ throw Exception (
152
+ ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
153
+ " First argument for this overload of {} must be a function with {} arguments, found {} instead" ,
154
+ getName (),
155
+ nested_types.size (),
156
+ arguments[0 ]->getName ());
157
+
158
+ size_t num_function_arguments = function_type->getArgumentTypes ().size ();
159
+ if (tuple_argument_size > 1
160
+ && tuple_argument_size == num_function_arguments)
161
+ {
162
+ assert (nested_types.size () == 1 );
163
+
164
+ auto argument_type = nested_types[0 ];
165
+ const auto & tuple_type = assert_cast<const DataTypeTuple &>(*argument_type);
166
+
167
+ nested_types.clear ();
168
+ nested_types.reserve (tuple_argument_size);
169
+
170
+ for (const auto & element : tuple_type.getElements ())
171
+ nested_types.push_back (element);
172
+ }
173
+
174
+ if (num_function_arguments != nested_types.size ())
144
175
throw Exception (
145
176
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
146
177
" First argument for this overload of {} must be a function with {} arguments, found {} instead" ,
147
- getName (), nested_types.size (), arguments[0 ]->getName ());
178
+ getName (),
179
+ nested_types.size (),
180
+ arguments[0 ]->getName ());
148
181
149
182
arguments[0 ] = std::make_shared<DataTypeFunction>(nested_types);
150
183
}
@@ -268,6 +301,9 @@ class FunctionArrayMapped : public IFunction
268
301
throw Exception (" First argument for function " + getName () + " must be a function." ,
269
302
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
270
303
304
+ const auto & type_function = assert_cast<const DataTypeFunction &>(*arguments[0 ].type );
305
+ size_t num_function_arguments = type_function.getArgumentTypes ().size ();
306
+
271
307
ColumnPtr offsets_column;
272
308
273
309
ColumnPtr column_first_array_ptr;
@@ -316,24 +352,45 @@ class FunctionArrayMapped : public IFunction
316
352
getName ());
317
353
}
318
354
355
+ const auto * column_tuple = dynamic_cast <const DB::ColumnMap*>(column_array)
356
+ ? checkAndGetColumn<ColumnTuple>(&dynamic_cast <const DB::ColumnMap*>(column_array)->getNestedData ())
357
+ : (dynamic_cast <const DB::ColumnArray*>(column_array)
358
+ ? checkAndGetColumn<ColumnTuple>(&dynamic_cast <const DB::ColumnArray*>(column_array)->getData ())
359
+ : throw Exception (ErrorCodes::BAD_ARGUMENTS, " Expected ColumnMap or ColumnArray, but received a different type." ));
360
+
361
+ size_t tuple_size = column_tuple ? column_tuple->getColumns ().size () : 0 ;
362
+
319
363
if (i == 1 )
320
364
{
321
365
column_first_array_ptr = column_array_ptr;
322
366
column_first_array = column_array;
323
367
}
324
368
325
- if constexpr (is_argument_type_map )
369
+ if (tuple_size > 1 && tuple_size == num_function_arguments )
326
370
{
327
- arrays.emplace_back (ColumnWithTypeAndName (
328
- column_array->getNestedData ().getColumnPtr (0 ), recursiveRemoveLowCardinality (array_type->getKeyType ()), array_with_type_and_name.name +" .key" ));
329
- arrays.emplace_back (ColumnWithTypeAndName (
330
- column_array->getNestedData ().getColumnPtr (1 ), recursiveRemoveLowCardinality (array_type->getValueType ()), array_with_type_and_name.name +" .value" ));
371
+ const auto & type_tuple = assert_cast<const DataTypeTuple &>(*array_type->getNestedType ());
372
+ const auto & tuple_names = type_tuple.getElementNames ();
373
+
374
+ arrays.reserve (column_tuple->getColumns ().size ());
375
+ for (size_t j = 0 ; j < tuple_size; ++j)
376
+ arrays.emplace_back (ColumnWithTypeAndName (
377
+ column_tuple->getColumnPtr (j), recursiveRemoveLowCardinality (type_tuple.getElement (j)), array_with_type_and_name.name + " ." + tuple_names[j]));
331
378
}
332
379
else
333
380
{
334
- arrays.emplace_back (ColumnWithTypeAndName (column_array->getDataPtr (),
335
- recursiveRemoveLowCardinality (array_type->getNestedType ()),
336
- array_with_type_and_name.name ));
381
+ if constexpr (is_argument_type_map)
382
+ {
383
+ arrays.emplace_back (ColumnWithTypeAndName (
384
+ column_array->getNestedData ().getColumnPtr (0 ), recursiveRemoveLowCardinality (array_type->getKeyType ()), array_with_type_and_name.name +" .key" ));
385
+ arrays.emplace_back (ColumnWithTypeAndName (
386
+ column_array->getNestedData ().getColumnPtr (1 ), recursiveRemoveLowCardinality (array_type->getValueType ()), array_with_type_and_name.name +" .value" ));
387
+ }
388
+ else
389
+ {
390
+ arrays.emplace_back (ColumnWithTypeAndName (column_array->getDataPtr (),
391
+ recursiveRemoveLowCardinality (array_type->getNestedType ()),
392
+ array_with_type_and_name.name ));
393
+ }
337
394
}
338
395
}
339
396
0 commit comments