You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by xi...@apache.org on 2023/12/20 00:54:56 UTC

(pinot) branch master updated: Support array literal functions (#12118)

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

xiangfu 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 85b5779cff Support array literal functions (#12118)
85b5779cff is described below

commit 85b5779cff8d33412937ceb6d4dfc972b6c8bd97
Author: Xiang Fu <xi...@gmail.com>
AuthorDate: Tue Dec 19 16:54:50 2023 -0800

    Support array literal functions (#12118)
---
 .../requesthandler/BaseBrokerRequestHandler.java   |  31 +-
 .../common/function/TransformFunctionType.java     |   5 +
 .../apache/pinot/common/request/BrokerRequest.java |   2 +-
 .../apache/pinot/common/request/DataSource.java    |   2 +-
 .../apache/pinot/common/request/Expression.java    |   2 +-
 .../pinot/common/request/ExpressionType.java       |   2 +-
 .../org/apache/pinot/common/request/Function.java  |  38 +-
 .../apache/pinot/common/request/Identifier.java    |   2 +-
 .../pinot/common/request/InstanceRequest.java      |   2 +-
 .../java/org/apache/pinot/common/request/Join.java |   2 +-
 .../org/apache/pinot/common/request/JoinType.java  |   2 +-
 .../org/apache/pinot/common/request/Literal.java   | 469 ++++++++++++++++++++-
 .../apache/pinot/common/request/PinotQuery.java    |   2 +-
 .../apache/pinot/common/request/QuerySource.java   |   2 +-
 .../pinot/common/response/ProcessingException.java |   2 +-
 .../pinot/common/utils/request/RequestUtils.java   |  49 +++
 pinot-common/src/thrift/query.thrift               |   5 +
 .../transform/function/CastTransformFunction.java  |  17 +
 .../pinot/integration/tests/custom/ArrayTest.java  | 114 +++++
 .../rel/rules/PinotEvaluateLiteralRule.java        |  22 +
 .../query/runtime/operator/utils/TypeUtils.java    |   8 +
 21 files changed, 747 insertions(+), 33 deletions(-)

diff --git a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseBrokerRequestHandler.java b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseBrokerRequestHandler.java
index c93248fbe4..b2da166510 100644
--- a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseBrokerRequestHandler.java
+++ b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseBrokerRequestHandler.java
@@ -95,6 +95,7 @@ import org.apache.pinot.spi.eventlistener.query.BrokerQueryEventListener;
 import org.apache.pinot.spi.exception.BadQueryRequestException;
 import org.apache.pinot.spi.trace.RequestContext;
 import org.apache.pinot.spi.trace.Tracing;
+import org.apache.pinot.spi.utils.BigDecimalUtils;
 import org.apache.pinot.spi.utils.BytesUtils;
 import org.apache.pinot.spi.utils.CommonConstants;
 import org.apache.pinot.spi.utils.CommonConstants.Broker;
@@ -1496,10 +1497,18 @@ public abstract class BaseBrokerRequestHandler implements BrokerRequestHandler {
         columnTypes.add(DataSchema.ColumnDataType.LONG);
         row.add(literal.getLongValue());
         break;
+      case FLOAT_VALUE:
+        columnTypes.add(DataSchema.ColumnDataType.FLOAT);
+        row.add(Float.intBitsToFloat(literal.getFloatValue()));
+        break;
       case DOUBLE_VALUE:
         columnTypes.add(DataSchema.ColumnDataType.DOUBLE);
         row.add(literal.getDoubleValue());
         break;
+      case BIG_DECIMAL_VALUE:
+        columnTypes.add(DataSchema.ColumnDataType.BIG_DECIMAL);
+        row.add(BigDecimalUtils.deserialize(literal.getBigDecimalValue()));
+        break;
       case STRING_VALUE:
         columnTypes.add(DataSchema.ColumnDataType.STRING);
         row.add(literal.getStringValue());
@@ -1512,8 +1521,28 @@ public abstract class BaseBrokerRequestHandler implements BrokerRequestHandler {
         columnTypes.add(DataSchema.ColumnDataType.UNKNOWN);
         row.add(null);
         break;
-      default:
+      case INT_ARRAY_VALUE:
+        columnTypes.add(DataSchema.ColumnDataType.INT_ARRAY);
+        row.add(literal.getIntArrayValue());
+        break;
+      case LONG_ARRAY_VALUE:
+        columnTypes.add(DataSchema.ColumnDataType.LONG_ARRAY);
+        row.add(literal.getLongArrayValue());
         break;
+      case FLOAT_ARRAY_VALUE:
+        columnTypes.add(DataSchema.ColumnDataType.FLOAT_ARRAY);
+        row.add(literal.getFloatArrayValue().stream().map(Float::intBitsToFloat).collect(Collectors.toList()));
+        break;
+      case DOUBLE_ARRAY_VALUE:
+        columnTypes.add(DataSchema.ColumnDataType.DOUBLE_ARRAY);
+        row.add(literal.getDoubleArrayValue());
+        break;
+      case STRING_ARRAY_VALUE:
+        columnTypes.add(DataSchema.ColumnDataType.STRING_ARRAY);
+        row.add(literal.getStringArrayValue());
+        break;
+      default:
+        throw new IllegalStateException("Unsupported literal: " + literal);
     }
   }
 
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/function/TransformFunctionType.java b/pinot-common/src/main/java/org/apache/pinot/common/function/TransformFunctionType.java
index 330890a2f9..38fb21e89a 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/function/TransformFunctionType.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/function/TransformFunctionType.java
@@ -176,6 +176,11 @@ public enum TransformFunctionType {
 
   EXTRACT("extract"),
 
+  // string functions
+  SPLIT("split", ReturnTypes.TO_ARRAY, OperandTypes.family(
+      ImmutableList.of(SqlTypeFamily.CHARACTER, SqlTypeFamily.CHARACTER, SqlTypeFamily.INTEGER),
+      ordinal -> ordinal > 1), "split"),
+
   // array functions
   // The only column accepted by "cardinality" function is multi-value array, thus putting "cardinality" as alias.
   // TODO: once we support other types of multiset, we should make CARDINALITY its own function
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/request/BrokerRequest.java b/pinot-common/src/main/java/org/apache/pinot/common/request/BrokerRequest.java
index 54d3edca6c..e7ba3c58aa 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/request/BrokerRequest.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/BrokerRequest.java
@@ -25,7 +25,7 @@
 package org.apache.pinot.common.request;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-09-27")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-12-07")
 public class BrokerRequest implements org.apache.thrift.TBase<BrokerRequest, BrokerRequest._Fields>, java.io.Serializable, Cloneable, Comparable<BrokerRequest> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("BrokerRequest");
 
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/request/DataSource.java b/pinot-common/src/main/java/org/apache/pinot/common/request/DataSource.java
index bb45e0ab7a..72cf69b401 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/request/DataSource.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/DataSource.java
@@ -25,7 +25,7 @@
 package org.apache.pinot.common.request;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-09-27")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-12-07")
 public class DataSource implements org.apache.thrift.TBase<DataSource, DataSource._Fields>, java.io.Serializable, Cloneable, Comparable<DataSource> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("DataSource");
 
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/request/Expression.java b/pinot-common/src/main/java/org/apache/pinot/common/request/Expression.java
index 40683bd1b7..4a75908a6d 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/request/Expression.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/Expression.java
@@ -25,7 +25,7 @@
 package org.apache.pinot.common.request;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-09-27")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-12-07")
 public class Expression implements org.apache.thrift.TBase<Expression, Expression._Fields>, java.io.Serializable, Cloneable, Comparable<Expression> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Expression");
 
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/request/ExpressionType.java b/pinot-common/src/main/java/org/apache/pinot/common/request/ExpressionType.java
index 16891a3386..5ac86ce9c5 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/request/ExpressionType.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/ExpressionType.java
@@ -25,7 +25,7 @@
 package org.apache.pinot.common.request;
 
 
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-09-27")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-12-07")
 public enum ExpressionType implements org.apache.thrift.TEnum {
   LITERAL(0),
   IDENTIFIER(1),
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/request/Function.java b/pinot-common/src/main/java/org/apache/pinot/common/request/Function.java
index 8055f29402..197843b7f0 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/request/Function.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/Function.java
@@ -25,7 +25,7 @@
 package org.apache.pinot.common.request;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-09-27")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-12-07")
 public class Function implements org.apache.thrift.TBase<Function, Function._Fields>, java.io.Serializable, Cloneable, Comparable<Function> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Function");
 
@@ -437,14 +437,14 @@ public class Function implements org.apache.thrift.TBase<Function, Function._Fie
           case 2: // OPERANDS
             if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
               {
-                org.apache.thrift.protocol.TList _list54 = iprot.readListBegin();
-                struct.operands = new java.util.ArrayList<Expression>(_list54.size);
-                @org.apache.thrift.annotation.Nullable Expression _elem55;
-                for (int _i56 = 0; _i56 < _list54.size; ++_i56)
+                org.apache.thrift.protocol.TList _list94 = iprot.readListBegin();
+                struct.operands = new java.util.ArrayList<Expression>(_list94.size);
+                @org.apache.thrift.annotation.Nullable Expression _elem95;
+                for (int _i96 = 0; _i96 < _list94.size; ++_i96)
                 {
-                  _elem55 = new Expression();
-                  _elem55.read(iprot);
-                  struct.operands.add(_elem55);
+                  _elem95 = new Expression();
+                  _elem95.read(iprot);
+                  struct.operands.add(_elem95);
                 }
                 iprot.readListEnd();
               }
@@ -476,9 +476,9 @@ public class Function implements org.apache.thrift.TBase<Function, Function._Fie
           oprot.writeFieldBegin(OPERANDS_FIELD_DESC);
           {
             oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.operands.size()));
-            for (Expression _iter57 : struct.operands)
+            for (Expression _iter97 : struct.operands)
             {
-              _iter57.write(oprot);
+              _iter97.write(oprot);
             }
             oprot.writeListEnd();
           }
@@ -511,9 +511,9 @@ public class Function implements org.apache.thrift.TBase<Function, Function._Fie
       if (struct.isSetOperands()) {
         {
           oprot.writeI32(struct.operands.size());
-          for (Expression _iter58 : struct.operands)
+          for (Expression _iter98 : struct.operands)
           {
-            _iter58.write(oprot);
+            _iter98.write(oprot);
           }
         }
       }
@@ -527,14 +527,14 @@ public class Function implements org.apache.thrift.TBase<Function, Function._Fie
       java.util.BitSet incoming = iprot.readBitSet(1);
       if (incoming.get(0)) {
         {
-          org.apache.thrift.protocol.TList _list59 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
-          struct.operands = new java.util.ArrayList<Expression>(_list59.size);
-          @org.apache.thrift.annotation.Nullable Expression _elem60;
-          for (int _i61 = 0; _i61 < _list59.size; ++_i61)
+          org.apache.thrift.protocol.TList _list99 = iprot.readListBegin(org.apache.thrift.protocol.TType.STRUCT);
+          struct.operands = new java.util.ArrayList<Expression>(_list99.size);
+          @org.apache.thrift.annotation.Nullable Expression _elem100;
+          for (int _i101 = 0; _i101 < _list99.size; ++_i101)
           {
-            _elem60 = new Expression();
-            _elem60.read(iprot);
-            struct.operands.add(_elem60);
+            _elem100 = new Expression();
+            _elem100.read(iprot);
+            struct.operands.add(_elem100);
           }
         }
         struct.setOperandsIsSet(true);
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/request/Identifier.java b/pinot-common/src/main/java/org/apache/pinot/common/request/Identifier.java
index d52140725a..a85ef75080 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/request/Identifier.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/Identifier.java
@@ -25,7 +25,7 @@
 package org.apache.pinot.common.request;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-09-27")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-12-07")
 public class Identifier implements org.apache.thrift.TBase<Identifier, Identifier._Fields>, java.io.Serializable, Cloneable, Comparable<Identifier> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Identifier");
 
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/request/InstanceRequest.java b/pinot-common/src/main/java/org/apache/pinot/common/request/InstanceRequest.java
index d266fef76b..28ec30fc46 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/request/InstanceRequest.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/InstanceRequest.java
@@ -25,7 +25,7 @@
 package org.apache.pinot.common.request;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-11-16")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-12-07")
 public class InstanceRequest implements org.apache.thrift.TBase<InstanceRequest, InstanceRequest._Fields>, java.io.Serializable, Cloneable, Comparable<InstanceRequest> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("InstanceRequest");
 
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/request/Join.java b/pinot-common/src/main/java/org/apache/pinot/common/request/Join.java
index bfe4ec3bbe..6479785cd7 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/request/Join.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/Join.java
@@ -25,7 +25,7 @@
 package org.apache.pinot.common.request;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-09-27")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-12-07")
 public class Join implements org.apache.thrift.TBase<Join, Join._Fields>, java.io.Serializable, Cloneable, Comparable<Join> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Join");
 
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/request/JoinType.java b/pinot-common/src/main/java/org/apache/pinot/common/request/JoinType.java
index e9d53f88f5..0b1e6aec50 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/request/JoinType.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/JoinType.java
@@ -25,7 +25,7 @@
 package org.apache.pinot.common.request;
 
 
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-09-27")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-12-07")
 public enum JoinType implements org.apache.thrift.TEnum {
   INNER(0),
   LEFT(1),
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/request/Literal.java b/pinot-common/src/main/java/org/apache/pinot/common/request/Literal.java
index 9c442a091f..2070e0fa68 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/request/Literal.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/Literal.java
@@ -25,7 +25,7 @@
 package org.apache.pinot.common.request;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-09-27")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-12-07")
 public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Literal");
   private static final org.apache.thrift.protocol.TField BOOL_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("boolValue", org.apache.thrift.protocol.TType.BOOL, (short)1);
@@ -39,6 +39,11 @@ public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields>
   private static final org.apache.thrift.protocol.TField NULL_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("nullValue", org.apache.thrift.protocol.TType.BOOL, (short)9);
   private static final org.apache.thrift.protocol.TField BIG_DECIMAL_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("bigDecimalValue", org.apache.thrift.protocol.TType.STRING, (short)10);
   private static final org.apache.thrift.protocol.TField FLOAT_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("floatValue", org.apache.thrift.protocol.TType.I32, (short)11);
+  private static final org.apache.thrift.protocol.TField INT_ARRAY_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("intArrayValue", org.apache.thrift.protocol.TType.LIST, (short)12);
+  private static final org.apache.thrift.protocol.TField LONG_ARRAY_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("longArrayValue", org.apache.thrift.protocol.TType.LIST, (short)13);
+  private static final org.apache.thrift.protocol.TField FLOAT_ARRAY_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("floatArrayValue", org.apache.thrift.protocol.TType.LIST, (short)14);
+  private static final org.apache.thrift.protocol.TField DOUBLE_ARRAY_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("doubleArrayValue", org.apache.thrift.protocol.TType.LIST, (short)15);
+  private static final org.apache.thrift.protocol.TField STRING_ARRAY_VALUE_FIELD_DESC = new org.apache.thrift.protocol.TField("stringArrayValue", org.apache.thrift.protocol.TType.LIST, (short)16);
 
   /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
   public enum _Fields implements org.apache.thrift.TFieldIdEnum {
@@ -52,7 +57,12 @@ public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields>
     BINARY_VALUE((short)8, "binaryValue"),
     NULL_VALUE((short)9, "nullValue"),
     BIG_DECIMAL_VALUE((short)10, "bigDecimalValue"),
-    FLOAT_VALUE((short)11, "floatValue");
+    FLOAT_VALUE((short)11, "floatValue"),
+    INT_ARRAY_VALUE((short)12, "intArrayValue"),
+    LONG_ARRAY_VALUE((short)13, "longArrayValue"),
+    FLOAT_ARRAY_VALUE((short)14, "floatArrayValue"),
+    DOUBLE_ARRAY_VALUE((short)15, "doubleArrayValue"),
+    STRING_ARRAY_VALUE((short)16, "stringArrayValue");
 
     private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
 
@@ -90,6 +100,16 @@ public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields>
           return BIG_DECIMAL_VALUE;
         case 11: // FLOAT_VALUE
           return FLOAT_VALUE;
+        case 12: // INT_ARRAY_VALUE
+          return INT_ARRAY_VALUE;
+        case 13: // LONG_ARRAY_VALUE
+          return LONG_ARRAY_VALUE;
+        case 14: // FLOAT_ARRAY_VALUE
+          return FLOAT_ARRAY_VALUE;
+        case 15: // DOUBLE_ARRAY_VALUE
+          return DOUBLE_ARRAY_VALUE;
+        case 16: // STRING_ARRAY_VALUE
+          return STRING_ARRAY_VALUE;
         default:
           return null;
       }
@@ -155,6 +175,21 @@ public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields>
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
     tmpMap.put(_Fields.FLOAT_VALUE, new org.apache.thrift.meta_data.FieldMetaData("floatValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
+    tmpMap.put(_Fields.INT_ARRAY_VALUE, new org.apache.thrift.meta_data.FieldMetaData("intArrayValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
+            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))));
+    tmpMap.put(_Fields.LONG_ARRAY_VALUE, new org.apache.thrift.meta_data.FieldMetaData("longArrayValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
+            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64))));
+    tmpMap.put(_Fields.FLOAT_ARRAY_VALUE, new org.apache.thrift.meta_data.FieldMetaData("floatArrayValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
+            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))));
+    tmpMap.put(_Fields.DOUBLE_ARRAY_VALUE, new org.apache.thrift.meta_data.FieldMetaData("doubleArrayValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
+            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.DOUBLE))));
+    tmpMap.put(_Fields.STRING_ARRAY_VALUE, new org.apache.thrift.meta_data.FieldMetaData("stringArrayValue", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
+            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
     metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Literal.class, metaDataMap);
   }
@@ -252,6 +287,36 @@ public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields>
     return x;
   }
 
+  public static Literal intArrayValue(java.util.List<java.lang.Integer> value) {
+    Literal x = new Literal();
+    x.setIntArrayValue(value);
+    return x;
+  }
+
+  public static Literal longArrayValue(java.util.List<java.lang.Long> value) {
+    Literal x = new Literal();
+    x.setLongArrayValue(value);
+    return x;
+  }
+
+  public static Literal floatArrayValue(java.util.List<java.lang.Integer> value) {
+    Literal x = new Literal();
+    x.setFloatArrayValue(value);
+    return x;
+  }
+
+  public static Literal doubleArrayValue(java.util.List<java.lang.Double> value) {
+    Literal x = new Literal();
+    x.setDoubleArrayValue(value);
+    return x;
+  }
+
+  public static Literal stringArrayValue(java.util.List<java.lang.String> value) {
+    Literal x = new Literal();
+    x.setStringArrayValue(value);
+    return x;
+  }
+
 
   @Override
   protected void checkType(_Fields setField, java.lang.Object value) throws java.lang.ClassCastException {
@@ -311,6 +376,31 @@ public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields>
           break;
         }
         throw new java.lang.ClassCastException("Was expecting value of type java.lang.Integer for field 'floatValue', but got " + value.getClass().getSimpleName());
+      case INT_ARRAY_VALUE:
+        if (value instanceof java.util.List) {
+          break;
+        }
+        throw new java.lang.ClassCastException("Was expecting value of type java.util.List<java.lang.Integer> for field 'intArrayValue', but got " + value.getClass().getSimpleName());
+      case LONG_ARRAY_VALUE:
+        if (value instanceof java.util.List) {
+          break;
+        }
+        throw new java.lang.ClassCastException("Was expecting value of type java.util.List<java.lang.Long> for field 'longArrayValue', but got " + value.getClass().getSimpleName());
+      case FLOAT_ARRAY_VALUE:
+        if (value instanceof java.util.List) {
+          break;
+        }
+        throw new java.lang.ClassCastException("Was expecting value of type java.util.List<java.lang.Integer> for field 'floatArrayValue', but got " + value.getClass().getSimpleName());
+      case DOUBLE_ARRAY_VALUE:
+        if (value instanceof java.util.List) {
+          break;
+        }
+        throw new java.lang.ClassCastException("Was expecting value of type java.util.List<java.lang.Double> for field 'doubleArrayValue', but got " + value.getClass().getSimpleName());
+      case STRING_ARRAY_VALUE:
+        if (value instanceof java.util.List) {
+          break;
+        }
+        throw new java.lang.ClassCastException("Was expecting value of type java.util.List<java.lang.String> for field 'stringArrayValue', but got " + value.getClass().getSimpleName());
       default:
         throw new java.lang.IllegalArgumentException("Unknown field id " + setField);
     }
@@ -420,6 +510,101 @@ public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields>
             org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
             return null;
           }
+        case INT_ARRAY_VALUE:
+          if (field.type == INT_ARRAY_VALUE_FIELD_DESC.type) {
+            java.util.List<java.lang.Integer> intArrayValue;
+            {
+              org.apache.thrift.protocol.TList _list54 = iprot.readListBegin();
+              intArrayValue = new java.util.ArrayList<java.lang.Integer>(_list54.size);
+              int _elem55;
+              for (int _i56 = 0; _i56 < _list54.size; ++_i56)
+              {
+                _elem55 = iprot.readI32();
+                intArrayValue.add(_elem55);
+              }
+              iprot.readListEnd();
+            }
+            return intArrayValue;
+          } else {
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
+            return null;
+          }
+        case LONG_ARRAY_VALUE:
+          if (field.type == LONG_ARRAY_VALUE_FIELD_DESC.type) {
+            java.util.List<java.lang.Long> longArrayValue;
+            {
+              org.apache.thrift.protocol.TList _list57 = iprot.readListBegin();
+              longArrayValue = new java.util.ArrayList<java.lang.Long>(_list57.size);
+              long _elem58;
+              for (int _i59 = 0; _i59 < _list57.size; ++_i59)
+              {
+                _elem58 = iprot.readI64();
+                longArrayValue.add(_elem58);
+              }
+              iprot.readListEnd();
+            }
+            return longArrayValue;
+          } else {
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
+            return null;
+          }
+        case FLOAT_ARRAY_VALUE:
+          if (field.type == FLOAT_ARRAY_VALUE_FIELD_DESC.type) {
+            java.util.List<java.lang.Integer> floatArrayValue;
+            {
+              org.apache.thrift.protocol.TList _list60 = iprot.readListBegin();
+              floatArrayValue = new java.util.ArrayList<java.lang.Integer>(_list60.size);
+              int _elem61;
+              for (int _i62 = 0; _i62 < _list60.size; ++_i62)
+              {
+                _elem61 = iprot.readI32();
+                floatArrayValue.add(_elem61);
+              }
+              iprot.readListEnd();
+            }
+            return floatArrayValue;
+          } else {
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
+            return null;
+          }
+        case DOUBLE_ARRAY_VALUE:
+          if (field.type == DOUBLE_ARRAY_VALUE_FIELD_DESC.type) {
+            java.util.List<java.lang.Double> doubleArrayValue;
+            {
+              org.apache.thrift.protocol.TList _list63 = iprot.readListBegin();
+              doubleArrayValue = new java.util.ArrayList<java.lang.Double>(_list63.size);
+              double _elem64;
+              for (int _i65 = 0; _i65 < _list63.size; ++_i65)
+              {
+                _elem64 = iprot.readDouble();
+                doubleArrayValue.add(_elem64);
+              }
+              iprot.readListEnd();
+            }
+            return doubleArrayValue;
+          } else {
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
+            return null;
+          }
+        case STRING_ARRAY_VALUE:
+          if (field.type == STRING_ARRAY_VALUE_FIELD_DESC.type) {
+            java.util.List<java.lang.String> stringArrayValue;
+            {
+              org.apache.thrift.protocol.TList _list66 = iprot.readListBegin();
+              stringArrayValue = new java.util.ArrayList<java.lang.String>(_list66.size);
+              @org.apache.thrift.annotation.Nullable java.lang.String _elem67;
+              for (int _i68 = 0; _i68 < _list66.size; ++_i68)
+              {
+                _elem67 = iprot.readString();
+                stringArrayValue.add(_elem67);
+              }
+              iprot.readListEnd();
+            }
+            return stringArrayValue;
+          } else {
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
+            return null;
+          }
         default:
           throw new java.lang.IllegalStateException("setField wasn't null, but didn't match any of the case statements!");
       }
@@ -476,6 +661,61 @@ public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields>
         java.lang.Integer floatValue = (java.lang.Integer)value_;
         oprot.writeI32(floatValue);
         return;
+      case INT_ARRAY_VALUE:
+        java.util.List<java.lang.Integer> intArrayValue = (java.util.List<java.lang.Integer>)value_;
+        {
+          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.I32, intArrayValue.size()));
+          for (int _iter69 : intArrayValue)
+          {
+            oprot.writeI32(_iter69);
+          }
+          oprot.writeListEnd();
+        }
+        return;
+      case LONG_ARRAY_VALUE:
+        java.util.List<java.lang.Long> longArrayValue = (java.util.List<java.lang.Long>)value_;
+        {
+          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.I64, longArrayValue.size()));
+          for (long _iter70 : longArrayValue)
+          {
+            oprot.writeI64(_iter70);
+          }
+          oprot.writeListEnd();
+        }
+        return;
+      case FLOAT_ARRAY_VALUE:
+        java.util.List<java.lang.Integer> floatArrayValue = (java.util.List<java.lang.Integer>)value_;
+        {
+          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.I32, floatArrayValue.size()));
+          for (int _iter71 : floatArrayValue)
+          {
+            oprot.writeI32(_iter71);
+          }
+          oprot.writeListEnd();
+        }
+        return;
+      case DOUBLE_ARRAY_VALUE:
+        java.util.List<java.lang.Double> doubleArrayValue = (java.util.List<java.lang.Double>)value_;
+        {
+          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.DOUBLE, doubleArrayValue.size()));
+          for (double _iter72 : doubleArrayValue)
+          {
+            oprot.writeDouble(_iter72);
+          }
+          oprot.writeListEnd();
+        }
+        return;
+      case STRING_ARRAY_VALUE:
+        java.util.List<java.lang.String> stringArrayValue = (java.util.List<java.lang.String>)value_;
+        {
+          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, stringArrayValue.size()));
+          for (java.lang.String _iter73 : stringArrayValue)
+          {
+            oprot.writeString(_iter73);
+          }
+          oprot.writeListEnd();
+        }
+        return;
       default:
         throw new java.lang.IllegalStateException("Cannot write union with unknown field " + setField_);
     }
@@ -530,6 +770,76 @@ public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields>
           java.lang.Integer floatValue;
           floatValue = iprot.readI32();
           return floatValue;
+        case INT_ARRAY_VALUE:
+          java.util.List<java.lang.Integer> intArrayValue;
+          {
+            org.apache.thrift.protocol.TList _list74 = iprot.readListBegin();
+            intArrayValue = new java.util.ArrayList<java.lang.Integer>(_list74.size);
+            int _elem75;
+            for (int _i76 = 0; _i76 < _list74.size; ++_i76)
+            {
+              _elem75 = iprot.readI32();
+              intArrayValue.add(_elem75);
+            }
+            iprot.readListEnd();
+          }
+          return intArrayValue;
+        case LONG_ARRAY_VALUE:
+          java.util.List<java.lang.Long> longArrayValue;
+          {
+            org.apache.thrift.protocol.TList _list77 = iprot.readListBegin();
+            longArrayValue = new java.util.ArrayList<java.lang.Long>(_list77.size);
+            long _elem78;
+            for (int _i79 = 0; _i79 < _list77.size; ++_i79)
+            {
+              _elem78 = iprot.readI64();
+              longArrayValue.add(_elem78);
+            }
+            iprot.readListEnd();
+          }
+          return longArrayValue;
+        case FLOAT_ARRAY_VALUE:
+          java.util.List<java.lang.Integer> floatArrayValue;
+          {
+            org.apache.thrift.protocol.TList _list80 = iprot.readListBegin();
+            floatArrayValue = new java.util.ArrayList<java.lang.Integer>(_list80.size);
+            int _elem81;
+            for (int _i82 = 0; _i82 < _list80.size; ++_i82)
+            {
+              _elem81 = iprot.readI32();
+              floatArrayValue.add(_elem81);
+            }
+            iprot.readListEnd();
+          }
+          return floatArrayValue;
+        case DOUBLE_ARRAY_VALUE:
+          java.util.List<java.lang.Double> doubleArrayValue;
+          {
+            org.apache.thrift.protocol.TList _list83 = iprot.readListBegin();
+            doubleArrayValue = new java.util.ArrayList<java.lang.Double>(_list83.size);
+            double _elem84;
+            for (int _i85 = 0; _i85 < _list83.size; ++_i85)
+            {
+              _elem84 = iprot.readDouble();
+              doubleArrayValue.add(_elem84);
+            }
+            iprot.readListEnd();
+          }
+          return doubleArrayValue;
+        case STRING_ARRAY_VALUE:
+          java.util.List<java.lang.String> stringArrayValue;
+          {
+            org.apache.thrift.protocol.TList _list86 = iprot.readListBegin();
+            stringArrayValue = new java.util.ArrayList<java.lang.String>(_list86.size);
+            @org.apache.thrift.annotation.Nullable java.lang.String _elem87;
+            for (int _i88 = 0; _i88 < _list86.size; ++_i88)
+            {
+              _elem87 = iprot.readString();
+              stringArrayValue.add(_elem87);
+            }
+            iprot.readListEnd();
+          }
+          return stringArrayValue;
         default:
           throw new java.lang.IllegalStateException("setField wasn't null, but didn't match any of the case statements!");
       }
@@ -585,6 +895,61 @@ public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields>
         java.lang.Integer floatValue = (java.lang.Integer)value_;
         oprot.writeI32(floatValue);
         return;
+      case INT_ARRAY_VALUE:
+        java.util.List<java.lang.Integer> intArrayValue = (java.util.List<java.lang.Integer>)value_;
+        {
+          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.I32, intArrayValue.size()));
+          for (int _iter89 : intArrayValue)
+          {
+            oprot.writeI32(_iter89);
+          }
+          oprot.writeListEnd();
+        }
+        return;
+      case LONG_ARRAY_VALUE:
+        java.util.List<java.lang.Long> longArrayValue = (java.util.List<java.lang.Long>)value_;
+        {
+          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.I64, longArrayValue.size()));
+          for (long _iter90 : longArrayValue)
+          {
+            oprot.writeI64(_iter90);
+          }
+          oprot.writeListEnd();
+        }
+        return;
+      case FLOAT_ARRAY_VALUE:
+        java.util.List<java.lang.Integer> floatArrayValue = (java.util.List<java.lang.Integer>)value_;
+        {
+          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.I32, floatArrayValue.size()));
+          for (int _iter91 : floatArrayValue)
+          {
+            oprot.writeI32(_iter91);
+          }
+          oprot.writeListEnd();
+        }
+        return;
+      case DOUBLE_ARRAY_VALUE:
+        java.util.List<java.lang.Double> doubleArrayValue = (java.util.List<java.lang.Double>)value_;
+        {
+          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.DOUBLE, doubleArrayValue.size()));
+          for (double _iter92 : doubleArrayValue)
+          {
+            oprot.writeDouble(_iter92);
+          }
+          oprot.writeListEnd();
+        }
+        return;
+      case STRING_ARRAY_VALUE:
+        java.util.List<java.lang.String> stringArrayValue = (java.util.List<java.lang.String>)value_;
+        {
+          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, stringArrayValue.size()));
+          for (java.lang.String _iter93 : stringArrayValue)
+          {
+            oprot.writeString(_iter93);
+          }
+          oprot.writeListEnd();
+        }
+        return;
       default:
         throw new java.lang.IllegalStateException("Cannot write union with unknown field " + setField_);
     }
@@ -615,6 +980,16 @@ public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields>
         return BIG_DECIMAL_VALUE_FIELD_DESC;
       case FLOAT_VALUE:
         return FLOAT_VALUE_FIELD_DESC;
+      case INT_ARRAY_VALUE:
+        return INT_ARRAY_VALUE_FIELD_DESC;
+      case LONG_ARRAY_VALUE:
+        return LONG_ARRAY_VALUE_FIELD_DESC;
+      case FLOAT_ARRAY_VALUE:
+        return FLOAT_ARRAY_VALUE_FIELD_DESC;
+      case DOUBLE_ARRAY_VALUE:
+        return DOUBLE_ARRAY_VALUE_FIELD_DESC;
+      case STRING_ARRAY_VALUE:
+        return STRING_ARRAY_VALUE_FIELD_DESC;
       default:
         throw new java.lang.IllegalArgumentException("Unknown field id " + setField);
     }
@@ -799,6 +1174,71 @@ public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields>
     value_ = value;
   }
 
+  public java.util.List<java.lang.Integer> getIntArrayValue() {
+    if (getSetField() == _Fields.INT_ARRAY_VALUE) {
+      return (java.util.List<java.lang.Integer>)getFieldValue();
+    } else {
+      throw new java.lang.RuntimeException("Cannot get field 'intArrayValue' because union is currently set to " + getFieldDesc(getSetField()).name);
+    }
+  }
+
+  public void setIntArrayValue(java.util.List<java.lang.Integer> value) {
+    setField_ = _Fields.INT_ARRAY_VALUE;
+    value_ = java.util.Objects.requireNonNull(value,"_Fields.INT_ARRAY_VALUE");
+  }
+
+  public java.util.List<java.lang.Long> getLongArrayValue() {
+    if (getSetField() == _Fields.LONG_ARRAY_VALUE) {
+      return (java.util.List<java.lang.Long>)getFieldValue();
+    } else {
+      throw new java.lang.RuntimeException("Cannot get field 'longArrayValue' because union is currently set to " + getFieldDesc(getSetField()).name);
+    }
+  }
+
+  public void setLongArrayValue(java.util.List<java.lang.Long> value) {
+    setField_ = _Fields.LONG_ARRAY_VALUE;
+    value_ = java.util.Objects.requireNonNull(value,"_Fields.LONG_ARRAY_VALUE");
+  }
+
+  public java.util.List<java.lang.Integer> getFloatArrayValue() {
+    if (getSetField() == _Fields.FLOAT_ARRAY_VALUE) {
+      return (java.util.List<java.lang.Integer>)getFieldValue();
+    } else {
+      throw new java.lang.RuntimeException("Cannot get field 'floatArrayValue' because union is currently set to " + getFieldDesc(getSetField()).name);
+    }
+  }
+
+  public void setFloatArrayValue(java.util.List<java.lang.Integer> value) {
+    setField_ = _Fields.FLOAT_ARRAY_VALUE;
+    value_ = java.util.Objects.requireNonNull(value,"_Fields.FLOAT_ARRAY_VALUE");
+  }
+
+  public java.util.List<java.lang.Double> getDoubleArrayValue() {
+    if (getSetField() == _Fields.DOUBLE_ARRAY_VALUE) {
+      return (java.util.List<java.lang.Double>)getFieldValue();
+    } else {
+      throw new java.lang.RuntimeException("Cannot get field 'doubleArrayValue' because union is currently set to " + getFieldDesc(getSetField()).name);
+    }
+  }
+
+  public void setDoubleArrayValue(java.util.List<java.lang.Double> value) {
+    setField_ = _Fields.DOUBLE_ARRAY_VALUE;
+    value_ = java.util.Objects.requireNonNull(value,"_Fields.DOUBLE_ARRAY_VALUE");
+  }
+
+  public java.util.List<java.lang.String> getStringArrayValue() {
+    if (getSetField() == _Fields.STRING_ARRAY_VALUE) {
+      return (java.util.List<java.lang.String>)getFieldValue();
+    } else {
+      throw new java.lang.RuntimeException("Cannot get field 'stringArrayValue' because union is currently set to " + getFieldDesc(getSetField()).name);
+    }
+  }
+
+  public void setStringArrayValue(java.util.List<java.lang.String> value) {
+    setField_ = _Fields.STRING_ARRAY_VALUE;
+    value_ = java.util.Objects.requireNonNull(value,"_Fields.STRING_ARRAY_VALUE");
+  }
+
   public boolean isSetBoolValue() {
     return setField_ == _Fields.BOOL_VALUE;
   }
@@ -854,6 +1294,31 @@ public class Literal extends org.apache.thrift.TUnion<Literal, Literal._Fields>
   }
 
 
+  public boolean isSetIntArrayValue() {
+    return setField_ == _Fields.INT_ARRAY_VALUE;
+  }
+
+
+  public boolean isSetLongArrayValue() {
+    return setField_ == _Fields.LONG_ARRAY_VALUE;
+  }
+
+
+  public boolean isSetFloatArrayValue() {
+    return setField_ == _Fields.FLOAT_ARRAY_VALUE;
+  }
+
+
+  public boolean isSetDoubleArrayValue() {
+    return setField_ == _Fields.DOUBLE_ARRAY_VALUE;
+  }
+
+
+  public boolean isSetStringArrayValue() {
+    return setField_ == _Fields.STRING_ARRAY_VALUE;
+  }
+
+
   public boolean equals(java.lang.Object other) {
     if (other instanceof Literal) {
       return equals((Literal)other);
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/request/PinotQuery.java b/pinot-common/src/main/java/org/apache/pinot/common/request/PinotQuery.java
index 8bc9113e95..1ee367d30f 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/request/PinotQuery.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/PinotQuery.java
@@ -25,7 +25,7 @@
 package org.apache.pinot.common.request;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-09-27")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-12-07")
 public class PinotQuery implements org.apache.thrift.TBase<PinotQuery, PinotQuery._Fields>, java.io.Serializable, Cloneable, Comparable<PinotQuery> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("PinotQuery");
 
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/request/QuerySource.java b/pinot-common/src/main/java/org/apache/pinot/common/request/QuerySource.java
index c65e2fbbb3..2ad8965879 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/request/QuerySource.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/request/QuerySource.java
@@ -25,7 +25,7 @@
 package org.apache.pinot.common.request;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-09-27")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-12-07")
 public class QuerySource implements org.apache.thrift.TBase<QuerySource, QuerySource._Fields>, java.io.Serializable, Cloneable, Comparable<QuerySource> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("QuerySource");
 
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/response/ProcessingException.java b/pinot-common/src/main/java/org/apache/pinot/common/response/ProcessingException.java
index 68a7b37816..a7c7df7e73 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/response/ProcessingException.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/response/ProcessingException.java
@@ -29,7 +29,7 @@ package org.apache.pinot.common.response;
  * Processing exception
  * 
  */
-@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-09-27")
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2023-12-07")
 public class ProcessingException extends org.apache.thrift.TException implements org.apache.thrift.TBase<ProcessingException, ProcessingException._Fields>, java.io.Serializable, Cloneable, Comparable<ProcessingException> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ProcessingException");
 
diff --git a/pinot-common/src/main/java/org/apache/pinot/common/utils/request/RequestUtils.java b/pinot-common/src/main/java/org/apache/pinot/common/utils/request/RequestUtils.java
index 448a9dbdc4..42abb0b80d 100644
--- a/pinot-common/src/main/java/org/apache/pinot/common/utils/request/RequestUtils.java
+++ b/pinot-common/src/main/java/org/apache/pinot/common/utils/request/RequestUtils.java
@@ -24,9 +24,12 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableSet;
 import java.math.BigDecimal;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 import org.apache.calcite.sql.SqlLiteral;
 import org.apache.calcite.sql.SqlNumericLiteral;
 import org.apache.commons.lang3.StringUtils;
@@ -211,6 +214,37 @@ public class RequestUtils {
     return expression;
   }
 
+  public static Expression getLiteralExpression(int[] value) {
+    Expression expression = createNewLiteralExpression();
+    expression.getLiteral().setIntArrayValue(Arrays.stream(value).boxed().collect(Collectors.toList()));
+    return expression;
+  }
+
+  public static Expression getLiteralExpression(long[] value) {
+    Expression expression = createNewLiteralExpression();
+    expression.getLiteral().setLongArrayValue(Arrays.stream(value).boxed().collect(Collectors.toList()));
+    return expression;
+  }
+
+  public static Expression getLiteralExpression(float[] value) {
+    Expression expression = createNewLiteralExpression();
+    expression.getLiteral().setFloatArrayValue(
+        IntStream.range(0, value.length).mapToObj(i -> Float.floatToRawIntBits(value[i])).collect(Collectors.toList()));
+    return expression;
+  }
+
+  public static Expression getLiteralExpression(double[] value) {
+    Expression expression = createNewLiteralExpression();
+    expression.getLiteral().setDoubleArrayValue(Arrays.stream(value).boxed().collect(Collectors.toList()));
+    return expression;
+  }
+
+  public static Expression getLiteralExpression(String[] value) {
+    Expression expression = createNewLiteralExpression();
+    expression.getLiteral().setStringArrayValue(Arrays.asList(value));
+    return expression;
+  }
+
   public static Expression getNullLiteralExpression() {
     Expression expression = createNewLiteralExpression();
     expression.getLiteral().setNullValue(true);
@@ -249,6 +283,21 @@ public class RequestUtils {
     if (object instanceof Boolean) {
       return RequestUtils.getLiteralExpression((boolean) object);
     }
+    if (object instanceof int[]) {
+      return RequestUtils.getLiteralExpression((int[]) object);
+    }
+    if (object instanceof long[]) {
+      return RequestUtils.getLiteralExpression((long[]) object);
+    }
+    if (object instanceof float[]) {
+      return RequestUtils.getLiteralExpression((float[]) object);
+    }
+    if (object instanceof double[]) {
+      return RequestUtils.getLiteralExpression((double[]) object);
+    }
+    if (object instanceof String[]) {
+      return RequestUtils.getLiteralExpression((String[]) object);
+    }
     return RequestUtils.getLiteralExpression(object.toString());
   }
 
diff --git a/pinot-common/src/thrift/query.thrift b/pinot-common/src/thrift/query.thrift
index a88f964e73..8602a032aa 100644
--- a/pinot-common/src/thrift/query.thrift
+++ b/pinot-common/src/thrift/query.thrift
@@ -81,6 +81,11 @@ union Literal {
   10: optional binary bigDecimalValue;
   // Use i32 to represent float since there is no native float type
   11: optional i32 floatValue;
+  12: optional list<i32> intArrayValue;
+  13: optional list<i64> longArrayValue;
+  14: optional list<i32> floatArrayValue;
+  15: optional list<double> doubleArrayValue;
+  16: optional list<string> stringArrayValue;
 }
 
 struct Identifier {
diff --git a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/CastTransformFunction.java b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/CastTransformFunction.java
index f500e601f7..02d6a42629 100644
--- a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/CastTransformFunction.java
+++ b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/CastTransformFunction.java
@@ -88,6 +88,23 @@ public class CastTransformFunction extends BaseTransformFunction {
         case "VARCHAR":
           _resultMetadata = sourceSV ? STRING_SV_NO_DICTIONARY_METADATA : STRING_MV_NO_DICTIONARY_METADATA;
           break;
+        case "INT_ARRAY":
+        case "INTEGER_ARRAY":
+          _resultMetadata = INT_MV_NO_DICTIONARY_METADATA;
+          break;
+        case "LONG_ARRAY":
+          _resultMetadata = LONG_MV_NO_DICTIONARY_METADATA;
+          break;
+        case "FLOAT_ARRAY":
+          _resultMetadata = FLOAT_MV_NO_DICTIONARY_METADATA;
+          break;
+        case "DOUBLE_ARRAY":
+          _resultMetadata = DOUBLE_MV_NO_DICTIONARY_METADATA;
+          break;
+        case "STRING_ARRAY":
+        case "VARCHAR_ARRAY":
+          _resultMetadata = STRING_MV_NO_DICTIONARY_METADATA;
+          break;
         case "JSON":
           _resultMetadata = sourceSV ? JSON_SV_NO_DICTIONARY_METADATA : JSON_MV_NO_DICTIONARY_METADATA;
           break;
diff --git a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/custom/ArrayTest.java b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/custom/ArrayTest.java
index 0555c3a201..9275d3ce90 100644
--- a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/custom/ArrayTest.java
+++ b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/custom/ArrayTest.java
@@ -179,6 +179,120 @@ public class ArrayTest extends CustomDataQueryClusterIntegrationTest {
     }
   }
 
+  @Test(dataProvider = "useBothQueryEngines")
+  public void testStringSplitFunction(boolean useMultiStageQueryEngine)
+      throws Exception {
+    setUseMultiStageQueryEngine(useMultiStageQueryEngine);
+    String query =
+        String.format("SELECT "
+            + "split('t1,t2,t3', ',') "
+            + "FROM %s LIMIT 1", getTableName());
+    JsonNode jsonNode = postQuery(query);
+    JsonNode rows = jsonNode.get("resultTable").get("rows");
+    Assert.assertEquals(rows.size(), 1);
+    JsonNode row = rows.get(0);
+    Assert.assertEquals(row.size(), 1);
+    Assert.assertEquals(row.get(0).size(), 3);
+    Assert.assertEquals(row.get(0).get(0).asText(), "t1");
+    Assert.assertEquals(row.get(0).get(1).asText(), "t2");
+    Assert.assertEquals(row.get(0).get(2).asText(), "t3");
+  }
+
+  @Test(dataProvider = "useBothQueryEngines")
+  public void testIntArrayLiteral(boolean useMultiStageQueryEngine)
+      throws Exception {
+    setUseMultiStageQueryEngine(useMultiStageQueryEngine);
+    String query =
+        String.format("SELECT "
+            + "ARRAY[1,2,3] "
+            + "FROM %s LIMIT 1", getTableName());
+    JsonNode jsonNode = postQuery(query);
+    JsonNode rows = jsonNode.get("resultTable").get("rows");
+    Assert.assertEquals(rows.size(), 1);
+    JsonNode row = rows.get(0);
+    Assert.assertEquals(row.size(), 1);
+    Assert.assertEquals(row.get(0).size(), 3);
+    Assert.assertEquals(row.get(0).get(0).asInt(), 1);
+    Assert.assertEquals(row.get(0).get(1).asInt(), 2);
+    Assert.assertEquals(row.get(0).get(2).asInt(), 3);
+  }
+
+  @Test(dataProvider = "useBothQueryEngines")
+  public void testLongArrayLiteral(boolean useMultiStageQueryEngine)
+      throws Exception {
+    setUseMultiStageQueryEngine(useMultiStageQueryEngine);
+    String query =
+        String.format("SELECT "
+            + "ARRAY[2147483648,2147483649,2147483650] "
+            + "FROM %s LIMIT 1", getTableName());
+    JsonNode jsonNode = postQuery(query);
+    JsonNode rows = jsonNode.get("resultTable").get("rows");
+    Assert.assertEquals(rows.size(), 1);
+    JsonNode row = rows.get(0);
+    Assert.assertEquals(row.size(), 1);
+    Assert.assertEquals(row.get(0).size(), 3);
+    Assert.assertEquals(row.get(0).get(0).asLong(), 2147483648L);
+    Assert.assertEquals(row.get(0).get(1).asLong(), 2147483649L);
+    Assert.assertEquals(row.get(0).get(2).asLong(), 2147483650L);
+  }
+
+  @Test(dataProvider = "useBothQueryEngines")
+  public void testFloatArrayLiteral(boolean useMultiStageQueryEngine)
+      throws Exception {
+    setUseMultiStageQueryEngine(useMultiStageQueryEngine);
+    String query =
+        String.format("SELECT "
+            + "ARRAY[0.1, 0.2, 0.3] "
+            + "FROM %s LIMIT 1", getTableName());
+    JsonNode jsonNode = postQuery(query);
+    JsonNode rows = jsonNode.get("resultTable").get("rows");
+    Assert.assertEquals(rows.size(), 1);
+    JsonNode row = rows.get(0);
+    Assert.assertEquals(row.size(), 1);
+    Assert.assertEquals(row.get(0).size(), 3);
+    Assert.assertEquals(row.get(0).get(0).asDouble(), 0.1);
+    Assert.assertEquals(row.get(0).get(1).asDouble(), 0.2);
+    Assert.assertEquals(row.get(0).get(2).asDouble(), 0.3);
+  }
+
+  @Test(dataProvider = "useBothQueryEngines")
+  public void testDoubleArrayLiteral(boolean useMultiStageQueryEngine)
+      throws Exception {
+    setUseMultiStageQueryEngine(useMultiStageQueryEngine);
+    String query =
+        String.format("SELECT "
+            + "ARRAY[CAST(0.1 AS DOUBLE), CAST(0.2 AS DOUBLE), CAST(0.3 AS DOUBLE)] "
+            + "FROM %s LIMIT 1", getTableName());
+    JsonNode jsonNode = postQuery(query);
+    JsonNode rows = jsonNode.get("resultTable").get("rows");
+    Assert.assertEquals(rows.size(), 1);
+    JsonNode row = rows.get(0);
+    Assert.assertEquals(row.size(), 1);
+    Assert.assertEquals(row.get(0).size(), 3);
+    Assert.assertEquals(row.get(0).get(0).asDouble(), 0.1);
+    Assert.assertEquals(row.get(0).get(1).asDouble(), 0.2);
+    Assert.assertEquals(row.get(0).get(2).asDouble(), 0.3);
+  }
+
+  @Test(dataProvider = "useBothQueryEngines")
+  public void testStringArrayLiteral(boolean useMultiStageQueryEngine)
+      throws Exception {
+    setUseMultiStageQueryEngine(useMultiStageQueryEngine);
+    String query =
+        String.format("SELECT "
+            + "ARRAY['a', 'bb', 'ccc'] "
+            + "FROM %s LIMIT 1", getTableName());
+    JsonNode jsonNode = postQuery(query);
+    JsonNode rows = jsonNode.get("resultTable").get("rows");
+    Assert.assertEquals(rows.size(), 1);
+    JsonNode row = rows.get(0);
+    Assert.assertEquals(row.size(), 1);
+    Assert.assertEquals(row.get(0).size(), 3);
+    Assert.assertEquals(row.get(0).get(0).asText(), "a");
+    Assert.assertEquals(row.get(0).get(1).asText(), "bb");
+    Assert.assertEquals(row.get(0).get(2).asText(), "ccc");
+  }
+
   @Override
   public String getTableName() {
     return DEFAULT_TABLE_NAME;
diff --git a/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotEvaluateLiteralRule.java b/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotEvaluateLiteralRule.java
index 28ff9d6ff3..02d44ade9b 100644
--- a/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotEvaluateLiteralRule.java
+++ b/pinot-query-planner/src/main/java/org/apache/calcite/rel/rules/PinotEvaluateLiteralRule.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.GregorianCalendar;
 import java.util.List;
+import java.util.Objects;
 import javax.annotation.Nullable;
 import org.apache.calcite.avatica.util.ByteString;
 import org.apache.calcite.plan.RelOptRule;
@@ -36,6 +37,7 @@ import org.apache.calcite.rex.RexCall;
 import org.apache.calcite.rex.RexLiteral;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.rex.RexShuttle;
+import org.apache.calcite.sql.type.ArraySqlType;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.tools.RelBuilderFactory;
 import org.apache.calcite.util.NlsString;
@@ -159,6 +161,16 @@ public class PinotEvaluateLiteralRule {
       FunctionInvoker invoker = new FunctionInvoker(functionInfo);
       invoker.convertTypes(arguments);
       resultValue = invoker.invoke(arguments);
+      if (rexNodeType.getSqlTypeName() == SqlTypeName.ARRAY) {
+        RelDataType componentType = rexNodeType.getComponentType();
+        if (componentType != null) {
+          if (Objects.requireNonNull(componentType.getSqlTypeName()) == SqlTypeName.CHAR) {
+            // Calcite uses CHAR for STRING, but we need to use VARCHAR for STRING
+            rexNodeType = rexBuilder.getTypeFactory().createArrayType(
+                rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR), -1);
+          }
+        }
+      }
     } catch (Exception e) {
       throw new SqlCompilationException(
           "Caught exception while invoking method: " + functionInfo.getMethod() + " with arguments: " + Arrays.toString(
@@ -170,7 +182,17 @@ public class PinotEvaluateLiteralRule {
       throw new SqlCompilationException(
           "Caught exception while converting result value: " + resultValue + " to type: " + rexNodeType, e);
     }
+    if (resultValue == null) {
+      return rexBuilder.makeNullLiteral(rexNodeType);
+    }
     try {
+      if (rexNodeType instanceof ArraySqlType) {
+        List<Object> resultValues = new ArrayList<>();
+        for (Object value : (Object[]) resultValue) {
+          resultValues.add(convertResultValue(value, rexNodeType.getComponentType()));
+        }
+        return rexBuilder.makeLiteral(resultValues, rexNodeType, false);
+      }
       return rexBuilder.makeLiteral(resultValue, rexNodeType, false);
     } catch (Exception e) {
       throw new SqlCompilationException(
diff --git a/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/utils/TypeUtils.java b/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/utils/TypeUtils.java
index a50d48b31a..933c3be95f 100644
--- a/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/utils/TypeUtils.java
+++ b/pinot-query-runtime/src/main/java/org/apache/pinot/query/runtime/operator/utils/TypeUtils.java
@@ -66,6 +66,14 @@ public class TypeUtils {
         if (value instanceof FloatArrayList) {
           // For ArrayAggregationFunction
           return ((FloatArrayList) value).elements();
+        } else if (value instanceof double[]) {
+          // This is due to for parsing array literal value like [0.1, 0.2, 0.3].
+          // The parsed value is stored as double[] in java, however the calcite type is FLOAT_ARRAY.
+          float[] floatArray = new float[((double[]) value).length];
+          for (int i = 0; i < floatArray.length; i++) {
+            floatArray[i] = (float) ((double[]) value)[i];
+          }
+          return floatArray;
         } else {
           return value;
         }


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