-
Notifications
You must be signed in to change notification settings - Fork 0
3618: feat: Support Spark expression second_of_time #41
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
base: main
Are you sure you want to change the base?
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -408,4 +408,50 @@ trait CommonStringExprs { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def secondOfTimeToProto( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| expr: Expression, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inputs: Seq[Attribute], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| binding: Boolean): Option[Expr] = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val childOpt = expr.children.headOption.orElse { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| withInfo(expr, "SecondOfTime has no child expression") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| childOpt.flatMap { child => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val timeZoneId = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val exprClass = expr.getClass | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val timeZoneIdMethod = exprClass.getMethod("timeZoneId") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| timeZoneIdMethod.invoke(expr).asInstanceOf[Option[String]] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case _: NoSuchMethodException => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val timeZoneIdField = exprClass.getField("timeZoneId") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| timeZoneIdField.get(expr).asInstanceOf[Option[String]] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case _: NoSuchFieldException | _: SecurityException => None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+422
to
+436
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. The reflection logic to get
I suggest refactoring this part to un-nest the
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exprToProtoInternal(child, inputs, binding) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .map { childExpr => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val builder = ExprOuterClass.Second.newBuilder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| builder.setChild(childExpr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| val timeZone = timeZoneId.getOrElse("UTC") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| builder.setTimezone(timeZone) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ExprOuterClass.Expr | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .newBuilder() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .setSecond(builder) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .build() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .orElse { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| withInfo(expr, child) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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. Datetime function misplaced in string expressions traitLow Severity
Owner
Author
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. value:good-to-have; category:bug; feedback: The Bugbot AI reviewer is correct! The logic is Time-related, so it should be added to datetime.rs module instead of strings.rs |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,9 +21,11 @@ package org.apache.comet.shims | |
|
|
||
| import org.apache.spark.sql.catalyst.expressions._ | ||
|
|
||
| import org.apache.comet.CometSparkSessionExtensions.withInfo | ||
|
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. These new imports ( Severity: medium Other Locations
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
Owner
Author
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. value:good-to-have; category:bug; feedback: The Augment AI reviewer is correct! The unused imports will lead to warnings (or errors if the project's CI is configured to report warnings as errors). The unused imports should be removed |
||
| import org.apache.comet.expressions.CometEvalMode | ||
| import org.apache.comet.serde.CommonStringExprs | ||
| import org.apache.comet.serde.ExprOuterClass.{BinaryOutputStyle, Expr} | ||
| import org.apache.comet.serde.QueryPlanSerde.exprToProtoInternal | ||
|
|
||
| /** | ||
| * `CometExprShim` acts as a shim for parsing expressions from different Spark versions. | ||
|
|
@@ -43,6 +45,9 @@ trait CometExprShim extends CommonStringExprs { | |
| // Right child is the encoding expression. | ||
| stringDecode(expr, s.charset, s.bin, inputs, binding) | ||
|
|
||
| case _ if expr.getClass.getSimpleName == "SecondOfTime" => | ||
| secondOfTimeToProto(expr, inputs, binding) | ||
|
|
||
| case _ => None | ||
| } | ||
| } | ||
|
|
||


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.
The reflective
timeZoneIdlookup only handles missing method/field;invoke/access/cast can still throw (e.g.,IllegalAccessException,InvocationTargetException,ClassCastException) and crash serde/planning. Consider catchingNonFataland falling back toNone(withwithInfo) instead of letting it propagate.Severity: medium
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
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.
value:useful; category:bug; feedback: The Augment AI reviewer is correct! The SecondsOfTime class has neither timeZoneId method nor a field with that name, so this reflection based lookups always fail. The timezone lookups should be removed and UTC should be used if a timezone is really needed.