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

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


The following commit(s) were added to refs/heads/master by this push:
     new a2fe26b6d9 Revert "[multistage] Fix leaf stage return (#9892)" (#9916)
a2fe26b6d9 is described below

commit a2fe26b6d9d738be3482e2fcecc80b8608f37dbb
Author: Rong Rong <[email protected]>
AuthorDate: Mon Dec 5 18:58:34 2022 -0800

    Revert "[multistage] Fix leaf stage return (#9892)" (#9916)
    
    This reverts commit e6d3dcdbdaf9e08f0ffd939e55361bb946b03f93.
---
 .../apache/pinot/query/runtime/QueryRunner.java    |  46 +++-
 .../LeafStageTransferableBlockOperator.java        | 234 ++-------------------
 .../LeafStageTransferableBlockOperatorTest.java    |  78 ++-----
 .../src/test/resources/queries/Aggregates.json     |  93 +++-----
 .../src/test/resources/queries/Distincts.json      |  47 -----
 .../test/resources/queries/LexicalStructure.json   |  21 +-
 .../test/resources/queries/SelectExpressions.json  |  15 +-
 7 files changed, 120 insertions(+), 414 deletions(-)

diff --git 
a/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/QueryRunner.java
 
b/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/QueryRunner.java
index 5cf1cfa999..7b69aa40ce 100644
--- 
a/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/QueryRunner.java
+++ 
b/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/QueryRunner.java
@@ -20,8 +20,10 @@ package org.apache.pinot.query.runtime;
 
 import com.google.common.base.Preconditions;
 import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.ExecutorService;
 import org.apache.helix.HelixManager;
 import org.apache.helix.store.zk.ZkHelixPropertyStore;
@@ -29,10 +31,13 @@ import org.apache.helix.zookeeper.datamodel.ZNRecord;
 import org.apache.pinot.common.exception.QueryException;
 import org.apache.pinot.common.metadata.ZKMetadataProvider;
 import org.apache.pinot.common.metrics.ServerMetrics;
+import org.apache.pinot.common.utils.DataSchema;
 import org.apache.pinot.core.data.manager.InstanceDataManager;
 import org.apache.pinot.core.operator.blocks.InstanceResponseBlock;
+import org.apache.pinot.core.operator.blocks.results.SelectionResultsBlock;
 import org.apache.pinot.core.query.executor.ServerQueryExecutorV1Impl;
 import org.apache.pinot.core.query.request.ServerQueryRequest;
+import org.apache.pinot.core.query.selection.SelectionOperatorUtils;
 import org.apache.pinot.core.transport.ServerInstance;
 import org.apache.pinot.query.mailbox.MailboxService;
 import org.apache.pinot.query.mailbox.MultiplexingMailboxService;
@@ -184,10 +189,47 @@ public class QueryRunner {
   private InstanceResponseBlock processServerQuery(ServerQueryRequest 
serverQueryRequest,
       ExecutorService executorService) {
     try {
-      return _serverExecutor.execute(serverQueryRequest, executorService);
+      InstanceResponseBlock result = 
_serverExecutor.execute(serverQueryRequest, executorService);
+
+      if (result.getRows() != null && 
serverQueryRequest.getQueryContext().getOrderByExpressions() != null) {
+        // we only re-arrange columns to match the projection in the case of 
order by - this is to ensure
+        // that V1 results match what the expected projection schema in the 
calcite logical operator; if
+        // we realize that there are other situations where we need to 
post-process v1 results to adhere to
+        // the expected results we should factor this out and also apply the 
canonicalization of the data
+        // types during this post-process step (also see 
LeafStageTransferableBlockOperator#canonicalizeRow)
+        DataSchema dataSchema = result.getDataSchema();
+        List<String> selectionColumns =
+            
SelectionOperatorUtils.getSelectionColumns(serverQueryRequest.getQueryContext(),
 dataSchema);
+
+        int[] columnIndices = 
SelectionOperatorUtils.getColumnIndices(selectionColumns, dataSchema);
+        int numColumns = columnIndices.length;
+
+        DataSchema resultDataSchema = 
SelectionOperatorUtils.getSchemaForProjection(dataSchema, columnIndices);
+
+        // Extract the result rows
+        LinkedList<Object[]> rowsInSelectionResults = new LinkedList<>();
+        for (Object[] row : result.getRows()) {
+          assert row != null;
+          Object[] extractedRow = new Object[numColumns];
+          for (int i = 0; i < numColumns; i++) {
+            Object value = row[columnIndices[i]];
+            if (value != null) {
+              extractedRow[i] = value;
+            }
+          }
+
+          rowsInSelectionResults.addFirst(extractedRow);
+        }
+
+        return new InstanceResponseBlock(
+            new SelectionResultsBlock(resultDataSchema, 
rowsInSelectionResults),
+            serverQueryRequest.getQueryContext());
+      } else {
+        return result;
+      }
     } catch (Exception e) {
       InstanceResponseBlock errorResponse = new InstanceResponseBlock();
-      
errorResponse.getExceptions().put(QueryException.QUERY_EXECUTION_ERROR_CODE, 
e.getMessage());
+      
errorResponse.getExceptions().put(QueryException.QUERY_EXECUTION_ERROR_CODE, 
Objects.toString(e.getMessage()));
       return errorResponse;
     }
   }
diff --git 
a/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/LeafStageTransferableBlockOperator.java
 
b/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/LeafStageTransferableBlockOperator.java
index 8def59dd32..551955c388 100644
--- 
a/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/LeafStageTransferableBlockOperator.java
+++ 
b/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/LeafStageTransferableBlockOperator.java
@@ -18,14 +18,11 @@
  */
 package org.apache.pinot.query.runtime.operator;
 
-import com.clearspring.analytics.util.Preconditions;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.PriorityQueue;
-import java.util.stream.Collectors;
 import javax.annotation.Nullable;
 import org.apache.pinot.common.datablock.DataBlock;
 import org.apache.pinot.common.datablock.DataBlockUtils;
@@ -35,13 +32,7 @@ import org.apache.pinot.common.utils.DataSchema;
 import org.apache.pinot.core.common.Operator;
 import org.apache.pinot.core.operator.BaseOperator;
 import org.apache.pinot.core.operator.blocks.InstanceResponseBlock;
-import org.apache.pinot.core.operator.blocks.results.AggregationResultsBlock;
 import org.apache.pinot.core.operator.blocks.results.BaseResultsBlock;
-import org.apache.pinot.core.operator.blocks.results.DistinctResultsBlock;
-import org.apache.pinot.core.operator.blocks.results.GroupByResultsBlock;
-import org.apache.pinot.core.operator.blocks.results.SelectionResultsBlock;
-import 
org.apache.pinot.core.query.aggregation.function.DistinctAggregationFunction;
-import org.apache.pinot.core.query.selection.SelectionOperatorUtils;
 import org.apache.pinot.query.runtime.blocks.TransferableBlock;
 
 
@@ -63,12 +54,10 @@ public class LeafStageTransferableBlockOperator extends 
BaseOperator<Transferabl
 
   private final InstanceResponseBlock _errorBlock;
   private final List<InstanceResponseBlock> _baseResultBlock;
-  private final DataSchema _desiredDataSchema;
   private int _currentIndex;
 
   public LeafStageTransferableBlockOperator(List<InstanceResponseBlock> 
baseResultBlock, DataSchema dataSchema) {
     _baseResultBlock = baseResultBlock;
-    _desiredDataSchema = dataSchema;
     _errorBlock = baseResultBlock.stream().filter(e -> 
!e.getExceptions().isEmpty()).findFirst().orElse(null);
     _currentIndex = 0;
   }
@@ -95,10 +84,13 @@ public class LeafStageTransferableBlockOperator extends 
BaseOperator<Transferabl
     } else {
       if (_currentIndex < _baseResultBlock.size()) {
         InstanceResponseBlock responseBlock = 
_baseResultBlock.get(_currentIndex++);
-        if (responseBlock.getResultsBlock() != null) {
-          return composeTransferableBlock(responseBlock, _desiredDataSchema);
+        BaseResultsBlock resultsBlock = responseBlock.getResultsBlock();
+        if (resultsBlock != null) {
+          List<Object[]> rows =
+              toList(resultsBlock.getRows(responseBlock.getQueryContext()), 
responseBlock.getDataSchema());
+          return new TransferableBlock(rows, responseBlock.getDataSchema(), 
DataBlock.Type.ROW);
         } else {
-          return new TransferableBlock(Collections.emptyList(), 
_desiredDataSchema, DataBlock.Type.ROW);
+          return new TransferableBlock(Collections.emptyList(), 
responseBlock.getDataSchema(), DataBlock.Type.ROW);
         }
       } else {
         _currentIndex = -1;
@@ -107,181 +99,6 @@ public class LeafStageTransferableBlockOperator extends 
BaseOperator<Transferabl
     }
   }
 
-  /**
-   * this is data transfer block compose method is here to ensure that V1 
results match what the expected projection
-   * schema in the calcite logical operator.
-   * <p> it applies different clean up mechanism based on different type of 
{@link BaseResultsBlock} and the
-   *     {@link org.apache.pinot.core.query.request.context.QueryContext}.</p>
-   * <p> this also applies to the canonicalization of the data types during 
post post-process step.</p>
-   *
-   * @param responseBlock result block from leaf stage
-   * @param desiredDataSchema the desired schema for send operator
-   * @return the converted {@link TransferableBlock} that conform with the 
desiredDataSchema
-   */
-  private static TransferableBlock 
composeTransferableBlock(InstanceResponseBlock responseBlock,
-      DataSchema desiredDataSchema) {
-    BaseResultsBlock resultsBlock = responseBlock.getResultsBlock();
-    if (resultsBlock instanceof SelectionResultsBlock) {
-      return composeSelectTransferableBlock(responseBlock, desiredDataSchema);
-    } else if (resultsBlock instanceof AggregationResultsBlock) {
-      return composeAggregationTransferableBlock(responseBlock, 
desiredDataSchema);
-    } else if (resultsBlock instanceof GroupByResultsBlock) {
-      return composeGroupByTransferableBlock(responseBlock, desiredDataSchema);
-    } else if (resultsBlock instanceof DistinctResultsBlock) {
-      return composeDistinctTransferableBlock(responseBlock, 
desiredDataSchema);
-    } else {
-      throw new IllegalArgumentException("Unsupported result block type: " + 
resultsBlock);
-    }
-  }
-
-  /**
-   * we only need to rearrange columns when distinct is not conforming with 
selection columns, specifically:
-   * <ul>
-   *   <li> when distinct is not returning final result:
-   *       it should never happen as non-final result contains Object opaque 
columns v2 engine can't process.</li>
-   *   <li> when distinct columns are not all being selected:
-   *       it should never happen as leaf stage MUST return the entire 
list.</li>
-   * </ul>
-   *
-   * @see 
LeafStageTransferableBlockOperator#composeTransferableBlock(InstanceResponseBlock,
 DataSchema).
-   */
-  @SuppressWarnings("ConstantConditions")
-  private static TransferableBlock 
composeDistinctTransferableBlock(InstanceResponseBlock responseBlock,
-      DataSchema desiredDataSchema) {
-    List<String> selectionColumns = Arrays.asList(
-        ((DistinctAggregationFunction) 
responseBlock.getQueryContext().getAggregationFunctions()[0]).getColumns());
-    int[] columnIndices = 
SelectionOperatorUtils.getColumnIndices(selectionColumns, desiredDataSchema);
-    Preconditions.checkState(inOrder(columnIndices), "Incompatible distinct 
table schema for leaf stage."
-        + "Expected: " + desiredDataSchema + ". Actual: " + desiredDataSchema);
-    return composeDirectTransferableBlock(responseBlock, desiredDataSchema);
-  }
-
-  /**
-   * Calcite generated {@link DataSchema} should conform with Pinot's group by 
result schema thus we only need to check
-   * for correctness similar to distinct case.
-   *
-   * @see 
LeafStageTransferableBlockOperator#composeDirectTransferableBlock(InstanceResponseBlock,
 DataSchema).
-   * @see 
LeafStageTransferableBlockOperator#composeTransferableBlock(InstanceResponseBlock,
 DataSchema).
-   */
-  @SuppressWarnings("ConstantConditions")
-  private static TransferableBlock 
composeGroupByTransferableBlock(InstanceResponseBlock responseBlock,
-      DataSchema desiredDataSchema) {
-    DataSchema resultSchema = responseBlock.getDataSchema();
-    // GROUP-BY column names conforms with selection expression
-    List<String> selectionColumns = 
responseBlock.getQueryContext().getSelectExpressions().stream()
-        .map(e -> e.toString()).collect(Collectors.toList());
-    int[] columnIndices = 
SelectionOperatorUtils.getColumnIndices(selectionColumns, resultSchema);
-    Preconditions.checkState(inOrder(columnIndices), "Incompatible group by 
result schema for leaf stage."
-        + "Expected: " + desiredDataSchema + ". Actual: " + resultSchema);
-    return composeDirectTransferableBlock(responseBlock, desiredDataSchema);
-  }
-
-
-  /**
-   * Calcite generated {@link DataSchema} should conform with Pinot's agg 
result schema thus we only need to check
-   * for correctness similar to distinct case.
-   *
-   * @see 
LeafStageTransferableBlockOperator#composeDirectTransferableBlock(InstanceResponseBlock,
 DataSchema).
-   * @see 
LeafStageTransferableBlockOperator#composeTransferableBlock(InstanceResponseBlock,
 DataSchema).
-   */
-  @SuppressWarnings("ConstantConditions")
-  private static TransferableBlock 
composeAggregationTransferableBlock(InstanceResponseBlock responseBlock,
-      DataSchema desiredDataSchema) {
-    DataSchema resultSchema = responseBlock.getDataSchema();
-    // AGG-ONLY column names are derived from AggFunction.getColumnName()
-    List<String> selectionColumns = 
Arrays.stream(responseBlock.getQueryContext().getAggregationFunctions()).map(
-        a -> a.getColumnName()).collect(Collectors.toList());
-    int[] columnIndices = 
SelectionOperatorUtils.getColumnIndices(selectionColumns, resultSchema);
-    Preconditions.checkState(inOrder(columnIndices), "Incompatible aggregate 
result schema for leaf stage."
-        + "Expected: " + desiredDataSchema + ". Actual: " + resultSchema);
-    return composeDirectTransferableBlock(responseBlock, desiredDataSchema);
-  }
-
-  /**
-   * Only re-arrange columns to match the projection in the case of select / 
order-by, when the desiredDataSchema
-   * doesn't conform with the result block schema exactly.
-   *
-   * @see 
LeafStageTransferableBlockOperator#composeTransferableBlock(InstanceResponseBlock,
 DataSchema).
-   */
-  @SuppressWarnings("ConstantConditions")
-  private static TransferableBlock 
composeSelectTransferableBlock(InstanceResponseBlock responseBlock,
-      DataSchema desiredDataSchema) {
-    DataSchema resultSchema = responseBlock.getDataSchema();
-    List<String> selectionColumns = 
SelectionOperatorUtils.getSelectionColumns(responseBlock.getQueryContext(),
-        resultSchema);
-    int[] columnIndices = 
SelectionOperatorUtils.getColumnIndices(selectionColumns, resultSchema);
-    if (!inOrder(columnIndices)) {
-      DataSchema adjustedResultSchema = 
SelectionOperatorUtils.getSchemaForProjection(resultSchema, columnIndices);
-      
Preconditions.checkState(isDataSchemaColumnTypesCompatible(desiredDataSchema.getColumnDataTypes(),
-          adjustedResultSchema.getColumnDataTypes()), "Incompatible result 
data schema: "
-          + "Expecting: " + desiredDataSchema + " Actual: " + 
adjustedResultSchema);
-      // Extract the result rows
-      Collection<Object[]> resultRows = responseBlock.getRows();
-      List<Object[]> extractedRows = new ArrayList<>(resultRows.size());
-      return composeColumnIndexedTransferableBlock(responseBlock, 
adjustedResultSchema, columnIndices);
-    } else {
-      return composeDirectTransferableBlock(responseBlock, desiredDataSchema);
-    }
-  }
-
-  /**
-   * Created {@link TransferableBlock} using column indices.
-   *
-   * @see 
LeafStageTransferableBlockOperator#composeTransferableBlock(InstanceResponseBlock,
 DataSchema).
-   */
-  private static TransferableBlock 
composeColumnIndexedTransferableBlock(InstanceResponseBlock responseBlock,
-      DataSchema desiredDataSchema, int[] columnIndices) {
-    Collection<Object[]> resultRows = responseBlock.getRows();
-    List<Object[]> extractedRows = new ArrayList<>(resultRows.size());
-    if (responseBlock.getQueryContext().getOrderByExpressions() != null) {
-      // extract result row in ordered fashion
-      PriorityQueue<Object[]> priorityQueue = (PriorityQueue<Object[]>) 
resultRows;
-      while (!priorityQueue.isEmpty()) {
-        extractedRows.add(canonicalizeRow(priorityQueue.poll(), 
desiredDataSchema, columnIndices));
-      }
-    } else {
-      // extract result row in non-ordered fashion
-      for (Object[] row : resultRows) {
-        extractedRows.add(canonicalizeRow(row, desiredDataSchema, 
columnIndices));
-      }
-    }
-    return new TransferableBlock(extractedRows, desiredDataSchema, 
DataBlock.Type.ROW);
-  }
-
-  /**
-   * Fallback mechanism for {@link TransferableBlock}, used when no special 
handling is necessary. This method only
-   * performs {@link DataSchema.ColumnDataType} canonicalization.
-   *
-   * @see 
LeafStageTransferableBlockOperator#composeTransferableBlock(InstanceResponseBlock,
 DataSchema).
-   */
-  private static TransferableBlock 
composeDirectTransferableBlock(InstanceResponseBlock responseBlock,
-      DataSchema desiredDataSchema) {
-    Collection<Object[]> resultRows = responseBlock.getRows();
-    List<Object[]> extractedRows = new ArrayList<>(resultRows.size());
-    if (resultRows instanceof List) {
-      for (Object[] orgRow : resultRows) {
-        extractedRows.add(canonicalizeRow(orgRow, desiredDataSchema));
-      }
-    } else if (resultRows instanceof PriorityQueue) {
-      PriorityQueue<Object[]> priorityQueue = (PriorityQueue<Object[]>) 
resultRows;
-      while (!priorityQueue.isEmpty()) {
-        extractedRows.add(canonicalizeRow(priorityQueue.poll(), 
desiredDataSchema));
-      }
-    } else {
-      throw new UnsupportedOperationException("Unsupported collection type: " 
+ resultRows.getClass());
-    }
-    return new TransferableBlock(extractedRows, desiredDataSchema, 
DataBlock.Type.ROW);
-  }
-
-  private static boolean inOrder(int[] columnIndices) {
-    for (int i = 0; i < columnIndices.length; i++) {
-      if (columnIndices[i] != i) {
-        return false;
-      }
-    }
-    return true;
-  }
-
   /**
    * This util is used to canonicalize row generated from V1 engine, which is 
stored using
    * {@link DataSchema#getStoredColumnDataTypes()} format. However, the 
transferable block ser/de stores data in the
@@ -294,35 +111,28 @@ public class LeafStageTransferableBlockOperator extends 
BaseOperator<Transferabl
   private static Object[] canonicalizeRow(Object[] row, DataSchema dataSchema) 
{
     Object[] resultRow = new Object[row.length];
     for (int colId = 0; colId < row.length; colId++) {
-      Object value = row[colId];
-      if (value != null) {
-        resultRow[colId] = dataSchema.getColumnDataType(colId).convert(value);
-      }
+      resultRow[colId] = 
dataSchema.getColumnDataType(colId).convert(row[colId]);
     }
     return resultRow;
   }
 
-  private static Object[] canonicalizeRow(Object[] row, DataSchema dataSchema, 
int[] columnIndices) {
-    Object[] resultRow = new Object[columnIndices.length];
-    for (int colId = 0; colId < columnIndices.length; colId++) {
-      Object value = row[columnIndices[colId]];
-      if (value != null) {
-        resultRow[colId] = dataSchema.getColumnDataType(colId).convert(value);
-      }
+  private static List<Object[]> toList(Collection<Object[]> collection, 
DataSchema dataSchema) {
+    if (collection == null || collection.isEmpty()) {
+      return new ArrayList<>();
     }
-    return resultRow;
-  }
-
-  private static boolean 
isDataSchemaColumnTypesCompatible(DataSchema.ColumnDataType[] desiredTypes,
-      DataSchema.ColumnDataType[] givenTypes) {
-    if (desiredTypes.length != givenTypes.length) {
-      return false;
-    }
-    for (int i = 0; i < desiredTypes.length; i++) {
-      if (desiredTypes[i] != givenTypes[i] && 
!givenTypes[i].isSuperTypeOf(desiredTypes[i])) {
-        return false;
+    List<Object[]> resultRows = new ArrayList<>(collection.size());
+    if (collection instanceof List) {
+      for (Object[] orgRow : collection) {
+        resultRows.add(canonicalizeRow(orgRow, dataSchema));
       }
+    } else if (collection instanceof PriorityQueue) {
+      PriorityQueue<Object[]> priorityQueue = (PriorityQueue<Object[]>) 
collection;
+      while (!priorityQueue.isEmpty()) {
+        resultRows.add(canonicalizeRow(priorityQueue.poll(), dataSchema));
+      }
+    } else {
+      throw new UnsupportedOperationException("Unsupported collection type: " 
+ collection.getClass());
     }
-    return true;
+    return resultRows;
   }
 }
diff --git 
a/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/LeafStageTransferableBlockOperatorTest.java
 
b/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/LeafStageTransferableBlockOperatorTest.java
index 89df15c62b..496a09e4d5 100644
--- 
a/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/LeafStageTransferableBlockOperatorTest.java
+++ 
b/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/LeafStageTransferableBlockOperatorTest.java
@@ -26,57 +26,28 @@ import org.apache.pinot.common.exception.QueryException;
 import org.apache.pinot.common.utils.DataSchema;
 import org.apache.pinot.core.operator.blocks.InstanceResponseBlock;
 import org.apache.pinot.core.operator.blocks.results.SelectionResultsBlock;
-import org.apache.pinot.core.query.request.context.QueryContext;
-import 
org.apache.pinot.core.query.request.context.utils.QueryContextConverterUtils;
 import org.apache.pinot.query.runtime.blocks.TransferableBlock;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
 
-// TODO: add tests for Agg / GroupBy / Distinct result blocks
 public class LeafStageTransferableBlockOperatorTest {
 
   @Test
   public void shouldReturnDataBlockThenMetadataBlock() {
     // Given:
-    QueryContext queryContext = 
QueryContextConverterUtils.getQueryContext("SELECT strCol, intCol FROM tbl");
     DataSchema schema = new DataSchema(new String[]{"strCol", "intCol"},
         new DataSchema.ColumnDataType[]{DataSchema.ColumnDataType.STRING, 
DataSchema.ColumnDataType.INT});
     List<InstanceResponseBlock> resultsBlockList = 
Collections.singletonList(new InstanceResponseBlock(
-        new SelectionResultsBlock(schema, Arrays.asList(new Object[]{"foo", 
1}, new Object[]{"", 2})), queryContext));
+        new SelectionResultsBlock(schema, Arrays.asList(new Object[]{"foo", 
1}, new Object[]{"", 2})), null));
     LeafStageTransferableBlockOperator operator = new 
LeafStageTransferableBlockOperator(resultsBlockList, schema);
 
     // When:
-    TransferableBlock resultBlock = operator.nextBlock();
+    TransferableBlock transferableBlock = operator.nextBlock();
 
     // Then:
-    Assert.assertEquals(resultBlock.getContainer().get(0), new Object[]{"foo", 
1});
-    Assert.assertEquals(resultBlock.getContainer().get(1), new Object[]{"", 
2});
-    Assert.assertTrue(operator.nextBlock().isEndOfStreamBlock(), "Expected EOS 
after reading two rows");
-  }
-
-  @Test
-  public void shouldHandleDesiredDataSchemaConversionCorrectly() {
-    // Given:
-    QueryContext queryContext = QueryContextConverterUtils.getQueryContext(
-        "SELECT boolCol, tsCol, boolCol AS newNamedBoolCol FROM tbl");
-    DataSchema resultSchema = new DataSchema(new String[]{"boolCol", "tsCol"},
-        new DataSchema.ColumnDataType[]{DataSchema.ColumnDataType.BOOLEAN, 
DataSchema.ColumnDataType.TIMESTAMP});
-    DataSchema desiredSchema = new DataSchema(new String[]{"boolCol", "tsCol", 
"newNamedBoolCol"},
-        new DataSchema.ColumnDataType[]{DataSchema.ColumnDataType.BOOLEAN, 
DataSchema.ColumnDataType.TIMESTAMP,
-            DataSchema.ColumnDataType.BOOLEAN});
-    List<InstanceResponseBlock> resultsBlockList = 
Collections.singletonList(new InstanceResponseBlock(
-        new SelectionResultsBlock(resultSchema, Arrays.asList(new Object[]{1, 
1660000000000L},
-            new Object[]{0, 1600000000000L})), queryContext));
-    LeafStageTransferableBlockOperator operator = new 
LeafStageTransferableBlockOperator(resultsBlockList,
-        desiredSchema);
-
-    // When:
-    TransferableBlock resultBlock = operator.nextBlock();
-
-    // Then:
-    Assert.assertEquals(resultBlock.getContainer().get(0), new Object[]{true, 
new Timestamp(1660000000000L), true});
-    Assert.assertEquals(resultBlock.getContainer().get(1), new Object[]{false, 
new Timestamp(1600000000000L), false});
+    Assert.assertEquals(transferableBlock.getContainer().get(0), new 
Object[]{"foo", 1});
+    Assert.assertEquals(transferableBlock.getContainer().get(1), new 
Object[]{"", 2});
     Assert.assertTrue(operator.nextBlock().isEndOfStreamBlock(), "Expected EOS 
after reading two rows");
   }
 
@@ -84,70 +55,67 @@ public class LeafStageTransferableBlockOperatorTest {
   public void shouldHandleCanonicalizationCorrectly() {
     // TODO: not all stored types are supported, add additional datatype when 
they are supported.
     // Given:
-    QueryContext queryContext = 
QueryContextConverterUtils.getQueryContext("SELECT boolCol, tsCol FROM tbl");
     DataSchema schema = new DataSchema(new String[]{"boolCol", "tsCol"},
         new DataSchema.ColumnDataType[]{DataSchema.ColumnDataType.BOOLEAN, 
DataSchema.ColumnDataType.TIMESTAMP});
     List<InstanceResponseBlock> resultsBlockList = 
Collections.singletonList(new InstanceResponseBlock(
         new SelectionResultsBlock(schema, Arrays.asList(new Object[]{1, 
1660000000000L},
-            new Object[]{0, 1600000000000L})), queryContext));
+            new Object[]{0, 1600000000000L})), null));
     LeafStageTransferableBlockOperator operator = new 
LeafStageTransferableBlockOperator(resultsBlockList, schema);
 
     // When:
-    TransferableBlock resultBlock = operator.nextBlock();
+    TransferableBlock transferableBlock = operator.nextBlock();
 
     // Then:
-    Assert.assertEquals(resultBlock.getContainer().get(0), new Object[]{true, 
new Timestamp(1660000000000L)});
-    Assert.assertEquals(resultBlock.getContainer().get(1), new Object[]{false, 
new Timestamp(1600000000000L)});
+    Assert.assertEquals(transferableBlock.getContainer().get(0), new 
Object[]{true, new Timestamp(1660000000000L)});
+    Assert.assertEquals(transferableBlock.getContainer().get(1), new 
Object[]{false, new Timestamp(1600000000000L)});
     Assert.assertTrue(operator.nextBlock().isEndOfStreamBlock(), "Expected EOS 
after reading two rows");
   }
 
   @Test
   public void shouldReturnMultipleDataBlockThenMetadataBlock() {
     // Given:
-    QueryContext queryContext = 
QueryContextConverterUtils.getQueryContext("SELECT strCol, intCol FROM tbl");
     DataSchema schema = new DataSchema(new String[]{"strCol", "intCol"},
         new DataSchema.ColumnDataType[]{DataSchema.ColumnDataType.STRING, 
DataSchema.ColumnDataType.INT});
     List<InstanceResponseBlock> resultsBlockList = Arrays.asList(
         new InstanceResponseBlock(new SelectionResultsBlock(schema,
-            Arrays.asList(new Object[]{"foo", 1}, new Object[]{"", 2})), 
queryContext),
+            Arrays.asList(new Object[]{"foo", 1}, new Object[]{"", 2})), null),
         new InstanceResponseBlock(new SelectionResultsBlock(schema,
-            Arrays.asList(new Object[]{"bar", 3}, new Object[]{"foo", 4})), 
queryContext),
-        new InstanceResponseBlock(new SelectionResultsBlock(schema, 
Collections.emptyList()), queryContext));
+            Arrays.asList(new Object[]{"bar", 3}, new Object[]{"foo", 4})), 
null),
+        new InstanceResponseBlock(new SelectionResultsBlock(schema, 
Collections.emptyList()), null));
     LeafStageTransferableBlockOperator operator = new 
LeafStageTransferableBlockOperator(resultsBlockList, schema);
 
     // When:
-    TransferableBlock resultBlock1 = operator.nextBlock();
-    TransferableBlock resultBlock2 = operator.nextBlock();
-    TransferableBlock resultBlock3 = operator.nextBlock();
+    TransferableBlock transferableBlock1 = operator.nextBlock();
+    TransferableBlock transferableBlock2 = operator.nextBlock();
+    TransferableBlock transferableBlock3 = operator.nextBlock();
 
     // Then:
-    Assert.assertEquals(resultBlock1.getContainer().get(0), new 
Object[]{"foo", 1});
-    Assert.assertEquals(resultBlock1.getContainer().get(1), new Object[]{"", 
2});
-    Assert.assertEquals(resultBlock2.getContainer().get(0), new 
Object[]{"bar", 3});
-    Assert.assertEquals(resultBlock2.getContainer().get(1), new 
Object[]{"foo", 4});
-    Assert.assertEquals(resultBlock3.getContainer().size(), 0);
+    Assert.assertEquals(transferableBlock1.getContainer().get(0), new 
Object[]{"foo", 1});
+    Assert.assertEquals(transferableBlock1.getContainer().get(1), new 
Object[]{"", 2});
+    Assert.assertEquals(transferableBlock2.getContainer().get(0), new 
Object[]{"bar", 3});
+    Assert.assertEquals(transferableBlock2.getContainer().get(1), new 
Object[]{"foo", 4});
+    Assert.assertEquals(transferableBlock3.getContainer().size(), 0);
     Assert.assertTrue(operator.nextBlock().isEndOfStreamBlock(), "Expected EOS 
after reading two rows");
   }
 
   @Test
   public void shouldGetErrorBlockWhenInstanceResponseContainsError() {
     // Given:
-    QueryContext queryContext = 
QueryContextConverterUtils.getQueryContext("SELECT strCol, intCol FROM tbl");
     DataSchema schema = new DataSchema(new String[]{"strCol", "intCol"},
         new DataSchema.ColumnDataType[]{DataSchema.ColumnDataType.STRING, 
DataSchema.ColumnDataType.INT});
     InstanceResponseBlock errorBlock = new InstanceResponseBlock();
     
errorBlock.addException(QueryException.QUERY_EXECUTION_ERROR.getErrorCode(), 
"foobar");
     List<InstanceResponseBlock> resultsBlockList = Arrays.asList(
         new InstanceResponseBlock(new SelectionResultsBlock(schema,
-            Arrays.asList(new Object[]{"foo", 1}, new Object[]{"", 2})), 
queryContext),
+            Arrays.asList(new Object[]{"foo", 1}, new Object[]{"", 2})), null),
         errorBlock,
-        new InstanceResponseBlock(new SelectionResultsBlock(schema, 
Collections.emptyList()), queryContext));
+        new InstanceResponseBlock(new SelectionResultsBlock(schema, 
Collections.emptyList()), null));
     LeafStageTransferableBlockOperator operator = new 
LeafStageTransferableBlockOperator(resultsBlockList, schema);
 
     // When:
-    TransferableBlock resultBlock = operator.nextBlock();
+    TransferableBlock transferableBlock = operator.nextBlock();
 
     // Then:
-    Assert.assertTrue(resultBlock.isErrorBlock());
+    Assert.assertTrue(transferableBlock.isErrorBlock());
   }
 }
diff --git a/pinot-query-runtime/src/test/resources/queries/Aggregates.json 
b/pinot-query-runtime/src/test/resources/queries/Aggregates.json
index cba6bab972..b82be2cb5e 100644
--- a/pinot-query-runtime/src/test/resources/queries/Aggregates.json
+++ b/pinot-query-runtime/src/test/resources/queries/Aggregates.json
@@ -3,19 +3,19 @@
     "tables": {
       "tbl": {
         "schema": [
-          {"name": "int_col", "type": "INT"},
-          {"name": "double_col", "type": "DOUBLE"},
-          {"name": "string_col", "type": "STRING"},
-          {"name": "bool_col", "type": "BOOLEAN"}
+          { "name": "int_col", "type": "INT" },
+          { "name": "double_col", "type": "DOUBLE" },
+          { "name": "string_col", "type": "STRING" },
+          { "name": "bool_col", "type": "BOOLEAN" }
         ],
         "inputs": [
-          [2, 300, "a", true],
-          [2, 400, "a", true],
-          [3, 100, "b", false],
-          [100, 1, "b", false],
-          [101, 1.01, "c", false],
-          [150, 1.5, "c", false],
-          [175, 1.75, "c", true]
+          [ 2, 300, "a", true ],
+          [ 2, 400, "a", true ],
+          [ 3, 100, "b", false ],
+          [ 100, 1, "b", false ],
+          [ 101, 1.01, "c", false ],
+          [ 150, 1.5, "c", false ],
+          [ 175, 1.75, "c", true ]
         ]
       }
     },
@@ -147,21 +147,21 @@
     "tables": {
       "tbl": {
         "schema": [
-          {"name": "int_col", "type": "INT"},
-          {"name": "double_col", "type": "DOUBLE"},
-          {"name": "string_col", "type": "STRING"},
-          {"name": "bool_col", "type": "BOOLEAN"}
+          { "name": "int_col", "type": "INT" },
+          { "name": "double_col", "type": "DOUBLE" },
+          { "name": "string_col", "type": "STRING" },
+          { "name": "bool_col", "type": "BOOLEAN" }
         ],
         "inputs": [
-          [2, 300, "a", false],
-          [2, 400, "a", true],
-          [3, 100, "b", true],
-          [0.001, 1, "b", false],
-          [101, 1.01, "c", false],
-          [150, 1.5, "c", true],
-          [175, 1.75, "c", true],
-          [-10000, 1.75, "c", false],
-          [-2, 0.5, "c", false]
+          [ 2, 300, "a", false ],
+          [ 2, 400, "a", true ],
+          [ 3, 100, "b", true ],
+          [ 0.001, 1, "b", false ],
+          [ 101, 1.01, "c", false ],
+          [ 150, 1.5, "c", true ],
+          [ 175, 1.75, "c", true ],
+          [ -10000, 1.75, "c", false ],
+          [ -2, 0.5, "c", false ]
         ]
       }
     },
@@ -211,48 +211,5 @@
         "sql": "select string_col, count(int_col) from {tbl} a group by 
string_col order by string_col having (select count(*) from {tbl} b where 
count(int_col) = b.int_col) > 0;"
       }
     ]
-  },
-  "additional_aggregate": {
-    "tables": {
-      "tbl": {
-        "schema": [
-          {"name": "int_col", "type": "INT"},
-          {"name": "double_col", "type": "DOUBLE"},
-          {"name": "string_col", "type": "STRING"},
-          {"name": "bool_col", "type": "BOOLEAN"}
-        ],
-        "inputs": [
-          [2, 300, "a", false],
-          [2, 400, "a", true],
-          [3, 100, "b", true],
-          [0.001, 1, "b", false],
-          [101, 1.01, "c", false],
-          [150, 1.5, "c", true],
-          [175, 1.75, "c", true],
-          [-10000, 1.75, "c", false],
-          [-2, 0.5, "c", false]
-        ]
-      }
-    },
-    "queries": [
-      { "sql": "SELECT min(int_col), min(int_col) FROM {tbl} WHERE int_col < 
100" },
-      { "sql": "SELECT min(int_col), count(int_col), count(*) FROM {tbl}" },
-      { "sql": "SELECT string_col, min(int_col), count(int_col), count(*) FROM 
{tbl} GROUP BY string_col" },
-      { "sql": "SELECT string_col, bool_col, min(int_col), count(int_col), 
count(*) FROM {tbl} GROUP BY string_col, bool_col" },
-      { "sql": "SELECT string_col, bool_col, min(int_col), count(int_col), 
count(*) FROM {tbl} GROUP BY bool_col, string_col" },
-      { "sql": "SELECT string_col, string_col AS alias, count(int_col), 
count(*) FROM {tbl} GROUP BY bool_col, string_col" },
-      { "sql": "SELECT string_col, bool_col, bool_col AS alias, sum(int_col), 
count(int_col), count(*) FROM {tbl} GROUP BY bool_col, string_col" },
-      { "sql": "SELECT sum(int_col), count(int_col) FROM {tbl} GROUP BY 
string_col" },
-      { "sql": "SELECT string_col, min(int_col), count(int_col), count(*) FROM 
{tbl} GROUP BY string_col ORDER BY string_col" },
-      { "sql": "SELECT string_col, bool_col, min(int_col), count(int_col), 
count(*) FROM {tbl} GROUP BY string_col, bool_col ORDER BY string_col" },
-      { "sql": "SELECT string_col, bool_col, min(int_col), count(int_col), 
count(*) FROM {tbl} GROUP BY string_col, bool_col ORDER BY bool_col, 
string_col" },
-      { "sql": "SELECT string_col, bool_col, min(int_col), count(int_col), 
count(*) FROM {tbl} GROUP BY bool_col, string_col ORDER BY bool_col, 
string_col" },
-      { "sql": "SELECT string_col, string_col AS alias, count(int_col), 
count(*) FROM {tbl} GROUP BY bool_col, string_col ORDER BY string_col" },
-      { "sql": "SELECT string_col, string_col AS alias, count(int_col), 
count(*) FROM {tbl} GROUP BY bool_col, string_col ORDER BY bool_col, alias"},
-      { "sql": "SELECT string_col, bool_col, bool_col AS alias, sum(int_col), 
count(int_col), count(*) FROM {tbl} GROUP BY bool_col, string_col ORDER BY 
alias" },
-      { "sql": "SELECT sum(int_col), count(int_col) FROM {tbl} GROUP BY 
string_col ORDER BY string_col" },
-      { "sql": "SELECT * FROM (SELECT string_col, bool_col, min(int_col) AS m, 
count(int_col), count(*) AS c FROM {tbl} GROUP BY string_col, bool_col ORDER BY 
string_col) WHERE c < m" },
-      { "sql": "SELECT * FROM (SELECT string_col, bool_col, min(int_col) AS m, 
count(int_col), count(*) AS c FROM {tbl} GROUP BY string_col, bool_col ORDER BY 
bool_col, string_col) WHERE c < m" }
-    ]
   }
-}
\ No newline at end of file
+}
diff --git a/pinot-query-runtime/src/test/resources/queries/Distincts.json 
b/pinot-query-runtime/src/test/resources/queries/Distincts.json
deleted file mode 100644
index 22ee05725c..0000000000
--- a/pinot-query-runtime/src/test/resources/queries/Distincts.json
+++ /dev/null
@@ -1,47 +0,0 @@
-{
-  "general_distinct": {
-    "tables": {
-      "tbl": {
-        "schema": [
-          { "name": "intCol", "type": "INT" },
-          { "name": "doubleCol", "type": "DOUBLE" },
-          { "name": "strCol", "type": "STRING" },
-          { "name": "boolCol", "type": "BOOLEAN" }
-        ],
-        "inputs": [
-          [ 2, 300, "a", true ],
-          [ 2, 400, "a", true ],
-          [ 3, 100, "b", false ],
-          [ 100, 1, "b", false ],
-          [ 101, 1.01, "c", false ],
-          [ 150, 1.5, "c", false ],
-          [ 175, 1.75, "c", true ]
-        ]
-      }
-    },
-    "queries": [
-      { "sql":  "SELECT DISTINCT intCol FROM {tbl}" },
-      { "sql":  "SELECT intCol FROM {tbl} GROUP BY intCol" },
-      { "sql":  "SELECT DISTINCT strCol, boolCol FROM {tbl}" },
-      { "sql":  "SELECT strCol, boolCol FROM {tbl} GROUP BY strCol, boolCol" },
-      { "sql":  "SELECT strCol, boolCol FROM {tbl} GROUP BY boolCol, strCol" },
-      { "sql":  "SELECT strCol FROM {tbl} GROUP BY strCol, boolCol" },
-      { "sql":  "SELECT boolCol FROM {tbl} GROUP BY strCol, boolCol" },
-      { "sql":  "SELECT DISTINCT intCol, doubleCol FROM {tbl} ORDER BY 
doubleCol" },
-      { "sql":  "SELECT intCol FROM {tbl} GROUP BY intCol ORDER BY intCol" },
-      { "sql":  "SELECT DISTINCT strCol, boolCol, intCol FROM {tbl} ORDER BY 
intCol" },
-      { "sql":  "SELECT strCol, boolCol FROM {tbl} GROUP BY strCol, boolCol 
ORDER BY boolCol" },
-      { "sql":  "SELECT strCol, boolCol FROM {tbl} GROUP BY boolCol, strCol 
ORDER BY strCol" },
-      { "sql":  "SELECT strCol FROM {tbl} GROUP BY strCol, boolCol ORDER BY 
boolCol" },
-      { "sql":  "SELECT strCol FROM (SELECT strCol FROM {tbl} GROUP BY 
boolCol, strCol ORDER BY strCol) WHERE strCol <> 'foo'" },
-      { "sql":  "SELECT intCol FROM (SELECT DISTINCT intCol FROM {tbl}) WHERE 
intCol < 100" },
-      { "sql":  "SELECT intCol FROM (SELECT intCol FROM {tbl} GROUP BY intCol) 
WHERE intCol < 100" },
-      { "sql":  "SELECT strCol FROM (SELECT DISTINCT strCol, boolCol FROM 
{tbl}) WHERE boolCol = false" },
-      { "sql":  "SELECT strCol FROM (SELECT strCol, boolCol FROM {tbl} GROUP 
BY strCol, boolCol) WHERE strCol <> 'foo'" },
-      { "sql":  "SELECT strCol, boolCol FROM (SELECT strCol, boolCol FROM 
{tbl} GROUP BY boolCol, strCol) WHERE strCol <> 'foo'" },
-      { "sql":  "SELECT strCol FROM (SELECT strCol FROM {tbl} GROUP BY strCol, 
boolCol) WHERE strCol != 'lol'" },
-      { "sql":  "SELECT intCol FROM (SELECT DISTINCT intCol, doubleCol FROM 
{tbl} ORDER BY doubleCol) WHERE doubleCol < 100" },
-      { "sql":  "SELECT strCol FROM (SELECT DISTINCT strCol, boolCol, intCol 
FROM {tbl} ORDER BY intCol) WHERE intCol > 10" }
-    ]
-  }
-}
diff --git 
a/pinot-query-runtime/src/test/resources/queries/LexicalStructure.json 
b/pinot-query-runtime/src/test/resources/queries/LexicalStructure.json
index ea6e139ddc..400ed57fac 100644
--- a/pinot-query-runtime/src/test/resources/queries/LexicalStructure.json
+++ b/pinot-query-runtime/src/test/resources/queries/LexicalStructure.json
@@ -135,22 +135,11 @@
         "inputs": [["1"]]
       }
     },
-    "queries": [
-      {
-        "ignored": true,
-        "comments": "numeric constant without specific type will cast all 
floating points into BIG DECIMAL which is not supported by type-hoisting on 
leaf stage",
-        "psql": "4.1.2.6",
-        "description": "numeric constant supports",
-        "sql": "SELECT data, 42, 3.5, 4., .001, 5e2, 1.925e-3 FROM {tbl}"
-      },
-      {
-        "ignored": true,
-        "comments": "floating point comparison missing precision checker",
-        "psql": "4.1.2.6",
-        "description": "numeric constant supports",
-        "sql": "SELECT data, 42, CAST(3.5 AS FLOAT), CAST(4. AS FLOAT), 
CAST(.001 AS FLOAT), CAST(5e2 AS FLOAT), CAST(1.925e-3 AS FLOAT) FROM {tbl}"
-      }
-    ]
+    "queries": [{
+      "psql": "4.1.2.6",
+      "description": "numeric constant supports",
+      "sql": "SELECT data, 42, 3.5, 4., .001, 5e2, 1.925e-3 FROM {tbl}"
+    }]
   },
   "constant_casting": {
     "tables": {
diff --git 
a/pinot-query-runtime/src/test/resources/queries/SelectExpressions.json 
b/pinot-query-runtime/src/test/resources/queries/SelectExpressions.json
index af925382ef..f214307b2a 100644
--- a/pinot-query-runtime/src/test/resources/queries/SelectExpressions.json
+++ b/pinot-query-runtime/src/test/resources/queries/SelectExpressions.json
@@ -37,20 +37,7 @@
       { "sql": "SELECT intCol as \"from\" FROM {tbl1}"},
       { "sql": "SELECT intCol as key, SUM(doubleCol + floatCol) AS aggSum FROM 
{tbl1} GROUP BY intCol"},
       { "sql": "SELECT intCol, SUM(avgVal) FROM (SELECT strCol, intCol, 
AVG(doubleCol) AS avgVal FROM {tbl1} GROUP BY intCol, strCol) GROUP BY intCol"},
-      { "sql": "SELECT strCol, MAX(sumVal), MAX(sumVal + avgVal) AS transVal 
FROM (SELECT strCol, intCol, SUM(floatCol + 2 * intCol) AS sumVal, 
AVG(doubleCol) AS avgVal FROM {tbl1} GROUP BY strCol, intCol) GROUP BY strCol 
ORDER BY MAX(sumVal)" },
-      { "sql": "SELECT intCol, intCol FROM {tbl1} WHERE intCol < 100" },
-      { "sql": "SELECT intCol, intCol, doubleCol, strCol, strCol FROM {tbl1}" 
},
-      { "sql": "SELECT intCol, intCol FROM {tbl1} WHERE intCol < 100 ORDER BY 
doubleCol" },
-      { "sql": "SELECT intCol, intCol FROM {tbl1} WHERE intCol < 100 ORDER BY 
intCol" },
-      { "sql": "SELECT intCol, intCol, doubleCol, strCol, strCol FROM {tbl1} 
ORDER BY intCol" },
-      { "sql": "SELECT intCol, intCol, doubleCol, strCol, strCol FROM {tbl1} 
ORDER BY strCol, intCol" },
-      { "sql": "SELECT intCol, intCol, doubleCol, strCol, strCol FROM {tbl1} 
ORDER BY floatCol, intCol" },
-      { "sql": "SELECT intCol, intCol, doubleCol, strCol, strCol FROM {tbl1} 
ORDER BY floatCol" },
-
-      { "sql": "SELECT intCol + alias FROM (SELECT intCol, intCol as alias 
FROM {tbl1}) WHERE intCol < 100" },
-      { "sql": "SELECT intCol, intCol, doubleCol, strCol, strCol FROM {tbl1}" 
},
-      { "sql": "SELECT {tbl1}.intCol, {tbl1}.intCol, {tbl1}.doubleCol, 
{tbl2}.strCol, {tbl2}.strCol FROM {tbl1}, {tbl2} WHERE {tbl1}.intCol = 
{tbl2}.intCol" },
-      { "sql": "SELECT {tbl2}.intCol, {tbl2}.intCol FROM {tbl1}, {tbl2} WHERE 
{tbl1}.intCol = {tbl2}.intCol AND {tbl1}.intCol < 100 ORDER BY 
{tbl1}.doubleCol" }
+      { "sql": "SELECT strCol, MAX(sumVal), MAX(sumVal + avgVal) AS transVal 
FROM (SELECT strCol, intCol, SUM(floatCol + 2 * intCol) AS sumVal, 
AVG(doubleCol) AS avgVal FROM {tbl1} GROUP BY strCol, intCol) GROUP BY strCol 
ORDER BY MAX(sumVal)" }
     ]
   }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to