Search in sources :

Example 1 with ColumnType

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

the class IndexedTableColumnSelectorFactory method columnCapabilities.

@Nullable
static ColumnCapabilities columnCapabilities(final IndexedTable table, final String columnName) {
    final ColumnType valueType = table.rowSignature().getColumnType(columnName).orElse(null);
    if (valueType != null) {
        final ColumnCapabilitiesImpl capabilities = new ColumnCapabilitiesImpl().setType(valueType);
        if (valueType.is(ValueType.STRING)) {
            // IndexedTables are not _really_ dictionary-encoded, but we fake it using the row number as the dict. code.
            capabilities.setDictionaryEncoded(true);
        }
        capabilities.setDictionaryValuesSorted(false);
        capabilities.setDictionaryValuesUnique(false);
        capabilities.setHasMultipleValues(false);
        return capabilities;
    } else {
        return null;
    }
}
Also used : ColumnType(org.apache.druid.segment.column.ColumnType) ColumnCapabilitiesImpl(org.apache.druid.segment.column.ColumnCapabilitiesImpl) Nullable(javax.annotation.Nullable)

Example 2 with ColumnType

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

the class IndexIO method validateRowValues.

private static void validateRowValues(RowPointer rp1, IndexableAdapter adapter1, RowPointer rp2, IndexableAdapter adapter2) {
    if (rp1.getTimestamp() != rp2.getTimestamp()) {
        throw new SegmentValidationException("Timestamp mismatch. Expected %d found %d", rp1.getTimestamp(), rp2.getTimestamp());
    }
    final List<Object> dims1 = rp1.getDimensionValuesForDebug();
    final List<Object> dims2 = rp2.getDimensionValuesForDebug();
    if (dims1.size() != dims2.size()) {
        throw new SegmentValidationException("Dim lengths not equal %s vs %s", dims1, dims2);
    }
    final List<String> dim1Names = adapter1.getDimensionNames();
    final List<String> dim2Names = adapter2.getDimensionNames();
    int dimCount = dims1.size();
    for (int i = 0; i < dimCount; ++i) {
        final String dim1Name = dim1Names.get(i);
        final String dim2Name = dim2Names.get(i);
        ColumnCapabilities capabilities1 = adapter1.getCapabilities(dim1Name);
        ColumnCapabilities capabilities2 = adapter2.getCapabilities(dim2Name);
        ColumnType dim1Type = capabilities1.toColumnType();
        ColumnType dim2Type = capabilities2.toColumnType();
        if (!Objects.equals(dim1Type, dim2Type)) {
            throw new SegmentValidationException("Dim [%s] types not equal. Expected %d found %d", dim1Name, dim1Type, dim2Type);
        }
        Object vals1 = dims1.get(i);
        Object vals2 = dims2.get(i);
        if (isNullRow(vals1) ^ isNullRow(vals2)) {
            throw notEqualValidationException(dim1Name, vals1, vals2);
        }
        boolean vals1IsList = vals1 instanceof List;
        boolean vals2IsList = vals2 instanceof List;
        if (vals1IsList ^ vals2IsList) {
            if (vals1IsList) {
                if (((List) vals1).size() != 1 || !Objects.equals(((List) vals1).get(0), vals2)) {
                    throw notEqualValidationException(dim1Name, vals1, vals2);
                }
            } else {
                if (((List) vals2).size() != 1 || !Objects.equals(((List) vals2).get(0), vals1)) {
                    throw notEqualValidationException(dim1Name, vals1, vals2);
                }
            }
        } else {
            if (!Objects.equals(vals1, vals2)) {
                throw notEqualValidationException(dim1Name, vals1, vals2);
            }
        }
    }
}
Also used : ColumnType(org.apache.druid.segment.column.ColumnType) List(java.util.List) ColumnCapabilities(org.apache.druid.segment.column.ColumnCapabilities)

Example 3 with ColumnType

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

the class GroupByQueryEngineV2Test method testCanPushDownLimitForComplexSelector.

@Test
public void testCanPushDownLimitForComplexSelector() {
    ColumnCapabilitiesImpl capabilities = new ColumnCapabilitiesImpl().setType(new ColumnType(ValueType.COMPLEX, "foo", null)).setHasBitmapIndexes(false).setHasMultipleValues(false).setDictionaryEncoded(false).setDictionaryValuesSorted(false).setDictionaryValuesUnique(false);
    EasyMock.expect(factory.getColumnCapabilities(DIM)).andReturn(capabilities).once();
    EasyMock.replay(factory);
    Assert.assertTrue(GroupByQueryEngineV2.canPushDownLimit(factory, DIM));
    EasyMock.verify(factory);
}
Also used : ColumnType(org.apache.druid.segment.column.ColumnType) ColumnCapabilitiesImpl(org.apache.druid.segment.column.ColumnCapabilitiesImpl) Test(org.junit.Test)

Example 4 with ColumnType

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

the class DruidQuery method computeDimensions.

/**
 * Returns dimensions corresponding to {@code aggregate.getGroupSet()}, in the same order.
 *
 * @param partialQuery          partial query
 * @param plannerContext        planner context
 * @param rowSignature          source row signature
 * @param virtualColumnRegistry re-usable virtual column references
 *
 * @return dimensions
 *
 * @throws CannotBuildQueryException if dimensions cannot be computed
 */
private static List<DimensionExpression> computeDimensions(final PartialDruidQuery partialQuery, final PlannerContext plannerContext, final RowSignature rowSignature, final VirtualColumnRegistry virtualColumnRegistry) {
    final Aggregate aggregate = Preconditions.checkNotNull(partialQuery.getAggregate());
    final List<DimensionExpression> dimensions = new ArrayList<>();
    final String outputNamePrefix = Calcites.findUnusedPrefixForDigits("d", rowSignature.getColumnNames());
    int outputNameCounter = 0;
    for (int i : aggregate.getGroupSet()) {
        // Dimension might need to create virtual columns. Avoid giving it a name that would lead to colliding columns.
        final RexNode rexNode = Expressions.fromFieldAccess(rowSignature, partialQuery.getSelectProject(), i);
        final DruidExpression druidExpression = Expressions.toDruidExpression(plannerContext, rowSignature, rexNode);
        if (druidExpression == null) {
            throw new CannotBuildQueryException(aggregate, rexNode);
        }
        final RelDataType dataType = rexNode.getType();
        final ColumnType outputType = Calcites.getColumnTypeForRelDataType(dataType);
        if (Types.isNullOr(outputType, ValueType.COMPLEX)) {
            // Can't group on unknown or COMPLEX types.
            plannerContext.setPlanningError("SQL requires a group-by on a column of type %s that is unsupported.", outputType);
            throw new CannotBuildQueryException(aggregate, rexNode);
        }
        final String dimOutputName = outputNamePrefix + outputNameCounter++;
        if (!druidExpression.isSimpleExtraction()) {
            final String virtualColumn = virtualColumnRegistry.getOrCreateVirtualColumnForExpression(druidExpression, dataType);
            dimensions.add(DimensionExpression.ofVirtualColumn(virtualColumn, dimOutputName, druidExpression, outputType));
        } else {
            dimensions.add(DimensionExpression.ofSimpleColumn(dimOutputName, druidExpression, outputType));
        }
    }
    return dimensions;
}
Also used : ColumnType(org.apache.druid.segment.column.ColumnType) DruidExpression(org.apache.druid.sql.calcite.expression.DruidExpression) IntArrayList(it.unimi.dsi.fastutil.ints.IntArrayList) ArrayList(java.util.ArrayList) DimensionExpression(org.apache.druid.sql.calcite.aggregation.DimensionExpression) RelDataType(org.apache.calcite.rel.type.RelDataType) Aggregate(org.apache.calcite.rel.core.Aggregate) RexNode(org.apache.calcite.rex.RexNode)

Example 5 with ColumnType

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

the class DruidSchema method buildDruidTable.

@VisibleForTesting
DruidTable buildDruidTable(final String dataSource) {
    ConcurrentSkipListMap<SegmentId, AvailableSegmentMetadata> segmentsMap = segmentMetadataInfo.get(dataSource);
    final Map<String, ColumnType> columnTypes = new TreeMap<>();
    if (segmentsMap != null) {
        for (AvailableSegmentMetadata availableSegmentMetadata : segmentsMap.values()) {
            final RowSignature rowSignature = availableSegmentMetadata.getRowSignature();
            if (rowSignature != null) {
                for (String column : rowSignature.getColumnNames()) {
                    // Newer column types should override older ones.
                    final ColumnType columnType = rowSignature.getColumnType(column).orElseThrow(() -> new ISE("Encountered null type for column[%s]", column));
                    columnTypes.putIfAbsent(column, columnType);
                }
            }
        }
    }
    final RowSignature.Builder builder = RowSignature.builder();
    columnTypes.forEach(builder::add);
    final TableDataSource tableDataSource;
    // to be a GlobalTableDataSource instead of a TableDataSource, it must appear on all servers (inferred by existing
    // in the segment cache, which in this case belongs to the broker meaning only broadcast segments live here)
    // to be joinable, it must be possibly joinable according to the factory. we only consider broadcast datasources
    // at this time, and isGlobal is currently strongly coupled with joinable, so only make a global table datasource
    // if also joinable
    final GlobalTableDataSource maybeGlobal = new GlobalTableDataSource(dataSource);
    final boolean isJoinable = joinableFactory.isDirectlyJoinable(maybeGlobal);
    final boolean isBroadcast = segmentManager.getDataSourceNames().contains(dataSource);
    if (isBroadcast && isJoinable) {
        tableDataSource = maybeGlobal;
    } else {
        tableDataSource = new TableDataSource(dataSource);
    }
    return new DruidTable(tableDataSource, builder.build(), null, isJoinable, isBroadcast);
}
Also used : ColumnType(org.apache.druid.segment.column.ColumnType) SegmentId(org.apache.druid.timeline.SegmentId) GlobalTableDataSource(org.apache.druid.query.GlobalTableDataSource) DruidTable(org.apache.druid.sql.calcite.table.DruidTable) TreeMap(java.util.TreeMap) GlobalTableDataSource(org.apache.druid.query.GlobalTableDataSource) TableDataSource(org.apache.druid.query.TableDataSource) ISE(org.apache.druid.java.util.common.ISE) RowSignature(org.apache.druid.segment.column.RowSignature) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Aggregations

ColumnType (org.apache.druid.segment.column.ColumnType)43 Nullable (javax.annotation.Nullable)16 ISE (org.apache.druid.java.util.common.ISE)15 RowSignature (org.apache.druid.segment.column.RowSignature)14 AggregatorFactory (org.apache.druid.query.aggregation.AggregatorFactory)13 RexNode (org.apache.calcite.rex.RexNode)12 DruidExpression (org.apache.druid.sql.calcite.expression.DruidExpression)12 List (java.util.List)11 IAE (org.apache.druid.java.util.common.IAE)11 RelDataType (org.apache.calcite.rel.type.RelDataType)9 DimensionSpec (org.apache.druid.query.dimension.DimensionSpec)9 Collectors (java.util.stream.Collectors)8 ArrayList (java.util.ArrayList)7 SqlAggFunction (org.apache.calcite.sql.SqlAggFunction)5 DefaultDimensionSpec (org.apache.druid.query.dimension.DefaultDimensionSpec)5 StringComparator (org.apache.druid.query.ordering.StringComparator)5 Aggregation (org.apache.druid.sql.calcite.aggregation.Aggregation)5 JsonCreator (com.fasterxml.jackson.annotation.JsonCreator)4 Preconditions (com.google.common.base.Preconditions)4 Collections (java.util.Collections)4