Github user viirya commented on a diff in the pull request: https://github.com/apache/spark/pull/20085#discussion_r158760292 --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/objects/objects.scala --- @@ -182,6 +182,114 @@ case class StaticInvoke( } } +/** + * Invokes a call to reference to a static field. + * + * @param staticObject The target of the static call. This can either be the object itself + * (methods defined on scala objects), or the class object + * (static methods defined in java). + * @param dataType The expected return type of the function call. + * @param fieldName The field to reference. + */ +case class StaticField( + staticObject: Class[_], + dataType: DataType, + fieldName: String) extends Expression with NonSQLExpression { + + val objectName = staticObject.getName.stripSuffix("$") + + override def nullable: Boolean = false + override def children: Seq[Expression] = Nil + + override def eval(input: InternalRow): Any = + throw new UnsupportedOperationException("Only code-generated evaluation is supported.") + + override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = { + val javaType = ctx.javaType(dataType) + + val code = s""" + final $javaType ${ev.value} = $objectName.$fieldName; + """ + + ev.copy(code = code, isNull = "false") + } +} + +/** + * Wraps an expression in a try-catch block, which can be used if the body expression may throw a + * exception. + * + * @param body The expression body to wrap in a try-catch block. + * @param dataType The return type of the try block. + * @param returnNullable When false, indicating the invoked method will always return + * non-null value. + */ +case class WrapException( + body: Expression, + dataType: DataType, + returnNullable: Boolean = true) extends Expression with NonSQLExpression { + + override def nullable: Boolean = returnNullable + override def children: Seq[Expression] = Seq(body) + + override def eval(input: InternalRow): Any = + throw new UnsupportedOperationException("Only code-generated evaluation is supported.") + + override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = { + val javaType = ctx.javaType(dataType) + val returnName = ctx.freshName("returnName") + + val bodyExpr = body.genCode(ctx) + + val code = + s""" + |final $javaType $returnName; + |try { + | ${bodyExpr.code} + | $returnName = ${bodyExpr.value}; + |} catch (Exception e) { + | org.apache.spark.unsafe.Platform.throwException(e); + |} + """.stripMargin + + ev.copy(code = code, isNull = bodyExpr.isNull, value = returnName) + } +} + +/** + * Returns the value if it is of the specified type, or null otherwise + * + * @param value The value to returned + * @param checkedType The type to check against the value via instanceOf + * @param dataType The type returned by the expression + */ +case class ValueIfType( + value: Expression, + checkedType: Class[_], + dataType: DataType) extends Expression with NonSQLExpression { --- End diff -- Will we have different data type other than `value.dataType`?
--- --------------------------------------------------------------------- To unsubscribe, e-mail: reviews-unsubscr...@spark.apache.org For additional commands, e-mail: reviews-h...@spark.apache.org