1919
2020package  org .apache .comet .serde .literals 
2121
22+ import  java .lang 
23+ 
2224import  org .apache .spark .internal .Logging 
2325import  org .apache .spark .sql .catalyst .expressions .{Attribute , Literal }
2426import  org .apache .spark .sql .catalyst .util .GenericArrayData 
@@ -27,7 +29,6 @@ import org.apache.spark.unsafe.types.UTF8String
2729
2830import  com .google .protobuf .ByteString 
2931
30- import  org .apache .comet .CometConf 
3132import  org .apache .comet .CometSparkSessionExtensions .withInfo 
3233import  org .apache .comet .DataTypeSupport .isComplexType 
3334import  org .apache .comet .serde .{CometExpressionSerde , Compatible , ExprOuterClass , LiteralOuterClass , SupportLevel , Unsupported }
@@ -41,13 +42,15 @@ object CometLiteral extends CometExpressionSerde[Literal] with Logging {
4142    if  (supportedDataType(
4243        expr.dataType,
4344        allowComplex =  expr.value ==  null  || 
45+ 
4446          //  Nested literal support for native reader
4547          //  can be tracked https://github.com/apache/datafusion-comet/issues/1937
46-           //  now supports only Array of primitive
47-           (Seq (CometConf .SCAN_NATIVE_ICEBERG_COMPAT , CometConf .SCAN_NATIVE_DATAFUSION )
48-             .contains(CometConf .COMET_NATIVE_SCAN_IMPL .get()) &&  expr.dataType
49-             .isInstanceOf [ArrayType ]) &&  ! isComplexType(
50-             expr.dataType.asInstanceOf [ArrayType ].elementType))) {
48+           (expr.dataType
49+             .isInstanceOf [ArrayType ] &&  (! isComplexType(
50+             expr.dataType.asInstanceOf [ArrayType ].elementType) ||  expr.dataType
51+             .asInstanceOf [ArrayType ]
52+             .elementType
53+             .isInstanceOf [ArrayType ])))) {
5154      Compatible (None )
5255    } else  {
5356      Unsupported (Some (s " Unsupported data type  ${expr.dataType}" ))
@@ -86,84 +89,10 @@ object CometLiteral extends CometExpressionSerde[Literal] with Logging {
8689          val  byteStr  = 
8790            com.google.protobuf.ByteString .copyFrom(value.asInstanceOf [Array [Byte ]])
8891          exprBuilder.setBytesVal(byteStr)
89-         case  a : ArrayType  => 
90-           val  listLiteralBuilder  =  ListLiteral .newBuilder()
91-           val  array  =  value.asInstanceOf [GenericArrayData ].array
92-           a.elementType match  {
93-             case  NullType  => 
94-               array.foreach(_ =>  listLiteralBuilder.addNullMask(true ))
95-             case  BooleanType  => 
96-               array.foreach(v =>  {
97-                 val  casted  =  v.asInstanceOf [java.lang.Boolean ]
98-                 listLiteralBuilder.addBooleanValues(casted)
99-                 listLiteralBuilder.addNullMask(casted !=  null )
100-               })
101-             case  ByteType  => 
102-               array.foreach(v =>  {
103-                 val  casted  =  v.asInstanceOf [java.lang.Integer ]
104-                 listLiteralBuilder.addByteValues(casted)
105-                 listLiteralBuilder.addNullMask(casted !=  null )
106-               })
107-             case  ShortType  => 
108-               array.foreach(v =>  {
109-                 val  casted  =  v.asInstanceOf [java.lang.Short ]
110-                 listLiteralBuilder.addShortValues(
111-                   if  (casted !=  null ) casted.intValue()
112-                   else  null .asInstanceOf [java.lang.Integer ])
113-                 listLiteralBuilder.addNullMask(casted !=  null )
114-               })
115-             case  IntegerType  |  DateType  => 
116-               array.foreach(v =>  {
117-                 val  casted  =  v.asInstanceOf [java.lang.Integer ]
118-                 listLiteralBuilder.addIntValues(casted)
119-                 listLiteralBuilder.addNullMask(casted !=  null )
120-               })
121-             case  LongType  |  TimestampType  |  TimestampNTZType  => 
122-               array.foreach(v =>  {
123-                 val  casted  =  v.asInstanceOf [java.lang.Long ]
124-                 listLiteralBuilder.addLongValues(casted)
125-                 listLiteralBuilder.addNullMask(casted !=  null )
126-               })
127-             case  FloatType  => 
128-               array.foreach(v =>  {
129-                 val  casted  =  v.asInstanceOf [java.lang.Float ]
130-                 listLiteralBuilder.addFloatValues(casted)
131-                 listLiteralBuilder.addNullMask(casted !=  null )
132-               })
133-             case  DoubleType  => 
134-               array.foreach(v =>  {
135-                 val  casted  =  v.asInstanceOf [java.lang.Double ]
136-                 listLiteralBuilder.addDoubleValues(casted)
137-                 listLiteralBuilder.addNullMask(casted !=  null )
138-               })
139-             case  StringType  => 
140-               array.foreach(v =>  {
141-                 val  casted  =  v.asInstanceOf [org.apache.spark.unsafe.types.UTF8String ]
142-                 listLiteralBuilder.addStringValues(if  (casted !=  null ) casted.toString else  " "  )
143-                 listLiteralBuilder.addNullMask(casted !=  null )
144-               })
145-             case  _ : DecimalType  => 
146-               array
147-                 .foreach(v =>  {
148-                   val  casted  = 
149-                     v.asInstanceOf [Decimal ]
150-                   listLiteralBuilder.addDecimalValues(if  (casted !=  null ) {
151-                     com.google.protobuf.ByteString 
152-                       .copyFrom(casted.toBigDecimal.underlying.unscaledValue.toByteArray)
153-                   } else  ByteString .EMPTY )
154-                   listLiteralBuilder.addNullMask(casted !=  null )
155-                 })
156-             case  _ : BinaryType  => 
157-               array
158-                 .foreach(v =>  {
159-                   val  casted  = 
160-                     v.asInstanceOf [Array [Byte ]]
161-                   listLiteralBuilder.addBytesValues(if  (casted !=  null ) {
162-                     com.google.protobuf.ByteString .copyFrom(casted)
163-                   } else  ByteString .EMPTY )
164-                   listLiteralBuilder.addNullMask(casted !=  null )
165-                 })
166-           }
92+ 
93+         case  arr : ArrayType  => 
94+           val  listLiteralBuilder :  ListLiteral .Builder  = 
95+             makeListLiteral(value.asInstanceOf [GenericArrayData ].array, arr)
16796          exprBuilder.setListVal(listLiteralBuilder.build())
16897          exprBuilder.setDatatype(serializeDataType(dataType).get)
16998        case  dt => 
@@ -188,4 +117,92 @@ object CometLiteral extends CometExpressionSerde[Literal] with Logging {
188117    }
189118
190119  }
120+ 
121+   private  def  makeListLiteral (array : Array [Any ], arrayType : ArrayType ):  ListLiteral .Builder  =  {
122+     val  listLiteralBuilder  =  ListLiteral .newBuilder()
123+     arrayType.elementType match  {
124+       case  NullType  => 
125+         array.foreach(_ =>  listLiteralBuilder.addNullMask(true ))
126+       case  BooleanType  => 
127+         array.foreach(v =>  {
128+           val  casted  =  v.asInstanceOf [lang.Boolean ]
129+           listLiteralBuilder.addBooleanValues(casted)
130+           listLiteralBuilder.addNullMask(casted !=  null )
131+         })
132+       case  ByteType  => 
133+         array.foreach(v =>  {
134+           val  casted  =  v.asInstanceOf [Integer ]
135+           listLiteralBuilder.addByteValues(casted)
136+           listLiteralBuilder.addNullMask(casted !=  null )
137+         })
138+       case  ShortType  => 
139+         array.foreach(v =>  {
140+           val  casted  =  v.asInstanceOf [lang.Short ]
141+           listLiteralBuilder.addShortValues(
142+             if  (casted !=  null ) casted.intValue()
143+             else  null .asInstanceOf [Integer ])
144+           listLiteralBuilder.addNullMask(casted !=  null )
145+         })
146+       case  IntegerType  |  DateType  => 
147+         array.foreach(v =>  {
148+           val  casted  =  v.asInstanceOf [Integer ]
149+           listLiteralBuilder.addIntValues(casted)
150+           listLiteralBuilder.addNullMask(casted !=  null )
151+         })
152+       case  LongType  |  TimestampType  |  TimestampNTZType  => 
153+         array.foreach(v =>  {
154+           val  casted  =  v.asInstanceOf [lang.Long ]
155+           listLiteralBuilder.addLongValues(casted)
156+           listLiteralBuilder.addNullMask(casted !=  null )
157+         })
158+       case  FloatType  => 
159+         array.foreach(v =>  {
160+           val  casted  =  v.asInstanceOf [lang.Float ]
161+           listLiteralBuilder.addFloatValues(casted)
162+           listLiteralBuilder.addNullMask(casted !=  null )
163+         })
164+       case  DoubleType  => 
165+         array.foreach(v =>  {
166+           val  casted  =  v.asInstanceOf [lang.Double ]
167+           listLiteralBuilder.addDoubleValues(casted)
168+           listLiteralBuilder.addNullMask(casted !=  null )
169+         })
170+       case  StringType  => 
171+         array.foreach(v =>  {
172+           val  casted  =  v.asInstanceOf [UTF8String ]
173+           listLiteralBuilder.addStringValues(if  (casted !=  null ) casted.toString else  " "  )
174+           listLiteralBuilder.addNullMask(casted !=  null )
175+         })
176+       case  _ : DecimalType  => 
177+         array
178+           .foreach(v =>  {
179+             val  casted  = 
180+               v.asInstanceOf [Decimal ]
181+             listLiteralBuilder.addDecimalValues(if  (casted !=  null ) {
182+               com.google.protobuf.ByteString 
183+                 .copyFrom(casted.toBigDecimal.underlying.unscaledValue.toByteArray)
184+             } else  ByteString .EMPTY )
185+             listLiteralBuilder.addNullMask(casted !=  null )
186+           })
187+       case  _ : BinaryType  => 
188+         array
189+           .foreach(v =>  {
190+             val  casted  = 
191+               v.asInstanceOf [Array [Byte ]]
192+             listLiteralBuilder.addBytesValues(if  (casted !=  null ) {
193+               com.google.protobuf.ByteString .copyFrom(casted)
194+             } else  ByteString .EMPTY )
195+             listLiteralBuilder.addNullMask(casted !=  null )
196+           })
197+       case  a : ArrayType  => 
198+         array.foreach(v =>  {
199+           val  casted  =  v.asInstanceOf [GenericArrayData ]
200+           listLiteralBuilder.addListValues(if  (casted !=  null ) {
201+             makeListLiteral(casted.array, a)
202+           } else  ListLiteral .newBuilder())
203+           listLiteralBuilder.addNullMask(casted !=  null )
204+         })
205+     }
206+     listLiteralBuilder
207+   }
191208}
0 commit comments