/*
 * 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.drill.exec.fn.impl;

import org.apache.drill.exec.record.metadata.SchemaBuilder;
import org.apache.drill.exec.record.metadata.TupleMetadata;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.drill.common.exceptions.UserRemoteException;
import org.apache.drill.common.types.Types;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.planner.physical.PlannerSettings;
import org.apache.drill.exec.record.RecordBatchLoader;
import org.apache.drill.exec.record.VectorWrapper;
import org.apache.drill.exec.util.Text;
import org.apache.drill.categories.EasyOutOfMemory;
import org.apache.drill.categories.OperatorTest;
import org.apache.drill.categories.PlannerTest;
import org.apache.drill.categories.SqlFunctionTest;
import org.apache.drill.categories.UnlikelyTest;
import org.apache.drill.common.expression.SchemaPath;
import org.apache.drill.common.types.TypeProtos;
import org.apache.drill.exec.proto.UserBitShared;
import org.apache.drill.exec.rpc.user.QueryDataBatch;
import org.apache.drill.test.ClusterFixture;
import org.apache.drill.test.ClusterTest;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.ExpectedException;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.math.BigDecimal;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import static org.apache.drill.test.TestBuilder.listOf;
import static org.apache.drill.test.TestBuilder.mapOf;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

@Category({ SqlFunctionTest.class, OperatorTest.class, PlannerTest.class, EasyOutOfMemory.class })
public class TestAggregateFunctions extends ClusterTest {

  @Rule
  public ExpectedException thrown = ExpectedException.none();

  @BeforeClass
  public static void setUp() throws Exception {
    startCluster(ClusterFixture.builder(dirTestWatcher));
    dirTestWatcher.copyResourceToRoot(Paths.get("agg"));
  }

  /*
   * Test checks the count of a nullable column within a map
   * and verifies count is equal only to the number of times the
   * column appears and doesn't include the null count
   */
  @Test
  public void testCountOnNullableColumn() throws Exception {
    testBuilder()
        .sqlQuery("select count(t.x.y)  as cnt1, count(`integer`) as cnt2 from cp.`jsoninput/input2.json` t")
        .ordered()
        .baselineColumns("cnt1", "cnt2")
        .baselineValues(3L, 4L)
        .go();
  }

  @Test
  public void testCountDistinctOnBoolColumn() throws Exception {
    testBuilder()
        .sqlQuery("select count(distinct `bool_val`) as cnt from `sys`.`options_old`")
        .ordered()
        .baselineColumns("cnt")
        .baselineValues(2L)
        .go();
  }

  @Test
  public void testMaxWithZeroInput() throws Exception {
    try {
      client.alterSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY, false);
      testBuilder()
          .sqlQuery("select max(employee_id * 0.0) as max_val from cp.`employee.json`")
          .unOrdered()
          .baselineColumns("max_val")
          .baselineValues(0.0)
          .go();
    } finally {
      client.resetSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY);
    }
  }

  @Ignore
  @Test // DRILL-2092: count distinct, non distinct aggregate with group-by
  public void testDrill2092() throws Exception {
    String query = "select a1, b1, count(distinct c1) as dist1, \n"
        + "sum(c1) as sum1, count(c1) as cnt1, count(*) as cnt \n"
        + "from cp.`agg/bugs/drill2092/input.json` \n"
        + "group by a1, b1 order by a1, b1";

    String baselineQuery =
        "select case when columns[0]='null' then cast(null as bigint) else cast(columns[0] as bigint) end as a1, \n"
        + "case when columns[1]='null' then cast(null as bigint) else cast(columns[1] as bigint) end as b1, \n"
        + "case when columns[2]='null' then cast(null as bigint) else cast(columns[2] as bigint) end as dist1, \n"
        + "case when columns[3]='null' then cast(null as bigint) else cast(columns[3] as bigint) end as sum1, \n"
        + "case when columns[4]='null' then cast(null as bigint) else cast(columns[4] as bigint) end as cnt1, \n"
        + "case when columns[5]='null' then cast(null as bigint) else cast(columns[5] as bigint) end as cnt \n"
        + "from cp.`agg/bugs/drill2092/result.tsv`";


    // NOTE: this type of query gets rewritten by Calcite into an inner join of subqueries, so
    // we need to test with both hash join and merge join

    testBuilder()
        .sqlQuery(query)
        .ordered()
        .optionSettingQueriesForTestQuery("alter system set `planner.enable_hashjoin` = true")
        .sqlBaselineQuery(baselineQuery)
        .build().run();

    testBuilder()
    .sqlQuery(query)
    .ordered()
    .optionSettingQueriesForTestQuery("alter system set `planner.enable_hashjoin` = false")
    .sqlBaselineQuery(baselineQuery)
    .build().run();

  }

  @Test // DRILL-2170: Subquery has group-by, order-by on aggregate function and limit
  @Category(UnlikelyTest.class)
  public void testDrill2170() throws Exception {
    String query =
        "select count(*) as cnt from "
        + "cp.`tpch/orders.parquet` o inner join\n"
        + "(select l_orderkey, sum(l_quantity), sum(l_extendedprice) \n"
        + "from cp.`tpch/lineitem.parquet` \n"
        + "group by l_orderkey order by 3 limit 100) sq \n"
        + "on sq.l_orderkey = o.o_orderkey";

    testBuilder()
    .sqlQuery(query)
    .ordered()
    .optionSettingQueriesForTestQuery("alter system set `planner.slice_target` = 1000")
    .baselineColumns("cnt")
    .baselineValues(100L)
    .go();
  }

  @Test // DRILL-2168
  @Category(UnlikelyTest.class)
  public void testGBExprWithDrillFunc() throws Exception {
    testBuilder()
        .ordered()
        .sqlQuery("select concat(n_name, cast(n_nationkey as varchar(10))) as name, count(*) as cnt " +
            "from cp.`tpch/nation.parquet` " +
            "group by concat(n_name, cast(n_nationkey as varchar(10))) " +
            "having concat(n_name, cast(n_nationkey as varchar(10))) > 'UNITED'" +
            "order by concat(n_name, cast(n_nationkey as varchar(10)))")
        .baselineColumns("name", "cnt")
        .baselineValues("UNITED KINGDOM23", 1L)
        .baselineValues("UNITED STATES24", 1L)
        .baselineValues("VIETNAM21", 1L)
        .build().run();
  }

  @Test //DRILL-2242
  @Category(UnlikelyTest.class)
  public void testDRILLNestedGBWithSubsetKeys() throws Exception {
    String sql = " select count(*) as cnt from (select l_partkey from\n" +
        "   (select l_partkey, l_suppkey from cp.`tpch/lineitem.parquet`\n" +
        "      group by l_partkey, l_suppkey) \n" +
        "   group by l_partkey )";

    client.alterSession(ExecConstants.SLICE_TARGET, 1);
    client.alterSession(PlannerSettings.MULTIPHASE.getOptionName(), false);

    testBuilder()
        .ordered()
        .sqlQuery(sql)
        .baselineColumns("cnt")
        .baselineValues(2000L)
        .build().run();

    client.alterSession(ExecConstants.SLICE_TARGET, 1);
    client.alterSession(PlannerSettings.MULTIPHASE.getOptionName(), true);

    testBuilder()
        .ordered()
        .sqlQuery(sql)
        .baselineColumns("cnt")
        .baselineValues(2000L)
        .build().run();

    client.alterSession(ExecConstants.SLICE_TARGET, 1000);
  }

  @Test
  public void testAvgWithNullableScalarFunction() throws Exception {
    String query = " select avg(length(b1)) as col from cp.`jsoninput/nullable1.json`";
    testBuilder()
        .sqlQuery(query)
        .unOrdered()
        .baselineColumns("col")
        .baselineValues(3.0d)
        .go();
  }

  @Test
  public void testCountWithAvg() throws Exception {
    testBuilder()
        .sqlQuery("select count(a) col1, avg(b) col2 from cp.`jsoninput/nullable3.json`")
        .unOrdered()
        .baselineColumns("col1", "col2")
        .baselineValues(2L, 3.0d)
        .go();

    testBuilder()
        .sqlQuery("select count(a) col1, avg(a) col2 from cp.`jsoninput/nullable3.json`")
        .unOrdered()
        .baselineColumns("col1", "col2")
        .baselineValues(2L, 1.0d)
        .go();
  }

  @Test
  public void testAvgOnKnownType() throws Exception {
    testBuilder()
        .sqlQuery("select avg(cast(employee_id as bigint)) as col from cp.`employee.json`")
        .unOrdered()
        .baselineColumns("col")
        .baselineValues(578.9982683982684d)
        .go();
  }

  @Test
  public void testStddevOnKnownType() throws Exception {
    testBuilder()
        .sqlQuery("select stddev_samp(cast(employee_id as int)) as col from cp.`employee.json`")
        .unOrdered()
        .baselineColumns("col")
        .baselineValues(333.56708470261117d)
        .go();
  }

  @Test
  public void testVarSampDecimal() throws Exception {
    try {
      client.alterSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY, true);
      testBuilder()
          .sqlQuery("select var_samp(cast(employee_id as decimal(28, 20))) as dec20,\n" +
                "var_samp(cast(employee_id as decimal(28, 0))) as dec6,\n" +
                "var_samp(cast(employee_id as integer)) as d\n" +
                "from cp.`employee.json`")
          .unOrdered()
          .baselineColumns("dec20", "dec6", "d")
          .baselineValues(new BigDecimal("111266.99999699895713760532"),
              new BigDecimal("111266.999997"),
              111266.99999699896)
          .go();
    } finally {
      client.resetSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY);
    }
  }

  @Test
  public void testVarPopDecimal() throws Exception {
    try {
      client.alterSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY, true);
      testBuilder()
          .sqlQuery("select var_pop(cast(employee_id as decimal(28, 20))) as dec20,\n" +
              "var_pop(cast(employee_id as decimal(28, 0))) as dec6,\n" +
              "var_pop(cast(employee_id as integer)) as d\n" +
              "from cp.`employee.json`")
          .unOrdered()
          .baselineColumns("dec20", "dec6", "d")
          .baselineValues(new BigDecimal("111170.66493206649050804895"),
              new BigDecimal("111170.664932"),
              111170.66493206649)
          .go();
    } finally {
      client.resetSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY);
    }
  }

  @Test
  public void testStddevSampDecimal() throws Exception {
    try {
      client.alterSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY, true);
      testBuilder()
          .sqlQuery("select stddev_samp(cast(employee_id as decimal(28, 20))) as dec20,\n" +
              "stddev_samp(cast(employee_id as decimal(28, 0))) as dec6,\n" +
              "stddev_samp(cast(employee_id as integer)) as d\n" +
              "from cp.`employee.json`")
          .unOrdered()
          .baselineColumns("dec20", "dec6", "d")
          .baselineValues(new BigDecimal("333.56708470261114349632"),
              new BigDecimal("333.567085"),
              333.56708470261117) // last number differs because of double precision.
          // Was taken sqrt of 111266.99999699895713760531784795216338 and decimal result is correct
          .go();
    } finally {
      client.resetSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY);
    }
  }

  @Test
  public void testStddevPopDecimal() throws Exception {
    try {
      client.alterSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY, true);
      testBuilder()
          .sqlQuery("select stddev_pop(cast(employee_id as decimal(28, 20))) as dec20,\n" +
              "stddev_pop(cast(employee_id as decimal(28, 0))) as dec6,\n" +
              "stddev_pop(cast(employee_id as integer)) as d\n" +
              "from cp.`employee.json`")
          .unOrdered()
          .baselineColumns("dec20", "dec6", "d")
          .baselineValues(new BigDecimal("333.42265209800381903633"),
              new BigDecimal("333.422652"),
              333.4226520980038)
          .go();
    } finally {
      client.resetSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY);
    }
  }

  @Test
  public void testSumDecimal() throws Exception {
    try {
      client.alterSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY, true);
      testBuilder()
          .sqlQuery("select sum(cast(employee_id as decimal(9, 0))) as colDecS0,\n" +
              "sum(cast(employee_id as decimal(12, 3))) as colDecS3,\n" +
              "sum(cast(employee_id as integer)) as colInt\n" +
              "from cp.`employee.json`")
          .unOrdered()
          .baselineColumns("colDecS0", "colDecS3", "colInt")
          .baselineValues(BigDecimal.valueOf(668743), new BigDecimal("668743.000"), 668743L)
          .go();
    } finally {
      client.resetSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY);
    }
  }

  @Test
  public void testAvgDecimal() throws Exception {
    try {
      client.alterSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY, true);
      testBuilder()
          .sqlQuery("select avg(cast(employee_id as decimal(28, 20))) as colDec20,\n" +
              "avg(cast(employee_id as decimal(28, 0))) as colDec6,\n" +
              "avg(cast(employee_id as integer)) as colInt\n" +
              "from cp.`employee.json`")
          .unOrdered()
          .baselineColumns("colDec20", "colDec6", "colInt")
          .baselineValues(new BigDecimal("578.99826839826839826840"),
              new BigDecimal("578.998268"),
              578.9982683982684)
          .go();
    } finally {
      client.resetSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY);
    }
  }

  @Test
  public void testSumAvgDecimalLimit0() throws Exception {
    final List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema =
        ImmutableList.of(
            Pair.of(SchemaPath.getSimplePath("sum_col"),
                Types.withPrecisionAndScale(TypeProtos.MinorType.VARDECIMAL, TypeProtos.DataMode.OPTIONAL, 38, 3)),
            Pair.of(SchemaPath.getSimplePath("avg_col"),
                Types.withPrecisionAndScale(TypeProtos.MinorType.VARDECIMAL, TypeProtos.DataMode.OPTIONAL, 38, 6)),
            Pair.of(SchemaPath.getSimplePath("stddev_pop_col"),
                Types.withPrecisionAndScale(TypeProtos.MinorType.VARDECIMAL, TypeProtos.DataMode.OPTIONAL, 38, 6)),
            Pair.of(SchemaPath.getSimplePath("stddev_samp_col"),
                Types.withPrecisionAndScale(TypeProtos.MinorType.VARDECIMAL, TypeProtos.DataMode.OPTIONAL, 38, 6)),
            Pair.of(SchemaPath.getSimplePath("var_pop_col"),
                Types.withPrecisionAndScale(TypeProtos.MinorType.VARDECIMAL, TypeProtos.DataMode.OPTIONAL, 38, 6)),
            Pair.of(SchemaPath.getSimplePath("var_samp_col"),
                Types.withPrecisionAndScale(TypeProtos.MinorType.VARDECIMAL, TypeProtos.DataMode.OPTIONAL, 38, 6)),
            Pair.of(SchemaPath.getSimplePath("max_col"),
                Types.withPrecisionAndScale(TypeProtos.MinorType.VARDECIMAL, TypeProtos.DataMode.OPTIONAL, 9, 3)),
            Pair.of(SchemaPath.getSimplePath("min_col"),
                Types.withPrecisionAndScale(TypeProtos.MinorType.VARDECIMAL, TypeProtos.DataMode.OPTIONAL, 9, 3)));

    String query =
        "select\n" +
            "sum(cast(employee_id as decimal(9, 3))) sum_col,\n" +
            "avg(cast(employee_id as decimal(9, 3))) avg_col,\n" +
            "stddev_pop(cast(employee_id as decimal(9, 3))) stddev_pop_col,\n" +
            "stddev_samp(cast(employee_id as decimal(9, 3))) stddev_samp_col,\n" +
            "var_pop(cast(employee_id as decimal(9, 3))) var_pop_col,\n" +
            "var_samp(cast(employee_id as decimal(9, 3))) var_samp_col,\n" +
            "max(cast(employee_id as decimal(9, 3))) max_col,\n" +
            "min(cast(employee_id as decimal(9, 3))) min_col\n" +
            "from cp.`employee.json` limit 0";
    try {
      client.alterSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY, true);
      client.alterSession(ExecConstants.EARLY_LIMIT0_OPT_KEY, true);

      testBuilder()
          .sqlQuery(query)
          .schemaBaseLine(expectedSchema)
          .go();

      client.alterSession(ExecConstants.EARLY_LIMIT0_OPT_KEY, false);

      testBuilder()
        .sqlQuery(query)
        .schemaBaseLine(expectedSchema)
        .go();

    } finally {
      client.resetSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY);
      client.resetSession(ExecConstants.EARLY_LIMIT0_OPT_KEY);
    }
  }

  @Test // DRILL-6221
  public void testAggGroupByWithNullDecimal() throws Exception {
    String fileName = "table.json";
    try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(dirTestWatcher.getRootDir(), fileName)))) {
      writer.write("{\"a\": 1, \"b\": 0}");
      writer.write("{\"b\": 2}");
    }

    try {
      client.alterSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY, true);
      testBuilder()
          .sqlQuery("select sum(cast(a as decimal(9,0))) as s,\n" +
              "avg(cast(a as decimal(9,0))) as av,\n" +
              "var_samp(cast(a as decimal(9,0))) as varSamp,\n" +
              "var_pop(cast(a as decimal(9,0))) as varPop,\n" +
              "stddev_pop(cast(a as decimal(9,0))) as stddevPop,\n" +
              "stddev_samp(cast(a as decimal(9,0))) as stddevSamp," +
              "max(cast(a as decimal(9,0))) as mx," +
            "min(cast(a as decimal(9,0))) as mn from dfs.`%s` t group by a", fileName)
          .unOrdered()
          .baselineColumns("s", "av", "varSamp", "varPop", "stddevPop", "stddevSamp", "mx", "mn")
          .baselineValues(BigDecimal.valueOf(1), new BigDecimal("1.000000"), new BigDecimal("0.000000"),
              new BigDecimal("0.000000"), new BigDecimal("0.000000"), new BigDecimal("0.000000"),
              BigDecimal.valueOf(1), BigDecimal.valueOf(1))
          .baselineValues(null, null, null, null, null, null, null, null)
          .go();

    } finally {
      client.resetSession(PlannerSettings.ENABLE_DECIMAL_DATA_TYPE_KEY);
    }
  }

  @Test
  // test aggregates when input is empty and data type is optional
  public void countEmptyNullableInput() throws Exception {
    String query = "select " +
        "count(employee_id) col1, avg(employee_id) col2, sum(employee_id) col3 " +
        "from cp.`employee.json` where 1 = 0";

    testBuilder()
        .sqlQuery(query)
        .unOrdered()
        .baselineColumns("col1", "col2", "col3")
        .baselineValues(0L, null, null)
        .go();
  }

  @Test
  @Ignore("DRILL-4473")
  public void sumEmptyNonexistentNullableInput() throws Exception {
    final String query = "select "
        +
        "sum(int_col) col1, sum(bigint_col) col2, sum(float4_col) col3, sum(float8_col) col4, sum(interval_year_col) col5 "
        +
        "from cp.`employee.json` where 1 = 0";

    testBuilder()
        .sqlQuery(query)
        .unOrdered()
        .baselineColumns("col1", "col2", "col3", "col4", "col5")
        .baselineValues(null, null, null, null, null)
        .go();
  }

  @Test
  @Ignore("DRILL-4473")
  public void avgEmptyNonexistentNullableInput() throws Exception {
    // test avg function
    final String query = "select "
        +
        "avg(int_col) col1, avg(bigint_col) col2, avg(float4_col) col3, avg(float8_col) col4, avg(interval_year_col) col5 "
        +
        "from cp.`employee.json` where 1 = 0";

    testBuilder()
        .sqlQuery(query)
        .unOrdered()
        .baselineColumns("col1", "col2", "col3", "col4", "col5")
        .baselineValues(null, null, null, null, null)
        .go();
  }

  @Test
  public void stddevEmptyNonexistentNullableInput() throws Exception {
    // test stddev function
    final String query = "select " +
        "stddev_pop(int_col) col1, stddev_pop(bigint_col) col2, stddev_pop(float4_col) col3, " +
        "stddev_pop(float8_col) col4, stddev_pop(interval_year_col) col5 " +
        "from cp.`employee.json` where 1 = 0";

    testBuilder()
        .sqlQuery(query)
        .unOrdered()
        .baselineColumns("col1", "col2", "col3", "col4", "col5")
        .baselineValues(null, null, null, null, null)
        .go();

  }

  @Test
  public void minMaxEmptyNonNullableInput() throws Exception {
    // test min and max functions on required type

    final QueryDataBatch result = queryBuilder().sql("select * from cp.`parquet/alltypes_required.parquet` limit 0").results()
        .get(0);

    final Map<String, StringBuilder> functions = Maps.newHashMap();
    functions.put("min", new StringBuilder());
    functions.put("max", new StringBuilder());

    final Map<String, Object> resultingValues = Maps.newHashMap();
    for (UserBitShared.SerializedField field : result.getHeader().getDef().getFieldList()) {
      final String fieldName = field.getNamePart().getName();
      // Only COUNT aggregate function supported for Boolean type
      if (fieldName.equals("col_bln")) {
        continue;
      }
      resultingValues.put(String.format("`%s`", fieldName), null);
      for (Map.Entry<String, StringBuilder> function : functions.entrySet()) {
        function.getValue()
            .append(function.getKey())
            .append("(")
            .append(fieldName)
            .append(") ")
            .append(fieldName)
            .append(",");
      }
    }
    result.release();

    final String query = "select %s from cp.`parquet/alltypes_required.parquet` where 1 = 0";
    final List<Map<String, Object>> baselineRecords = Lists.newArrayList();
    baselineRecords.add(resultingValues);

    for (StringBuilder selectBody : functions.values()) {
      selectBody.setLength(selectBody.length() - 1);

      testBuilder()
          .sqlQuery(query, selectBody.toString())
          .unOrdered()
          .baselineRecords(baselineRecords)
          .go();
    }
  }

  @Test
  public void testSingleValueFunction() throws Exception {
    List<String> tableNames = Arrays.asList(
        "cp.`parquet/alltypes_required.parquet`",
        "cp.`parquet/alltypes_optional.parquet`");
    for (String tableName : tableNames) {
      final QueryDataBatch result =
          queryBuilder().sql("select * from %s limit 1", tableName).results().get(0);

      final Map<String, StringBuilder> functions = new HashMap<>();
      functions.put("single_value", new StringBuilder());

      final Map<String, Object> resultingValues = new HashMap<>();
      final List<String> columns = new ArrayList<>();

      final RecordBatchLoader loader = new RecordBatchLoader(cluster.allocator());
      loader.load(result.getHeader().getDef(), result.getData());

      for (VectorWrapper<?> vectorWrapper : loader.getContainer()) {
        final String fieldName = vectorWrapper.getField().getName();
        Object object = vectorWrapper.getValueVector().getAccessor().getObject(0);
        // VarCharVector returns Text instance, but baseline values should contain String value
        if (object instanceof Text) {
          object = object.toString();
        }
        resultingValues.put(String.format("`%s`", fieldName), object);
        for (Map.Entry<String, StringBuilder> function : functions.entrySet()) {
          function.getValue()
              .append(function.getKey())
              .append("(")
              .append(fieldName)
              .append(") ")
              .append(fieldName)
              .append(",");
        }
        columns.add(fieldName);
      }
      loader.clear();
      result.release();

      String columnsList = String.join(", ", columns);

      final List<Map<String, Object>> baselineRecords = new ArrayList<>();
      baselineRecords.add(resultingValues);

      for (StringBuilder selectBody : functions.values()) {
        selectBody.setLength(selectBody.length() - 1);

        testBuilder()
            .sqlQuery("select %s from (select %s from %s limit 1)",
                selectBody.toString(), columnsList, tableName)
            .unOrdered()
            .baselineRecords(baselineRecords)
            .go();
      }
    }
  }

  @Test
  public void testHashAggSingleValueFunction() throws Exception {
    List<String> tableNames = Arrays.asList(
        "cp.`parquet/alltypes_required.parquet`",
        "cp.`parquet/alltypes_optional.parquet`");
    for (String tableName : tableNames) {
      Map<String, Object> resultingValues = getBaselineRecords(tableName);

      List<Boolean> optionValues = Arrays.asList(true, false);

      try {
        for (Boolean optionValue : optionValues) {
          for (Map.Entry<String, Object> entry : resultingValues.entrySet()) {
            String columnName = String.format("`%s`", entry.getKey());

            // disable interval types when stream agg is disabled due to DRILL-7241
            if (optionValue || !columnName.startsWith("`col_intrvl")) {
              client.alterSession(PlannerSettings.STREAMAGG.getOptionName(), optionValue);
              testBuilder()
                  .sqlQuery("select single_value(t.%1$s) as %1$s\n" +
                      "from (select %1$s from %2$s limit 1) t group by t.%1$s", columnName, tableName)
                  .ordered()
                  .baselineRecords(Collections.singletonList(ImmutableMap.of(columnName, entry.getValue())))
                  .go();
            }
          }
        }
      } finally {
        client.resetSession(PlannerSettings.STREAMAGG.getOptionName());
      }
    }
  }

  private Map<String, Object> getBaselineRecords(String tableName) throws Exception {
    QueryDataBatch result =
        queryBuilder().sql("select * from %s limit 1", tableName).results().get(0);

    Map<String, Object> resultingValues = new HashMap<>();

    RecordBatchLoader loader = new RecordBatchLoader(cluster.allocator());
    loader.load(result.getHeader().getDef(), result.getData());

    for (VectorWrapper<?> vectorWrapper : loader.getContainer()) {
      String fieldName = vectorWrapper.getField().getName();
      Object object = vectorWrapper.getValueVector().getAccessor().getObject(0);
      // VarCharVector returns Text instance, but baseline values should contain String value
      if (object instanceof Text) {
        object = object.toString();
      }
      resultingValues.put(fieldName, object);
    }
    loader.clear();
    result.release();
    return resultingValues;
  }

  @Test
  public void testSingleValueWithComplexInput() throws Exception {
    String query = "select single_value(a) as any_a, single_value(f) as any_f, single_value(m) as any_m," +
        "single_value(p) as any_p from (select * from cp.`store/json/test_anyvalue.json` limit 1)";
    testBuilder()
        .sqlQuery(query)
        .unOrdered()
        .baselineColumns("any_a", "any_f", "any_m", "any_p")
        .baselineValues(listOf(mapOf("b", 10L, "c", 15L),
            mapOf("b", 20L, "c", 45L)),
            listOf(mapOf("g", mapOf("h",
                listOf(mapOf("k", 10L), mapOf("k", 20L))))),
            listOf(mapOf("n", listOf(1L, 2L, 3L))),
            mapOf("q", listOf(27L, 28L, 29L)))
        .go();
  }

  @Test
  public void testSingleValueWithMultipleValuesInputsAllTypes() throws Exception {
    List<String> tableNames = Arrays.asList(
        "cp.`parquet/alltypes_required.parquet`",
        "cp.`parquet/alltypes_optional.parquet`");
    for (String tableName : tableNames) {
      QueryDataBatch result =
          queryBuilder().sql("select * from %s limit 1", tableName).results().get(0);

      RecordBatchLoader loader = new RecordBatchLoader(cluster.allocator());
      loader.load(result.getHeader().getDef(), result.getData());

      List<String> columns = StreamSupport.stream(loader.getContainer().spliterator(), false)
          .map(vectorWrapper -> vectorWrapper.getField().getName())
          .collect(Collectors.toList());
      loader.clear();
      result.release();
      for (String columnName : columns) {
        try {
          run("select single_value(t.%1$s) as %1$s from %2$s t", columnName, tableName);
        } catch (UserRemoteException e) {
          assertTrue("No expected current \"FUNCTION ERROR\" and/or \"Input for single_value function has more than one row\"",
              e.getMessage().matches("^FUNCTION ERROR(.|\\n)*Input for single_value function has more than one row(.|\\n)*"));
        }
      }
    }
  }

  @Test
  public void testSingleValueWithMultipleComplexInputs() throws Exception {
    thrown.expect(UserRemoteException.class);
    thrown.expectMessage(containsString("FUNCTION ERROR"));
    thrown.expectMessage(containsString("Input for single_value function has more than one row"));
    run("select single_value(t1.a) from cp.`store/json/test_anyvalue.json` t1");
  }

  /*
   * Streaming agg on top of a filter produces wrong results if the first two batches are filtered out.
   * In the below test we have three files in the input directory and since the ordering of reading
   * of these files may not be deterministic, we have three tests to make sure we test the case where
   * streaming agg gets two empty batches.
   */
  @Test
  public void drill3069() throws Exception {
    final String query = "select max(foo) col1 from dfs.`agg/bugs/drill3069` where foo = %d";
    testBuilder()
        .sqlQuery(query, 2)
        .unOrdered()
        .baselineColumns("col1")
        .baselineValues(2L)
        .go();

    testBuilder()
        .sqlQuery(query, 4)
        .unOrdered()
        .baselineColumns("col1")
        .baselineValues(4L)
        .go();

    testBuilder()
        .sqlQuery(query, 6)
        .unOrdered()
        .baselineColumns("col1")
        .baselineValues(6L)
        .go();
  }

  @Test //DRILL-2748
  @Category(UnlikelyTest.class)
  public void testPushFilterPastAgg() throws Exception {
    final String query =
        " select cnt " +
        " from (select n_regionkey, count(*) cnt from cp.`tpch/nation.parquet` group by n_regionkey) " +
        " where n_regionkey = 2 ";

    // Validate the plan
    String expectedPlan = "(?s)(StreamAgg|HashAgg).*Filter";
    String excludedPatterns = "(?s)Filter.*(StreamAgg|HashAgg)";
    queryBuilder().sql(query)
        .planMatcher()
        .include(expectedPlan)
        .exclude(excludedPatterns)
        .match();

    testBuilder()
        .sqlQuery(query)
        .unOrdered()
        .baselineColumns("cnt")
        .baselineValues(5L)
        .build().run();

    // having clause
    String query2 =
        " select count(*) cnt from cp.`tpch/nation.parquet` group by n_regionkey " +
        " having n_regionkey = 2 ";
    queryBuilder().sql(query2)
        .planMatcher()
        .include(expectedPlan)
        .exclude(excludedPatterns)
        .match();

    testBuilder()
        .sqlQuery(query)
        .unOrdered()
        .baselineColumns("cnt")
        .baselineValues(5L)
        .build().run();
  }

  @Test
  public void testPushFilterInExprPastAgg() throws Exception {
    final String query =
        " select cnt " +
            " from (select n_regionkey, count(*) cnt from cp.`tpch/nation.parquet` group by n_regionkey) " +
            " where n_regionkey + 100 - 100 = 2 ";

    // Validate the plan
    String expectedPlan = "(?s)(StreamAgg|HashAgg).*Filter";
    String excludedPatterns = "(?s)Filter.*(StreamAgg|HashAgg)";
    queryBuilder().sql(query)
        .planMatcher()
        .include(expectedPlan)
        .exclude(excludedPatterns)
        .match();

    testBuilder()
        .sqlQuery(query)
        .unOrdered()
        .baselineColumns("cnt")
        .baselineValues(5L)
        .build().run();
  }

  @Test
  public void testNegPushFilterInExprPastAgg() throws Exception {
    // negative case: should not push filter, since it involves the aggregate result
    String query =
        " select cnt " +
            " from (select n_regionkey, count(*) cnt from cp.`tpch/nation.parquet` group by n_regionkey) " +
            " where cnt + 100 - 100 = 5 ";

    // Validate the plan
    String expectedPlan = "(?s)Filter(?!StreamAgg|!HashAgg)";
    String excludedPatterns = "(?s)(StreamAgg|HashAgg).*Filter";
    queryBuilder().sql(query)
        .planMatcher()
        .include(expectedPlan)
        .exclude(excludedPatterns)
        .match();

    // negative case: should not push filter, since it is expression of group key + agg result.
    String query2 =
        " select cnt " +
            " from (select n_regionkey, count(*) cnt from cp.`tpch/nation.parquet` group by n_regionkey) " +
            " where cnt + n_regionkey = 5 ";
    queryBuilder().sql(query2)
        .planMatcher()
        .include(expectedPlan)
        .exclude(excludedPatterns)
        .match();
  }

  @Test // DRILL-3781
  @Category(UnlikelyTest.class)
  // GROUP BY System functions in schema table.
  public void testGroupBySystemFuncSchemaTable() throws Exception {
    String query = "select count(*) as cnt from sys.version group by CURRENT_DATE";
    String expectedPlan = "(?s)(StreamAgg|HashAgg)";

    queryBuilder().sql(query)
        .planMatcher()
        .include(expectedPlan)
        .match();
  }

  @Test //DRILL-3781
  @Category(UnlikelyTest.class)
  // GROUP BY System functions in csv, parquet, json table.
  public void testGroupBySystemFuncFileSystemTable() throws Exception {
    testBuilder()
        .sqlQuery("select count(*) as cnt from cp.`nation/nation.tbl` group by CURRENT_DATE")
        .unOrdered()
        .baselineColumns("cnt")
        .baselineValues(25L)
        .build().run();

    testBuilder()
        .sqlQuery("select count(*) as cnt from cp.`tpch/nation.parquet` group by CURRENT_DATE")
        .unOrdered()
        .baselineColumns("cnt")
        .baselineValues(25L)
        .build().run();

    testBuilder()
        .sqlQuery("select count(*) as cnt from cp.`employee.json` group by CURRENT_DATE")
        .unOrdered()
        .baselineColumns("cnt")
        .baselineValues(1155L)
        .build().run();
  }

  @Test
  public void test4443() throws Exception {
    run("SELECT MIN(columns[1]) FROM cp.`agg/4443.csv` GROUP BY columns[0]");
  }

  @Test
  public void testCountStarRequired() throws Exception {
    final String query = "select count(*) as col from cp.`tpch/region.parquet`";
    List<Pair<SchemaPath, TypeProtos.MajorType>> expectedSchema = Lists.newArrayList();
    TypeProtos.MajorType majorType = TypeProtos.MajorType.newBuilder()
        .setMinorType(TypeProtos.MinorType.BIGINT)
        .setMode(TypeProtos.DataMode.REQUIRED)
        .build();
    expectedSchema.add(Pair.of(SchemaPath.getSimplePath("col"), majorType));

    testBuilder()
        .sqlQuery(query)
        .schemaBaseLine(expectedSchema)
        .build()
        .run();

    testBuilder()
        .sqlQuery(query)
        .unOrdered()
        .baselineColumns("col")
        .baselineValues(5L)
        .build()
        .run();
  }


  @Test // DRILL-4531
  @Category(UnlikelyTest.class)
  public void testPushFilterDown() throws Exception {
    final String sql =
        "SELECT  cust.custAddress, \n"
            + "       lineitem.provider \n"
            + "FROM ( \n"
            + "      SELECT cast(c_custkey AS bigint) AS custkey, \n"
            + "             c_address                 AS custAddress \n"
            + "      FROM   cp.`tpch/customer.parquet` ) cust \n"
            + "LEFT JOIN \n"
            + "  ( \n"
            + "    SELECT DISTINCT l_linenumber, \n"
            + "           CASE \n"
            + "             WHEN l_partkey IN (1, 2) THEN 'Store1'\n"
            + "             WHEN l_partkey IN (5, 6) THEN 'Store2'\n"
            + "           END AS provider \n"
            + "    FROM  cp.`tpch/lineitem.parquet` \n"
            + "    WHERE ( l_orderkey >=20160101 AND l_partkey <=20160301) \n"
            + "      AND   l_partkey IN (1,2, 5, 6) ) lineitem\n"
            + "ON        cust.custkey = lineitem.l_linenumber \n"
            + "WHERE     provider IS NOT NULL \n"
            + "GROUP BY  cust.custAddress, \n"
            + "          lineitem.provider \n"
            + "ORDER BY  cust.custAddress, \n"
            + "          lineitem.provider";

    // Validate the plan
    String expectedPlan = "(?s)(Join).*inner"; // With filter pushdown, left join will be converted into inner join
    String excludedPatterns = "(?s)(Join).*(left)";
    queryBuilder().sql(sql)
        .planMatcher()
        .include(expectedPlan)
        .exclude(excludedPatterns)
        .match();
  }

  @Test // DRILL-2385: count on complex objects failed with missing function implementation
  @Category(UnlikelyTest.class)
  public void testCountComplexObjects() throws Exception {
    final String query = "select count(t.%s) %s from cp.`complex/json/complex.json` t";
    Map<String, String> objectsMap = Maps.newHashMap();
    objectsMap.put("COUNT_BIG_INT_REPEATED", "sia");
    objectsMap.put("COUNT_FLOAT_REPEATED", "sfa");
    objectsMap.put("COUNT_MAP_REPEATED", "soa");
    objectsMap.put("COUNT_MAP_REQUIRED", "oooi");
    objectsMap.put("COUNT_LIST_REPEATED", "odd");
    objectsMap.put("COUNT_LIST_OPTIONAL", "sia");

    for (String object: objectsMap.keySet()) {
      String optionSetting = "";
      if (object.equals("COUNT_LIST_OPTIONAL")) {
        // if `exec.enable_union_type` parameter is true then BIGINT<REPEATED> object is converted to LIST<OPTIONAL> one
        optionSetting = "alter session set `exec.enable_union_type`=true";
      }
      try {
        testBuilder()
            .sqlQuery(query, objectsMap.get(object), object)
            .optionSettingQueriesForTestQuery(optionSetting)
            .unOrdered()
            .baselineColumns(object)
            .baselineValues(3L)
            .go();
      } finally {
        client.resetSession(ExecConstants.ENABLE_UNION_TYPE_KEY);
      }
    }
  }

  @Test // DRILL-4264
  @Category(UnlikelyTest.class)
  public void testCountOnFieldWithDots() throws Exception {
    String fileName = "table.json";
    try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(dirTestWatcher.getRootDir(), fileName)))) {
      writer.write("{\"rk.q\": \"a\", \"m\": {\"a.b\":\"1\", \"a\":{\"b\":\"2\"}, \"c\":\"3\"}}");
    }

    testBuilder()
      .sqlQuery("select count(t.m.`a.b`) as a,\n" +
        "count(t.m.a.b) as b,\n" +
        "count(t.m['a.b']) as c,\n" +
        "count(t.rk.q) as d,\n" +
        "count(t.`rk.q`) as e\n" +
        "from dfs.`%s` t", fileName)
      .unOrdered()
      .baselineColumns("a", "b", "c", "d", "e")
      .baselineValues(1L, 1L, 1L, 0L, 1L)
      .go();
  }

  @Test // DRILL-5768
  public void testGroupByWithoutAggregate() throws Exception {
    try {
      run("select * from cp.`tpch/nation.parquet` group by n_regionkey");
      fail("Exception was not thrown");
    } catch (UserRemoteException e) {
      assertTrue("No expected current \"Expression 'tpch/nation.parquet.**' is not being grouped\"",
          e.getMessage().matches(".*Expression 'tpch/nation\\.parquet\\.\\*\\*' is not being grouped(.*\\n*.*)"));
    }
  }

  @Test
  public void testCollectListStreamAgg() throws Exception {
    try {
      client.alterSession(PlannerSettings.HASHAGG.getOptionName(), false);
      testBuilder()
          .sqlQuery("select collect_list('n_nationkey', n_nationkey, " +
              "'n_name', n_name, 'n_regionkey', n_regionkey, 'n_comment', n_comment) as l " +
              "from (select * from cp.`tpch/nation.parquet` limit 2)")
          .unOrdered()
          .baselineColumns("l")
          .baselineValues(listOf(
              mapOf("n_nationkey", 0, "n_name", "ALGERIA",
                  "n_regionkey", 0, "n_comment", " haggle. carefully final deposits detect slyly agai"),
              mapOf("n_nationkey", 1, "n_name", "ARGENTINA", "n_regionkey", 1,
                  "n_comment", "al foxes promise slyly according to the regular accounts. bold requests alon")))
          .go();
    } finally {
      client.resetSession(PlannerSettings.HASHAGG.getOptionName());
    }
  }

  @Test
  public void testCollectListHashAgg() throws Exception {
    try {
      client.alterSession(PlannerSettings.STREAMAGG.getOptionName(), false);
      testBuilder()
          .sqlQuery("select collect_list('n_nationkey', n_nationkey, " +
              "'n_name', n_name, 'n_regionkey', n_regionkey, 'n_comment', n_comment) as l " +
              "from (select * from cp.`tpch/nation.parquet` limit 2) group by 'a'")
          .unOrdered()
          .baselineColumns("l")
          .baselineValues(listOf(
              mapOf("n_nationkey", 0, "n_name", "ALGERIA",
                  "n_regionkey", 0, "n_comment", " haggle. carefully final deposits detect slyly agai"),
              mapOf("n_nationkey", 1, "n_name", "ARGENTINA", "n_regionkey", 1,
                  "n_comment", "al foxes promise slyly according to the regular accounts. bold requests alon")))
          .go();
    } finally {
      client.resetSession(PlannerSettings.STREAMAGG.getOptionName());
    }
  }

  @Test
  public void testCollectToListVarcharStreamAgg() throws Exception {
    try {
      client.alterSession(PlannerSettings.HASHAGG.getOptionName(), false);
      testBuilder()
          .sqlQuery("select collect_to_list_varchar(`date`) as l from " +
              "(select * from cp.`store/json/clicks.json` limit 2)")
          .unOrdered()
          .baselineColumns("l")
          .baselineValues(listOf("2014-04-26", "2014-04-20"))
          .go();
    } finally {
      client.resetSession(PlannerSettings.HASHAGG.getOptionName());
    }
  }

  @Test
  public void testCollectToListVarcharHashAgg() throws Exception {
    try {
      client.alterSession(PlannerSettings.STREAMAGG.getOptionName(), false);
      testBuilder()
          .sqlQuery("select collect_to_list_varchar(`date`) as l from " +
              "(select * from cp.`store/json/clicks.json` limit 2) group by 'a'")
          .unOrdered()
          .baselineColumns("l")
          .baselineValues(listOf("2014-04-26", "2014-04-20"))
          .go();
    } finally {
      client.resetSession(PlannerSettings.STREAMAGG.getOptionName());
    }
  }

  @Test
  public void testSchemaFunctionStreamAgg() throws Exception {
    try {
      client.alterSession(PlannerSettings.HASHAGG.getOptionName(), false);
      TupleMetadata schema = new SchemaBuilder()
          .add("n_nationkey", TypeProtos.MinorType.INT)
          .add("n_name", TypeProtos.MinorType.VARCHAR)
          .add("n_regionkey", TypeProtos.MinorType.INT)
          .add("n_comment", TypeProtos.MinorType.VARCHAR)
          .build();

      testBuilder()
          .sqlQuery("select schema('n_nationkey', n_nationkey, " +
              "'n_name', n_name, 'n_regionkey', n_regionkey, 'n_comment', n_comment) as l from " +
              "(select * from cp.`tpch/nation.parquet` limit 2)")
          .unOrdered()
          .baselineColumns("l")
          .baselineValues(schema.jsonString())
          .go();
    } finally {
      client.resetSession(PlannerSettings.HASHAGG.getOptionName());
    }
  }

  @Test
  public void testSchemaFunctionHashAgg() throws Exception {
    try {
      client.alterSession(PlannerSettings.STREAMAGG.getOptionName(), false);
      TupleMetadata schema = new SchemaBuilder()
          .add("n_nationkey", TypeProtos.MinorType.INT)
          .add("n_name", TypeProtos.MinorType.VARCHAR)
          .add("n_regionkey", TypeProtos.MinorType.INT)
          .add("n_comment", TypeProtos.MinorType.VARCHAR)
          .build();

      testBuilder()
          .sqlQuery("select schema('n_nationkey', n_nationkey, " +
              "'n_name', n_name, 'n_regionkey', n_regionkey, 'n_comment', n_comment) as l from " +
              "(select * from cp.`tpch/nation.parquet` limit 2) group by 'a'")
          .unOrdered()
          .baselineColumns("l")
          .baselineValues(schema.jsonString())
          .go();
    } finally {
      client.resetSession(PlannerSettings.STREAMAGG.getOptionName());
    }
  }

  @Test
  public void testMergeSchemaFunctionStreamAgg() throws Exception {
    try {
      client.alterSession(PlannerSettings.HASHAGG.getOptionName(), false);
      String schema = new SchemaBuilder()
          .add("n_nationkey", TypeProtos.MinorType.INT)
          .add("n_name", TypeProtos.MinorType.VARCHAR)
          .add("n_regionkey", TypeProtos.MinorType.INT)
          .add("n_comment", TypeProtos.MinorType.VARCHAR)
          .build()
          .jsonString();

      testBuilder()
          .sqlQuery("select merge_schema('%s') as l from " +
              "(select * from cp.`tpch/nation.parquet` limit 2)", schema)
          .unOrdered()
          .baselineColumns("l")
          .baselineValues(schema)
          .go();
    } finally {
      client.resetSession(PlannerSettings.HASHAGG.getOptionName());
    }
  }

  @Test
  public void testMergeSchemaFunctionHashAgg() throws Exception {
    try {
      client.alterSession(PlannerSettings.STREAMAGG.getOptionName(), false);
      String schema = new SchemaBuilder()
          .add("n_nationkey", TypeProtos.MinorType.INT)
          .add("n_name", TypeProtos.MinorType.VARCHAR)
          .add("n_regionkey", TypeProtos.MinorType.INT)
          .add("n_comment", TypeProtos.MinorType.VARCHAR)
          .build()
          .jsonString();

      testBuilder()
          .sqlQuery("select merge_schema('%s') as l from " +
              "(select * from cp.`tpch/nation.parquet` limit 2) group by 'a'", schema)
          .unOrdered()
          .baselineColumns("l")
          .baselineValues(schema)
          .go();
    } finally {
      client.resetSession(PlannerSettings.STREAMAGG.getOptionName());
    }
  }

  @Test
  public void testInjectVariablesHashAgg() throws Exception {
    try {
      client.alterSession(PlannerSettings.STREAMAGG.getOptionName(), false);
      testBuilder()
          .sqlQuery("select tdigest(p.col_int) from " +
              "cp.`parquet/alltypes_required.parquet` p group by p.col_flt")
          .unOrdered()
          .expectsNumRecords(4)
          .go();
    } finally {
      client.resetSession(PlannerSettings.STREAMAGG.getOptionName());
    }
  }

  @Test //DRILL-7931
  public void testRowTypeMissMatch() throws Exception {
    testBuilder()
      .sqlQuery("select col1, stddev(col2) as g1, SUM(col2) as g2 FROM " +
        "(values ('UA', 3), ('USA', 2), ('UA', 3), ('USA', 5), ('USA', 1), " +
        "('UA', 9)) t(col1, col2) GROUP BY col1 order by col1")
      .unOrdered()
      .approximateEquality(0.000001)
      .baselineColumns("col1", "g1", "g2")
      .baselineValues("UA", 3.4641016151377544, 15L)
      .baselineValues("USA", 2.0816659994661326, 8L)
      .go();
  }

  @Test
  public void testAggregateWithFilterCall() throws Exception {
    testBuilder()
      .sqlQuery(
        "SELECT count(n_name) FILTER(WHERE n_regionkey = 1) AS nations_count_in_1_region," +
          "count(n_name) FILTER(WHERE n_regionkey = 2) AS nations_count_in_2_region," +
          "count(n_name) FILTER(WHERE n_regionkey = 3) AS nations_count_in_3_region," +
          "count(n_name) FILTER(WHERE n_regionkey = 4) AS nations_count_in_4_region," +
          "count(n_name) FILTER(WHERE n_regionkey = 0) AS nations_count_in_0_region\n" +
          "FROM cp.`tpch/nation.parquet`")
      .unOrdered()
      .baselineColumns("nations_count_in_1_region", "nations_count_in_2_region",
        "nations_count_in_3_region", "nations_count_in_4_region", "nations_count_in_0_region")
      .baselineValues(5L, 5L, 5L, 5L, 5L)
      .go();
  }

  @Test
  public void testAggregateWithPivot() throws Exception {
    String query = "SELECT * FROM (\n" +
        "SELECT education_level, salary, marital_status, extract(year from age('2023-02-23', birth_date)) age\n" +
        "FROM cp.`employee.json`)\n" +
        "PIVOT (avg(salary) avg_salary, avg(age) avg_age FOR marital_status IN ('M' married, 'S' single))";
    testBuilder()
      .sqlQuery(query)
      .unOrdered()
      .baselineColumns("education_level", "married_avg_salary", "married_avg_age", "single_avg_salary", "single_avg_age")
      .baselineValues("Graduate Degree", 4038.470588235294, 101.98823529411764, 4747.176470588235, 98.65882352941176)
      .baselineValues("Bachelors Degree", 4789.166666666667, 102.43055555555556, 4193.566433566433, 102.02797202797203)
      .baselineValues("Partial College", 4281.381578947368, 99.25657894736842, 3785.294117647059, 101.04411764705883)
      .baselineValues("High School Degree", 3459.2805755395684, 103.57553956834532, 3571.830985915493, 102.69014084507042)
      .baselineValues("Partial High School", 3555.8064516129034, 101.14516129032258, 3469.7014925373132, 103.3731343283582)
      .go();
  }

  @Test
  public void testMedian() throws Exception {

    // Test as String from CSV and aggregate
    String query = "SELECT category, median(`value`) AS med FROM cp.`orgs.csvh` GROUP BY category";
    testBuilder()
        .sqlQuery(query)
        .unOrdered()
        .baselineColumns("category", "med")
        .baselineValues("cat1", 5L)
        .baselineValues("cat2", 5L)
        .go();

    query = "SELECT category, median(CAST(`value` AS DOUBLE)) AS med FROM cp.`orgs.csvh` GROUP BY category";
    testBuilder()
        .sqlQuery(query)
        .unOrdered()
        .baselineColumns("category", "med")
        .baselineValues("cat1", 5.0)
        .baselineValues("cat2", 5.0)
        .go();

  }

  @Test
  public void testMedianWithPivot() throws Exception {
    String query = "SELECT * FROM (\n" +
        "SELECT education_level, salary, marital_status, extract(year from age('2023-02-23', birth_date)) age\n" +
        "FROM cp.`employee.json`)\n" +
        "PIVOT (median(salary) med_salary, median(age) med_age FOR marital_status IN ('M' married, 'S' single))";
    testBuilder()
        .sqlQuery(query)
        .unOrdered()
        .baselineColumns("education_level", "married_med_salary", "married_med_age", "single_med_salary", "single_med_age")
        .baselineValues("Graduate Degree", 4400.0, 109L, 20.0, 109L)
        .baselineValues("Bachelors Degree", 4400.0,109L, 4400.0, 109L)
        .baselineValues("Partial College", 4500.0, 109L, 4400.0, 109L)
        .baselineValues("High School Degree", 3700.0, 109L, 4400.0, 109L)
        .baselineValues("Partial High School", 4400.0, 109L, 20.0, 109L)
        .go();
  }
}
