Search in sources :

Example 6 with VirtualColumn

use of org.apache.druid.segment.VirtualColumn in project druid by druid-io.

the class VirtualColumnsTest method testSerde.

@Test
public void testSerde() throws Exception {
    final ObjectMapper mapper = TestHelper.makeJsonMapper();
    final ImmutableList<VirtualColumn> theColumns = ImmutableList.of(new ExpressionVirtualColumn("expr", "x + y", ColumnType.FLOAT, TestExprMacroTable.INSTANCE), new ExpressionVirtualColumn("expr2", "x + z", ColumnType.FLOAT, TestExprMacroTable.INSTANCE));
    final VirtualColumns virtualColumns = VirtualColumns.create(theColumns);
    Assert.assertEquals(virtualColumns, mapper.readValue(mapper.writeValueAsString(virtualColumns), VirtualColumns.class));
    Assert.assertEquals(theColumns, mapper.readValue(mapper.writeValueAsString(virtualColumns), mapper.getTypeFactory().constructParametricType(List.class, VirtualColumn.class)));
}
Also used : VirtualColumn(org.apache.druid.segment.VirtualColumn) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) VirtualColumns(org.apache.druid.segment.VirtualColumns) InitializedNullHandlingTest(org.apache.druid.testing.InitializedNullHandlingTest) Test(org.junit.Test)

Example 7 with VirtualColumn

use of org.apache.druid.segment.VirtualColumn in project druid by druid-io.

the class ScanQueryQueryToolChest method resultArraySignature.

@Override
public RowSignature resultArraySignature(final ScanQuery query) {
    if (query.getColumns() == null || query.getColumns().isEmpty()) {
        // will include none of them.
        return RowSignature.empty();
    } else {
        final RowSignature.Builder builder = RowSignature.builder();
        if (query.withNonNullLegacy(scanQueryConfig).isLegacy()) {
            builder.add(ScanQueryEngine.LEGACY_TIMESTAMP_KEY, null);
        }
        for (String columnName : query.getColumns()) {
            // With the Scan query we only know the columnType for virtual columns. Let's report those, at least.
            final ColumnType columnType;
            final VirtualColumn virtualColumn = query.getVirtualColumns().getVirtualColumn(columnName);
            if (virtualColumn != null) {
                columnType = virtualColumn.capabilities(columnName).toColumnType();
            } else {
                // Unknown type. In the future, it would be nice to have a way to fill these in.
                columnType = null;
            }
            builder.add(columnName, columnType);
        }
        return builder.build();
    }
}
Also used : ColumnType(org.apache.druid.segment.column.ColumnType) VirtualColumn(org.apache.druid.segment.VirtualColumn) RowSignature(org.apache.druid.segment.column.RowSignature)

Example 8 with VirtualColumn

use of org.apache.druid.segment.VirtualColumn in project druid by druid-io.

the class ArrayConcatSqlAggregator method toDruidAggregation.

@Nullable
@Override
public Aggregation toDruidAggregation(PlannerContext plannerContext, RowSignature rowSignature, VirtualColumnRegistry virtualColumnRegistry, RexBuilder rexBuilder, String name, AggregateCall aggregateCall, Project project, List<Aggregation> existingAggregations, boolean finalizeAggregations) {
    final List<RexNode> arguments = aggregateCall.getArgList().stream().map(i -> Expressions.fromFieldAccess(rowSignature, project, i)).collect(Collectors.toList());
    Integer maxSizeBytes = null;
    if (arguments.size() > 1) {
        RexNode maxBytes = arguments.get(1);
        if (!maxBytes.isA(SqlKind.LITERAL)) {
            // maxBytes must be a literal
            return null;
        }
        maxSizeBytes = ((Number) RexLiteral.value(maxBytes)).intValue();
    }
    final DruidExpression arg = Expressions.toDruidExpression(plannerContext, rowSignature, arguments.get(0));
    final ExprMacroTable macroTable = plannerContext.getExprMacroTable();
    final String fieldName;
    final ColumnType druidType = Calcites.getValueTypeForRelDataTypeFull(aggregateCall.getType());
    if (druidType == null || !druidType.isArray()) {
        // must be an array
        return null;
    }
    final String initialvalue = ExpressionType.fromColumnTypeStrict(druidType).asTypeString() + "[]";
    if (arg.isDirectColumnAccess()) {
        fieldName = arg.getDirectColumn();
    } else {
        VirtualColumn vc = virtualColumnRegistry.getOrCreateVirtualColumnForExpression(plannerContext, arg, druidType);
        fieldName = vc.getOutputName();
    }
    if (aggregateCall.isDistinct()) {
        return Aggregation.create(new ExpressionLambdaAggregatorFactory(name, ImmutableSet.of(fieldName), null, initialvalue, null, true, false, false, StringUtils.format("array_set_add_all(\"__acc\", \"%s\")", fieldName), StringUtils.format("array_set_add_all(\"__acc\", \"%s\")", name), null, null, maxSizeBytes != null ? new HumanReadableBytes(maxSizeBytes) : null, macroTable));
    } else {
        return Aggregation.create(new ExpressionLambdaAggregatorFactory(name, ImmutableSet.of(fieldName), null, initialvalue, null, true, false, false, StringUtils.format("array_concat(\"__acc\", \"%s\")", fieldName), StringUtils.format("array_concat(\"__acc\", \"%s\")", name), null, null, maxSizeBytes != null ? new HumanReadableBytes(maxSizeBytes) : null, macroTable));
    }
}
Also used : Project(org.apache.calcite.rel.core.Project) SqlAggregator(org.apache.druid.sql.calcite.aggregation.SqlAggregator) ReturnTypes(org.apache.calcite.sql.type.ReturnTypes) DruidExpression(org.apache.druid.sql.calcite.expression.DruidExpression) HumanReadableBytes(org.apache.druid.java.util.common.HumanReadableBytes) Optionality(org.apache.calcite.util.Optionality) RexNode(org.apache.calcite.rex.RexNode) ExpressionType(org.apache.druid.math.expr.ExpressionType) VirtualColumnRegistry(org.apache.druid.sql.calcite.rel.VirtualColumnRegistry) PlannerContext(org.apache.druid.sql.calcite.planner.PlannerContext) Nullable(javax.annotation.Nullable) ImmutableSet(com.google.common.collect.ImmutableSet) SqlKind(org.apache.calcite.sql.SqlKind) ExpressionLambdaAggregatorFactory(org.apache.druid.query.aggregation.ExpressionLambdaAggregatorFactory) InferTypes(org.apache.calcite.sql.type.InferTypes) RexBuilder(org.apache.calcite.rex.RexBuilder) RexLiteral(org.apache.calcite.rex.RexLiteral) VirtualColumn(org.apache.druid.segment.VirtualColumn) SqlFunctionCategory(org.apache.calcite.sql.SqlFunctionCategory) StringUtils(org.apache.druid.java.util.common.StringUtils) Aggregation(org.apache.druid.sql.calcite.aggregation.Aggregation) Collectors(java.util.stream.Collectors) ExprMacroTable(org.apache.druid.math.expr.ExprMacroTable) List(java.util.List) RowSignature(org.apache.druid.segment.column.RowSignature) OperandTypes(org.apache.calcite.sql.type.OperandTypes) ColumnType(org.apache.druid.segment.column.ColumnType) AggregateCall(org.apache.calcite.rel.core.AggregateCall) SqlAggFunction(org.apache.calcite.sql.SqlAggFunction) Calcites(org.apache.druid.sql.calcite.planner.Calcites) Expressions(org.apache.druid.sql.calcite.expression.Expressions) ColumnType(org.apache.druid.segment.column.ColumnType) ExpressionLambdaAggregatorFactory(org.apache.druid.query.aggregation.ExpressionLambdaAggregatorFactory) DruidExpression(org.apache.druid.sql.calcite.expression.DruidExpression) VirtualColumn(org.apache.druid.segment.VirtualColumn) HumanReadableBytes(org.apache.druid.java.util.common.HumanReadableBytes) ExprMacroTable(org.apache.druid.math.expr.ExprMacroTable) RexNode(org.apache.calcite.rex.RexNode) Nullable(javax.annotation.Nullable)

Example 9 with VirtualColumn

use of org.apache.druid.segment.VirtualColumn in project druid by druid-io.

the class Queries method computeRequiredColumns.

/**
 * Helper for implementations of {@link Query#getRequiredColumns()}. Returns the list of columns that will be read
 * out of a datasource by a query that uses the provided objects in the usual way.
 *
 * The returned set always contains {@code __time}, no matter what.
 *
 * If the virtual columns, filter, dimensions, aggregators, or additional columns refer to a virtual column, then the
 * inputs of the virtual column will be returned instead of the name of the virtual column itself. Therefore, the
 * returned list will never contain the names of any virtual columns.
 *
 * @param virtualColumns    virtual columns whose inputs should be included.
 * @param filter            optional filter whose inputs should be included.
 * @param dimensions        dimension specs whose inputs should be included.
 * @param aggregators       aggregators whose inputs should be included.
 * @param additionalColumns additional columns to include. Each of these will be added to the returned set, unless it
 *                          refers to a virtual column, in which case the virtual column inputs will be added instead.
 */
public static Set<String> computeRequiredColumns(final VirtualColumns virtualColumns, @Nullable final DimFilter filter, final List<DimensionSpec> dimensions, final List<AggregatorFactory> aggregators, final List<String> additionalColumns) {
    final Set<String> requiredColumns = new HashSet<>();
    // Everyone needs __time (it's used by intervals filters).
    requiredColumns.add(ColumnHolder.TIME_COLUMN_NAME);
    for (VirtualColumn virtualColumn : virtualColumns.getVirtualColumns()) {
        for (String column : virtualColumn.requiredColumns()) {
            if (!virtualColumns.exists(column)) {
                requiredColumns.addAll(virtualColumn.requiredColumns());
            }
        }
    }
    if (filter != null) {
        for (String column : filter.getRequiredColumns()) {
            if (!virtualColumns.exists(column)) {
                requiredColumns.add(column);
            }
        }
    }
    for (DimensionSpec dimensionSpec : dimensions) {
        if (!virtualColumns.exists(dimensionSpec.getDimension())) {
            requiredColumns.add(dimensionSpec.getDimension());
        }
    }
    for (AggregatorFactory aggregator : aggregators) {
        for (String column : aggregator.requiredFields()) {
            if (!virtualColumns.exists(column)) {
                requiredColumns.add(column);
            }
        }
    }
    for (String column : additionalColumns) {
        if (!virtualColumns.exists(column)) {
            requiredColumns.add(column);
        }
    }
    return requiredColumns;
}
Also used : DimensionSpec(org.apache.druid.query.dimension.DimensionSpec) VirtualColumn(org.apache.druid.segment.VirtualColumn) AggregatorFactory(org.apache.druid.query.aggregation.AggregatorFactory) HashSet(java.util.HashSet)

Example 10 with VirtualColumn

use of org.apache.druid.segment.VirtualColumn in project hive by apache.

the class DruidStorageHandlerUtils method addDynamicFilters.

public static org.apache.druid.query.Query addDynamicFilters(org.apache.druid.query.Query query, ExprNodeGenericFuncDesc filterExpr, Configuration conf, boolean resolveDynamicValues) {
    List<VirtualColumn> virtualColumns = Arrays.asList(getVirtualColumns(query).getVirtualColumns());
    org.apache.druid.query.Query rv = query;
    DimFilter joinReductionFilter = toDruidFilter(filterExpr, conf, virtualColumns, resolveDynamicValues);
    if (joinReductionFilter != null) {
        String type = query.getType();
        DimFilter filter = new AndDimFilter(joinReductionFilter, query.getFilter());
        switch(type) {
            case org.apache.druid.query.Query.TIMESERIES:
                rv = Druids.TimeseriesQueryBuilder.copy((TimeseriesQuery) query).filters(filter).virtualColumns(VirtualColumns.create(virtualColumns)).build();
                break;
            case org.apache.druid.query.Query.TOPN:
                rv = new TopNQueryBuilder((TopNQuery) query).filters(filter).virtualColumns(VirtualColumns.create(virtualColumns)).build();
                break;
            case org.apache.druid.query.Query.GROUP_BY:
                rv = new GroupByQuery.Builder((GroupByQuery) query).setDimFilter(filter).setVirtualColumns(VirtualColumns.create(virtualColumns)).build();
                break;
            case org.apache.druid.query.Query.SCAN:
                rv = Druids.ScanQueryBuilder.copy((ScanQuery) query).filters(filter).virtualColumns(VirtualColumns.create(virtualColumns)).build();
                break;
            default:
                throw new UnsupportedOperationException("Unsupported Query type " + type);
        }
    }
    return rv;
}
Also used : TopNQueryBuilder(org.apache.druid.query.topn.TopNQueryBuilder) AndDimFilter(org.apache.druid.query.filter.AndDimFilter) TopNQueryBuilder(org.apache.druid.query.topn.TopNQueryBuilder) GenericUDFToString(org.apache.hadoop.hive.ql.udf.generic.GenericUDFToString) VirtualColumn(org.apache.druid.segment.VirtualColumn) ExpressionVirtualColumn(org.apache.druid.segment.virtual.ExpressionVirtualColumn) AndDimFilter(org.apache.druid.query.filter.AndDimFilter) DimFilter(org.apache.druid.query.filter.DimFilter) BoundDimFilter(org.apache.druid.query.filter.BoundDimFilter) BloomDimFilter(org.apache.druid.query.filter.BloomDimFilter) OrDimFilter(org.apache.druid.query.filter.OrDimFilter)

Aggregations

VirtualColumn (org.apache.druid.segment.VirtualColumn)19 ArrayList (java.util.ArrayList)10 ExpressionVirtualColumn (org.apache.druid.segment.virtual.ExpressionVirtualColumn)9 Filter (org.apache.druid.query.filter.Filter)7 InDimFilter (org.apache.druid.query.filter.InDimFilter)5 FalseFilter (org.apache.druid.segment.filter.FalseFilter)5 OrFilter (org.apache.druid.segment.filter.OrFilter)5 SelectorFilter (org.apache.druid.segment.filter.SelectorFilter)5 HashSet (java.util.HashSet)4 List (java.util.List)4 Set (java.util.Set)4 Test (org.junit.Test)4 ImmutableSet (com.google.common.collect.ImmutableSet)3 Lists (com.google.common.collect.Lists)3 Arrays (java.util.Arrays)3 Nullable (javax.annotation.Nullable)3 Interval (org.joda.time.Interval)3 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 Iterables (com.google.common.collect.Iterables)2 Collections (java.util.Collections)2