Search in sources :

Example 1 with SupportsReadingMetadata

use of org.apache.flink.table.connector.source.abilities.SupportsReadingMetadata in project flink by apache.

the class PushProjectIntoTableSourceScanRule method matches.

@Override
public boolean matches(RelOptRuleCall call) {
    final LogicalTableScan scan = call.rel(1);
    final TableSourceTable sourceTable = scan.getTable().unwrap(TableSourceTable.class);
    if (sourceTable == null) {
        return false;
    }
    final DynamicTableSource source = sourceTable.tableSource();
    // The source supports projection push-down.
    if (supportsProjectionPushDown(source)) {
        return Arrays.stream(sourceTable.abilitySpecs()).noneMatch(spec -> spec instanceof ProjectPushDownSpec);
    }
    // (for physical columns) is not supported.
    if (supportsMetadata(source)) {
        if (Arrays.stream(sourceTable.abilitySpecs()).anyMatch(spec -> spec instanceof ReadingMetadataSpec)) {
            return false;
        }
        return ((SupportsReadingMetadata) source).supportsMetadataProjection();
    }
    return false;
}
Also used : ProjectPushDownSpec(org.apache.flink.table.planner.plan.abilities.source.ProjectPushDownSpec) SupportsReadingMetadata(org.apache.flink.table.connector.source.abilities.SupportsReadingMetadata) TableSourceTable(org.apache.flink.table.planner.plan.schema.TableSourceTable) ReadingMetadataSpec(org.apache.flink.table.planner.plan.abilities.source.ReadingMetadataSpec) LogicalTableScan(org.apache.calcite.rel.logical.LogicalTableScan) DynamicTableSource(org.apache.flink.table.connector.source.DynamicTableSource)

Example 2 with SupportsReadingMetadata

use of org.apache.flink.table.connector.source.abilities.SupportsReadingMetadata in project flink by apache.

the class DynamicSourceUtils method validateAndApplyMetadata.

private static void validateAndApplyMetadata(String tableDebugName, ResolvedSchema schema, DynamicTableSource source) {
    final List<MetadataColumn> metadataColumns = extractMetadataColumns(schema);
    if (metadataColumns.isEmpty()) {
        return;
    }
    if (!(source instanceof SupportsReadingMetadata)) {
        throw new ValidationException(String.format("Table '%s' declares metadata columns, but the underlying %s doesn't implement " + "the %s interface. Therefore, metadata cannot be read from the given source.", source.asSummaryString(), DynamicTableSource.class.getSimpleName(), SupportsReadingMetadata.class.getSimpleName()));
    }
    final SupportsReadingMetadata metadataSource = (SupportsReadingMetadata) source;
    final Map<String, DataType> metadataMap = metadataSource.listReadableMetadata();
    metadataColumns.forEach(c -> {
        final String metadataKey = c.getMetadataKey().orElse(c.getName());
        final LogicalType metadataType = c.getDataType().getLogicalType();
        final DataType expectedMetadataDataType = metadataMap.get(metadataKey);
        // check that metadata key is valid
        if (expectedMetadataDataType == null) {
            throw new ValidationException(String.format("Invalid metadata key '%s' in column '%s' of table '%s'. " + "The %s class '%s' supports the following metadata keys for reading:\n%s", metadataKey, c.getName(), tableDebugName, DynamicTableSource.class.getSimpleName(), source.getClass().getName(), String.join("\n", metadataMap.keySet())));
        }
        // check that types are compatible
        if (!supportsExplicitCast(expectedMetadataDataType.getLogicalType(), metadataType)) {
            if (metadataKey.equals(c.getName())) {
                throw new ValidationException(String.format("Invalid data type for metadata column '%s' of table '%s'. " + "The column cannot be declared as '%s' because the type must be " + "castable from metadata type '%s'.", c.getName(), tableDebugName, expectedMetadataDataType.getLogicalType(), metadataType));
            } else {
                throw new ValidationException(String.format("Invalid data type for metadata column '%s' with metadata key '%s' of table '%s'. " + "The column cannot be declared as '%s' because the type must be " + "castable from metadata type '%s'.", c.getName(), metadataKey, tableDebugName, expectedMetadataDataType.getLogicalType(), metadataType));
            }
        }
    });
    metadataSource.applyReadableMetadata(createRequiredMetadataKeys(schema, source), TypeConversions.fromLogicalToDataType(createProducedType(schema, source)));
}
Also used : MetadataColumn(org.apache.flink.table.catalog.Column.MetadataColumn) ValidationException(org.apache.flink.table.api.ValidationException) SupportsReadingMetadata(org.apache.flink.table.connector.source.abilities.SupportsReadingMetadata) DataType(org.apache.flink.table.types.DataType) RelDataType(org.apache.calcite.rel.type.RelDataType) LogicalType(org.apache.flink.table.types.logical.LogicalType)

Example 3 with SupportsReadingMetadata

use of org.apache.flink.table.connector.source.abilities.SupportsReadingMetadata in project flink by apache.

the class ReadingMetadataSpec method apply.

@Override
public void apply(DynamicTableSource tableSource, SourceAbilityContext context) {
    if (tableSource instanceof SupportsReadingMetadata) {
        checkArgument(getProducedType().isPresent());
        DataType producedDataType = TypeConversions.fromLogicalToDataType(getProducedType().get());
        ((SupportsReadingMetadata) tableSource).applyReadableMetadata(metadataKeys, producedDataType);
    } else {
        throw new TableException(String.format("%s does not support SupportsReadingMetadata.", tableSource.getClass().getName()));
    }
}
Also used : TableException(org.apache.flink.table.api.TableException) SupportsReadingMetadata(org.apache.flink.table.connector.source.abilities.SupportsReadingMetadata) DataType(org.apache.flink.table.types.DataType)

Example 4 with SupportsReadingMetadata

use of org.apache.flink.table.connector.source.abilities.SupportsReadingMetadata in project flink by apache.

the class DynamicSourceUtils method pushMetadataProjection.

/**
 * Creates a projection that reorders physical and metadata columns according to the given
 * schema. It casts metadata columns into the expected data type to be accessed by computed
 * columns in the next step. Computed columns are ignored here.
 *
 * @see SupportsReadingMetadata
 */
private static void pushMetadataProjection(FlinkRelBuilder relBuilder, ResolvedSchema schema) {
    final RexBuilder rexBuilder = relBuilder.getRexBuilder();
    final List<String> fieldNames = schema.getColumns().stream().filter(c -> !(c instanceof ComputedColumn)).map(Column::getName).collect(Collectors.toList());
    final List<RexNode> fieldNodes = schema.getColumns().stream().filter(c -> !(c instanceof ComputedColumn)).map(c -> {
        final RelDataType relDataType = relBuilder.getTypeFactory().createFieldTypeFromLogicalType(c.getDataType().getLogicalType());
        if (c instanceof MetadataColumn) {
            final MetadataColumn metadataColumn = (MetadataColumn) c;
            final String metadataKey = metadataColumn.getMetadataKey().orElse(metadataColumn.getName());
            return rexBuilder.makeAbstractCast(relDataType, relBuilder.field(metadataKey));
        } else {
            return relBuilder.field(c.getName());
        }
    }).collect(Collectors.toList());
    relBuilder.projectNamed(fieldNodes, fieldNames, true);
}
Also used : DataType(org.apache.flink.table.types.DataType) ScanRuntimeProvider(org.apache.flink.table.connector.source.ScanTableSource.ScanRuntimeProvider) ChangelogMode(org.apache.flink.table.connector.ChangelogMode) Column(org.apache.flink.table.catalog.Column) ResolvedSchema(org.apache.flink.table.catalog.ResolvedSchema) ShortcutUtils(org.apache.flink.table.planner.utils.ShortcutUtils) RowType(org.apache.flink.table.types.logical.RowType) ScanTableSource(org.apache.flink.table.connector.source.ScanTableSource) FlinkRelBuilder(org.apache.flink.table.planner.calcite.FlinkRelBuilder) MetadataColumn(org.apache.flink.table.catalog.Column.MetadataColumn) ReadableConfig(org.apache.flink.configuration.ReadableConfig) RexNode(org.apache.calcite.rex.RexNode) RowField(org.apache.flink.table.types.logical.RowType.RowField) RelHint(org.apache.calcite.rel.hint.RelHint) Map(java.util.Map) LogicalTypeCasts.supportsExplicitCast(org.apache.flink.table.types.logical.utils.LogicalTypeCasts.supportsExplicitCast) ResolvedCatalogTable(org.apache.flink.table.catalog.ResolvedCatalogTable) ContextResolvedTable(org.apache.flink.table.catalog.ContextResolvedTable) RelDataType(org.apache.calcite.rel.type.RelDataType) DynamicTableSource(org.apache.flink.table.connector.source.DynamicTableSource) TableConfig(org.apache.flink.table.api.TableConfig) WatermarkSpec(org.apache.flink.table.catalog.WatermarkSpec) RexBuilder(org.apache.calcite.rex.RexBuilder) TableException(org.apache.flink.table.api.TableException) Set(java.util.Set) ExpressionConverter(org.apache.flink.table.planner.expressions.converter.ExpressionConverter) RelNode(org.apache.calcite.rel.RelNode) Collectors(java.util.stream.Collectors) SourceAbilitySpec(org.apache.flink.table.planner.plan.abilities.source.SourceAbilitySpec) TableSourceTable(org.apache.flink.table.planner.plan.schema.TableSourceTable) ComputedColumn(org.apache.flink.table.catalog.Column.ComputedColumn) DataStream(org.apache.flink.streaming.api.datastream.DataStream) List(java.util.List) Stream(java.util.stream.Stream) LogicalType(org.apache.flink.table.types.logical.LogicalType) FlinkStatistic(org.apache.flink.table.planner.plan.stats.FlinkStatistic) RowKind(org.apache.flink.types.RowKind) ValidationException(org.apache.flink.table.api.ValidationException) SupportsReadingMetadata(org.apache.flink.table.connector.source.abilities.SupportsReadingMetadata) Internal(org.apache.flink.annotation.Internal) TypeConversions(org.apache.flink.table.types.utils.TypeConversions) ExecutionConfigOptions(org.apache.flink.table.api.config.ExecutionConfigOptions) Collections(java.util.Collections) ScanRuntimeProviderContext(org.apache.flink.table.runtime.connector.source.ScanRuntimeProviderContext) LogicalTableScan(org.apache.calcite.rel.logical.LogicalTableScan) MetadataColumn(org.apache.flink.table.catalog.Column.MetadataColumn) RexBuilder(org.apache.calcite.rex.RexBuilder) ComputedColumn(org.apache.flink.table.catalog.Column.ComputedColumn) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

SupportsReadingMetadata (org.apache.flink.table.connector.source.abilities.SupportsReadingMetadata)4 DataType (org.apache.flink.table.types.DataType)3 LogicalTableScan (org.apache.calcite.rel.logical.LogicalTableScan)2 RelDataType (org.apache.calcite.rel.type.RelDataType)2 TableException (org.apache.flink.table.api.TableException)2 ValidationException (org.apache.flink.table.api.ValidationException)2 MetadataColumn (org.apache.flink.table.catalog.Column.MetadataColumn)2 DynamicTableSource (org.apache.flink.table.connector.source.DynamicTableSource)2 TableSourceTable (org.apache.flink.table.planner.plan.schema.TableSourceTable)2 LogicalType (org.apache.flink.table.types.logical.LogicalType)2 Collections (java.util.Collections)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 Collectors (java.util.stream.Collectors)1 Stream (java.util.stream.Stream)1 RelNode (org.apache.calcite.rel.RelNode)1 RelHint (org.apache.calcite.rel.hint.RelHint)1 RexBuilder (org.apache.calcite.rex.RexBuilder)1 RexNode (org.apache.calcite.rex.RexNode)1