twalthr commented on code in PR #26638: URL: https://github.com/apache/flink/pull/26638#discussion_r2132132754
########## flink-table/flink-table-common/src/main/java/org/apache/flink/table/api/DataTypes.java: ########## @@ -928,37 +928,88 @@ public static <T> UnresolvedDataType RAW(TypeInformation<T> typeInformation) { } /** - * Data type of a user-defined object structured type. Structured types contain zero, one or - * more attributes. Each attribute consists of a name and a type. A type cannot be defined so - * that one of its attribute types (transitively) uses itself. - * - * <p>There are two kinds of structured types. Types that are stored in a catalog and are - * identified by an {@link ObjectIdentifier} or anonymously defined, unregistered types (usually - * reflectively extracted) that are identified by an implementation {@link Class}. - * - * <p>This method helps in manually constructing anonymous, unregistered types. This is useful - * in cases where the reflective extraction using {@link DataTypes#of(Class)} is not applicable. - * However, {@link DataTypes#of(Class)} is the recommended way of creating inline structured - * types as it also considers {@link DataTypeHint}s. - * - * <p>Structured types are converted to internal data structures by the runtime. The given - * implementation class is only used at the edges of the table ecosystem (e.g. when bridging to - * a function or connector). Serialization and equality ({@code hashCode/equals}) are handled by - * the runtime based on the logical type. An implementation class must offer a default - * constructor with zero arguments or a full constructor that assigns all attributes. - * - * <p>Note: A caller of this method must make sure that the {@link - * DataType#getConversionClass()} of the given fields matches with the attributes of the given - * implementation class, otherwise an exception might be thrown during runtime. + * Data type of a user-defined object structured type. Structured types are identified by a + * class name and contain zero, one or more attributes. Each attribute consists of a name and a + * type. A type cannot be defined in such a way that one of its attribute types (transitively) + * refers to itself. + * + * <p>Compared to {@link #ROW(Field...)}, which may also be considered a "struct-like" type, + * structured types are distinguishable even if they contain the same set of fields. For + * example, "Visit(amount DOUBLE)" is distinct from "Interaction(amount DOUBLE)" due its + * identifier. + * + * <p>This method allows for manually constructing an inline structured type. This is useful in + * cases where the reflective extraction using {@link DataTypes#of(Class)} is not applicable. + * However, {@link DataTypes#of(Class)} is the recommended approach for creating inline + * structured types, as it also considers {@link DataTypeHint}s. + * + * <p>Structured types are internally converted by the system into suitable data structures. + * Serialization and equality checks (e.g. {@code hashCode/equals}) are managed by the system + * based on the logical type. + * + * <p>If an optional implementation class is provided, the system will convert a structured + * object to a JVM object at the edges of the table ecosystem (e.g. when bridging to a function + * or connector). The implementation class must provide either a zero-argument constructor or a + * full constructor that assigns all attributes. The class name does not need to be resolvable + * in the classpath; it may be used solely to distinguish between objects with identical + * attribute sets. However, in Table API and UDF calls, the system will attempt to resolve the + * class name to an actual implementation class. If resolution fails, {@link Row} is used as a + * fallback. + * + * <p>Note: The caller of this method must ensure that the {@link DataType#getConversionClass()} + * of each field matches the corresponding attribute in the implementation class. Otherwise, a + * runtime exception may be thrown. * * @see DataTypes#of(Class) * @see StructuredType */ public static <T> DataType STRUCTURED(Class<T> implementationClass, Field... fields) { // some basic validation of the class to prevent common mistakes validateStructuredClass(implementationClass); + return buildStructuredType(StructuredType.newBuilder(implementationClass), fields); + } - final StructuredType.Builder builder = StructuredType.newBuilder(implementationClass); + /** + * Data type of a user-defined object structured type. Structured types are identified by a + * class name and contain zero, one or more attributes. Each attribute consists of a name and a + * type. A type cannot be defined in such a way that one of its attribute types (transitively) + * refers to itself. + * + * <p>Compared to {@link #ROW(Field...)}, which may also be considered a "struct-like" type, + * structured types are distinguishable even if they contain the same set of fields. For + * example, "Visit(amount DOUBLE)" is distinct from "Interaction(amount DOUBLE)" due its + * identifier. + * + * <p>This method allows for manually constructing an inline structured type. This is useful in + * cases where the reflective extraction using {@link DataTypes#of(Class)} is not applicable. + * However, {@link DataTypes#of(Class)} is the recommended approach for creating inline + * structured types, as it also considers {@link DataTypeHint}s. + * + * <p>Structured types are internally converted by the system into suitable data structures. + * Serialization and equality checks (e.g. {@code hashCode/equals}) are managed by the system + * based on the logical type. + * + * <p>If an optional implementation class is provided, the system will convert a structured + * object to a JVM object at the edges of the table ecosystem (e.g. when bridging to a function + * or connector). The implementation class must provide either a zero-argument constructor or a + * full constructor that assigns all attributes. The class name does not need to be resolvable + * in the classpath; it may be used solely to distinguish between objects with identical + * attribute sets. However, in Table API and UDF calls, the system will attempt to resolve the + * class name to an actual implementation class. If resolution fails, {@link Row} is used as a + * fallback. + * + * <p>Note: The caller of this method must ensure that the {@link DataType#getConversionClass()} + * of each field matches the corresponding attribute in the implementation class. Otherwise, a + * runtime exception may be thrown. + * + * @see DataTypes#of(Class) + * @see StructuredType + */ + public static <T> DataType STRUCTURED(String className, Field... fields) { + return buildStructuredType(StructuredType.newBuilder(className), fields); Review Comment: The builder is currently only used internally, via `DataTypes.STRUCTURED` and other locations. When instantiating the StructuredType we run `checkClassName` which will do the full validation. Additional checks just spam the code. -- 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. To unsubscribe, e-mail: issues-unsubscr...@flink.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org