protected Optional<RowDataPredicate> generatePredicate(
      final Schema projectedSchema, final ResolvedExpression flinkExpression) {
    if (flinkExpression == null) {
      return Optional.empty();
    }

    final Map<String, Integer> fieldIndexMap = new HashMap<>();
    final Map<String, DataType> fieldDataTypeMap = new HashMap<>();
    List<Types.NestedField> fields = projectedSchema.asStruct().fields();
    for (int i = 0; i < fields.size(); i++) {
      Types.NestedField field = fields.get(i);
      fieldIndexMap.put(field.name(), i);
      fieldDataTypeMap.put(
          field.name(),
          TypeConversions.fromLogicalToDataType(FlinkSchemaUtil.convert(field.type())));
    }

    RowDataPredicateExpressionVisitor visitor =
        generateExpressionVisitor(fieldIndexMap, fieldDataTypeMap);
    return flinkExpression.accept(visitor);
  }
@param tableName tableName
@param mixedFormatDynamicSource underlying source
@param mixedTable mixedTable
@param properties With all mixed-format table properties and sql options
@param tableLoader
amoro-format-mixed/amoro-mixed-flink/v1.15/amoro-mixed-flink-1.15/src/main/java/org/apache/amoro/flink/table/MixedFormatDynamicSource.java