-
Notifications
You must be signed in to change notification settings - Fork 28.7k
[SPARK-8223][SPARK-8224][SQL] shift left and shift right #7178
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
ac7fe9d
44ee324
9434a28
5189690
3b56f2a
f628706
f3f64e6
8023bb5
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 |
---|---|---|
|
@@ -351,6 +351,104 @@ case class Pow(left: Expression, right: Expression) | |
} | ||
} | ||
|
||
case class ShiftLeft(left: Expression, right: Expression) extends BinaryExpression { | ||
|
||
override def checkInputDataTypes(): TypeCheckResult = { | ||
(left.dataType, right.dataType) match { | ||
case (NullType, _) | (_, NullType) => return TypeCheckResult.TypeCheckSuccess | ||
case (_, IntegerType) => left.dataType match { | ||
case LongType | IntegerType | ShortType | ByteType => | ||
return TypeCheckResult.TypeCheckSuccess | ||
case _ => // failed | ||
} | ||
case _ => // failed | ||
} | ||
TypeCheckResult.TypeCheckFailure( | ||
s"ShiftLeft expects long, integer, short or byte value as first argument and an " + | ||
s"integer value as second argument, not (${left.dataType}, ${right.dataType})") | ||
} | ||
|
||
override def eval(input: InternalRow): Any = { | ||
val valueLeft = left.eval(input) | ||
if (valueLeft != null) { | ||
val valueRight = right.eval(input) | ||
if (valueRight != null) { | ||
valueLeft match { | ||
case l: Long => l << valueRight.asInstanceOf[Integer] | ||
case i: Integer => i << valueRight.asInstanceOf[Integer] | ||
case s: Short => s << valueRight.asInstanceOf[Integer] | ||
case b: Byte => b << valueRight.asInstanceOf[Integer] | ||
} | ||
} else { | ||
null | ||
} | ||
} else { | ||
null | ||
} | ||
} | ||
|
||
override def dataType: DataType = { | ||
left.dataType match { | ||
case LongType => LongType | ||
case IntegerType | ShortType | ByteType => IntegerType | ||
case _ => NullType | ||
} | ||
} | ||
|
||
override protected def genCode(ctx: CodeGenContext, ev: GeneratedExpressionCode): String = { | ||
nullSafeCodeGen(ctx, ev, (result, left, right) => s"$result = $left << $right;") | ||
} | ||
} | ||
|
||
case class ShiftRight(left: Expression, right: Expression) extends BinaryExpression { | ||
|
||
override def checkInputDataTypes(): TypeCheckResult = { | ||
(left.dataType, right.dataType) match { | ||
case (NullType, _) | (_, NullType) => return TypeCheckResult.TypeCheckSuccess | ||
case (_, IntegerType) => left.dataType match { | ||
case LongType | IntegerType | ShortType | ByteType => | ||
return TypeCheckResult.TypeCheckSuccess | ||
case _ => // failed | ||
} | ||
case _ => // failed | ||
} | ||
TypeCheckResult.TypeCheckFailure( | ||
s"ShiftRight expects long, integer, short or byte value as first argument and an " + | ||
s"integer value as second argument, not (${left.dataType}, ${right.dataType})") | ||
} | ||
|
||
override def eval(input: InternalRow): Any = { | ||
val valueLeft = left.eval(input) | ||
if (valueLeft != null) { | ||
val valueRight = right.eval(input) | ||
if (valueRight != null) { | ||
valueLeft match { | ||
case l: Long => l >> valueRight.asInstanceOf[Integer] | ||
case i: Integer => i >> valueRight.asInstanceOf[Integer] | ||
case s: Short => s >> valueRight.asInstanceOf[Integer] | ||
case b: Byte => b >> valueRight.asInstanceOf[Integer] | ||
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. Should we use 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 a special Jira ticket for that: https://issues.apache.org/jira/browse/SPARK-8226. Someone created already a PR. 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. I see. 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. Why not pattern matching the data type? instead of the value? Will that cause extra box/unbox for primtives? 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. That might be a good hint. I am going to take a look on the generated code and will come back to this and create maybe a follow-up. 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. @chenghao-intel I investigated it a little bit, see the gist: https://gist.github.com/tarekauel/6994983b83a51668c5dc . The interesting part is that the match on the value is even faster, did I something wrong? |
||
} | ||
} else { | ||
null | ||
} | ||
} else { | ||
null | ||
} | ||
} | ||
|
||
override def dataType: DataType = { | ||
left.dataType match { | ||
case LongType => LongType | ||
case IntegerType | ShortType | ByteType => IntegerType | ||
case _ => NullType | ||
} | ||
} | ||
|
||
override protected def genCode(ctx: CodeGenContext, ev: GeneratedExpressionCode): String = { | ||
nullSafeCodeGen(ctx, ev, (result, left, right) => s"$result = $left >> $right;") | ||
} | ||
} | ||
|
||
/** | ||
* Performs the inverse operation of HEX. | ||
* Resulting characters are returned as a byte array. | ||
|
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.
Should we handle overflow?
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.
What do you mean by overflow?
(1111 1111 << 1) = 1111 1110, is expected, isn't?
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, thanks!