twalthr commented on a change in pull request #8360: 
[FLINK-12393][table-common] Add the user-facing classes of the new type system
URL: https://github.com/apache/flink/pull/8360#discussion_r282348005
 
 

 ##########
 File path: 
flink-table/flink-table-common/src/main/java/org/apache/flink/table/api/DataTypes.java
 ##########
 @@ -0,0 +1,703 @@
+/*
+ * 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.flink.table.api;
+
+import org.apache.flink.annotation.PublicEvolving;
+import org.apache.flink.api.common.ExecutionConfig;
+import org.apache.flink.api.common.typeinfo.TypeInformation;
+import org.apache.flink.api.common.typeutils.TypeSerializer;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.AnyType;
+import org.apache.flink.table.types.logical.ArrayType;
+import org.apache.flink.table.types.logical.BigIntType;
+import org.apache.flink.table.types.logical.BinaryType;
+import org.apache.flink.table.types.logical.BooleanType;
+import org.apache.flink.table.types.logical.CharType;
+import org.apache.flink.table.types.logical.DateType;
+import org.apache.flink.table.types.logical.DayTimeIntervalType;
+import 
org.apache.flink.table.types.logical.DayTimeIntervalType.DayTimeResolution;
+import org.apache.flink.table.types.logical.DecimalType;
+import org.apache.flink.table.types.logical.DoubleType;
+import org.apache.flink.table.types.logical.FloatType;
+import org.apache.flink.table.types.logical.IntType;
+import org.apache.flink.table.types.logical.LocalZonedTimestampType;
+import org.apache.flink.table.types.logical.LogicalType;
+import org.apache.flink.table.types.logical.MapType;
+import org.apache.flink.table.types.logical.MultisetType;
+import org.apache.flink.table.types.logical.NullType;
+import org.apache.flink.table.types.logical.RowType;
+import org.apache.flink.table.types.logical.SmallIntType;
+import org.apache.flink.table.types.logical.TimeType;
+import org.apache.flink.table.types.logical.TimestampType;
+import org.apache.flink.table.types.logical.TinyIntType;
+import org.apache.flink.table.types.logical.TypeInformationAnyType;
+import org.apache.flink.table.types.logical.VarBinaryType;
+import org.apache.flink.table.types.logical.VarCharType;
+import org.apache.flink.table.types.logical.YearMonthIntervalType;
+import 
org.apache.flink.table.types.logical.YearMonthIntervalType.YearMonthResolution;
+import org.apache.flink.table.types.logical.ZonedTimestampType;
+import org.apache.flink.util.Preconditions;
+
+import javax.annotation.Nullable;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.BiFunction;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * A {@link DataType} can be used to declare input and/or output types of 
operations. This class
+ * enumerates all supported data types of the Table & SQL API.
+ */
+@PublicEvolving
+public final class DataTypes {
+
+       // we use SQL-like naming for data types and avoid Java keyword clashes
+       // CHECKSTYLE.OFF: MethodName
+
+       /**
+        * Data type of a fixed-length character string {@code CHAR(n)} where 
{@code n} is the number
+        * of code points. {@code n} must have a value between 1 and 255 (both 
inclusive).
+        *
+        * @see CharType
+        */
+       public static DataType.AtomicDataType CHAR(int n) {
+               return new DataType.AtomicDataType(new CharType(n));
+       }
+
+       /**
+        * Data type of a variable-length character string {@code VARCHAR(n)} 
where {@code n} is the
+        * maximum number of code points. {@code n} must have a value between 1 
and {@link Integer#MAX_VALUE}
+        * (both inclusive).
+        *
+        * @see VarCharType
+        */
+       public static DataType.AtomicDataType VARCHAR(int n) {
+               return new DataType.AtomicDataType(new VarCharType(n));
+       }
+
+       /**
+        * Data type of a variable-length character string with defined maximum 
length. This is a shortcut
+        * for {@code VARCHAR(2147483647)} for representing JVM strings.
+        *
+        * @see VarCharType
+        */
+       public static DataType.AtomicDataType STRING() {
+               return VARCHAR(Integer.MAX_VALUE);
+       }
+
+       /**
+        * Data type of a boolean with a (possibly) three-valued logic of 
{@code TRUE, FALSE, UNKNOWN}.
+        *
+        * @see BooleanType
+        */
+       public static DataType.AtomicDataType BOOLEAN() {
+               return new DataType.AtomicDataType(new BooleanType());
+       }
+
+       /**
+        * Data type of a fixed-length binary string (=a sequence of bytes) 
{@code BINARY(n)} where
+        * {@code n} is the number of bytes. {@code n} must have a value 
between 1 and {@link Integer#MAX_VALUE}
+        * (both inclusive).
+        *
+        * @see BinaryType
+        */
+       public static DataType.AtomicDataType BINARY(int n) {
+               return new DataType.AtomicDataType(new BinaryType(n));
+       }
+
+       /**
+        * Data type of a variable-length binary string (=a sequence of bytes) 
{@code VARBINARY(n)} where
+        * {@code n} is the maximum number of bytes. {@code n} must have a 
value between 1 and {@link Integer#MAX_VALUE}
+        * (both inclusive).
+        *
+        * @see VarBinaryType
+        */
+       public static DataType.AtomicDataType VARBINARY(int n) {
+               return new DataType.AtomicDataType(new VarBinaryType(n));
+       }
+
+       /**
+        * Data type of a variable-length binary string (=a sequence of bytes) 
with defined maximum length.
+        * This is a shortcut for {@code VARBINARY(2147483647)} for 
representing JVM byte arrays.
+        *
+        * @see VarBinaryType
+        */
+       public static DataType.AtomicDataType BYTES() {
+               return VARBINARY(Integer.MAX_VALUE);
+       }
+
+       /**
+        * Data type of a decimal number with fixed precision and scale {@code 
DECIMAL(p, s)} where {@code p}
+        * is the number of digits in a number (=precision) and {@code s} is 
the number of digits to the
+        * right of the decimal point in a number (=scale). {@code p} must have 
a value between 1 and 38
+        * (both inclusive). {@code s} must have a value between 0 and {@code 
p} (both inclusive).
+        *
+        * @see DecimalType
+        */
+       public static DataType.AtomicDataType DECIMAL(int precision, int scale) 
{
+               return new DataType.AtomicDataType(new DecimalType(precision, 
scale));
+       }
+
+       /**
+        * Data type of a 1-byte signed integer with values from -128 to 127.
+        *
+        * @see TinyIntType
+        */
+       public static DataType.AtomicDataType TINYINT() {
+               return new DataType.AtomicDataType(new TinyIntType());
+       }
+
+       /**
+        * Data type of a 2-byte signed integer with values from -32,768 to 
32,767.
+        *
+        * @see SmallIntType
+        */
+       public static DataType.AtomicDataType SMALLINT() {
+               return new DataType.AtomicDataType(new SmallIntType());
+       }
+
+       /**
+        * Data type of a 4-byte signed integer with values from -2,147,483,648 
to 2,147,483,647.
+        *
+        * @see IntType
+        */
+       public static DataType.AtomicDataType INT() {
+               return new DataType.AtomicDataType(new IntType());
+       }
+
+       /**
+        * Data type of an 8-byte signed integer with values from 
-9,223,372,036,854,775,808 to
+        * 9,223,372,036,854,775,807.
+        *
+        * @see BigIntType
+        */
+       public static DataType.AtomicDataType BIGINT() {
+               return new DataType.AtomicDataType(new BigIntType());
+       }
+
+       /**
+        * Data type of a 4-byte single precision floating point number.
+        *
+        * @see FloatType
+        */
+       public static DataType.AtomicDataType FLOAT() {
+               return new DataType.AtomicDataType(new FloatType());
+       }
+
+       /**
+        * Data type of an 8-byte double precision floating point number.
+        *
+        * @see DoubleType
+        */
+       public static DataType.AtomicDataType DOUBLE() {
+               return new DataType.AtomicDataType(new DoubleType());
+       }
+
+       /**
+        * Data type of a date consisting of {@code year-month-day} with values 
ranging from {@code 0000-01-01}
+        * to {@code 9999-12-31}.
+        *
+        * <p>Compared to the SQL standard, the range starts at year {@code 
0000}.
+        *
+        * @see DataType
+        */
+       public static DataType.AtomicDataType DATE() {
+               return new DataType.AtomicDataType(new DateType());
+       }
+
+       /**
+        * Data type of a time WITHOUT time zone {@code TIME(p)} where {@code 
p} is the number of digits
+        * of fractional seconds (=precision). {@code p} must have a value 
between 0 and 9 (both inclusive).
+        *
+        * <p>An instance consists of {@code hour:minute:second[.fractional]} 
with up to nanosecond precision
+        * and values ranging from {@code 00:00:00.000000000} to {@code 
23:59:59.999999999}.
+        *
+        * <p>Compared to the SQL standard, leap seconds (23:59:60 and 
23:59:61) are not supported as the
+        * semantics are closer to {@link java.time.LocalTime}. A time WITH 
time zone is not provided.
+        *
+        * @see TimeType
+        */
+       public static DataType.AtomicDataType TIME(int precision) {
+               return new DataType.AtomicDataType(new TimeType(precision));
+       }
+
+       /**
+        * Data type of a timestamp WITHOUT time zone {@code TIMESTAMP(p)} 
where {@code p} is the number
+        * of digits of fractional seconds (=precision). {@code p} must have a 
value between 0 and 9 (both
+        * inclusive).
+        *
+        * <p>An instance consists of {@code year-month-day 
hour:minute:second[.fractional]} with up to
+        * nanosecond precision and values ranging from {@code 0000-01-01 
00:00:00.000000000} to
+        * {@code 9999-12-31 23:59:59.999999999}.
+        *
+        * <p>Compared to the SQL standard, leap seconds (23:59:60 and 
23:59:61) are not supported as the
+        * semantics are closer to {@link java.time.LocalDateTime}.
+        *
+        * @see #TIMESTAMP_WITH_TIME_ZONE(int)
+        * @see #TIMESTAMP_WITH_LOCAL_TIME_ZONE(int)
+        * @see TimestampType
+        */
+       public static DataType.AtomicDataType TIMESTAMP(int precision) {
+               return new DataType.AtomicDataType(new 
TimestampType(precision));
+       }
+
+       /**
+        * Data type of a timestamp WITH time zone {@code TIMESTAMP(p) WITH 
TIME ZONE} where {@code p} is
+        * the number of digits of fractional seconds (=precision). {@code p} 
must have a value between 0
+        * and 9 (both inclusive).
+        *
+        * <p>An instance consists of {@code year-month-day 
hour:minute:second[.fractional] zone} with up
+        * to nanosecond precision and values ranging from {@code 0000-01-01 
00:00:00.000000000 +14:59} to
+        * {@code 9999-12-31 23:59:59.999999999 -14:59}.
+        *
+        * <p>Compared to the SQL standard, leap seconds (23:59:60 and 
23:59:61) are not supported as the
+        * semantics are closer to {@link java.time.OffsetDateTime}.
+        *
+        * @see #TIMESTAMP(int)
+        * @see #TIMESTAMP_WITH_LOCAL_TIME_ZONE(int)
+        * @see ZonedTimestampType
+        */
+       public static DataType.AtomicDataType TIMESTAMP_WITH_TIME_ZONE(int 
precision) {
+               return new DataType.AtomicDataType(new 
ZonedTimestampType(precision));
+       }
+
+       /**
+        * Data type of a timestamp WITH LOCAL time zone {@code TIMESTAMP(p) 
WITH LOCAL TIME ZONE} where
+        * {@code p} is the number of digits of fractional seconds 
(=precision). {@code p} must have a value
+        * between 0 and 9 (both inclusive).
+        *
+        * <p>An instance consists of {@code year-month-day 
hour:minute:second[.fractional] zone} with up
+        * to nanosecond precision and values ranging from {@code 0000-01-01 
00:00:00.000000000 +14:59} to
+        * {@code 9999-12-31 23:59:59.999999999 -14:59}. Leap seconds (23:59:60 
and 23:59:61) are not supported
+        * as the semantics are closer to {@link java.time.OffsetDateTime}.
+        *
+        * <p>Compared to {@link ZonedTimestampType}, the time zone offset 
information is not stored physically
+        * in every datum. Instead, the type assumes {@link java.time.Instant} 
semantics in UTC time zone
+        * at the edges of the table ecosystem. Every datum is interpreted in 
the local time zone configured
+        * in the current session for computation and visualization.
+        *
+        * <p>This type fills the gap between time zone free and time zone 
mandatory timestamp types by
+        * allowing the interpretation of UTC timestamps according to the 
configured session timezone.
+        *
+        * @see #TIMESTAMP(int)
+        * @see #TIMESTAMP_WITH_TIME_ZONE(int)
+        * @see LocalZonedTimestampType
+        */
+       public static DataType.AtomicDataType 
TIMESTAMP_WITH_LOCAL_TIME_ZONE(int precision) {
+               return new DataType.AtomicDataType(new 
LocalZonedTimestampType(precision));
+       }
+
+       /**
+        * Data type of a temporal interval. There are two types of temporal 
intervals: day-time intervals
+        * with up to nanosecond granularity or year-month intervals with up to 
month granularity.
+        *
+        * <p>An interval of day-time consists of {@code +days 
hours:months:seconds.fractional} with values
+        * ranging from {@code -999999 23:59:59.999999999} to {@code +999999 
23:59:59.999999999}. The type
+        * must be parameterized to one of the following resolutions: interval 
of days, interval of days to
+        * hours, interval of days to minutes, interval of days to seconds, 
interval of hours, interval of
+        * hours to minutes, interval of hours to seconds, interval of minutes, 
interval of minutes to seconds,
+        * or interval of seconds. The value representation is the same for all 
types of resolutions. For
+        * example, an interval of seconds of 70 is always represented in an 
interval-of-days-to-seconds
+        * format (with default precisions): {@code +00 00:01:10.000000}).
+        *
+        * <p>An interval of year-month consists of {@code +years-months} with 
values ranging from {@code -9999-11}
+        * to {@code +9999-11}. The type must be parameterized to one of the 
following resolutions: interval
+        * of years, interval of years to months, or interval of months. The 
value representation is the
+        * same for all types of resolutions. For example, an interval of 
months of 50 is always represented
+        * in an interval-of-years-to-months format (with default year 
precision): {@code +04-02}.
+        *
+        * <p>Examples: {@code INTERVAL(DAY(2))} for a day-time interval or 
{@code INTERVAL(YEAR(4))} for
+        * a year-month interval.
+        *
+        * @see DayTimeIntervalType
+        * @see YearMonthIntervalType
+        */
+       public static DataType.AtomicDataType INTERVAL(Resolution resolution) {
+               Preconditions.checkNotNull(resolution, "Interval resolution 
must not be null.");
+               return new 
DataType.AtomicDataType(Resolution.resolveInterval(resolution, null));
+       }
+
+       /**
+        * Data type of a temporal interval. There are two types of temporal 
intervals: day-time intervals
+        * with up to nanosecond granularity or year-month intervals with up to 
month granularity.
+        *
+        * <p>An interval of day-time consists of {@code +days 
hours:months:seconds.fractional} with values
+        * ranging from {@code -999999 23:59:59.999999999} to {@code +999999 
23:59:59.999999999}. The type
+        * must be parameterized to one of the following resolutions: interval 
of days, interval of days to
+        * hours, interval of days to minutes, interval of days to seconds, 
interval of hours, interval of
+        * hours to minutes, interval of hours to seconds, interval of minutes, 
interval of minutes to seconds,
+        * or interval of seconds. The value representation is the same for all 
types of resolutions. For
+        * example, an interval of seconds of 70 is always represented in an 
interval-of-days-to-seconds
+        * format (with default precisions): {@code +00 00:01:10.000000}).
+        *
+        * <p>An interval of year-month consists of {@code +years-months} with 
values ranging from {@code -9999-11}
+        * to {@code +9999-11}. The type must be parameterized to one of the 
following resolutions: interval
+        * of years, interval of years to months, or interval of months. The 
value representation is the
+        * same for all types of resolutions. For example, an interval of 
months of 50 is always represented
+        * in an interval-of-years-to-months format (with default year 
precision): {@code +04-02}.
+        *
+        * <p>Examples: {@code INTERVAL(DAY(2), SECOND(9))} for a day-time 
interval or {@code INTERVAL(YEAR(4), MONTH())}
+        * for a year-month interval.
+        *
+        * @see DayTimeIntervalType
+        * @see YearMonthIntervalType
+        */
+       public static DataType.AtomicDataType INTERVAL(Resolution 
upperResolution, Resolution lowerResolution) {
+               Preconditions.checkNotNull(upperResolution, "Upper interval 
resolution must not be null.");
+               Preconditions.checkNotNull(lowerResolution, "Lower interval 
resolution must not be null.");
+               return new 
DataType.AtomicDataType(Resolution.resolveInterval(upperResolution, 
lowerResolution));
+       }
+
+       /**
+        * Data type of an array of elements with same subtype.
+        *
+        * <p>Compared to the SQL standard, the maximum cardinality of an array 
cannot be specified but
+        * is fixed at {@link Integer#MAX_VALUE}. Also, any valid type is 
supported as a subtype.
+        *
+        * @see ArrayType
+        */
+       public static DataType.ElementDataType ARRAY(DataType elementDataType) {
+               Preconditions.checkNotNull(elementDataType, "Element data type 
must not be null.");
+               return new DataType.ElementDataType(new 
ArrayType(elementDataType.getLogicalType()), elementDataType);
+       }
+
+       /**
+        * Data type of a multiset (=bag). Unlike a set, it allows for multiple 
instances for each of its
+        * elements with a common subtype. Each unique value (including {@code 
NULL}) is mapped to some
+        * multiplicity.
+        *
+        * <p>There is no restriction of element types; it is the 
responsibility of the user to ensure
+        * uniqueness.
+        *
+        * @see MultisetType
+        */
+       public static DataType.ElementDataType MULTISET(DataType 
elementDataType) {
+               Preconditions.checkNotNull(elementDataType, "Element data type 
must not be null.");
+               return new DataType.ElementDataType(new 
MultisetType(elementDataType.getLogicalType()), elementDataType);
+       }
+
+       /**
+        * Data type of an associative array that maps keys (including {@code 
NULL}) to values (including
+        * {@code NULL}). A map cannot contain duplicate keys; each key can map 
to at most one value.
+        *
+        * <p>There is no restriction of key types; it is the responsibility of 
the user to ensure uniqueness.
+        * The map type is an extension to the SQL standard.
+        *
+        * @see MapType
+        */
+       public static DataType.KeyValueDataType MAP(DataType keyDataType, 
DataType valueDataType) {
+               Preconditions.checkNotNull(keyDataType, "Key data type must not 
be null.");
+               Preconditions.checkNotNull(valueDataType, "Value data type must 
not be null.");
+               return new DataType.KeyValueDataType(
+                       new MapType(keyDataType.getLogicalType(), 
valueDataType.getLogicalType()),
+                       keyDataType,
+                       valueDataType);
+       }
+
+       /**
+        * Data type of a sequence of fields. A field consists of a field name, 
field type, and an optional
+        * description. The most specific type of a row of a table is a row 
type. In this case, each column
+        * of the row corresponds to the field of the row type that has the 
same ordinal position as the
+        * column.
+        *
+        * <p>Compared to the SQL standard, an optional field description 
simplifies the handling with
+        * complex structures.
+        *
+        * @see RowType
+        */
+       public static DataType.FieldsDataType ROW(Field... fields) {
+               final List<RowType.RowField> logicalFields = Stream.of(fields)
+                       .map(f -> Preconditions.checkNotNull(f, "Field 
definition must not be null."))
+                       .map(f -> new RowType.RowField(f.name, 
f.dataType.getLogicalType(), f.description))
+                       .collect(Collectors.toList());
+               final Map<String, DataType> fieldDataTypes = Stream.of(fields)
+                       .collect(Collectors.toMap(f -> f.name, f -> 
f.dataType));
+               return new DataType.FieldsDataType(new RowType(logicalFields), 
fieldDataTypes);
+       }
+
+       /**
+        * Data type for representing untyped {@code NULL} values. A null type 
has no other value except
+        * {@code NULL}, thus, it can be cast to any nullable type similar to 
JVM semantics.
+        *
+        * <p>This type helps in representing unknown types in API calls that 
use a {@code NULL} literal
+        * as well as bridging to formats such as JSON or Avro that define such 
a type as well.
+        *
+        * <p>The null type is an extension to the SQL standard.
+        *
+        * @see NullType
+        */
+       public static DataType.AtomicDataType NULL() {
+               return new DataType.AtomicDataType(new NullType());
+       }
+
+       /**
+        * Data type of an arbitrary serialized type. This type is a black box 
within the table ecosystem
+        * and is only deserialized at the edges.
+        *
+        * <p>The any type is an extension to the SQL standard.
+        *
+        * <p>This method assumes that a {@link TypeSerializer} instance is 
present. Use {@link #ANY(TypeInformation)}
+        * for generating a serializer from Flink's core type system 
automatically in subsequent layers.
+        *
+        * @param clazz originating value class
+        * @param serializer type serializer
+        *
+        * @see AnyType
+        */
+       public static <T> DataType.AtomicDataType ANY(Class<T> clazz, 
TypeSerializer<T> serializer) {
+               return new DataType.AtomicDataType(new AnyType<>(clazz, 
serializer));
+       }
+
+       /**
+        * Data type of an arbitrary serialized type backed by {@link 
TypeInformation}. This type is
+        * a black box within the table ecosystem and is only deserialized at 
the edges.
+        *
+        * <p>The any type is an extension to the SQL standard.
+        *
+        * <p>Compared to an {@link #ANY(Class, TypeSerializer)}, this type 
does not contain a {@link TypeSerializer}
+        * yet. The serializer will be generated from the enclosed {@link 
TypeInformation} but needs access
+        * to the {@link ExecutionConfig} of the current execution environment. 
Thus, this type is just a
+        * placeholder.
+        *
+        * @see TypeInformationAnyType
+        */
+       public static <T> DataType.AtomicDataType ANY(TypeInformation<T> 
typeInformation) {
+               return new DataType.AtomicDataType(new 
TypeInformationAnyType<>(typeInformation));
+       }
+
+       // 
--------------------------------------------------------------------------------------------
+       // Helper functions
+       // 
--------------------------------------------------------------------------------------------
+
+       /**
+        * Resolution in seconds and (possibly) fractional seconds. The 
precision is the number of
+        * digits of fractional seconds. It must have a value between 0 and 9 
(both inclusive). If
+        * no fractional is specified, it is equal to 6 by default.
+        */
+       public static Resolution SECOND(int precision) {
+               return new Resolution(Resolution.IntervalUnit.SECOND, 
precision);
+       }
+
+       /**
+        * Resolution in minutes.
+        */
+       public static Resolution MINUTE() {
+               return new Resolution(Resolution.IntervalUnit.MINUTE);
+       }
+
+       /**
+        * Resolution in hours.
+        */
+       public static Resolution HOUR() {
+               return new Resolution(Resolution.IntervalUnit.HOUR);
+       }
+
+       /**
+        * Resolution in days. The precision is the number of digits of days. 
It must have a value
+        * between 1 and 6 (both inclusive). If no precision is specified, it 
is equal to 2 by default.
+        */
+       public static Resolution DAY(int precision) {
 
 Review comment:
   Sounds good.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to