/**
   * @param idx Column index.
   * @param rows Rows.
   * @return Column as list.
   */
  private static <X> List<X> column(int idx, List<List<?>> rows) {
    List<X> res = new ArrayList<>(rows.size());

    for (List<?> row : rows) res.add((X) row.get(idx));

    return res;
  }
  /** @throws Exception If failed. */
  public void testGroupIndexOperations() throws Exception {
    IgniteCache<Integer, GroupIndexTestValue> c =
        ignite(0)
            .getOrCreateCache(cacheConfig("grp", false, Integer.class, GroupIndexTestValue.class));

    try {
      // Check group index usage.
      String qry = "select 1 from GroupIndexTestValue ";

      String plan = columnQuery(c, "explain " + qry + "where a = 1 and b > 0").get(0).toString();

      info("Plan: " + plan);

      assertTrue(plan.contains("grpIdx"));

      // Sorted list
      List<GroupIndexTestValue> list =
          F.asList(
              new GroupIndexTestValue(0, 0),
              new GroupIndexTestValue(0, 5),
              new GroupIndexTestValue(1, 1),
              new GroupIndexTestValue(1, 3),
              new GroupIndexTestValue(2, -1),
              new GroupIndexTestValue(2, 2));

      // Fill cache.
      for (int i = 0; i < list.size(); i++) c.put(i, list.get(i));

      // Check results.
      assertEquals(1, columnQuery(c, qry + "where a = 1 and b = 1").size());
      assertEquals(2, columnQuery(c, qry + "where a = 1 and b < 4").size());
      assertEquals(2, columnQuery(c, qry + "where a = 1 and b <= 3").size());
      assertEquals(1, columnQuery(c, qry + "where a = 1 and b < 3").size());
      assertEquals(2, columnQuery(c, qry + "where a = 1 and b > 0").size());
      assertEquals(1, columnQuery(c, qry + "where a = 1 and b > 1").size());
      assertEquals(2, columnQuery(c, qry + "where a = 1 and b >= 1").size());
      assertEquals(4, columnQuery(c, qry + "where a > 0 and b > 0").size());
      assertEquals(4, columnQuery(c, qry + "where a > 0 and b >= 1").size());
      assertEquals(3, columnQuery(c, qry + "where a > 0 and b > 1").size());
    } finally {
      c.destroy();
    }
  }