@ScalarFunction(value = "destructure_tdigest", visibility = EXPERIMENTAL)
    @Description("Return the raw TDigest, including arrays of centroid means and weights, as well as min, max, sum, count, and compression factor.")
    @SqlType("row(centroid_means array(double), centroid_weights array(integer), compression double, min double, max double, sum double, count bigint)")
    public static Block destructureTDigest(@SqlType("tdigest(double)") Slice input)
    {
        TDigest tDigest = createTDigest(input);

        BlockBuilder blockBuilder = TDIGEST_CENTROIDS_ROW_TYPE.createBlockBuilder(null, 1);
        BlockBuilder rowBuilder = blockBuilder.beginBlockEntry();

        // Centroid means / weights
        BlockBuilder meansBuilder = DOUBLE.createBlockBuilder(null, tDigest.centroidCount());
        BlockBuilder weightsBuilder = INTEGER.createBlockBuilder(null, tDigest.centroidCount());
        for (Centroid centroid : tDigest.centroids()) {
            int weight = (int) centroid.getWeight();
            DOUBLE.writeDouble(meansBuilder, centroid.getMean());
            INTEGER.writeLong(weightsBuilder, weight);
        }
        rowBuilder.appendStructure(meansBuilder);
        rowBuilder.appendStructure(weightsBuilder);

        // Compression, min, max, sum, count
        DOUBLE.writeDouble(rowBuilder, tDigest.getCompressionFactor());
        DOUBLE.writeDouble(rowBuilder, tDigest.getMin());
        DOUBLE.writeDouble(rowBuilder, tDigest.getMax());
        DOUBLE.writeDouble(rowBuilder, tDigest.getSum());
        BIGINT.writeLong(rowBuilder, (long) tDigest.getSize());

        blockBuilder.closeEntry();
        return TDIGEST_CENTROIDS_ROW_TYPE.getObject(blockBuilder, blockBuilder.getPositionCount() - 1);
    }
@Test
    public void testDestructureTDigest()
    {
        TDigest tDigest = createTDigest(STANDARD_COMPRESSION_FACTOR);
        ImmutableList<Double> values = ImmutableList.of(0.0d, 1.0d, 2.0d, 3.0d, 4.0d, 5.0d, 6.0d, 7.0d, 8.0d, 9.0d);
        values.stream().forEach(tDigest::add);

        List<Integer> weights = Collections.nCopies(values.size(), 1);
        double compression = Double.valueOf(STANDARD_COMPRESSION_FACTOR);
        double min = values.stream().reduce(Double.POSITIVE_INFINITY, Double::min);
        double max = values.stream().reduce(Double.NEGATIVE_INFINITY, Double::max);
        double sum = values.stream().reduce(0.0d, Double::sum);
        long count = values.size();

        String sql = format("destructure_tdigest(%s)", toSqlString(tDigest));

        functionAssertions.assertFunction(
                sql,
                TDIGEST_CENTROIDS_ROW_TYPE,
                ImmutableList.of(values, weights, compression, min, max, sum, count));

        functionAssertions.assertFunction(format("%s.compression", sql), DOUBLE, compression);
        functionAssertions.assertFunction(format("%s.min", sql), DOUBLE, min);
        functionAssertions.assertFunction(format("%s.max", sql), DOUBLE, max);
        functionAssertions.assertFunction(format("%s.sum", sql), DOUBLE, sum);
        functionAssertions.assertFunction(format("%s.count", sql), BIGINT, count);
        functionAssertions.assertFunction(
                format("%s.centroid_means", sql),
                new ArrayType(DOUBLE),
                values);
        functionAssertions.assertFunction(
                format("%s.centroid_weights", sql),
                new ArrayType(INTEGER),
                weights);
    }