-
Notifications
You must be signed in to change notification settings - Fork 28.9k
[SPARK-30858][SQL] Make IntegralDivide's dataType independent from SQL config changes #27628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -403,11 +403,18 @@ case class Divide(left: Expression, right: Expression) extends DivModLike { | |
""", | ||
since = "3.0.0") | ||
// scalastyle:on line.size.limit | ||
case class IntegralDivide(left: Expression, right: Expression) extends DivModLike { | ||
case class IntegralDivide( | ||
left: Expression, | ||
right: Expression, | ||
returnLong: Boolean) extends DivModLike { | ||
|
||
def this(left: Expression, right: Expression) = { | ||
this(left, right, SQLConf.get.integralDivideReturnLong) | ||
} | ||
|
||
override def inputType: AbstractDataType = TypeCollection(IntegralType, DecimalType) | ||
|
||
override def dataType: DataType = if (SQLConf.get.integralDivideReturnLong) { | ||
override def dataType: DataType = if (returnLong) { | ||
LongType | ||
} else { | ||
left.dataType | ||
|
@@ -416,7 +423,7 @@ case class IntegralDivide(left: Expression, right: Expression) extends DivModLik | |
override def symbol: String = "/" | ||
override def decimalMethod: String = "quot" | ||
override def decimalToDataTypeCodeGen(decimalResult: String): String = { | ||
if (SQLConf.get.integralDivideReturnLong) { | ||
if (returnLong) { | ||
s"$decimalResult.toLong()" | ||
} else { | ||
decimalResult | ||
|
@@ -433,7 +440,7 @@ case class IntegralDivide(left: Expression, right: Expression) extends DivModLik | |
d.asIntegral.asInstanceOf[Integral[Any]] | ||
} | ||
val divide = integral.quot _ | ||
if (SQLConf.get.integralDivideReturnLong) { | ||
if (returnLong) { | ||
val toLong = integral.asInstanceOf[Integral[Any]].toLong _ | ||
(x, y) => { | ||
val res = divide(x, y) | ||
|
@@ -451,6 +458,12 @@ case class IntegralDivide(left: Expression, right: Expression) extends DivModLik | |
override def evalOperation(left: Any, right: Any): Any = div(left, right) | ||
} | ||
|
||
object IntegralDivide { | ||
def apply(left: Expression, right: Expression): IntegralDivide = { | ||
new IntegralDivide(left, right) | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shall we define There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is only one place where we unapply There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I define |
||
|
||
@ExpressionDescription( | ||
usage = "expr1 _FUNC_ expr2 - Returns the remainder after `expr1`/`expr2`.", | ||
examples = """ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we just add a
private val returnLong = SQLConf.get.integralDivideReturnLong
in the class body? Then the config value is fixed when the expression is created. And it can be serialized to executors.The spark Expression constructor is kind of exposed to end users when they call functions in SQL. BTW
Cast
already use aval
to store config values.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That can potentially change value every time you transform the tree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or how about we create 2 expressions
IntegralDivide
andIntegralDivideReturnLong
? I'm just worried about we allow end users to specify thereturnLong
parameter which becomes an API.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't allow that:
fails with:
I ran the command on the PR changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the non-expression parameter doesn't count? Then I'm fine with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we count only expressions, see
spark/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/FunctionRegistry.scala
Lines 601 to 602 in 919d551