-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-29774][SQL] Date and Timestamp type +/- null should be null as Postgres #26412
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 11 commits
0b293db
f726297
e7225a3
b925517
cd49411
57b13e9
eab6a83
e8b75ba
02b3738
e89d806
0694e07
0f5618b
efab3ec
1c27be1
5df6980
9817d2d
9808b9c
b190612
e544137
83705fd
846802d
4af7edb
a67be30
9a1affd
ae70022
571225b
6052e5a
928fd86
254d2d2
5dd632c
c84d46e
a44948e
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 |
|---|---|---|
|
|
@@ -34,7 +34,7 @@ import org.apache.spark.sql.catalyst.expressions.aggregate._ | |
| import org.apache.spark.sql.catalyst.expressions.objects._ | ||
| import org.apache.spark.sql.catalyst.plans._ | ||
| import org.apache.spark.sql.catalyst.plans.logical._ | ||
| import org.apache.spark.sql.catalyst.rules._ | ||
| import org.apache.spark.sql.catalyst.rules.{Rule, _} | ||
| import org.apache.spark.sql.catalyst.trees.TreeNodeRef | ||
| import org.apache.spark.sql.catalyst.util.toPrettySQL | ||
| import org.apache.spark.sql.connector.catalog.{CatalogManager, CatalogPlugin, CatalogV2Util, Identifier, LookupCatalog, Table, TableCatalog, TableChange, V1Table} | ||
|
|
@@ -228,6 +228,7 @@ class Analyzer( | |
| ResolveLambdaVariables(conf) :: | ||
| ResolveTimeZone(conf) :: | ||
| ResolveRandomSeed :: | ||
| ResolveBinaryArithmetic(conf) :: | ||
| TypeCoercion.typeCoercionRules(conf) ++ | ||
| extendedResolutionRules : _*), | ||
| Batch("PostgreSQL Dialect", Once, PostgreSQLDialect.postgreSQLDialectRules: _*), | ||
|
|
@@ -246,6 +247,68 @@ class Analyzer( | |
| CleanupAliases) | ||
| ) | ||
|
|
||
| /** | ||
| * For [[UnresolvedAdd]]: | ||
| * 1. If one side is timestamp/date/string and the other side is interval, turns it to | ||
|
||
| * [[TimeAdd]]; | ||
| * 2. else if one side is date, turns it to [[DateAdd]] ; | ||
| * 3. else turns it to [[Add]]. | ||
| * | ||
| * For [[UnresolvedSubtract]]: | ||
| * 1. If the left side is timestamp/date/string and the right side is an interval, turns it to | ||
|
||
| * [[TimeSub]]; | ||
| * 2. else if one side is timestamp and the other side is date/timestamp, turns it to | ||
| * [[SubtractTimestamps]]; | ||
| * 3. else if both side are dates, turns it to [[DateDiff]]/[[SubtractDates]]; | ||
| * 4. else if the left side is date, turns it to [[DateSub]]; | ||
| * 5. else turns it to [[Subtract]]. | ||
| * | ||
| * For [[UnresolvedMultiply]]: | ||
| * 1. If one side is interval and the other side is numeric, turns it to [[MultiplyInterval]]; | ||
| * 2. otherwise, turns it to [[Multiply]]. | ||
| * | ||
| * For [[UnresolvedDivide]]: | ||
| * 1. If the left side is interval and the right side is numeric, turns it to | ||
| * [[DivideInterval]]; | ||
| * 2. otherwise, turns it to [[Divide]]. | ||
| */ | ||
| case class ResolveBinaryArithmetic(conf: SQLConf) extends Rule[LogicalPlan] { | ||
| override def apply(plan: LogicalPlan): LogicalPlan = plan.resolveOperatorsUp { | ||
| case p: LogicalPlan => p.transformExpressionsUp { | ||
| case u @ UnresolvedAdd(l, r) if u.childrenResolved => (l.dataType, r.dataType) match { | ||
| case (TimestampType | DateType | StringType, CalendarIntervalType) => | ||
|
||
| Cast(TimeAdd(l, r), l.dataType) | ||
| case (CalendarIntervalType, TimestampType | DateType | StringType) => | ||
| Cast(TimeAdd(r, l), r.dataType) | ||
| case (DateType, _) => DateAdd(l, r) | ||
cloud-fan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| case (_, DateType) => DateAdd(r, l) | ||
| case (_, _) => Add(l, r) | ||
| } | ||
| case u @ UnresolvedSubtract(l, r) if u.childrenResolved => (l.dataType, r.dataType) match { | ||
| case (TimestampType | DateType | StringType, CalendarIntervalType) => | ||
| Cast(TimeSub(l, r), l.dataType) | ||
|
||
| case (TimestampType, TimestampType | DateType | NullType) => SubtractTimestamps(l, r) | ||
| case (DateType | NullType, TimestampType) => SubtractTimestamps(Cast(l, TimestampType), r) | ||
| case (DateType | NullType, DateType) => if (conf.usePostgreSQLDialect) { | ||
|
||
| DateDiff(l, r) | ||
| } else { | ||
| SubtractDates(l, r) | ||
| } | ||
| case (DateType, _) => DateSub(l, r) | ||
| case (_, _) => Subtract(l, r) | ||
| } | ||
| case u @ UnresolvedMultiply(l, r) if u.childrenResolved => (l.dataType, r.dataType) match { | ||
| case (CalendarIntervalType, _: NumericType | NullType) => MultiplyInterval(l, r) | ||
|
||
| case (_: NumericType | NullType, CalendarIntervalType) => MultiplyInterval(r, l) | ||
|
||
| case (_, _) => Multiply(l, r) | ||
| } | ||
| case u @ UnresolvedDivide(l, r) if u.childrenResolved => (l.dataType, r.dataType) match { | ||
| case (CalendarIntervalType, _: NumericType | NullType) => DivideInterval(l, r) | ||
| case (_, _) => Divide(l, r) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| /** | ||
| * Substitute child plan with WindowSpecDefinitions. | ||
| */ | ||
|
|
||
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.
Why this change?