You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@flink.apache.org by GitBox <gi...@apache.org> on 2021/10/19 14:39:42 UTC

[GitHub] [flink] matriv commented on a change in pull request #17522: [FLINK-24462][table] Introduce CastRule interface to reorganize casting code

matriv commented on a change in pull request #17522:
URL: https://github.com/apache/flink/pull/17522#discussion_r731901591



##########
File path: flink-table/flink-table-planner/src/main/java/org/apache/flink/table/data/casting/CastRuleProvider.java
##########
@@ -0,0 +1,155 @@
+/*
+ * 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.data.casting;
+
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.table.data.casting.rules.IdentityCastRule$;
+import org.apache.flink.table.data.casting.rules.TimestampToStringCastRule$;
+import org.apache.flink.table.data.casting.rules.UpcastToBigIntCastRule$;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.LogicalType;
+import org.apache.flink.table.types.logical.LogicalTypeFamily;
+import org.apache.flink.table.types.logical.LogicalTypeRoot;
+
+import javax.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** This class resolves {@link CastRule} starting from the input and the target type. */

Review comment:
       Shouldn't it be `starting from the target type and then the input type` ?

##########
File path: flink-table/flink-table-planner/src/test/java/org/apache/flink/table/data/casting/CastRulesTest.java
##########
@@ -0,0 +1,165 @@
+/*
+ * 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.data.casting;
+
+import org.apache.flink.table.data.StringData;
+import org.apache.flink.table.data.TimestampData;
+import org.apache.flink.table.types.DataType;
+
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Stream;
+
+import static org.apache.flink.table.api.DataTypes.BIGINT;
+import static org.apache.flink.table.api.DataTypes.INT;
+import static org.apache.flink.table.api.DataTypes.SMALLINT;
+import static org.apache.flink.table.api.DataTypes.STRING;
+import static org.apache.flink.table.api.DataTypes.TIMESTAMP;
+import static org.apache.flink.table.api.DataTypes.TIMESTAMP_LTZ;
+import static org.apache.flink.table.api.DataTypes.TINYINT;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+class CastRulesTest {

Review comment:
       Why not `public`?

##########
File path: flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/planner/codegen/calls/ScalarOperatorGens.scala
##########
@@ -916,446 +915,481 @@ object ScalarOperatorGens {
       ctx: CodeGeneratorContext,
       operand: GeneratedExpression,
       targetType: LogicalType)
-    : GeneratedExpression = (operand.resultType.getTypeRoot, targetType.getTypeRoot) match {
+    : GeneratedExpression = {
+    // Try to use the new cast rules
+    val rule = CastRuleProvider.resolve(operand.resultType, targetType)
+    rule match {
+      case codeGeneratorCastRule: CodeGeneratorCastRule[_, _] =>
+        val castContext = new CodeGeneratorCastRule.Context {
+          override def getSessionTimeZoneTerm: String = ctx.addReusableSessionTimeZone()
+        }
+        val castExpression = codeGeneratorCastRule.generate(
+          castContext, operand.resultTerm, operand.resultType, targetType
+        )
+        return generateUnaryOperatorIfNotNull(ctx, castExpression.getReturnType, operand) {
+          _ => s"${castExpression.getCode}"
+        }
+      case _ => if (rule != null) {

Review comment:
       I would remove this code and maybe put it in a gist, and link it to the PR and the jira issue in case it becomes useful in the future.

##########
File path: flink-table/flink-table-planner/src/main/java/org/apache/flink/table/data/casting/CastRuleProvider.java
##########
@@ -0,0 +1,155 @@
+/*
+ * 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.data.casting;
+
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.table.data.casting.rules.IdentityCastRule$;
+import org.apache.flink.table.data.casting.rules.TimestampToStringCastRule$;
+import org.apache.flink.table.data.casting.rules.UpcastToBigIntCastRule$;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.LogicalType;
+import org.apache.flink.table.types.logical.LogicalTypeFamily;
+import org.apache.flink.table.types.logical.LogicalTypeRoot;
+
+import javax.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** This class resolves {@link CastRule} starting from the input and the target type. */
+@Internal
+public class CastRuleProvider {
+
+    /* ------- Entrypoint ------- */
+
+    /**
+     * Resolve a {@link CastRule} for the provided input data type and target data type. Returns
+     * {@code null} if no rule can be resolved.
+     */
+    public static @Nullable CastRule<?, ?> resolve(
+            LogicalType inputDataType, LogicalType targetDataType) {
+        return INSTANCE.internalResolve(inputDataType, targetDataType);
+    }
+
+    /** @see #resolve(LogicalType, LogicalType) */
+    public static @Nullable CastRule<?, ?> resolve(
+            DataType inputDataType, DataType targetDataType) {
+        return resolve(inputDataType.getLogicalType(), targetDataType.getLogicalType());
+    }
+
+    /* ------ Implementation ------ */
+
+    private static final CastRuleProvider INSTANCE = new CastRuleProvider();
+
+    static {
+        INSTANCE.addRule(TimestampToStringCastRule$.MODULE$)
+                .addRule(IdentityCastRule$.MODULE$)
+                .addRule(UpcastToBigIntCastRule$.MODULE$)
+                .freeze();
+    }
+
+    // Map<Target family or root, Map<Input family or root, rule>>
+    private Map<Object, Map<Object, CastRule<?, ?>>> rules = new HashMap<>();
+    private List<CastRule<?, ?>> rulesWithCustomPredicate = new ArrayList<>();
+
+    private CastRuleProvider addRule(CastRule<?, ?> rule) {
+        CastRulePredicate predicate = rule.getPredicateDefinition();
+
+        for (LogicalTypeRoot targetTypeRoot : predicate.getTargetTypes()) {
+            Map<Object, CastRule<?, ?>> map =
+                    rules.computeIfAbsent(targetTypeRoot, k -> new HashMap<>());
+            for (LogicalTypeRoot inputTypeRoot : predicate.getInputTypes()) {
+                map.put(inputTypeRoot, rule);
+            }
+            for (LogicalTypeFamily inputTypeFamily : predicate.getInputTypeFamilies()) {
+                map.put(inputTypeFamily, rule);
+            }
+        }
+        for (LogicalTypeFamily targetTypeFamily : predicate.getTargetTypeFamilies()) {
+            Map<Object, CastRule<?, ?>> map =
+                    rules.computeIfAbsent(targetTypeFamily, k -> new HashMap<>());
+            for (LogicalTypeRoot inputTypeRoot : predicate.getInputTypes()) {
+                map.put(inputTypeRoot, rule);
+            }
+            for (LogicalTypeFamily inputTypeFamily : predicate.getInputTypeFamilies()) {
+                map.put(inputTypeFamily, rule);
+            }
+        }
+
+        if (predicate.getCustomPredicate() != null) {
+            rulesWithCustomPredicate.add(rule);
+        }
+
+        return this;
+    }
+
+    private CastRule<?, ?> internalResolve(LogicalType inputDataType, LogicalType targetDataType) {
+        // Lookup by target type
+        Map<Object, CastRule<?, ?>> inputTypeToCastRuleMap =
+                lookupTypeInMap(rules, targetDataType.getTypeRoot());
+
+        // If nothing found, just return null
+        if (inputTypeToCastRuleMap == null) {
+            return null;
+        }
+
+        CastRule<?, ?> rule = lookupTypeInMap(inputTypeToCastRuleMap, inputDataType.getTypeRoot());
+        if (rule == null) {
+            // Try with the rules using custom predicates
+            rule =
+                    rulesWithCustomPredicate.stream()
+                            .filter(
+                                    r ->
+                                            r.getPredicateDefinition()
+                                                    .getCustomPredicate()
+                                                    .test(inputDataType, targetDataType))
+                            .findFirst()
+                            .orElse(null);
+        }
+
+        return rule;
+    }
+
+    private void freeze() {
+        rules.replaceAll((k, m) -> Collections.unmodifiableMap(m));
+        rules = Collections.unmodifiableMap(rules);
+        rulesWithCustomPredicate = Collections.unmodifiableList(rulesWithCustomPredicate);
+    }
+
+    /**
+     * Function that performs a map lookup first based on the type root, then on any of its
+     * families.
+     */
+    private static <T> T lookupTypeInMap(Map<Object, T> map, LogicalTypeRoot type) {
+        T out = map.get(type);
+        if (out == null) {
+            /* lookup by any family matching */
+            for (LogicalTypeFamily family : type.getFamilies()) {
+                out = map.get(family);
+                if (out != null) {
+                    break;

Review comment:
       ```suggestion
                       return out;
   ```

##########
File path: flink-table/flink-table-common/src/main/java/org/apache/flink/table/data/casting/CastRulePredicate.java
##########
@@ -0,0 +1,147 @@
+/*
+ * 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.data.casting;
+
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.table.types.logical.LogicalType;
+import org.apache.flink.table.types.logical.LogicalTypeFamily;
+import org.apache.flink.table.types.logical.LogicalTypeRoot;
+
+import javax.annotation.Nullable;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.BiPredicate;
+
+/**
+ * In order to apply a {@link CastRule}, the runtime checks if a particular rule matches the tuple
+ * of input and target type using this class. In particular, a rule is applied if:
+ *
+ * <ol>
+ *   <li>{@link #getTargetTypes()} includes the {@link LogicalTypeRoot} of target type and either
+ *       <ol>
+ *         <li>{@link #getInputTypes()} includes the {@link LogicalTypeRoot} of input type or
+ *         <li>{@link #getInputTypeFamilies()} includes one of the {@link LogicalTypeFamily} of
+ *             input type
+ *       </ol>
+ *   <li>Or {@link #getTargetTypeFamilies()} includes one of the {@link LogicalTypeFamily} of target
+ *       type and either
+ *       <ol>
+ *         <li>{@link #getInputTypes()} includes the {@link LogicalTypeRoot} of input type or
+ *         <li>{@link #getInputTypeFamilies()} includes one of the {@link LogicalTypeFamily} of
+ *             input type
+ *       </ol>
+ *   <li>Or, if {@link #getCustomPredicate()} is not null, the input type and target type matches

Review comment:
       Maybe clarify that this is for when we want to match exact concrete types, maybe use an example for when this is useful.

##########
File path: flink-table/flink-table-common/src/main/java/org/apache/flink/table/data/casting/CastRule.java
##########
@@ -0,0 +1,60 @@
+/*
+ * 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.data.casting;
+
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.table.types.logical.LogicalType;
+
+import java.time.ZoneId;
+
+/**
+ * Casting executor factory performs the pre-flight of a casting operation.

Review comment:
       I think `factory` should be changed to something else ?

##########
File path: flink-table/flink-table-common/src/main/java/org/apache/flink/table/data/casting/CastExecutor.java
##########
@@ -0,0 +1,37 @@
+/*
+ * 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.data.casting;
+
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.table.api.TableException;
+
+/**
+ * Interface to model a function that performs the casting of one value to another type.

Review comment:
       ```suggestion
    * Interface to model a function that performs the casting of a value from one type to another.
   ```

##########
File path: flink-table/flink-table-planner/src/main/java/org/apache/flink/table/data/casting/CastRuleProvider.java
##########
@@ -0,0 +1,155 @@
+/*
+ * 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.data.casting;
+
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.table.data.casting.rules.IdentityCastRule$;
+import org.apache.flink.table.data.casting.rules.TimestampToStringCastRule$;
+import org.apache.flink.table.data.casting.rules.UpcastToBigIntCastRule$;
+import org.apache.flink.table.types.DataType;
+import org.apache.flink.table.types.logical.LogicalType;
+import org.apache.flink.table.types.logical.LogicalTypeFamily;
+import org.apache.flink.table.types.logical.LogicalTypeRoot;
+
+import javax.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** This class resolves {@link CastRule} starting from the input and the target type. */
+@Internal
+public class CastRuleProvider {
+
+    /* ------- Entrypoint ------- */
+
+    /**
+     * Resolve a {@link CastRule} for the provided input data type and target data type. Returns
+     * {@code null} if no rule can be resolved.
+     */
+    public static @Nullable CastRule<?, ?> resolve(
+            LogicalType inputDataType, LogicalType targetDataType) {
+        return INSTANCE.internalResolve(inputDataType, targetDataType);
+    }
+
+    /** @see #resolve(LogicalType, LogicalType) */
+    public static @Nullable CastRule<?, ?> resolve(
+            DataType inputDataType, DataType targetDataType) {
+        return resolve(inputDataType.getLogicalType(), targetDataType.getLogicalType());
+    }
+
+    /* ------ Implementation ------ */
+
+    private static final CastRuleProvider INSTANCE = new CastRuleProvider();
+
+    static {
+        INSTANCE.addRule(TimestampToStringCastRule$.MODULE$)
+                .addRule(IdentityCastRule$.MODULE$)
+                .addRule(UpcastToBigIntCastRule$.MODULE$)
+                .freeze();
+    }
+
+    // Map<Target family or root, Map<Input family or root, rule>>
+    private Map<Object, Map<Object, CastRule<?, ?>>> rules = new HashMap<>();
+    private List<CastRule<?, ?>> rulesWithCustomPredicate = new ArrayList<>();
+
+    private CastRuleProvider addRule(CastRule<?, ?> rule) {
+        CastRulePredicate predicate = rule.getPredicateDefinition();
+
+        for (LogicalTypeRoot targetTypeRoot : predicate.getTargetTypes()) {
+            Map<Object, CastRule<?, ?>> map =
+                    rules.computeIfAbsent(targetTypeRoot, k -> new HashMap<>());
+            for (LogicalTypeRoot inputTypeRoot : predicate.getInputTypes()) {
+                map.put(inputTypeRoot, rule);
+            }
+            for (LogicalTypeFamily inputTypeFamily : predicate.getInputTypeFamilies()) {
+                map.put(inputTypeFamily, rule);
+            }
+        }
+        for (LogicalTypeFamily targetTypeFamily : predicate.getTargetTypeFamilies()) {
+            Map<Object, CastRule<?, ?>> map =
+                    rules.computeIfAbsent(targetTypeFamily, k -> new HashMap<>());
+            for (LogicalTypeRoot inputTypeRoot : predicate.getInputTypes()) {
+                map.put(inputTypeRoot, rule);
+            }
+            for (LogicalTypeFamily inputTypeFamily : predicate.getInputTypeFamilies()) {
+                map.put(inputTypeFamily, rule);
+            }
+        }
+
+        if (predicate.getCustomPredicate() != null) {
+            rulesWithCustomPredicate.add(rule);
+        }
+
+        return this;
+    }
+
+    private CastRule<?, ?> internalResolve(LogicalType inputDataType, LogicalType targetDataType) {
+        // Lookup by target type
+        Map<Object, CastRule<?, ?>> inputTypeToCastRuleMap =
+                lookupTypeInMap(rules, targetDataType.getTypeRoot());
+
+        // If nothing found, just return null
+        if (inputTypeToCastRuleMap == null) {
+            return null;

Review comment:
       Why return null here? shouldn't we continue with  the custom predicate rule in this case?

##########
File path: flink-table/flink-table-planner/src/main/scala/org/apache/flink/table/data/casting/rules/AbstractCharacterFamilyTargetRule.scala
##########
@@ -0,0 +1,60 @@
+/*
+ * 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.data.casting.rules
+
+import org.apache.flink.table.data.StringData
+import org.apache.flink.table.data.binary.BinaryStringData
+import org.apache.flink.table.data.casting.{CastExpression, CastRulePredicate, CodeGeneratorCastRule}
+import org.apache.flink.table.planner.codegen.CodeGenUtils.className
+import org.apache.flink.table.types.logical.{CharType, LogicalType, VarCharType}
+
+abstract class AbstractCharacterFamilyTargetRule[IN](predicate: CastRulePredicate)
+  extends AbstractCodeGeneratorCastRule[IN, StringData](predicate) {
+
+  def generateStringExpression(context: CodeGeneratorCastRule.Context,
+                               inputArgumentName: String,
+                               inputLogicalType: LogicalType,
+                               targetLogicalType: LogicalType): String
+
+  override def generate(
+                         context: CodeGeneratorCastRule.Context,
+                         inputArgumentName: String,
+                         inputLogicalType: LogicalType,
+                         targetLogicalType: LogicalType): CastExpression = {
+    val limit: Int = targetLogicalType match {

Review comment:
       I'd suggest to not change/fix behaviour with these PR, just replace existing rules, as a guide for the upcoming changes, but fixing some behaviour in parallel with introducing this new layout can lead to confusion, also with the jira tickets that this PR addresses.

##########
File path: flink-table/flink-table-planner/src/main/java/org/apache/flink/table/data/casting/CastExpression.java
##########
@@ -0,0 +1,56 @@
+/*
+ * 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.data.casting;
+
+import org.apache.flink.table.types.logical.LogicalType;
+
+import java.util.Objects;
+
+/** Generated cast expression result. */

Review comment:
       Could you please make it more descriptive? It holds the code needed by the code generator to perform the actual casting.




-- 
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-unsubscribe@flink.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org