diff --git a/sql/catalyst/src/main/java/org/apache/spark/sql/types/DataTypes.java b/sql/catalyst/src/main/java/org/apache/spark/sql/types/DataTypes.java index d786374f69e20..eac0d91acdba7 100644 --- a/sql/catalyst/src/main/java/org/apache/spark/sql/types/DataTypes.java +++ b/sql/catalyst/src/main/java/org/apache/spark/sql/types/DataTypes.java @@ -94,6 +94,16 @@ public class DataTypes { */ public static final DataType NullType = NullType$.MODULE$; + /** + * Gets the DayTimeIntervalType object. + */ + public static final DataType DayTimeIntervalType = DayTimeIntervalType$.MODULE$; + + /** + * Gets the YearMonthIntervalType object. + */ + public static final DataType YearMonthIntervalType = YearMonthIntervalType$.MODULE$; + /** * Creates an ArrayType by specifying the data type of elements ({@code elementType}). * The field of {@code containsNull} is set to {@code true}. diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/types/DayTimeIntervalType.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/types/DayTimeIntervalType.scala new file mode 100644 index 0000000000000..9060b5e03af43 --- /dev/null +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/types/DayTimeIntervalType.scala @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.spark.sql.types + +import scala.math.Ordering +import scala.reflect.runtime.universe.typeTag + +import org.apache.spark.annotation.Unstable + +/** + * The type represents day-time intervals of the SQL standard. A day-time interval is made up + * of a contiguous subset of the following fields: + * - SECOND, seconds within minutes and possibly fractions of a second [0..59.999999], + * - MINUTE, minutes within hours [0..59], + * - HOUR, hours within days [0..23], + * - DAY, days in the range [0..106751991]. + * + * `DayTimeIntervalType` represents positive as well as negative day-time intervals. + * + * Please use the singleton `DataTypes.DayTimeIntervalType` to refer the type. + * + * @since 3.2.0 + */ +@Unstable +class DayTimeIntervalType private() extends AtomicType { + /** + * Internally, values of day-time intervals are stored in `Long` values as amount of time in terms + * of microseconds that are calculated by the formula: + * -/+ (24*60*60 * DAY + 60*60 * HOUR + 60 * MINUTE + SECOND) * 1000000 + */ + private[sql] type InternalType = Long + + @transient private[sql] lazy val tag = typeTag[InternalType] + + private[sql] val ordering = implicitly[Ordering[InternalType]] + + /** + * The day-time interval type has constant precision. A value of the type always occupies 8 bytes. + * The DAY field is constrained by the upper bound 106751991 to fit to `Long`. + */ + override def defaultSize: Int = 8 + + private[spark] override def asNullable: DayTimeIntervalType = this +} + +/** + * The companion case object and its class is separated so the companion object also subclasses + * the DayTimeIntervalType class. Otherwise, the companion object would be of type + * "DayTimeIntervalType$" in byte code. Defined with a private constructor so the companion object + * is the only possible instantiation. + * + * @since 3.2.0 + */ +@Unstable +case object DayTimeIntervalType extends DayTimeIntervalType diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/types/YearMonthIntervalType.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/types/YearMonthIntervalType.scala new file mode 100644 index 0000000000000..254ecd277aa3e --- /dev/null +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/types/YearMonthIntervalType.scala @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.spark.sql.types + +import scala.math.Ordering +import scala.reflect.runtime.universe.typeTag + +import org.apache.spark.annotation.Unstable + +/** + * The type represents year-month intervals of the SQL standard. A year-month interval is made up + * of a contiguous subset of the following fields: + * - MONTH, months within years [0..11], + * - YEAR, years in the range [0..178956970]. + * + * `YearMonthIntervalType` represents positive as well as negative year-month intervals. + * + * Please use the singleton `DataTypes.YearMonthIntervalType` to refer the type. + * + * @since 3.2.0 + */ +@Unstable +class YearMonthIntervalType private() extends AtomicType { + /** + * Internally, values of year-month intervals are stored in `Int` values as amount of months + * that are calculated by the formula: + * -/+ (12 * YEAR + MONTH) + */ + private[sql] type InternalType = Int + + @transient private[sql] lazy val tag = typeTag[InternalType] + + private[sql] val ordering = implicitly[Ordering[InternalType]] + + /** + * Year-month interval values always occupy 4 bytes. + * The YEAR field is constrained by the upper bound 178956970 to fit to `Int`. + */ + override def defaultSize: Int = 4 + + private[spark] override def asNullable: YearMonthIntervalType = this +} + +/** + * The companion case object and its class is separated so the companion object also subclasses + * the YearMonthIntervalType class. Otherwise, the companion object would be of type + * "YearMonthIntervalType$" in byte code. Defined with a private constructor so the companion object + * is the only possible instantiation. + * + * @since 3.2.0 + */ +@Unstable +case object YearMonthIntervalType extends YearMonthIntervalType diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/types/DataTypeSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/types/DataTypeSuite.scala index 8c2e5db6e9364..b0d09dacd6c22 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/types/DataTypeSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/types/DataTypeSuite.scala @@ -320,6 +320,8 @@ class DataTypeSuite extends SparkFunSuite { checkDefaultSize(CharType(100), 100) checkDefaultSize(VarcharType(5), 5) checkDefaultSize(VarcharType(10), 10) + checkDefaultSize(YearMonthIntervalType, 4) + checkDefaultSize(DayTimeIntervalType, 8) def checkEqualsIgnoreCompatibleNullability( from: DataType,