You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by gi...@apache.org on 2020/08/10 22:19:09 UTC

[druid] branch master updated: Vectorization support for long, double, float min & max aggregators. (#10260)

This is an automated email from the ASF dual-hosted git repository.

gian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new dc16aba  Vectorization support for long, double, float min & max aggregators. (#10260)
dc16aba is described below

commit dc16abae34ca9f4159f692ee866a122f70de9cdf
Author: Abhishek Radhakrishnan <ab...@gmail.com>
AuthorDate: Mon Aug 10 15:18:55 2020 -0700

    Vectorization support for long, double, float min & max aggregators. (#10260)
    
    * LongMaxVectorAggregator support and test case.
    
    * DoubleMinVectorAggregator and test cases.
    
    * DoubleMaxVectorAggregator and unit test.
    
    * FloatMinVectorAggregator and FloatMaxVectorAggregator.
    
    * Documentation update to include the other vector aggregators.
    
    * Bug fix.
    
    * checkstyle formatting fixes.
    
    * CalciteQueryTest cases update.
    
    * Separate test classes for FloatMaxAggregation and FloatMniAggregation.
    
    * remove the cannotVectorize for float max/min aggregator in test.
    
    * Tests in GroupByQueryRunner, GroupByTimeseriesQueryRunner and TimeseriesQueryRunner.
---
 docs/querying/query-context.md                     |   2 +-
 .../aggregation/DoubleMaxAggregatorFactory.java    |  29 +++++
 .../aggregation/DoubleMaxVectorAggregator.java     |  83 +++++++++++++++
 .../aggregation/DoubleMinAggregatorFactory.java    |  29 +++++
 .../aggregation/DoubleMinVectorAggregator.java     |  83 +++++++++++++++
 .../aggregation/FloatMaxAggregatorFactory.java     |  30 ++++++
 .../aggregation/FloatMaxVectorAggregator.java      |  83 +++++++++++++++
 .../aggregation/FloatMinAggregatorFactory.java     |  31 +++++-
 .../aggregation/FloatMinVectorAggregator.java      |  83 +++++++++++++++
 .../aggregation/LongMaxAggregatorFactory.java      |  29 +++++
 .../query/aggregation/LongMaxVectorAggregator.java |  83 +++++++++++++++
 .../apache/druid/query/QueryRunnerTestHelper.java  |  15 +++
 .../aggregation/DoubleMaxAggregationTest.java      |  52 +++++++++
 .../aggregation/DoubleMinAggregationTest.java      |  55 +++++++++-
 .../query/aggregation/FloatMaxAggregationTest.java |  94 ++++++++++++++++
 .../query/aggregation/FloatMinAggregationTest.java |  94 ++++++++++++++++
 .../query/aggregation/LongMaxAggregationTest.java  |  54 +++++++++-
 .../query/groupby/GroupByQueryRunnerTest.java      |  49 +++++++--
 .../groupby/GroupByTimeseriesQueryRunnerTest.java  |  14 ++-
 .../timeseries/TimeseriesQueryRunnerTest.java      | 118 ++++++++++++---------
 .../apache/druid/sql/calcite/CalciteQueryTest.java |  76 +++++++++----
 21 files changed, 1099 insertions(+), 87 deletions(-)

diff --git a/docs/querying/query-context.md b/docs/querying/query-context.md
index abb430b..12d51c9 100644
--- a/docs/querying/query-context.md
+++ b/docs/querying/query-context.md
@@ -90,7 +90,7 @@ requirements:
 include "selector", "bound", "in", "like", "regex", "search", "and", "or", and "not".
 - All filters in filtered aggregators must offer vectorized row-matchers.
 - All aggregators must offer vectorized implementations. These include "count", "doubleSum", "floatSum", "longSum", "longMin",
-"hyperUnique", and "filtered".
+ "longMax", "doubleMin", "doubleMax", "floatMin", "floatMax", "hyperUnique", and "filtered".
 - No virtual columns.
 - For GroupBy: All dimension specs must be "default" (no extraction functions or filtered dimension specs).
 - For GroupBy: No multi-value dimensions.
diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMaxAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMaxAggregatorFactory.java
index 1c697c8..46f017b 100644
--- a/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMaxAggregatorFactory.java
+++ b/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMaxAggregatorFactory.java
@@ -25,6 +25,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import org.apache.druid.java.util.common.StringUtils;
 import org.apache.druid.math.expr.ExprMacroTable;
 import org.apache.druid.segment.BaseDoubleColumnValueSelector;
+import org.apache.druid.segment.ColumnInspector;
+import org.apache.druid.segment.column.ColumnCapabilities;
+import org.apache.druid.segment.vector.VectorColumnSelectorFactory;
+import org.apache.druid.segment.vector.VectorValueSelector;
 
 import javax.annotation.Nullable;
 import java.nio.ByteBuffer;
@@ -70,6 +74,31 @@ public class DoubleMaxAggregatorFactory extends SimpleDoubleAggregatorFactory
   }
 
   @Override
+  protected VectorValueSelector vectorSelector(VectorColumnSelectorFactory columnSelectorFactory)
+  {
+    return columnSelectorFactory.makeValueSelector(fieldName);
+  }
+
+  @Override
+  protected VectorAggregator factorizeVector(
+      VectorColumnSelectorFactory columnSelectorFactory,
+      VectorValueSelector selector
+  )
+  {
+    return new DoubleMaxVectorAggregator(selector);
+  }
+
+  @Override
+  public boolean canVectorize(ColumnInspector columnInspector)
+  {
+    if (fieldName != null) {
+      final ColumnCapabilities capabilities = columnInspector.getColumnCapabilities(fieldName);
+      return expression == null && (capabilities == null || capabilities.getType().isNumeric());
+    }
+    return expression == null;
+  }
+
+  @Override
   @Nullable
   public Object combine(@Nullable Object lhs, @Nullable Object rhs)
   {
diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMaxVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMaxVectorAggregator.java
new file mode 100644
index 0000000..d47aaa7
--- /dev/null
+++ b/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMaxVectorAggregator.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.query.aggregation;
+
+import org.apache.druid.segment.vector.VectorValueSelector;
+
+import javax.annotation.Nullable;
+import java.nio.ByteBuffer;
+
+public class DoubleMaxVectorAggregator implements VectorAggregator
+{
+  private final VectorValueSelector selector;
+
+  public DoubleMaxVectorAggregator(final VectorValueSelector selector)
+  {
+    this.selector = selector;
+  }
+
+  @Override
+  public void init(final ByteBuffer buf, final int position)
+  {
+    buf.putDouble(position, Double.NEGATIVE_INFINITY);
+  }
+
+  @Override
+  public void aggregate(final ByteBuffer buf, final int position, final int startRow, final int endRow)
+  {
+    final double[] vector = selector.getDoubleVector();
+
+    double max = buf.getDouble(position);
+    for (int i = startRow; i < endRow; i++) {
+      max = Math.max(max, vector[i]);
+    }
+
+    buf.putDouble(position, max);
+  }
+
+  @Override
+  public void aggregate(
+      final ByteBuffer buf,
+      final int numRows,
+      final int[] positions,
+      @Nullable final int[] rows,
+      final int positionOffset
+  )
+  {
+    final double[] vector = selector.getDoubleVector();
+
+    for (int i = 0; i < numRows; i++) {
+      final int position = positions[i] + positionOffset;
+      buf.putDouble(position, Math.max(buf.getDouble(position), vector[rows != null ? rows[i] : i]));
+    }
+  }
+
+  @Override
+  public Object get(final ByteBuffer buf, final int position)
+  {
+    return buf.getDouble(position);
+  }
+
+  @Override
+  public void close()
+  {
+    // Nothing to close.
+  }
+}
diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMinAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMinAggregatorFactory.java
index d56d8ed..f0f4cf6 100644
--- a/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMinAggregatorFactory.java
+++ b/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMinAggregatorFactory.java
@@ -25,6 +25,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import org.apache.druid.java.util.common.StringUtils;
 import org.apache.druid.math.expr.ExprMacroTable;
 import org.apache.druid.segment.BaseDoubleColumnValueSelector;
+import org.apache.druid.segment.ColumnInspector;
+import org.apache.druid.segment.column.ColumnCapabilities;
+import org.apache.druid.segment.vector.VectorColumnSelectorFactory;
+import org.apache.druid.segment.vector.VectorValueSelector;
 
 import javax.annotation.Nullable;
 import java.nio.ByteBuffer;
@@ -70,6 +74,31 @@ public class DoubleMinAggregatorFactory extends SimpleDoubleAggregatorFactory
   }
 
   @Override
+  protected VectorValueSelector vectorSelector(VectorColumnSelectorFactory columnSelectorFactory)
+  {
+    return columnSelectorFactory.makeValueSelector(fieldName);
+  }
+
+  @Override
+  protected VectorAggregator factorizeVector(
+      VectorColumnSelectorFactory columnSelectorFactory,
+      VectorValueSelector selector
+  )
+  {
+    return new DoubleMinVectorAggregator(selector);
+  }
+
+  @Override
+  public boolean canVectorize(ColumnInspector columnInspector)
+  {
+    if (fieldName != null) {
+      final ColumnCapabilities capabilities = columnInspector.getColumnCapabilities(fieldName);
+      return expression == null && (capabilities == null || capabilities.getType().isNumeric());
+    }
+    return expression == null;
+  }
+
+  @Override
   @Nullable
   public Object combine(@Nullable Object lhs, @Nullable Object rhs)
   {
diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMinVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMinVectorAggregator.java
new file mode 100644
index 0000000..8e4788b
--- /dev/null
+++ b/processing/src/main/java/org/apache/druid/query/aggregation/DoubleMinVectorAggregator.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.query.aggregation;
+
+import org.apache.druid.segment.vector.VectorValueSelector;
+
+import javax.annotation.Nullable;
+import java.nio.ByteBuffer;
+
+public class DoubleMinVectorAggregator implements VectorAggregator
+{
+  private final VectorValueSelector selector;
+
+  public DoubleMinVectorAggregator(final VectorValueSelector selector)
+  {
+    this.selector = selector;
+  }
+
+  @Override
+  public void init(final ByteBuffer buf, final int position)
+  {
+    buf.putDouble(position, Double.POSITIVE_INFINITY);
+  }
+
+  @Override
+  public void aggregate(final ByteBuffer buf, final int position, final int startRow, final int endRow)
+  {
+    final double[] vector = selector.getDoubleVector();
+
+    double min = buf.getDouble(position);
+    for (int i = startRow; i < endRow; i++) {
+      min = Math.min(min, vector[i]);
+    }
+
+    buf.putDouble(position, min);
+  }
+
+  @Override
+  public void aggregate(
+      final ByteBuffer buf,
+      final int numRows,
+      final int[] positions,
+      @Nullable final int[] rows,
+      final int positionOffset
+  )
+  {
+    final double[] vector = selector.getDoubleVector();
+
+    for (int i = 0; i < numRows; i++) {
+      final int position = positions[i] + positionOffset;
+      buf.putDouble(position, Math.min(buf.getDouble(position), vector[rows != null ? rows[i] : i]));
+    }
+  }
+
+  @Override
+  public Object get(final ByteBuffer buf, final int position)
+  {
+    return buf.getDouble(position);
+  }
+
+  @Override
+  public void close()
+  {
+    // Nothing to close.
+  }
+}
diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/FloatMaxAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/FloatMaxAggregatorFactory.java
index 6f65b25..328f633 100644
--- a/processing/src/main/java/org/apache/druid/query/aggregation/FloatMaxAggregatorFactory.java
+++ b/processing/src/main/java/org/apache/druid/query/aggregation/FloatMaxAggregatorFactory.java
@@ -25,6 +25,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import org.apache.druid.java.util.common.StringUtils;
 import org.apache.druid.math.expr.ExprMacroTable;
 import org.apache.druid.segment.BaseFloatColumnValueSelector;
+import org.apache.druid.segment.ColumnInspector;
+import org.apache.druid.segment.column.ColumnCapabilities;
+import org.apache.druid.segment.vector.VectorColumnSelectorFactory;
+import org.apache.druid.segment.vector.VectorValueSelector;
 
 import javax.annotation.Nullable;
 import java.nio.ByteBuffer;
@@ -70,6 +74,32 @@ public class FloatMaxAggregatorFactory extends SimpleFloatAggregatorFactory
   }
 
   @Override
+  protected VectorValueSelector vectorSelector(VectorColumnSelectorFactory columnSelectorFactory)
+  {
+    return columnSelectorFactory.makeValueSelector(fieldName);
+  }
+
+  @Override
+  protected VectorAggregator factorizeVector(
+      VectorColumnSelectorFactory columnSelectorFactory,
+      VectorValueSelector selector
+  )
+  {
+    return new FloatMaxVectorAggregator(selector);
+  }
+
+  @Override
+  public boolean canVectorize(ColumnInspector columnInspector)
+  {
+    if (fieldName != null) {
+      final ColumnCapabilities capabilities = columnInspector.getColumnCapabilities(fieldName);
+      return expression == null && (capabilities == null || capabilities.getType().isNumeric());
+    }
+    return expression == null;
+  }
+
+
+  @Override
   @Nullable
   public Object combine(@Nullable Object lhs, @Nullable Object rhs)
   {
diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/FloatMaxVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/FloatMaxVectorAggregator.java
new file mode 100644
index 0000000..cd7e2d6
--- /dev/null
+++ b/processing/src/main/java/org/apache/druid/query/aggregation/FloatMaxVectorAggregator.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.query.aggregation;
+
+import org.apache.druid.segment.vector.VectorValueSelector;
+
+import javax.annotation.Nullable;
+import java.nio.ByteBuffer;
+
+public class FloatMaxVectorAggregator implements VectorAggregator
+{
+  private final VectorValueSelector selector;
+
+  public FloatMaxVectorAggregator(final VectorValueSelector selector)
+  {
+    this.selector = selector;
+  }
+
+  @Override
+  public void init(final ByteBuffer buf, final int position)
+  {
+    buf.putFloat(position, Float.NEGATIVE_INFINITY);
+  }
+
+  @Override
+  public void aggregate(final ByteBuffer buf, final int position, final int startRow, final int endRow)
+  {
+    final float[] vector = selector.getFloatVector();
+
+    float max = buf.getFloat(position);
+    for (int i = startRow; i < endRow; i++) {
+      max = Math.max(max, vector[i]);
+    }
+
+    buf.putFloat(position, max);
+  }
+
+  @Override
+  public void aggregate(
+      final ByteBuffer buf,
+      final int numRows,
+      final int[] positions,
+      @Nullable final int[] rows,
+      final int positionOffset
+  )
+  {
+    final float[] vector = selector.getFloatVector();
+
+    for (int i = 0; i < numRows; i++) {
+      final int position = positions[i] + positionOffset;
+      buf.putFloat(position, Math.max(buf.getFloat(position), vector[rows != null ? rows[i] : i]));
+    }
+  }
+
+  @Override
+  public Object get(final ByteBuffer buf, final int position)
+  {
+    return buf.getFloat(position);
+  }
+
+  @Override
+  public void close()
+  {
+    // Nothing to close.
+  }
+}
diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/FloatMinAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/FloatMinAggregatorFactory.java
index f81facf..27059c4 100644
--- a/processing/src/main/java/org/apache/druid/query/aggregation/FloatMinAggregatorFactory.java
+++ b/processing/src/main/java/org/apache/druid/query/aggregation/FloatMinAggregatorFactory.java
@@ -25,6 +25,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import org.apache.druid.java.util.common.StringUtils;
 import org.apache.druid.math.expr.ExprMacroTable;
 import org.apache.druid.segment.BaseFloatColumnValueSelector;
+import org.apache.druid.segment.ColumnInspector;
+import org.apache.druid.segment.column.ColumnCapabilities;
+import org.apache.druid.segment.vector.VectorColumnSelectorFactory;
+import org.apache.druid.segment.vector.VectorValueSelector;
 
 import javax.annotation.Nullable;
 import java.nio.ByteBuffer;
@@ -68,7 +72,32 @@ public class FloatMinAggregatorFactory extends SimpleFloatAggregatorFactory
   {
     return new FloatMinBufferAggregator(selector);
   }
-  
+
+  @Override
+  protected VectorValueSelector vectorSelector(VectorColumnSelectorFactory columnSelectorFactory)
+  {
+    return columnSelectorFactory.makeValueSelector(fieldName);
+  }
+
+  @Override
+  protected VectorAggregator factorizeVector(
+      VectorColumnSelectorFactory columnSelectorFactory,
+      VectorValueSelector selector
+  )
+  {
+    return new FloatMinVectorAggregator(selector);
+  }
+
+  @Override
+  public boolean canVectorize(ColumnInspector columnInspector)
+  {
+    if (fieldName != null) {
+      final ColumnCapabilities capabilities = columnInspector.getColumnCapabilities(fieldName);
+      return expression == null && (capabilities == null || capabilities.getType().isNumeric());
+    }
+    return expression == null;
+  }
+
   @Override
   @Nullable
   public Object combine(@Nullable Object lhs, @Nullable Object rhs)
diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/FloatMinVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/FloatMinVectorAggregator.java
new file mode 100644
index 0000000..a222e4d
--- /dev/null
+++ b/processing/src/main/java/org/apache/druid/query/aggregation/FloatMinVectorAggregator.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.query.aggregation;
+
+import org.apache.druid.segment.vector.VectorValueSelector;
+
+import javax.annotation.Nullable;
+import java.nio.ByteBuffer;
+
+public class FloatMinVectorAggregator implements VectorAggregator
+{
+  private final VectorValueSelector selector;
+
+  public FloatMinVectorAggregator(final VectorValueSelector selector)
+  {
+    this.selector = selector;
+  }
+
+  @Override
+  public void init(final ByteBuffer buf, final int position)
+  {
+    buf.putFloat(position, Float.POSITIVE_INFINITY);
+  }
+
+  @Override
+  public void aggregate(final ByteBuffer buf, final int position, final int startRow, final int endRow)
+  {
+    final float[] vector = selector.getFloatVector();
+
+    float min = buf.getFloat(position);
+    for (int i = startRow; i < endRow; i++) {
+      min = Math.min(min, vector[i]);
+    }
+
+    buf.putFloat(position, min);
+  }
+
+  @Override
+  public void aggregate(
+      final ByteBuffer buf,
+      final int numRows,
+      final int[] positions,
+      @Nullable final int[] rows,
+      final int positionOffset
+  )
+  {
+    final float[] vector = selector.getFloatVector();
+
+    for (int i = 0; i < numRows; i++) {
+      final int position = positions[i] + positionOffset;
+      buf.putFloat(position, Math.min(buf.getFloat(position), vector[rows != null ? rows[i] : i]));
+    }
+  }
+
+  @Override
+  public Object get(final ByteBuffer buf, final int position)
+  {
+    return buf.getFloat(position);
+  }
+
+  @Override
+  public void close()
+  {
+    // Nothing to close.
+  }
+}
diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/LongMaxAggregatorFactory.java b/processing/src/main/java/org/apache/druid/query/aggregation/LongMaxAggregatorFactory.java
index efc044e..a193f34 100644
--- a/processing/src/main/java/org/apache/druid/query/aggregation/LongMaxAggregatorFactory.java
+++ b/processing/src/main/java/org/apache/druid/query/aggregation/LongMaxAggregatorFactory.java
@@ -25,6 +25,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import org.apache.druid.java.util.common.StringUtils;
 import org.apache.druid.math.expr.ExprMacroTable;
 import org.apache.druid.segment.BaseLongColumnValueSelector;
+import org.apache.druid.segment.ColumnInspector;
+import org.apache.druid.segment.column.ColumnCapabilities;
+import org.apache.druid.segment.vector.VectorColumnSelectorFactory;
+import org.apache.druid.segment.vector.VectorValueSelector;
 
 import javax.annotation.Nullable;
 import java.nio.ByteBuffer;
@@ -70,6 +74,31 @@ public class LongMaxAggregatorFactory extends SimpleLongAggregatorFactory
   }
 
   @Override
+  protected VectorValueSelector vectorSelector(VectorColumnSelectorFactory columnSelectorFactory)
+  {
+    return columnSelectorFactory.makeValueSelector(fieldName);
+  }
+
+  @Override
+  protected VectorAggregator factorizeVector(
+      VectorColumnSelectorFactory columnSelectorFactory,
+      VectorValueSelector selector
+  )
+  {
+    return new LongMaxVectorAggregator(selector);
+  }
+
+  @Override
+  public boolean canVectorize(ColumnInspector columnInspector)
+  {
+    if (fieldName != null) {
+      final ColumnCapabilities capabilities = columnInspector.getColumnCapabilities(fieldName);
+      return expression == null && (capabilities == null || capabilities.getType().isNumeric());
+    }
+    return expression == null;
+  }
+
+  @Override
   @Nullable
   public Object combine(@Nullable Object lhs, @Nullable Object rhs)
   {
diff --git a/processing/src/main/java/org/apache/druid/query/aggregation/LongMaxVectorAggregator.java b/processing/src/main/java/org/apache/druid/query/aggregation/LongMaxVectorAggregator.java
new file mode 100644
index 0000000..7d7dbd9
--- /dev/null
+++ b/processing/src/main/java/org/apache/druid/query/aggregation/LongMaxVectorAggregator.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.query.aggregation;
+
+import org.apache.druid.segment.vector.VectorValueSelector;
+
+import javax.annotation.Nullable;
+import java.nio.ByteBuffer;
+
+public class LongMaxVectorAggregator implements VectorAggregator
+{
+  private final VectorValueSelector selector;
+
+  public LongMaxVectorAggregator(final VectorValueSelector selector)
+  {
+    this.selector = selector;
+  }
+
+  @Override
+  public void init(final ByteBuffer buf, final int position)
+  {
+    buf.putLong(position, Long.MIN_VALUE);
+  }
+
+  @Override
+  public void aggregate(final ByteBuffer buf, final int position, final int startRow, final int endRow)
+  {
+    final long[] vector = selector.getLongVector();
+
+    long max = buf.getLong(position);
+    for (int i = startRow; i < endRow; i++) {
+      max = Math.max(max, vector[i]);
+    }
+
+    buf.putLong(position, max);
+  }
+
+  @Override
+  public void aggregate(
+      final ByteBuffer buf,
+      final int numRows,
+      final int[] positions,
+      @Nullable final int[] rows,
+      final int positionOffset
+  )
+  {
+    final long[] vector = selector.getLongVector();
+
+    for (int i = 0; i < numRows; i++) {
+      final int position = positions[i] + positionOffset;
+      buf.putLong(position, Math.max(buf.getLong(position), vector[rows != null ? rows[i] : i]));
+    }
+  }
+
+  @Override
+  public Object get(final ByteBuffer buf, final int position)
+  {
+    return buf.getLong(position);
+  }
+
+  @Override
+  public void close()
+  {
+    // Nothing to close.
+  }
+}
diff --git a/processing/src/test/java/org/apache/druid/query/QueryRunnerTestHelper.java b/processing/src/test/java/org/apache/druid/query/QueryRunnerTestHelper.java
index bf1b028..968df8f 100644
--- a/processing/src/test/java/org/apache/druid/query/QueryRunnerTestHelper.java
+++ b/processing/src/test/java/org/apache/druid/query/QueryRunnerTestHelper.java
@@ -34,9 +34,14 @@ import org.apache.druid.java.util.common.guava.Sequences;
 import org.apache.druid.js.JavaScriptConfig;
 import org.apache.druid.query.aggregation.AggregatorFactory;
 import org.apache.druid.query.aggregation.CountAggregatorFactory;
+import org.apache.druid.query.aggregation.DoubleMaxAggregatorFactory;
+import org.apache.druid.query.aggregation.DoubleMinAggregatorFactory;
 import org.apache.druid.query.aggregation.DoubleSumAggregatorFactory;
+import org.apache.druid.query.aggregation.FloatMaxAggregatorFactory;
+import org.apache.druid.query.aggregation.FloatMinAggregatorFactory;
 import org.apache.druid.query.aggregation.FloatSumAggregatorFactory;
 import org.apache.druid.query.aggregation.JavaScriptAggregatorFactory;
+import org.apache.druid.query.aggregation.LongMaxAggregatorFactory;
 import org.apache.druid.query.aggregation.LongMinAggregatorFactory;
 import org.apache.druid.query.aggregation.LongSumAggregatorFactory;
 import org.apache.druid.query.aggregation.cardinality.CardinalityAggregatorFactory;
@@ -115,6 +120,11 @@ public class QueryRunnerTestHelper
   public static final String UNIQUE_METRIC = "uniques";
   public static final String ADD_ROWS_INDEX_CONSTANT_METRIC = "addRowsIndexConstant";
   public static final String LONG_MIN_INDEX_METRIC = "longMinIndex";
+  public static final String LONG_MAX_INDEX_METRIC = "longMaxIndex";
+  public static final String DOUBLE_MIN_INDEX_METRIC = "doubleMinIndex";
+  public static final String DOUBLE_MAX_INDEX_METRIC = "doubleMaxIndex";
+  public static final String FLOAT_MIN_INDEX_METRIC = "floatMinIndex";
+  public static final String FLOAT_MAX_INDEX_METRIC = "floatMaxIndex";
   public static String dependentPostAggMetric = "dependentPostAgg";
   public static final CountAggregatorFactory ROWS_COUNT = new CountAggregatorFactory("rows");
   public static final LongSumAggregatorFactory INDEX_LONG_SUM = new LongSumAggregatorFactory("index", INDEX_METRIC);
@@ -124,6 +134,11 @@ public class QueryRunnerTestHelper
       INDEX_METRIC
   );
   public static final LongMinAggregatorFactory INDEX_LONG_MIN = new LongMinAggregatorFactory(LONG_MIN_INDEX_METRIC, INDEX_METRIC);
+  public static final LongMaxAggregatorFactory INDEX_LONG_MAX = new LongMaxAggregatorFactory(LONG_MAX_INDEX_METRIC, INDEX_METRIC);
+  public static final DoubleMinAggregatorFactory INDEX_DOUBLE_MIN = new DoubleMinAggregatorFactory(DOUBLE_MIN_INDEX_METRIC, INDEX_METRIC);
+  public static final DoubleMaxAggregatorFactory INDEX_DOUBLE_MAX = new DoubleMaxAggregatorFactory(DOUBLE_MAX_INDEX_METRIC, INDEX_METRIC);
+  public static final FloatMinAggregatorFactory INDEX_FLOAT_MIN = new FloatMinAggregatorFactory(FLOAT_MIN_INDEX_METRIC, INDEX_METRIC);
+  public static final FloatMaxAggregatorFactory INDEX_FLOAT_MAX = new FloatMaxAggregatorFactory(FLOAT_MAX_INDEX_METRIC, INDEX_METRIC);
   public static final String JS_COMBINE_A_PLUS_B = "function combine(a, b) { return a + b; }";
   public static final String JS_RESET_0 = "function reset() { return 0; }";
   public static final JavaScriptAggregatorFactory JS_INDEX_SUM_IF_PLACEMENTISH_A = new JavaScriptAggregatorFactory(
diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/DoubleMaxAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/DoubleMaxAggregationTest.java
index 7342627..3945c4f 100644
--- a/processing/src/test/java/org/apache/druid/query/aggregation/DoubleMaxAggregationTest.java
+++ b/processing/src/test/java/org/apache/druid/query/aggregation/DoubleMaxAggregationTest.java
@@ -19,8 +19,13 @@
 
 package org.apache.druid.query.aggregation;
 
+import org.apache.druid.common.config.NullHandling;
 import org.apache.druid.segment.ColumnSelectorFactory;
 import org.apache.druid.segment.TestHelper;
+import org.apache.druid.segment.column.ColumnCapabilitiesImpl;
+import org.apache.druid.segment.column.ValueType;
+import org.apache.druid.segment.vector.VectorColumnSelectorFactory;
+import org.apache.druid.segment.vector.VectorValueSelector;
 import org.easymock.EasyMock;
 import org.junit.Assert;
 import org.junit.Before;
@@ -33,25 +38,44 @@ import java.nio.ByteBuffer;
 public class DoubleMaxAggregationTest
 {
   private DoubleMaxAggregatorFactory doubleMaxAggFactory;
+  private DoubleMaxAggregatorFactory doubleMaxVectorAggFactory;
+
   private ColumnSelectorFactory colSelectorFactory;
+  private VectorColumnSelectorFactory vectorColumnSelectorFactory;
   private TestDoubleColumnSelectorImpl selector;
 
   private double[] values = {1.1d, 2.7d, 3.5d, 1.3d};
+  private final double[] doubleValues1 = {5d, 2d, 4d, 100d, 1d, 5d, -2d, -3d, 0d, 55d};
 
   public DoubleMaxAggregationTest() throws Exception
   {
     String aggSpecJson = "{\"type\": \"doubleMax\", \"name\": \"billy\", \"fieldName\": \"nilly\"}";
     doubleMaxAggFactory = TestHelper.makeJsonMapper().readValue(aggSpecJson, DoubleMaxAggregatorFactory.class);
+
+    String vectorAggSpecJson = "{\"type\": \"doubleMax\", \"name\": \"dbl\", \"fieldName\": \"dblFld\"}";
+    doubleMaxVectorAggFactory = TestHelper.makeJsonMapper().readValue(vectorAggSpecJson, DoubleMaxAggregatorFactory.class);
   }
 
   @Before
   public void setup()
   {
+    NullHandling.initializeForTests();
     selector = new TestDoubleColumnSelectorImpl(values);
     colSelectorFactory = EasyMock.createMock(ColumnSelectorFactory.class);
     EasyMock.expect(colSelectorFactory.makeColumnValueSelector("nilly")).andReturn(selector);
     EasyMock.expect(colSelectorFactory.getColumnCapabilities("nilly")).andReturn(null);
     EasyMock.replay(colSelectorFactory);
+
+    VectorValueSelector vectorValueSelector = EasyMock.createMock(VectorValueSelector.class);
+    EasyMock.expect(vectorValueSelector.getDoubleVector()).andReturn(doubleValues1).anyTimes();
+    EasyMock.expect(vectorValueSelector.getNullVector()).andReturn(null).anyTimes();
+    EasyMock.replay(vectorValueSelector);
+
+    vectorColumnSelectorFactory = EasyMock.createMock(VectorColumnSelectorFactory.class);
+    EasyMock.expect(vectorColumnSelectorFactory.getColumnCapabilities("dblFld"))
+            .andReturn(new ColumnCapabilitiesImpl().setType(ValueType.DOUBLE).setDictionaryEncoded(true)).anyTimes();
+    EasyMock.expect(vectorColumnSelectorFactory.makeValueSelector("dblFld")).andReturn(vectorValueSelector).anyTimes();
+    EasyMock.replay(vectorColumnSelectorFactory);
   }
 
   @Test
@@ -88,6 +112,34 @@ public class DoubleMaxAggregationTest
   }
 
   @Test
+  public void testDoubleMaxVectorAggregator()
+  {
+    // Some sanity.
+    Assert.assertTrue(doubleMaxVectorAggFactory.canVectorize(vectorColumnSelectorFactory));
+    VectorValueSelector vectorValueSelector = doubleMaxVectorAggFactory.vectorSelector(vectorColumnSelectorFactory);
+    Assert.assertEquals(doubleValues1, vectorValueSelector.getDoubleVector());
+
+    VectorAggregator vectorAggregator = doubleMaxVectorAggFactory.factorizeVector(vectorColumnSelectorFactory);
+
+    final ByteBuffer buf = ByteBuffer.allocate(doubleMaxVectorAggFactory.getMaxIntermediateSizeWithNulls() * 3);
+    vectorAggregator.init(buf, 0);
+    vectorAggregator.aggregate(buf, 0, 0, 3);
+    Assert.assertEquals(doubleValues1[0], vectorAggregator.get(buf, 0));
+
+    vectorAggregator.init(buf, 8);
+    vectorAggregator.aggregate(buf, 8, 0, 3);
+    Assert.assertEquals(doubleValues1[0], vectorAggregator.get(buf, 8));
+
+    vectorAggregator.init(buf, 16);
+    vectorAggregator.aggregate(buf, 16, 4, 7);
+    Assert.assertEquals(doubleValues1[5], vectorAggregator.get(buf, 16));
+
+    vectorAggregator.init(buf, 0);
+    vectorAggregator.aggregate(buf, 0, 0, 10);
+    Assert.assertEquals(doubleValues1[3], vectorAggregator.get(buf, 0));
+  }
+
+  @Test
   public void testCombine()
   {
     Assert.assertEquals(3.4d, ((Double) doubleMaxAggFactory.combine(1.2, 3.4)).doubleValue(), 0.0001);
diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/DoubleMinAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/DoubleMinAggregationTest.java
index 89a4289..14702d1 100644
--- a/processing/src/test/java/org/apache/druid/query/aggregation/DoubleMinAggregationTest.java
+++ b/processing/src/test/java/org/apache/druid/query/aggregation/DoubleMinAggregationTest.java
@@ -19,8 +19,13 @@
 
 package org.apache.druid.query.aggregation;
 
+import org.apache.druid.common.config.NullHandling;
 import org.apache.druid.segment.ColumnSelectorFactory;
 import org.apache.druid.segment.TestHelper;
+import org.apache.druid.segment.column.ColumnCapabilitiesImpl;
+import org.apache.druid.segment.column.ValueType;
+import org.apache.druid.segment.vector.VectorColumnSelectorFactory;
+import org.apache.druid.segment.vector.VectorValueSelector;
 import org.easymock.EasyMock;
 import org.junit.Assert;
 import org.junit.Before;
@@ -33,25 +38,45 @@ import java.nio.ByteBuffer;
 public class DoubleMinAggregationTest
 {
   private DoubleMinAggregatorFactory doubleMinAggFactory;
+  private DoubleMinAggregatorFactory doubleMinVectorAggFactory;
+
   private ColumnSelectorFactory colSelectorFactory;
+  private VectorColumnSelectorFactory vectorColumnSelectorFactory;
   private TestDoubleColumnSelectorImpl selector;
 
-  private double[] values = {3.5d, 2.7d, 1.1d, 1.3d};
+  private final double[] values = {3.5d, 2.7d, 1.1d, 1.3d};
+  private final double[] doubleValues1 = {5d, 2d, 4d, 100d, 1d, 5d, -2d, -3d, 0d, 55d};
 
   public DoubleMinAggregationTest() throws Exception
   {
     String aggSpecJson = "{\"type\": \"doubleMin\", \"name\": \"billy\", \"fieldName\": \"nilly\"}";
     doubleMinAggFactory = TestHelper.makeJsonMapper().readValue(aggSpecJson, DoubleMinAggregatorFactory.class);
+
+    String vectorAggSpecJson = "{\"type\": \"doubleMin\", \"name\": \"dbl\", \"fieldName\": \"dblFld\"}";
+    doubleMinVectorAggFactory = TestHelper.makeJsonMapper().readValue(vectorAggSpecJson, DoubleMinAggregatorFactory.class);
   }
 
   @Before
   public void setup()
   {
+    NullHandling.initializeForTests();
     selector = new TestDoubleColumnSelectorImpl(values);
     colSelectorFactory = EasyMock.createMock(ColumnSelectorFactory.class);
     EasyMock.expect(colSelectorFactory.makeColumnValueSelector("nilly")).andReturn(selector);
     EasyMock.expect(colSelectorFactory.getColumnCapabilities("nilly")).andReturn(null);
     EasyMock.replay(colSelectorFactory);
+
+
+    VectorValueSelector vectorValueSelector = EasyMock.createMock(VectorValueSelector.class);
+    EasyMock.expect(vectorValueSelector.getDoubleVector()).andReturn(doubleValues1).anyTimes();
+    EasyMock.expect(vectorValueSelector.getNullVector()).andReturn(null).anyTimes();
+    EasyMock.replay(vectorValueSelector);
+
+    vectorColumnSelectorFactory = EasyMock.createMock(VectorColumnSelectorFactory.class);
+    EasyMock.expect(vectorColumnSelectorFactory.getColumnCapabilities("dblFld"))
+            .andReturn(new ColumnCapabilitiesImpl().setType(ValueType.DOUBLE).setDictionaryEncoded(true)).anyTimes();
+    EasyMock.expect(vectorColumnSelectorFactory.makeValueSelector("dblFld")).andReturn(vectorValueSelector).anyTimes();
+    EasyMock.replay(vectorColumnSelectorFactory);
   }
 
   @Test
@@ -88,6 +113,34 @@ public class DoubleMinAggregationTest
   }
 
   @Test
+  public void testDoubleMinVectorAggregator()
+  {
+    // Some sanity.
+    Assert.assertTrue(doubleMinVectorAggFactory.canVectorize(vectorColumnSelectorFactory));
+    VectorValueSelector vectorValueSelector = doubleMinVectorAggFactory.vectorSelector(vectorColumnSelectorFactory);
+    Assert.assertEquals(doubleValues1, vectorValueSelector.getDoubleVector());
+
+    VectorAggregator vectorAggregator = doubleMinVectorAggFactory.factorizeVector(vectorColumnSelectorFactory);
+
+    final ByteBuffer buf = ByteBuffer.allocate(doubleMinVectorAggFactory.getMaxIntermediateSizeWithNulls() * 3);
+    vectorAggregator.init(buf, 0);
+    vectorAggregator.aggregate(buf, 0, 0, 3);
+    Assert.assertEquals(doubleValues1[1], vectorAggregator.get(buf, 0));
+
+    vectorAggregator.init(buf, 8);
+    vectorAggregator.aggregate(buf, 8, 0, 3);
+    Assert.assertEquals(doubleValues1[1], vectorAggregator.get(buf, 8));
+
+    vectorAggregator.init(buf, 16);
+    vectorAggregator.aggregate(buf, 16, 3, 7);
+    Assert.assertEquals(doubleValues1[6], vectorAggregator.get(buf, 16));
+
+    vectorAggregator.init(buf, 0);
+    vectorAggregator.aggregate(buf, 0, 0, 10);
+    Assert.assertEquals(doubleValues1[7], vectorAggregator.get(buf, 0));
+  }
+
+  @Test
   public void testCombine()
   {
     Assert.assertEquals(1.2d, ((Double) doubleMinAggFactory.combine(1.2, 3.4)).doubleValue(), 0.0001);
diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/FloatMaxAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/FloatMaxAggregationTest.java
new file mode 100644
index 0000000..dc1dc15
--- /dev/null
+++ b/processing/src/test/java/org/apache/druid/query/aggregation/FloatMaxAggregationTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.query.aggregation;
+
+import org.apache.druid.common.config.NullHandling;
+import org.apache.druid.segment.TestHelper;
+import org.apache.druid.segment.column.ColumnCapabilitiesImpl;
+import org.apache.druid.segment.column.ValueType;
+import org.apache.druid.segment.vector.VectorColumnSelectorFactory;
+import org.apache.druid.segment.vector.VectorValueSelector;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+
+/**
+ */
+public class FloatMaxAggregationTest
+{
+  private final FloatMaxAggregatorFactory floatMaxAggregatorFactory;
+  private VectorColumnSelectorFactory vectorColumnSelectorFactory;
+
+  private final float[] floatValues1 = {5f, 2f, 4f, 100f, 1f, 5f, -2f, -3f, 0f, 55f};
+
+  public FloatMaxAggregationTest() throws Exception
+  {
+    String vectorAggSpecJson = "{\"type\": \"floatMax\", \"name\": \"flt\", \"fieldName\": \"fltFld\"}";
+    floatMaxAggregatorFactory = TestHelper.makeJsonMapper().readValue(vectorAggSpecJson, FloatMaxAggregatorFactory.class);
+  }
+
+  @Before
+  public void setup()
+  {
+    NullHandling.initializeForTests();
+
+    VectorValueSelector vectorValueSelector = EasyMock.createMock(VectorValueSelector.class);
+    EasyMock.expect(vectorValueSelector.getFloatVector()).andReturn(floatValues1).anyTimes();
+    EasyMock.expect(vectorValueSelector.getNullVector()).andReturn(null).anyTimes();
+    EasyMock.replay(vectorValueSelector);
+
+    vectorColumnSelectorFactory = EasyMock.createMock(VectorColumnSelectorFactory.class);
+    EasyMock.expect(vectorColumnSelectorFactory.getColumnCapabilities("fltFld"))
+            .andReturn(new ColumnCapabilitiesImpl().setType(ValueType.FLOAT).setDictionaryEncoded(true)).anyTimes();
+    EasyMock.expect(vectorColumnSelectorFactory.makeValueSelector("fltFld")).andReturn(vectorValueSelector).anyTimes();
+    EasyMock.replay(vectorColumnSelectorFactory);
+  }
+
+  @Test
+  public void testFloatMaxVectorAggregator()
+  {
+    // Some sanity.
+    Assert.assertTrue(floatMaxAggregatorFactory.canVectorize(vectorColumnSelectorFactory));
+    VectorValueSelector vectorValueSelector = floatMaxAggregatorFactory.vectorSelector(vectorColumnSelectorFactory);
+    Assert.assertEquals(floatValues1, vectorValueSelector.getFloatVector());
+
+    VectorAggregator vectorAggregator = floatMaxAggregatorFactory.factorizeVector(vectorColumnSelectorFactory);
+
+    final ByteBuffer buf = ByteBuffer.allocate(floatMaxAggregatorFactory.getMaxIntermediateSizeWithNulls() * 3);
+    vectorAggregator.init(buf, 0);
+    vectorAggregator.aggregate(buf, 0, 0, 3);
+    Assert.assertEquals(floatValues1[0], vectorAggregator.get(buf, 0));
+
+    vectorAggregator.init(buf, 4);
+    vectorAggregator.aggregate(buf, 4, 0, 3);
+    Assert.assertEquals(floatValues1[0], vectorAggregator.get(buf, 4));
+
+    vectorAggregator.init(buf, 8);
+    vectorAggregator.aggregate(buf, 8, 4, 7);
+    Assert.assertEquals(floatValues1[5], vectorAggregator.get(buf, 8));
+
+    vectorAggregator.init(buf, 0);
+    vectorAggregator.aggregate(buf, 0, 0, 10);
+    Assert.assertEquals(floatValues1[3], vectorAggregator.get(buf, 0));
+  }
+}
diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/FloatMinAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/FloatMinAggregationTest.java
new file mode 100644
index 0000000..a451d1c
--- /dev/null
+++ b/processing/src/test/java/org/apache/druid/query/aggregation/FloatMinAggregationTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.query.aggregation;
+
+import org.apache.druid.common.config.NullHandling;
+import org.apache.druid.segment.TestHelper;
+import org.apache.druid.segment.column.ColumnCapabilitiesImpl;
+import org.apache.druid.segment.column.ValueType;
+import org.apache.druid.segment.vector.VectorColumnSelectorFactory;
+import org.apache.druid.segment.vector.VectorValueSelector;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+
+/**
+ */
+public class FloatMinAggregationTest
+{
+  private final FloatMinAggregatorFactory floatMinAggregatorFactory;
+  private VectorColumnSelectorFactory vectorColumnSelectorFactory;
+
+  private final float[] floatValues1 = {5f, 2f, 4f, 100f, 1f, 5f, -2f, -3f, 0f, 55f};
+
+  public FloatMinAggregationTest() throws Exception
+  {
+    String vectorAggSpecJson = "{\"type\": \"floatMin\", \"name\": \"flt\", \"fieldName\": \"fltFld\"}";
+    floatMinAggregatorFactory = TestHelper.makeJsonMapper().readValue(vectorAggSpecJson, FloatMinAggregatorFactory.class);
+  }
+
+  @Before
+  public void setup()
+  {
+    NullHandling.initializeForTests();
+
+    VectorValueSelector vectorValueSelector = EasyMock.createMock(VectorValueSelector.class);
+    EasyMock.expect(vectorValueSelector.getFloatVector()).andReturn(floatValues1).anyTimes();
+    EasyMock.expect(vectorValueSelector.getNullVector()).andReturn(null).anyTimes();
+    EasyMock.replay(vectorValueSelector);
+
+    vectorColumnSelectorFactory = EasyMock.createMock(VectorColumnSelectorFactory.class);
+    EasyMock.expect(vectorColumnSelectorFactory.getColumnCapabilities("fltFld"))
+            .andReturn(new ColumnCapabilitiesImpl().setType(ValueType.FLOAT).setDictionaryEncoded(true)).anyTimes();
+    EasyMock.expect(vectorColumnSelectorFactory.makeValueSelector("fltFld")).andReturn(vectorValueSelector).anyTimes();
+    EasyMock.replay(vectorColumnSelectorFactory);
+  }
+
+  @Test
+  public void testFloatMinVectorAggregator()
+  {
+    // Some sanity.
+    Assert.assertTrue(floatMinAggregatorFactory.canVectorize(vectorColumnSelectorFactory));
+    VectorValueSelector vectorValueSelector = floatMinAggregatorFactory.vectorSelector(vectorColumnSelectorFactory);
+    Assert.assertEquals(floatValues1, vectorValueSelector.getFloatVector());
+
+    VectorAggregator vectorAggregator = floatMinAggregatorFactory.factorizeVector(vectorColumnSelectorFactory);
+
+    final ByteBuffer buf = ByteBuffer.allocate(floatMinAggregatorFactory.getMaxIntermediateSizeWithNulls() * 3);
+    vectorAggregator.init(buf, 0);
+    vectorAggregator.aggregate(buf, 0, 0, 3);
+    Assert.assertEquals(floatValues1[1], vectorAggregator.get(buf, 0));
+
+    vectorAggregator.init(buf, 4);
+    vectorAggregator.aggregate(buf, 4, 0, 3);
+    Assert.assertEquals(floatValues1[1], vectorAggregator.get(buf, 4));
+
+    vectorAggregator.init(buf, 8);
+    vectorAggregator.aggregate(buf, 8, 3, 7);
+    Assert.assertEquals(floatValues1[6], vectorAggregator.get(buf, 8));
+
+    vectorAggregator.init(buf, 0);
+    vectorAggregator.aggregate(buf, 0, 0, 10);
+    Assert.assertEquals(floatValues1[7], vectorAggregator.get(buf, 0));
+  }
+}
diff --git a/processing/src/test/java/org/apache/druid/query/aggregation/LongMaxAggregationTest.java b/processing/src/test/java/org/apache/druid/query/aggregation/LongMaxAggregationTest.java
index 14da2ad..838d396 100644
--- a/processing/src/test/java/org/apache/druid/query/aggregation/LongMaxAggregationTest.java
+++ b/processing/src/test/java/org/apache/druid/query/aggregation/LongMaxAggregationTest.java
@@ -19,8 +19,13 @@
 
 package org.apache.druid.query.aggregation;
 
+import org.apache.druid.common.config.NullHandling;
 import org.apache.druid.segment.ColumnSelectorFactory;
 import org.apache.druid.segment.TestHelper;
+import org.apache.druid.segment.column.ColumnCapabilitiesImpl;
+import org.apache.druid.segment.column.ValueType;
+import org.apache.druid.segment.vector.VectorColumnSelectorFactory;
+import org.apache.druid.segment.vector.VectorValueSelector;
 import org.easymock.EasyMock;
 import org.junit.Assert;
 import org.junit.Before;
@@ -33,25 +38,44 @@ import java.nio.ByteBuffer;
 public class LongMaxAggregationTest
 {
   private LongMaxAggregatorFactory longMaxAggFactory;
+  private LongMaxAggregatorFactory longMaxVectorAggFactory;
   private ColumnSelectorFactory colSelectorFactory;
+  private VectorColumnSelectorFactory vectorColumnSelectorFactory;
   private TestLongColumnSelector selector;
 
-  private long[] values = {9223372036854775802L, 9223372036854775803L, 9223372036854775806L, 9223372036854775805L};
+  private final long[] values = {9223372036854775802L, 9223372036854775803L, 9223372036854775806L, 9223372036854775805L};
+  private final long[] longValues1 = {5L, 2L, 4L, 100L, 1L, 5L, -2L, -3L, 0L, 55L};
 
   public LongMaxAggregationTest() throws Exception
   {
     String aggSpecJson = "{\"type\": \"longMax\", \"name\": \"billy\", \"fieldName\": \"nilly\"}";
     longMaxAggFactory = TestHelper.makeJsonMapper().readValue(aggSpecJson, LongMaxAggregatorFactory.class);
+
+    String vectorAggSpecJson = "{\"type\": \"longMax\", \"name\": \"lng\", \"fieldName\": \"lngFld\"}";
+    longMaxVectorAggFactory = TestHelper.makeJsonMapper().readValue(vectorAggSpecJson, LongMaxAggregatorFactory.class);
   }
 
   @Before
   public void setup()
   {
+    NullHandling.initializeForTests();
     selector = new TestLongColumnSelector(values);
     colSelectorFactory = EasyMock.createMock(ColumnSelectorFactory.class);
     EasyMock.expect(colSelectorFactory.makeColumnValueSelector("nilly")).andReturn(selector);
     EasyMock.expect(colSelectorFactory.getColumnCapabilities("nilly")).andReturn(null);
     EasyMock.replay(colSelectorFactory);
+
+
+    VectorValueSelector vectorValueSelector = EasyMock.createMock(VectorValueSelector.class);
+    EasyMock.expect(vectorValueSelector.getLongVector()).andReturn(longValues1).anyTimes();
+    EasyMock.expect(vectorValueSelector.getNullVector()).andReturn(null).anyTimes();
+    EasyMock.replay(vectorValueSelector);
+
+    vectorColumnSelectorFactory = EasyMock.createMock(VectorColumnSelectorFactory.class);
+    EasyMock.expect(vectorColumnSelectorFactory.getColumnCapabilities("lngFld"))
+            .andReturn(new ColumnCapabilitiesImpl().setType(ValueType.LONG).setDictionaryEncoded(true)).anyTimes();
+    EasyMock.expect(vectorColumnSelectorFactory.makeValueSelector("lngFld")).andReturn(vectorValueSelector).anyTimes();
+    EasyMock.replay(vectorColumnSelectorFactory);
   }
 
   @Test
@@ -87,6 +111,34 @@ public class LongMaxAggregationTest
     Assert.assertEquals((float) values[2], agg.getFloat(buffer, 0), 0.0001);
   }
 
+
+  @Test
+  public void testLongMaxVectorAggregator()
+  {
+    // Some sanity.
+    Assert.assertTrue(longMaxVectorAggFactory.canVectorize(vectorColumnSelectorFactory));
+    VectorValueSelector vectorValueSelector = longMaxVectorAggFactory.vectorSelector(vectorColumnSelectorFactory);
+    Assert.assertEquals(longValues1, vectorValueSelector.getLongVector());
+
+    VectorAggregator vectorAggregator = longMaxVectorAggFactory.factorizeVector(vectorColumnSelectorFactory);
+
+    final ByteBuffer buf = ByteBuffer.allocate(longMaxAggFactory.getMaxIntermediateSizeWithNulls() * 3);
+    vectorAggregator.init(buf, 0);
+
+    vectorAggregator.aggregate(buf, 0, 0, 3);
+    Assert.assertEquals(longValues1[0], (long) vectorAggregator.get(buf, 0));
+
+    vectorAggregator.aggregate(buf, 8, 0, 3);
+    Assert.assertEquals(longValues1[0], (long) vectorAggregator.get(buf, 8));
+
+    vectorAggregator.aggregate(buf, 16, 3, 7);
+    Assert.assertEquals(longValues1[3], (long) vectorAggregator.get(buf, 16));
+
+    vectorAggregator.init(buf, 0);
+    vectorAggregator.aggregate(buf, 0, 0, 10);
+    Assert.assertEquals(longValues1[3], (long) vectorAggregator.get(buf, 0));
+  }
+
   @Test
   public void testCombine()
   {
diff --git a/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryRunnerTest.java b/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryRunnerTest.java
index 393c558..8dfac83 100644
--- a/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryRunnerTest.java
+++ b/processing/src/test/java/org/apache/druid/query/groupby/GroupByQueryRunnerTest.java
@@ -4128,7 +4128,9 @@ public class GroupByQueryRunnerTest extends InitializedNullHandlingTest
         .setDataSource(QueryRunnerTestHelper.DATA_SOURCE)
         .setInterval("2011-01-25/2011-01-28")
         .setDimensions(new DefaultDimensionSpec("quality", "alias"))
-        .setAggregatorSpecs(QueryRunnerTestHelper.ROWS_COUNT, new DoubleSumAggregatorFactory("index", "index"), QueryRunnerTestHelper.INDEX_LONG_MIN)
+        .setAggregatorSpecs(QueryRunnerTestHelper.ROWS_COUNT, new DoubleSumAggregatorFactory("index", "index"), QueryRunnerTestHelper.INDEX_LONG_MIN,
+                            QueryRunnerTestHelper.INDEX_LONG_MAX, QueryRunnerTestHelper.INDEX_DOUBLE_MIN, QueryRunnerTestHelper.INDEX_DOUBLE_MAX,
+                            QueryRunnerTestHelper.INDEX_FLOAT_MIN, QueryRunnerTestHelper.INDEX_FLOAT_MAX)
         .setGranularity(Granularities.ALL)
         .setHavingSpec(new GreaterThanHavingSpec("index", 310L))
         .setLimitSpec(
@@ -4141,11 +4143,26 @@ public class GroupByQueryRunnerTest extends InitializedNullHandlingTest
     GroupByQuery fullQuery = builder.build();
 
     List<ResultRow> expectedResults = Arrays.asList(
-        makeRow(fullQuery, "2011-01-25", "alias", "business", "rows", 3L, "index", 312.38165283203125, QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 101L),
-        makeRow(fullQuery, "2011-01-25", "alias", "news", "rows", 3L, "index", 312.7834167480469, QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 102L),
-        makeRow(fullQuery, "2011-01-25", "alias", "technology", "rows", 3L, "index", 324.6412353515625, QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 102L),
-        makeRow(fullQuery, "2011-01-25", "alias", "travel", "rows", 3L, "index", 393.36322021484375, QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 122L),
-        makeRow(fullQuery, "2011-01-25", "alias", "health", "rows", 3L, "index", 511.2996826171875, QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 159L)
+        makeRow(fullQuery, "2011-01-25", "alias", "business", "rows", 3L, "index", 312.38165283203125,
+                QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 101L, QueryRunnerTestHelper.LONG_MAX_INDEX_METRIC, 105L,
+                QueryRunnerTestHelper.DOUBLE_MIN_INDEX_METRIC, 101.624789D, QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC, 105.873942D,
+                QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC, 101.62479F, QueryRunnerTestHelper.FLOAT_MAX_INDEX_METRIC, 105.87394F),
+        makeRow(fullQuery, "2011-01-25", "alias", "news", "rows", 3L, "index", 312.7834167480469,
+                QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 102L, QueryRunnerTestHelper.LONG_MAX_INDEX_METRIC, 105L,
+                QueryRunnerTestHelper.DOUBLE_MIN_INDEX_METRIC, 102.907866D, QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC, 105.266058D,
+                QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC, 102.90787F, QueryRunnerTestHelper.FLOAT_MAX_INDEX_METRIC, 105.26606F),
+        makeRow(fullQuery, "2011-01-25", "alias", "technology", "rows", 3L, "index", 324.6412353515625,
+                QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 102L, QueryRunnerTestHelper.LONG_MAX_INDEX_METRIC, 116L,
+                QueryRunnerTestHelper.DOUBLE_MIN_INDEX_METRIC, 102.044542D, QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC, 116.979005D,
+                QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC, 102.04454F, QueryRunnerTestHelper.FLOAT_MAX_INDEX_METRIC, 116.979004F),
+        makeRow(fullQuery, "2011-01-25", "alias", "travel", "rows", 3L, "index", 393.36322021484375,
+                QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 122L, QueryRunnerTestHelper.LONG_MAX_INDEX_METRIC, 149L,
+                QueryRunnerTestHelper.DOUBLE_MIN_INDEX_METRIC, 122.077247D, QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC, 149.125271D,
+                QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC, 122.07725F, QueryRunnerTestHelper.FLOAT_MAX_INDEX_METRIC, 149.12527F),
+        makeRow(fullQuery, "2011-01-25", "alias", "health", "rows", 3L, "index", 511.2996826171875,
+                QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 159L, QueryRunnerTestHelper.LONG_MAX_INDEX_METRIC, 180L,
+                QueryRunnerTestHelper.DOUBLE_MIN_INDEX_METRIC, 159.988606D, QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC, 180.575246D,
+                QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC, 159.9886F, QueryRunnerTestHelper.FLOAT_MAX_INDEX_METRIC, 180.57524F)
     );
 
     Iterable<ResultRow> results = GroupByQueryRunnerTestHelper.runQuery(factory, runner, fullQuery);
@@ -4266,16 +4283,28 @@ public class GroupByQueryRunnerTest extends InitializedNullHandlingTest
         .setDataSource(QueryRunnerTestHelper.DATA_SOURCE)
         .setInterval("2011-04-02/2011-04-04")
         .setDimensions(new DefaultDimensionSpec("quality", "alias"))
-        .setAggregatorSpecs(QueryRunnerTestHelper.ROWS_COUNT, new LongSumAggregatorFactory("idx", "index"), QueryRunnerTestHelper.INDEX_LONG_MIN)
+        .setAggregatorSpecs(QueryRunnerTestHelper.ROWS_COUNT, new LongSumAggregatorFactory("idx", "index"),
+                            QueryRunnerTestHelper.INDEX_LONG_MIN, QueryRunnerTestHelper.INDEX_LONG_MAX,
+                            QueryRunnerTestHelper.INDEX_DOUBLE_MIN, QueryRunnerTestHelper.INDEX_DOUBLE_MAX,
+                            QueryRunnerTestHelper.INDEX_FLOAT_MIN, QueryRunnerTestHelper.INDEX_FLOAT_MAX)
         .setGranularity(new PeriodGranularity(new Period("P1M"), null, null))
         .setHavingSpec(havingSpec);
 
     final GroupByQuery fullQuery = builder.build();
 
     List<ResultRow> expectedResults = Arrays.asList(
-        makeRow(fullQuery, "2011-04-01", "alias", "business", "rows", 2L, "idx", 217L, QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 105L),
-        makeRow(fullQuery, "2011-04-01", "alias", "mezzanine", "rows", 6L, "idx", 4420L, QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 107L),
-        makeRow(fullQuery, "2011-04-01", "alias", "premium", "rows", 6L, "idx", 4416L, QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 122L)
+        makeRow(fullQuery, "2011-04-01", "alias", "business", "rows", 2L, "idx", 217L, QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 105L,
+                QueryRunnerTestHelper.LONG_MAX_INDEX_METRIC, 112L, QueryRunnerTestHelper.DOUBLE_MIN_INDEX_METRIC, 105.735462D,
+                QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC, 112.987027D, QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC, 105.73546F,
+                QueryRunnerTestHelper.FLOAT_MAX_INDEX_METRIC, 112.98703F),
+        makeRow(fullQuery, "2011-04-01", "alias", "mezzanine", "rows", 6L, "idx", 4420L, QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 107L,
+                QueryRunnerTestHelper.LONG_MAX_INDEX_METRIC, 1193L, QueryRunnerTestHelper.DOUBLE_MIN_INDEX_METRIC, 107.047773D,
+                QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC, 1193.556278D, QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC, 107.047775F,
+                QueryRunnerTestHelper.FLOAT_MAX_INDEX_METRIC, 1193.5563F),
+        makeRow(fullQuery, "2011-04-01", "alias", "premium", "rows", 6L, "idx", 4416L, QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 122L,
+                QueryRunnerTestHelper.LONG_MAX_INDEX_METRIC, 1321L, QueryRunnerTestHelper.DOUBLE_MIN_INDEX_METRIC, 122.141707D,
+                QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC, 1321.375057D, QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC, 122.14171F,
+                QueryRunnerTestHelper.FLOAT_MAX_INDEX_METRIC, 1321.375F)
     );
 
     TestHelper.assertExpectedObjects(
diff --git a/processing/src/test/java/org/apache/druid/query/groupby/GroupByTimeseriesQueryRunnerTest.java b/processing/src/test/java/org/apache/druid/query/groupby/GroupByTimeseriesQueryRunnerTest.java
index 4e3f63b..8b80fc4 100644
--- a/processing/src/test/java/org/apache/druid/query/groupby/GroupByTimeseriesQueryRunnerTest.java
+++ b/processing/src/test/java/org/apache/druid/query/groupby/GroupByTimeseriesQueryRunnerTest.java
@@ -218,14 +218,19 @@ public class GroupByTimeseriesQueryRunnerTest extends TimeseriesQueryRunnerTest
   // GroupBy handles timestamps differently when granularity is ALL
   @Override
   @Test
-  public void testFullOnTimeseriesLongMin()
+  public void testFullOnTimeseriesMinMaxAggregators()
   {
     TimeseriesQuery query = Druids.newTimeseriesQueryBuilder()
                                   .dataSource(QueryRunnerTestHelper.DATA_SOURCE)
                                   .granularity(Granularities.ALL)
                                   .intervals(QueryRunnerTestHelper.FULL_ON_INTERVAL_SPEC)
                                   .aggregators(
-                                      QueryRunnerTestHelper.INDEX_LONG_MIN
+                                      QueryRunnerTestHelper.INDEX_LONG_MIN,
+                                      QueryRunnerTestHelper.INDEX_LONG_MAX,
+                                      QueryRunnerTestHelper.INDEX_DOUBLE_MIN,
+                                      QueryRunnerTestHelper.INDEX_DOUBLE_MAX,
+                                      QueryRunnerTestHelper.INDEX_FLOAT_MIN,
+                                      QueryRunnerTestHelper.INDEX_FLOAT_MAX
                                   )
                                   .descending(descending)
                                   .build();
@@ -243,6 +248,11 @@ public class GroupByTimeseriesQueryRunnerTest extends TimeseriesQueryRunnerTest
         result.getTimestamp().isAfter(expectedLast)
     );
     Assert.assertEquals(59L, (long) result.getValue().getLongMetric(QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC));
+    Assert.assertEquals(1870, (long) result.getValue().getLongMetric(QueryRunnerTestHelper.LONG_MAX_INDEX_METRIC));
+    Assert.assertEquals(59.021022D, result.getValue().getDoubleMetric(QueryRunnerTestHelper.DOUBLE_MIN_INDEX_METRIC), 0);
+    Assert.assertEquals(1870.061029D, result.getValue().getDoubleMetric(QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC), 0);
+    Assert.assertEquals(59.021023F, result.getValue().getFloatMetric(QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC), 0);
+    Assert.assertEquals(1870.061F, result.getValue().getFloatMetric(QueryRunnerTestHelper.FLOAT_MAX_INDEX_METRIC), 0);
   }
 
   @Override
diff --git a/processing/src/test/java/org/apache/druid/query/timeseries/TimeseriesQueryRunnerTest.java b/processing/src/test/java/org/apache/druid/query/timeseries/TimeseriesQueryRunnerTest.java
index ae4ab83..c67dfb5 100644
--- a/processing/src/test/java/org/apache/druid/query/timeseries/TimeseriesQueryRunnerTest.java
+++ b/processing/src/test/java/org/apache/druid/query/timeseries/TimeseriesQueryRunnerTest.java
@@ -335,9 +335,6 @@ public class TimeseriesQueryRunnerTest extends InitializedNullHandlingTest
   @Test
   public void testFullOnTimeseriesMaxMin()
   {
-    // Cannot vectorize due to "doubleMin", "doubleMax" aggregators.
-    cannotVectorize();
-
     TimeseriesQuery query = Druids.newTimeseriesQueryBuilder()
                                   .dataSource(QueryRunnerTestHelper.DATA_SOURCE)
                                   .granularity(Granularities.ALL)
@@ -371,14 +368,19 @@ public class TimeseriesQueryRunnerTest extends InitializedNullHandlingTest
   }
 
   @Test
-  public void testFullOnTimeseriesLongMin()
+  public void testFullOnTimeseriesMinMaxAggregators()
   {
     TimeseriesQuery query = Druids.newTimeseriesQueryBuilder()
                                   .dataSource(QueryRunnerTestHelper.DATA_SOURCE)
                                   .granularity(Granularities.ALL)
                                   .intervals(QueryRunnerTestHelper.FULL_ON_INTERVAL_SPEC)
                                   .aggregators(
-                                      QueryRunnerTestHelper.INDEX_LONG_MIN
+                                      QueryRunnerTestHelper.INDEX_LONG_MIN,
+                                      QueryRunnerTestHelper.INDEX_LONG_MAX,
+                                      QueryRunnerTestHelper.INDEX_DOUBLE_MIN,
+                                      QueryRunnerTestHelper.INDEX_DOUBLE_MAX,
+                                      QueryRunnerTestHelper.INDEX_FLOAT_MIN,
+                                      QueryRunnerTestHelper.INDEX_FLOAT_MAX
                                   )
                                   .descending(descending)
                                   .context(makeContext())
@@ -396,6 +398,11 @@ public class TimeseriesQueryRunnerTest extends InitializedNullHandlingTest
     );
 
     Assert.assertEquals(59L, (long) result.getValue().getLongMetric(QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC));
+    Assert.assertEquals(1870, (long) result.getValue().getLongMetric(QueryRunnerTestHelper.LONG_MAX_INDEX_METRIC));
+    Assert.assertEquals(59.021022D, result.getValue().getDoubleMetric(QueryRunnerTestHelper.DOUBLE_MIN_INDEX_METRIC), 0);
+    Assert.assertEquals(1870.061029D, result.getValue().getDoubleMetric(QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC), 0);
+    Assert.assertEquals(59.021023F, result.getValue().getFloatMetric(QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC), 0);
+    Assert.assertEquals(1870.061F, result.getValue().getFloatMetric(QueryRunnerTestHelper.FLOAT_MAX_INDEX_METRIC), 0);
   }
 
   @Test
@@ -468,7 +475,8 @@ public class TimeseriesQueryRunnerTest extends InitializedNullHandlingTest
                                               "index"
                                           ),
                                           QueryRunnerTestHelper.QUALITY_UNIQUES,
-                                          QueryRunnerTestHelper.INDEX_LONG_MIN
+                                          QueryRunnerTestHelper.INDEX_LONG_MIN,
+                                          QueryRunnerTestHelper.INDEX_FLOAT_MAX
                                       )
                                   )
                                   .descending(descending)
@@ -479,13 +487,17 @@ public class TimeseriesQueryRunnerTest extends InitializedNullHandlingTest
         new Result<>(
             DateTimes.of("2011-04-01"),
             new TimeseriesResultValue(
-                ImmutableMap.of("rows", 13L, "idx", 6619L, "uniques", QueryRunnerTestHelper.UNIQUES_9, QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 78L)
+                ImmutableMap.of("rows", 13L, "idx", 6619L, "uniques", QueryRunnerTestHelper.UNIQUES_9,
+                                QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 78L,
+                                QueryRunnerTestHelper.FLOAT_MAX_INDEX_METRIC, 1522.043701171875)
             )
         ),
         new Result<>(
             DateTimes.of("2011-04-02"),
             new TimeseriesResultValue(
-                ImmutableMap.of("rows", 13L, "idx", 5827L, "uniques", QueryRunnerTestHelper.UNIQUES_9, QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 97L)
+                ImmutableMap.of("rows", 13L, "idx", 5827L, "uniques", QueryRunnerTestHelper.UNIQUES_9,
+                                QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 97L,
+                                QueryRunnerTestHelper.FLOAT_MAX_INDEX_METRIC, 1321.375F)
             )
         )
     );
@@ -506,7 +518,9 @@ public class TimeseriesQueryRunnerTest extends InitializedNullHandlingTest
                                           QueryRunnerTestHelper.ROWS_COUNT,
                                           QueryRunnerTestHelper.INDEX_LONG_SUM,
                                           QueryRunnerTestHelper.QUALITY_UNIQUES,
-                                          QueryRunnerTestHelper.INDEX_LONG_MIN
+                                          QueryRunnerTestHelper.INDEX_LONG_MIN,
+                                          QueryRunnerTestHelper.INDEX_DOUBLE_MAX,
+                                          QueryRunnerTestHelper.INDEX_FLOAT_MIN
                                       )
                                   )
                                   .postAggregators(QueryRunnerTestHelper.ADD_ROWS_INDEX_CONSTANT)
@@ -515,43 +529,38 @@ public class TimeseriesQueryRunnerTest extends InitializedNullHandlingTest
                                   .build();
 
     List<Result<TimeseriesResultValue>> expectedResults = new ArrayList<>();
-
+    ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
     expectedResults.add(
         new Result<>(
             DateTimes.of("2011-04-01"),
             new TimeseriesResultValue(
-                ImmutableMap.of(
-                    "rows",
-                    13L,
-                    "index",
-                    6619L,
-                    "uniques",
-                    QueryRunnerTestHelper.UNIQUES_9,
-                    QueryRunnerTestHelper.ADD_ROWS_INDEX_CONSTANT_METRIC,
-                    6633.0,
-                    QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC,
-                    78L
-                )
+                builder
+                    .put("rows", 13L)
+                    .put("index", 6619L)
+                    .put("uniques", QueryRunnerTestHelper.UNIQUES_9)
+                    .put(QueryRunnerTestHelper.ADD_ROWS_INDEX_CONSTANT_METRIC, 6633.0)
+                    .put(QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 78L)
+                    .put(QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC, 1522.043733D)
+                    .put(QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC, 78.62254333496094F)
+                    .build()
             )
         )
     );
 
+    ImmutableMap.Builder<String, Object> builder2 = ImmutableMap.builder();
     expectedResults.add(
         new Result<>(
             DateTimes.of("2011-04-02"),
             new TimeseriesResultValue(
-                ImmutableMap.of(
-                    "rows",
-                    13L,
-                    "index",
-                    5827L,
-                    "uniques",
-                    QueryRunnerTestHelper.UNIQUES_9,
-                    QueryRunnerTestHelper.ADD_ROWS_INDEX_CONSTANT_METRIC,
-                    5841.0,
-                    QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC,
-                    97L
-                )
+                builder2
+                    .put("rows", 13L)
+                    .put("index", 5827L)
+                    .put("uniques", QueryRunnerTestHelper.UNIQUES_9)
+                    .put(QueryRunnerTestHelper.ADD_ROWS_INDEX_CONSTANT_METRIC, 5841.0)
+                    .put(QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 97L)
+                    .put(QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC, 1321.375057D)
+                    .put(QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC, 97.38743591308594F)
+                    .build()
             )
         )
     );
@@ -560,22 +569,20 @@ public class TimeseriesQueryRunnerTest extends InitializedNullHandlingTest
       Collections.reverse(expectedResults);
     }
 
+    ImmutableMap.Builder<String, Object> builder3 = ImmutableMap.builder();
     expectedResults.add(
         new Result<>(
             null,
             new TimeseriesResultValue(
-                ImmutableMap.of(
-                    "rows",
-                    26L,
-                    "index",
-                    12446L,
-                    "uniques",
-                    QueryRunnerTestHelper.UNIQUES_9,
-                    QueryRunnerTestHelper.ADD_ROWS_INDEX_CONSTANT_METRIC,
-                    12473.0,
-                    QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC,
-                    78L
-                )
+                builder3
+                    .put("rows", 26L)
+                    .put("index", 12446L)
+                    .put("uniques", QueryRunnerTestHelper.UNIQUES_9)
+                    .put(QueryRunnerTestHelper.ADD_ROWS_INDEX_CONSTANT_METRIC, 12473.0)
+                    .put(QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC, 78L)
+                    .put(QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC, 1522.043733D)
+                    .put(QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC, 78.62254333496094F)
+                    .build()
             )
         )
     );
@@ -605,7 +612,12 @@ public class TimeseriesQueryRunnerTest extends InitializedNullHandlingTest
                                       Arrays.asList(
                                           QueryRunnerTestHelper.ROWS_COUNT,
                                           QueryRunnerTestHelper.INDEX_LONG_SUM,
-                                          QueryRunnerTestHelper.INDEX_LONG_MIN
+                                          QueryRunnerTestHelper.INDEX_LONG_MIN,
+                                          QueryRunnerTestHelper.INDEX_LONG_MAX,
+                                          QueryRunnerTestHelper.INDEX_DOUBLE_MIN,
+                                          QueryRunnerTestHelper.INDEX_DOUBLE_MAX,
+                                          QueryRunnerTestHelper.INDEX_FLOAT_MIN,
+                                          QueryRunnerTestHelper.INDEX_FLOAT_MAX
                                       )
                                   )
                                   .postAggregators(QueryRunnerTestHelper.ADD_ROWS_INDEX_CONSTANT)
@@ -626,7 +638,17 @@ public class TimeseriesQueryRunnerTest extends InitializedNullHandlingTest
                     QueryRunnerTestHelper.ADD_ROWS_INDEX_CONSTANT_METRIC,
                     NullHandling.sqlCompatible() ? null : 1.0,
                     QueryRunnerTestHelper.LONG_MIN_INDEX_METRIC,
-                    NullHandling.sqlCompatible() ? null : Long.MAX_VALUE
+                    NullHandling.sqlCompatible() ? null : Long.MAX_VALUE,
+                    QueryRunnerTestHelper.LONG_MAX_INDEX_METRIC,
+                    NullHandling.sqlCompatible() ? null : Long.MIN_VALUE,
+                    QueryRunnerTestHelper.DOUBLE_MIN_INDEX_METRIC,
+                    NullHandling.sqlCompatible() ? null : Double.POSITIVE_INFINITY,
+                    QueryRunnerTestHelper.DOUBLE_MAX_INDEX_METRIC,
+                    NullHandling.sqlCompatible() ? null : Double.NEGATIVE_INFINITY,
+                    QueryRunnerTestHelper.FLOAT_MIN_INDEX_METRIC,
+                    NullHandling.sqlCompatible() ? null : Float.POSITIVE_INFINITY,
+                    QueryRunnerTestHelper.FLOAT_MAX_INDEX_METRIC,
+                    NullHandling.sqlCompatible() ? null : Float.NEGATIVE_INFINITY
                 )
             )
         )
diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java
index 86585d2..9409f81 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java
@@ -49,6 +49,7 @@ import org.apache.druid.query.ResourceLimitExceededException;
 import org.apache.druid.query.TableDataSource;
 import org.apache.druid.query.aggregation.CountAggregatorFactory;
 import org.apache.druid.query.aggregation.DoubleMaxAggregatorFactory;
+import org.apache.druid.query.aggregation.DoubleMinAggregatorFactory;
 import org.apache.druid.query.aggregation.DoubleSumAggregatorFactory;
 import org.apache.druid.query.aggregation.FilteredAggregatorFactory;
 import org.apache.druid.query.aggregation.FloatMaxAggregatorFactory;
@@ -4359,9 +4360,6 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
     // This query should actually return [0, null] rather than an empty result set, but it doesn't.
     // This test just "documents" the current behavior.
 
-    // Cannot vectorize due to "longMax" aggregator.
-    cannotVectorize();
-
     testQuery(
         "SELECT COUNT(*), MAX(cnt) FROM druid.foo WHERE dim1 = 'foobar'",
         ImmutableList.of(
@@ -4406,9 +4404,6 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
   @Test
   public void testGroupByWithFilterMatchingNothingWithGroupByLiteral() throws Exception
   {
-    // Cannot vectorize due to "longMax" aggregator.
-    cannotVectorize();
-
     testQuery(
         "SELECT COUNT(*), MAX(cnt) FROM druid.foo WHERE dim1 = 'foobar' GROUP BY 'dummy'",
         ImmutableList.of(
@@ -4804,7 +4799,7 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
   public void testSimpleLongAggregations() throws Exception
   {
     testQuery(
-        "SELECT  MIN(l1), MIN(cnt) FROM druid.numfoo",
+        "SELECT  MIN(l1), MIN(cnt), MAX(l1) FROM druid.numfoo",
         ImmutableList.of(
             Druids.newTimeseriesQueryBuilder()
                 .dataSource(CalciteTests.DATASOURCE3)
@@ -4812,24 +4807,68 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
                 .granularity(Granularities.ALL)
                 .aggregators(aggregators(
                                 new LongMinAggregatorFactory("a0", "l1"),
-                                new LongMinAggregatorFactory("a1", "cnt")
+                                new LongMinAggregatorFactory("a1", "cnt"),
+                                new LongMaxAggregatorFactory("a2", "l1")
                             ))
                 .context(TIMESERIES_CONTEXT_DEFAULT)
                 .build()
         ),
         ImmutableList.of(
-            new Object[]{0L, 1L}
+            new Object[]{0L, 1L, 325323L}
         )
     );
   }
 
+  @Test
+  public void testSimpleDoubleAggregations() throws Exception
+  {
+    testQuery(
+        "SELECT  MIN(d1), MAX(d1) FROM druid.numfoo",
+        ImmutableList.of(
+            Druids.newTimeseriesQueryBuilder()
+                  .dataSource(CalciteTests.DATASOURCE3)
+                  .intervals(querySegmentSpec(Filtration.eternity()))
+                  .granularity(Granularities.ALL)
+                  .aggregators(aggregators(
+                      new DoubleMinAggregatorFactory("a0", "d1"),
+                      new DoubleMaxAggregatorFactory("a1", "d1")
+                  ))
+                  .context(TIMESERIES_CONTEXT_DEFAULT)
+                  .build()
+        ),
+        ImmutableList.of(
+            new Object[]{0.0, 1.7}
+        )
+    );
+  }
 
   @Test
-  public void testSimpleAggregations() throws Exception
+  public void testSimpleFloatAggregations() throws Exception
   {
-    // Cannot vectorize due to "longMax" aggregator.
-    cannotVectorize();
+    testQuery(
+        "SELECT  MIN(m1), MAX(m1) FROM druid.numfoo",
+        ImmutableList.of(
+            Druids.newTimeseriesQueryBuilder()
+                  .dataSource(CalciteTests.DATASOURCE3)
+                  .intervals(querySegmentSpec(Filtration.eternity()))
+                  .granularity(Granularities.ALL)
+                  .aggregators(aggregators(
+                      new FloatMinAggregatorFactory("a0", "m1"),
+                      new FloatMaxAggregatorFactory("a1", "m1")
+                  ))
+                  .context(TIMESERIES_CONTEXT_DEFAULT)
+                  .build()
+        ),
+        ImmutableList.of(
+            new Object[]{1.0f, 6.0f}
+        )
+    );
+  }
 
+
+  @Test
+  public void testSimpleAggregations() throws Exception
+  {
     testQuery(
         "SELECT COUNT(*), COUNT(cnt), COUNT(dim1), AVG(cnt), SUM(cnt), SUM(cnt) + MIN(cnt) + MAX(cnt), COUNT(dim2), COUNT(d1), AVG(d1) FROM druid.numfoo",
         ImmutableList.of(
@@ -4961,10 +5000,6 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
   public void testGroupByWithSortOnPostAggregationNoTopNConfig() throws Exception
   {
     // Use PlannerConfig to disable topN, so this query becomes a groupBy.
-
-    // Cannot vectorize due to "floatMin", "floatMax" aggregators.
-    cannotVectorize();
-
     testQuery(
         PLANNER_CONFIG_NO_TOPN,
         "SELECT dim1, MIN(m1) + MAX(m1) AS x FROM druid.foo GROUP BY dim1 ORDER BY x LIMIT 3",
@@ -5008,9 +5043,6 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
   {
     // Use context to disable topN, so this query becomes a groupBy.
 
-    // Cannot vectorize due to "floatMin", "floatMax" aggregators.
-    cannotVectorize();
-
     testQuery(
         PLANNER_CONFIG_DEFAULT,
         QUERY_CONTEXT_NO_TOPN,
@@ -5057,7 +5089,7 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
   @Test
   public void testFilteredAggregations() throws Exception
   {
-    // Cannot vectorize due to "cardinality", "longMax" aggregators.
+    // Cannot vectorize due to "cardinality" aggregator.
     cannotVectorize();
 
     testQuery(
@@ -5231,7 +5263,7 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
   @Test
   public void testExpressionAggregations() throws Exception
   {
-    // Cannot vectorize due to "doubleMax" aggregator.
+    // Cannot vectorize due to expressions.
     cannotVectorize();
 
     final ExprMacroTable macroTable = CalciteTests.createExprMacroTable();
@@ -6681,8 +6713,6 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
   @Test
   public void testNestedGroupBy() throws Exception
   {
-    // Cannot vectorize due to virtual columns.
-    cannotVectorize();
 
     testQuery(
         "SELECT\n"


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org