presto-main/src/main/java/io/prestosql/operator/scalar/ArrayCombinationsFunction.java/ArrayCombinationsFunction/combinations
class ArrayCombinationsFunction:    @TypeParameter("T")
    @SqlType("array(array(T))")
    public static Block combinations(
            @TypeParameter("T") Type elementType,
            @SqlType("array(T)") Block array,
            @SqlType(INTEGER) long n)
    {
        int arrayLength = array.getPositionCount();
        int combinationLength = toIntExact(n);
        checkCondition(combinationLength >= 0, INVALID_FUNCTION_ARGUMENT, "combination size must not be negative: %s", combinationLength);
        checkCondition(combinationLength <= MAX_COMBINATION_LENGTH, INVALID_FUNCTION_ARGUMENT, "combination size must not exceed %s: %s", MAX_COMBINATION_LENGTH, combinationLength);

        ArrayType arrayType = new ArrayType(elementType);
        if (combinationLength > arrayLength) {
            return arrayType.createBlockBuilder(new PageBuilderStatus().createBlockBuilderStatus(), 0).build();
        }

        int combinationCount = combinationCount(arrayLength, combinationLength);
        checkCondition(combinationCount * (long) combinationLength <= MAX_RESULT_ELEMENTS, INVALID_FUNCTION_ARGUMENT, "combinations exceed max size");

        int[] ids = new int[combinationCount * combinationLength];
        int idsPosition = 0;

        int[] combination = firstCombination(arrayLength, combinationLength);
        do {
            arraycopy(combination, 0, ids, idsPosition, combinationLength);
            idsPosition += combinationLength;
        }
        while (nextCombination(combination, combinationLength));
        verify(idsPosition == ids.length, "idsPosition != ids.length, %s and %s respectively", idsPosition, ids.length);

        int[] offsets = new int[combinationCount + 1];
        setAll(offsets, i -> i * combinationLength);

        return ArrayBlock.fromElementBlock(combinationCount, Optional.empty(), offsets, new DictionaryBlock(array, ids));
    }