14. Data types of Flink's table api and sql: built-in data types and their attributes

Flink series of articles

1. Links to a series of comprehensive articles such as Flink deployment, concept introduction, source, transformation, sink usage examples, introduction and examples of the four cornerstones

13. Basic concepts of Flink's table api and sql, introduction to general api and getting started examples 14. Data types of Flink's table api and sql
: built-in data types and their attributes
A detailed introduction to dynamic tables, time attribute configuration (how to process update results), temporal tables, joins on streams, certainty on streams, and query configuration

22. Flink's table api and sql create table DDL


Based on the flink1.17 version, this article introduces all the data types of flink, including data type definition, custom data type, type conversion and extraction.
This article is divided into 4 parts, namely data type introduction, data type types, data type conversion and extraction.



Based on the flink1.17 version, this article introduces all the data types of flink, including data type definition, custom data type, type conversion and extraction.
This article is all illustrative, laying the foundation for subsequent use of table api and sql.
This article is divided into four parts, namely data type introduction, data type types, data type conversion and data type extraction.

1. Introduction to Flink SQL data types

1. Data type

In Flink's Table ecosystem, data types describe the logical type of data and can be used to represent the input and output types during the conversion process.
Flink's data types are similar to term data types in the SQL standard, but include nullability of values ​​to facilitate better handling of scalar expressions.

The following are some examples of data types:

INT
INT NOT NULL
INTERVAL DAY TO SECOND(3)
ROW<myField ARRAY<BOOLEAN>, myOtherField TIMESTAMP(3)>

All predefined data types can be found below.

2. Data types in Table API

When defining connectors, catalogs, and user-defined functions, users of JVM-related APIs may use some instances based on org.apache.flink.table.types.DataType in the Table API.
Data type instances have two responsibilities:

  • As a form of logical type, it defines the boundary between the JVM language or Python language and the Table ecosystem, rather than existing in the data transmission process or storage in a specific physical form.
  • Optional: When exchanging data with other APIs, provide Planner with relevant hints about the physical layer of these data.

For JVM-based languages, all predefined data types can be found under org.apache.flink.table.api.DataTypes.

When programming using the Table API, it is recommended to use asterisks to introduce all relevant dependencies for a smoother API usage experience:

import static org.apache.flink.table.api.DataTypes.*;

DataType t = INTERVAL(DAY(), SECOND(3));

In the Table ecosystem, physical cues are needed when data types in SQL need to be mapped to data types in actual programming languages. The physical hints clarify which data format should be used during the correspondence.

For example, when generating data on the source side, it can be stipulated that the logical type of TIMESTAMP should be represented by the class java.sql.Timestamp instead of the default java.time.LocalDateTime class at the bottom layer. Having physical hints helps the Flink runtime convert data into its internal data format based on the provided classes. Also on the sink side, the data format is defined so that data can be obtained and converted from the Flink runtime.

The following example shows how to declare a bridge conversion class:

// 告诉 Flink 运行时使用 java.sql.Timestamp 处理数据,而不是 java.time.LocalDateTime
DataType t = DataTypes.TIMESTAMP(3).bridgedTo(java.sql.Timestamp.class);

// 告诉 Flink 运行时使用基本的 int 数组来处理数据,而不是用包装类 Integer 数组
DataType t = DataTypes.ARRAY(DataTypes.INT().notNull()).bridgedTo(int[].class);

Physical hints are only needed when extending the API. When using predefined source, sink and Flink functions, no physical hints are needed. When writing programs using the Table API, Flink ignores physical hints (such as field.cast(TIMESTAMP(3).bridgedTo(Timestamp.class)))

2. Flink SQL data type types

This section introduces all predefined data types supported by Flink, which may be related to the Flink version. This section introduces Flink version 1.17.
All predefined data types can be viewed through org.apache.flink.table.api.DataTypes.
Insert image description here

1、Character Strings

1)、CHAR

fixed length string

  • sql type
CHAR
CHAR(n)
  • java type
DataTypes.CHAR(n)

When the length of n is not specified, it defaults to 1, and the range of n is [1, 2,147,483,647].
Insert image description here

2)、VARCHAR / STRING

variable length string

  • sql type
VARCHAR
VARCHAR(n)

STRING
  • java type
DataTypes.VARCHAR(n)

DataTypes.STRING()

When n is not specified, it defaults to 1. The range of n is [1, 2, 147, 483, 647].
STRING is VARCHAR(2147483647).
Insert image description here

2、Binary Strings

1)、BINARY

A fixed-length binary string, that is, a sequence of bytes. When n is not specified, it defaults to 1. The range of n is [1, 2, 147, 483, 647].

  • sql type
BINARY
BINARY(n)
  • java type
DataTypes.BINARY(n)

Insert image description here

2)、VARBINARY / BYTES

Variable-length binary string. When n is not specified, it defaults to 1. The range of n is [1, 2, 147, 483, 647].
BYTES is VARBINARY(2147483647).

  • sql type
VARBINARY
VARBINARY(n)

BYTES
  • java type
DataTypes.VARBINARY(n)

DataTypes.BYTES()

Insert image description here

3、Exact Numerics

1)、DECIMAL

Data type for decimal numbers with fixed precision and scale.
DECIMAL(p, s), p is the precision, that is, the number of digits in the number, s is the number of decimal places, the range of p is [1, 38], the range value of s is [0, p], when not specified, the default p is 10, s is 0
NUMERIC(p, s) and DEC(p, s) are the same.

  • sql type
DECIMAL
DECIMAL(p)
DECIMAL(p, s)

DEC
DEC(p)
DEC(p, s)

NUMERIC
NUMERIC(p)
NUMERIC(p, s)
  • java type
DataTypes.DECIMAL(p, s)

Insert image description here

2)、TINYINT

It is a 1-byte signed integer value, the range is [-128, 127]

  • sql type
TINYINT
  • java type
DataTypes.TINYINT()

Insert image description here

3)、SMALLINT

2-byte signed integer number, range is [-32,768, 32,767].

  • sql type
SMALLINT
  • java type
DataTypes.SMALLINT()

Insert image description here

4)、INT

4-byte signed integer number, the range is [-2,147,483,648, 2,147,483,647].
INT is the same as INTEGER.

  • sql type
INT

INTEGER
  • java type
DataTypes.INT()

Insert image description here

5)、BIGINT

An 8-byte signed integer number, the range is [-9,223,372,036,854,775,808, 9,223,372,036,854,775,807].

  • sql type
BIGINT
  • java type
DataTypes.BIGINT()

Insert image description here

4、Approximate Numerics

1)、FLOAT

Data type for 4-byte single-precision floating-point numbers.
In contrast to the SQL standard, this type does not take parameters.

  • sql type
FLOAT
  • java type
DataTypes.FLOAT()

Insert image description here

2)、DOUBLE

Data type for 8-byte double-precision floating-point numbers.
DOUBLE is the same as DOUBLE PRECISION.

  • sql type
DOUBLE

DOUBLE PRECISION
  • java type
DataTypes.DOUBLE()

Insert image description here

5、Date and Time

1)、DATE

A date data type consisting of year-month-day, with values ​​ranging from 0000-01-01 to 9999-12-31.
Compared to the SQL standard, the range starts at 0000.

  • sql type
DATE
  • java type
DataTypes.DATE()

Insert image description here

2)、TIME

Data type for time without time zone, consisting of hours:minutes:seconds[.fractions] with precision up to nanoseconds and values ​​ranging from 00:00:00.0000000000 to 23:59:59.9999999999.
Compared to the SQL standard, leap seconds (23:59:60 and 23:59:61) are not supported. No time zone provided.

The type can be declared with TIME(p), where p is the number of fractional seconds (precision) digits. The value of p must be between 0 and 9 inclusive. If precision is not specified, p equals 0.

  • sql type
TIME
TIME(p)
  • java type
DataTypes.TIME(p)

Insert image description here

3)、TIMESTAMP

Data type of timestamp without time zone, consisting of year-month-day hour:minute:second[.decimal], with precision up to nanoseconds, and value range from 0000-01-01 00:00:00.000000000 to 9999-12- 31 23:59:59.9999999999.

Compared to the SQL standard, leap seconds (23:59:60 and 23:59:61) are not supported and the semantics are closer to java.time.LocalDateTime.

Conversion to and from BIGINT, a JVM long type, is not supported. However, this type is not time zone restricted. For more java.time.Instant class semantics, use TIMESTAMP_LTZ.

Types can be declared using TIMESTAMP(p), where p is the number of fractional seconds (precision). The value of p must be between 0 and 9, inclusive. If precision is not specified, p equals 6.

TIMESTAMP§ without time zone is a synonym for this type.

  • sql type
TIMESTAMP
TIMESTAMP(p)

TIMESTAMP WITHOUT TIME ZONE
TIMESTAMP(p) WITHOUT TIME ZONE
  • java type
DataTypes.TIMESTAMP(p)

Insert image description here

4)、TIMESTAMP WITH TIME ZONE

A data type of a timestamp whose time zone consists of year-month-day hours:minutes:seconds [.fractional] area with up to nanosecond precision and values ​​ranging from 0000-01-01 00:00:00.000000000 +14:59 to 9999 -12-31 23:59:59.9999999999 -14:59.
In contrast to TIMESTAMP_LTZ, time zone offset information is physically stored in each datum. It is used individually for every calculation, visualization or communication with external systems.

  • sql type
TIMESTAMP WITH TIME ZONE
TIMESTAMP(p) WITH TIME ZONE
  • java type
DataTypes.TIMESTAMP_WITH_TIME_ZONE(p)

Insert image description here

5)、TIMESTAMP_LTZ

Data type for timestamp with local time zone, consisting of year-month-day hours:minutes:seconds [.fractional] area with up to nanosecond precision and values ​​ranging from 0000-01-01 00:00:00.000000000 +14:59 To 9999-12-31 23:59:59.9999999999-14:59
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 time zone.
You can use TIMESTAMP_LTZ ( ) declares the type, where p is the number of fractional seconds (precision). The value of p must be between 0 and 9, inclusive. If precision is not specified, p equals 6.

TIMESTAMP§ WITH LOCAL TIME ZONE is a synonym for this type.

  • sql type
TIMESTAMP_LTZ
TIMESTAMP_LTZ(p)

TIMESTAMP WITH LOCAL TIME ZONE
TIMESTAMP(p) WITH LOCAL TIME ZONE
  • java type
DataTypes.TIMESTAMP_LTZ(p)
DataTypes.TIMESTAMP_WITH_LOCAL_TIME_ZONE(p)

Insert image description here

6)、INTERVAL YEAR TO MONTH

A data type of a group of year and month intervals.

This type must be parameterized as one of the following:

  • interval of years,
  • interval of years to months,
  • or interval of months.

The year-month interval consists of +year-month, with values ​​ranging from -9999-11 to +9999-11.
The value representation is the same for all types of resolutions. For example, a month interval of 50 is always expressed in year-to-month interval format (with default year precision): +04-02.
Types can be declared using the above combination, where p is the number of years (year precision). The value of p must be between 1 and 4, inclusive. If year precision is not specified, p equals 2.

  • sql type
INTERVAL YEAR
INTERVAL YEAR(p)
INTERVAL YEAR(p) TO MONTH
INTERVAL MONTH
  • java type
DataTypes.INTERVAL(DataTypes.YEAR())
DataTypes.INTERVAL(DataTypes.YEAR(p))
DataTypes.INTERVAL(DataTypes.YEAR(p), DataTypes.MONTH())
DataTypes.INTERVAL(DataTypes.MONTH())

Insert image description here

7)、INTERVAL DAY TO SECOND

A set of data types for day-time interval types.
This type must be parameterized as one of the following:

  • 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 day-time interval consists of + days hours: months: seconds. decimals, and the value range is -999999 23:59:59.999999999 to +999999 23:59:59.9999999999. The value representation is the same for all types of resolutions. For example, the seconds interval 70 is always expressed in the days-to-seconds interval format (with default precision): +00 00:01:10.000000.

  • sql type
INTERVAL DAY
INTERVAL DAY(p1)
INTERVAL DAY(p1) TO HOUR
INTERVAL DAY(p1) TO MINUTE
INTERVAL DAY(p1) TO SECOND(p2)
INTERVAL HOUR
INTERVAL HOUR TO MINUTE
INTERVAL HOUR TO SECOND(p2)
INTERVAL MINUTE
INTERVAL MINUTE TO SECOND(p2)
INTERVAL SECOND
INTERVAL SECOND(p2)
  • java type
DataTypes.INTERVAL(DataTypes.DAY())
DataTypes.INTERVAL(DataTypes.DAY(p1))
DataTypes.INTERVAL(DataTypes.DAY(p1), DataTypes.HOUR())
DataTypes.INTERVAL(DataTypes.DAY(p1), DataTypes.MINUTE())
DataTypes.INTERVAL(DataTypes.DAY(p1), DataTypes.SECOND(p2))
DataTypes.INTERVAL(DataTypes.HOUR())
DataTypes.INTERVAL(DataTypes.HOUR(), DataTypes.MINUTE())
DataTypes.INTERVAL(DataTypes.HOUR(), DataTypes.SECOND(p2))
DataTypes.INTERVAL(DataTypes.MINUTE())
DataTypes.INTERVAL(DataTypes.MINUTE(), DataTypes.SECOND(p2))
DataTypes.INTERVAL(DataTypes.SECOND())
DataTypes.INTERVAL(DataTypes.SECOND(p2))

Insert image description here

You can declare types using a combination of the above, where p1 is the number of digits in days (day precision) and p2 is the number of decimal places in seconds (decimal precision). The value of P1 must be between 1 and 6 inclusive. The value of P2 must be between 0 and 9 inclusive. If p1 is not specified, it defaults to 2. If p2 is not specified, it defaults to 6.

6、Constructured Data Types

1)、ARRAY

Data type for arrays of elements with the same subtype.
Compared with the SQL standard, the maximum cardinality of an array cannot be specified, but is fixed at 2,147,483,647. Additionally, any valid type is supported as a subtype.

ARRAY, where t is the data type of the contained element.
t ARRAY is a synonym closer to the SQL standard. For example, INT ARRAY is equivalent to ARRAY

  • sql type
ARRAY<t>
t ARRAY
  • java type
DataTypes.ARRAY(t)

Insert image description here

2)、MAP

The data type of an associative array that maps key (including NULL) to value (including NULL). The map cannot contain duplicate keys; each key can be mapped to at most one value.
There are no restrictions on element types; uniqueness must be ensured.
The map type is an extension of the SQL standard.

  • sql type
MAP<kt, vt>
  • java type
DataTypes.MAP(kt, vt)

Insert image description here

MAP<kt, vt>, where kt is the data type of the key elements and vt is the data type of the value elements.

3)、MULTISET

A data type for a multiset (=bag), which, unlike a set, allows multiple instances of a common subtype per element. Every unique value (including NULL) is mapped to a certain multiplicity.
There are no restrictions on element types; uniqueness must be ensured.

  • sql type
MULTISET<t>
t MULTISET
  • java type
DataTypes.MULTISET(t)

Insert image description here

MULTISET, where t is the data type of the contained elements.
t MULTISET is a more SQL standard synonym. For example, INT MULTISET is equivalent to MULTISET.

4)、ROW

The data type for a sequence of fields.
A field consists of a field name, a field type, and an optional description. The most specific type of rows in a table is the row type. In this case, each column of the row corresponds to a field of the row type that has the same ordinal position as the column.
Optional field descriptions simplify handling of complex structures compared to the SQL standard.
ROW is similar to the STRUCT type known from other non-conforming frameworks.

  • sql type
ROW<n0 t0, n1 t1, ...>
ROW<n0 t0 'd0', n1 t1 'd1', ...>

ROW(n0 t0, n1 t1, ...>
ROW(n0 t0 'd0', n1 t1 'd1', ...)
  • java type
DataTypes.ROW(DataTypes.FIELD(n0, t0), DataTypes.FIELD(n1, t1), ...)
DataTypes.ROW(DataTypes.FIELD(n0, t0, d0), DataTypes.FIELD(n1, t1, d1), ...)

Insert image description here

You can use ROW<n0 t0 'd0', n1 t1 'd1', ...> where n is the unique name of the field, t is the logical type of the field, and d is the description of the field.
ROW(…) is a closer SQL standard synonym. For example, ROW(myField INT, myOtherField BOOLEAN) is equivalent to ROW<myField INT, myOtherField BOOLEAN>.

7、User-Defined Data Types

User-defined data types are not yet fully supported. They are currently (as of Flink 1.11) only exposed as unregistered structured types in the parameter and return types of functions.

Structured types are similar to objects in object-oriented programming languages. It contains zero, one or more attributes. Each attribute consists of a name and a type.
There are two structured types, as follows:

  • A type stored in a catalog and identified by a catalog identifier (such as cat.db.MyType). These are equivalent to the SQL standard definitions of structured types.
  • An anonymously defined unregistered type (typically extracted reflectively) identified by an implementing class such as com.myorg.model.MyType. These are useful when defining table procedures programmatically. They allow reuse of existing JVM classes without having to manually define the data type's schema again.

1)、Registered Structured Types

Currently (version 1.17) registered structured types are not supported. Therefore, they cannot be stored in the catalog or referenced in the create table DDL.

2)、Unregistered Structured Types

Unregistered structured types can be created from regular POJOs (Plain Old Java Objects Plain Old Java Objects) using automatic reflection extraction.
Implementing classes of structured types must meet the following requirements:

  • The class must be globally accessible, which means it must be declared public, static and not abstract.
  • The class must provide a default constructor with zero arguments or a full constructor that assigns all fields.
  • All fields of a class must be readable by public declarations or getters following common coding styles (like getField(), isField(), field()).
  • All fields of a class must be writable by a public declaration, a fully-assigned constructor, or a setter following common coding styles (such as setField(…), field(…)).
  • All fields must be implicitly mapped to a data type via reflection extraction, or explicitly mapped to a data type using the @DataTypeHint annotation.
  • Fields declared static or transient are ignored.

Reflective extraction supports arbitrary nesting of fields, as long as the field type does not (transitively) reference itself.
The declared field class (for example, public int age;) must be included in the list of supported JVM bridge classes defined for each data type in this document (for example, .java.lang.Integer or int for INT).

For some classes, annotations are required to map the class to a data type (e.g. @DataTypeHint("DECIMAL(10,2)") assigns a fixed precision and scale to java.math.BigDecimal).

Examples are as follows:

class User {
    
    

    // extract fields automatically
    public int age;
    public String name;

    // enrich the extraction with precision information
    public @DataTypeHint("DECIMAL(10, 2)") BigDecimal totalBalance;

    // enrich the extraction with forcing using RAW types
    public @DataTypeHint("RAW") Class<?> modelClass;
}

DataTypes.of(User.class);

Insert image description here

8、Other Data Types

1)BOOLEAN

Data type of a boolean with a (possibly) three-valued logic of TRUE, FALSE, and UNKNOWN
.

  • sql type
BOOLEAN
  • java type
DataTypes.BOOLEAN()

Insert image description here

2)、RAW

Data type of an arbitrary serialized type. This type is a black box within the table ecosystem and is only deserialized at the edges.
Data type of an arbitrary serialized type. This type is a black box in the table ecosystem and is only deserialized at the edge.
Primitive types are extensions of the SQL standard.

  • sql type
RAW('class', 'snapshot')
  • java type
DataTypes.RAW(class, serializer)

DataTypes.RAW(class)

Insert image description here

The type can be declared using RAW('class', 'snapshot'), where class is the original class and snapshot is the Base64-encoded serialized TypeSerializerSnapshot. Typically, type strings are not declared directly but are generated when retaining the type.

In the API, RAW types can be declared by providing a class + type serializer directly or by passing the class and letting the framework extract the class + type serializer from there.

3)、NULL

A data type used to represent untyped NULL values.
The NULL type is an extension of the SQL standard. The null type has no value other than NULL, so it can be converted to any nullable type similar to JVM semantics.
This type is useful for representing unknown types in API calls that use NULL literals, and for bridging to formats that define such types, such as JSON or Avro.
This type is not very useful in practice and is mentioned here for completeness.

  • sql type
NULL
  • java type
DataTypes.NULL()

Insert image description here

3. Type conversion

1. CAST method

Flink Table API and Flink SQL support conversion from input data types to target data types. Some conversions are guaranteed to succeed no matter what the input value is, while some conversions fail at runtime (that is, it is impossible to convert to a value corresponding to the target data type). For example, converting a value of the INT data type to the STRING data type is guaranteed to be successful, but converting a STRING data type to an INT data type is not guaranteed.

When generating execution plans, Flink's SQL checker will refuse to submit SQL that cannot be directly converted to the target data type and throw a ValidationException exception, such as converting from TIMESTAMP type to INTERVAL type. However, even if some queries pass the validation of SQL checker, they may still fail to convert during runtime, which requires users to handle these failures correctly.

In Flink Table API and Flink SQL, you can use the following two built-in methods to perform conversion operations:

  • CAST: The CAST method defined in the SQL standard. In some query scenarios that are prone to conversion failures, when the actual input data is invalid, the job will fail to run. Type deduction preserves the nullability of the input types.
  • TRY_CAST: An extension of the regular CAST method, returning NULL when the conversion fails. The return value of this method is allowed to be empty.
CAST('42' AS INT) --- 结果返回数字 42INT 格式(非空)
CAST(NULL AS VARCHAR) --- 结果返回 VARCHAR 类型的空值
CAST('non-number' AS INT) --- 抛出异常,并停止作业

TRY_CAST('42' AS INT) --- 结果返回数字 42INT 格式
TRY_CAST(NULL AS VARCHAR) --- 结果返回 VARCHAR 类型的空值
TRY_CAST('non-number' AS INT) --- 结果返回 INT 类型的空值
COALESCE(TRY_CAST('non-number' AS INT), 0) --- 结果返回数字 0INT 格式(非空)

The following table shows the degree of conversion of each type, "Y" means supported, "!" means conversion may fail, and "N" means not supported:
Insert image description here

Note:
All conversions to types with fixed or variable length will clip or fill the data according to the definition of the type.
In scenarios where the TO_TIMESTAMP method and TO_TIMESTAMP_LTZ method are used, do not use CAST or TRY_CAST.
Conversion is supported if and only if conversion is also supported using its internal data structures. The conversion may fail if and only if its internal data structures are used.
Conversion is supported if and only if the class using RAW is the same as the class's serializer.
Conversion is supported if and only if INTERVAL is used to convert "month" to "year".
Conversion is supported if and only if INTERVAL is used to convert "day" to "time".
Please note: Whether it is CAST or TRY_CAST, when the input is NULL, the output is also NULL.

2. Old version CAST method

Users can enable pre-1.15 CAST behavior by setting the parameter table.exec.legacy-cast-behaviour to enabled. In Flink version 1.15, this parameter is disabled by default.

If set to enabled, please note the following issues:

  • Conversion to CHAR/VARCHAR/BINARY/VARBINARY data types is no longer automatically trimmed or padded.
  • When using CAST, the job will no longer stop due to conversion failure, it will only return NULL, but the correct type will not be inferred like TRY_CAST.
  • There will be some slight differences in the conversion results of CHAR/VARCHAR/STRING.

It is not recommended to configure this parameter, but it is strongly recommended to keep this parameter disabled by default in new projects to use the latest version of the CAST method. In the next version, this parameter will be removed.

4. Data type extraction

In many places in the API, Flink tries to use the reflection mechanism to automatically extract the data type from the class information, so as to avoid manually defining the schema repeatedly. However, extracting data types via reflection is not always efficient because logical information may be missing. Therefore, it may be necessary to add additional information near the class or field declaration to support the extraction logic.

The following table lists classes that implicitly map to data types without further information.

If you plan to implement classes in Scala, it is recommended to use wrapper types (such as java.lang.Integer) instead of Scala's primitive types. As shown in the table below, Scala's basic types (such as Int or Double) are compiled into JVM basic types (such as int/double) and produce NOT NULL semantics. Additionally, Scala primitive types used in generics (such as java.util.Map[Int, Double]) are erased during compilation, resulting in class information similar to java.util.Map[java.lang.Object, java .lang.Object].
Insert image description here
Other JVM bridge classes mentioned in this document require the @DataTypeHint annotation.

Data type hints can parameterize or replace the default extraction logic for individual function parameters and return types, structured classes, or fields of structured classes. Implementers can choose how much the default extraction logic should be modified by declaring the @DataTypeHint annotation.

The @DataTypeHint annotation provides a set of optional hint parameters. Some of these parameters are shown in the following examples. More information can be found in the documentation for the annotation classes.

Examples are as follows:

import org.apache.flink.table.annotation.DataTypeHint;

class User {
    
    

    // 使用默认转换类 `java.lang.Integer` 定义 INT 数据类型
    public @DataTypeHint("INT") Object o;

    // 使用显式转换类定义毫秒精度的 TIMESTAMP 数据类型
    public @DataTypeHint(value = "TIMESTAMP(3)", bridgedTo = java.sql.Timestamp.class) Object o;

    // 通过强制使用 RAW 类型来丰富提取
    public @DataTypeHint("RAW") Class<?> modelClass;

    // 定义所有出现的 java.math.BigDecimal(包含嵌套字段)都将被提取为 DECIMAL(12, 2)
    public @DataTypeHint(defaultDecimalPrecision = 12, defaultDecimalScale = 2) AccountStatement stmt;

    // 定义当类型不能映射到数据类型时,总是将其视为 RAW 类型,而不是抛出异常
    public @DataTypeHint(allowRawGlobally = HintFlag.TRUE) ComplexModel model;
}

The above, based on flink version 1.17, introduces all the data types of flink, including data type definition, custom data type, type conversion and extraction.

Guess you like

Origin blog.csdn.net/chenwewi520feng/article/details/131953310