Search in sources :

Example 1 with ExpressionType

use of org.apache.druid.math.expr.ExpressionType in project druid by druid-io.

the class Projection method postAggregatorDirectColumnIsOk.

/**
 * Returns true if a post-aggregation "expression" can be realized as a direct field access. This is true if it's
 * a direct column access that doesn't require an implicit cast.
 *
 * @param aggregateRowSignature signature of the aggregation
 * @param expression            post-aggregation expression
 * @param rexNode               RexNode for the post-aggregation expression
 *
 * @return yes or no
 */
private static boolean postAggregatorDirectColumnIsOk(final RowSignature aggregateRowSignature, final DruidExpression expression, final RexNode rexNode) {
    if (!expression.isDirectColumnAccess()) {
        return false;
    }
    // We don't really have a way to cast complex type. So might as well not do anything and return.
    final ColumnType columnValueType = aggregateRowSignature.getColumnType(expression.getDirectColumn()).orElseThrow(() -> new ISE("Encountered null type for column[%s]", expression.getDirectColumn()));
    if (columnValueType.is(ValueType.COMPLEX)) {
        return true;
    }
    // Check if a cast is necessary.
    final ExpressionType toExprType = ExpressionType.fromColumnTypeStrict(columnValueType);
    final ExpressionType fromExprType = ExpressionType.fromColumnTypeStrict(Calcites.getColumnTypeForRelDataType(rexNode.getType()));
    return toExprType.equals(fromExprType);
}
Also used : ColumnType(org.apache.druid.segment.column.ColumnType) ISE(org.apache.druid.java.util.common.ISE) ExpressionType(org.apache.druid.math.expr.ExpressionType)

Example 2 with ExpressionType

use of org.apache.druid.math.expr.ExpressionType in project druid by druid-io.

the class ExpressionVectorSelectorsTest method sanityTestVectorizedExpressionSelectors.

public static void sanityTestVectorizedExpressionSelectors(String expression, @Nullable ExpressionType outputType, QueryableIndex index, Closer closer, int rowsPerSegment) {
    final List<Object> results = new ArrayList<>(rowsPerSegment);
    final VirtualColumns virtualColumns = VirtualColumns.create(ImmutableList.of(new ExpressionVirtualColumn("v", expression, ExpressionType.toColumnType(outputType), TestExprMacroTable.INSTANCE)));
    final QueryableIndexStorageAdapter storageAdapter = new QueryableIndexStorageAdapter(index);
    VectorCursor cursor = storageAdapter.makeVectorCursor(null, index.getDataInterval(), virtualColumns, false, 512, null);
    ColumnCapabilities capabilities = virtualColumns.getColumnCapabilities(storageAdapter, "v");
    int rowCount = 0;
    if (capabilities.isDictionaryEncoded().isTrue()) {
        SingleValueDimensionVectorSelector selector = cursor.getColumnSelectorFactory().makeSingleValueDimensionSelector(DefaultDimensionSpec.of("v"));
        while (!cursor.isDone()) {
            int[] row = selector.getRowVector();
            for (int i = 0; i < selector.getCurrentVectorSize(); i++, rowCount++) {
                results.add(selector.lookupName(row[i]));
            }
            cursor.advance();
        }
    } else {
        VectorValueSelector selector = null;
        VectorObjectSelector objectSelector = null;
        if (outputType != null && outputType.isNumeric()) {
            selector = cursor.getColumnSelectorFactory().makeValueSelector("v");
        } else {
            objectSelector = cursor.getColumnSelectorFactory().makeObjectSelector("v");
        }
        while (!cursor.isDone()) {
            boolean[] nulls;
            switch(outputType.getType()) {
                case LONG:
                    nulls = selector.getNullVector();
                    long[] longs = selector.getLongVector();
                    for (int i = 0; i < selector.getCurrentVectorSize(); i++, rowCount++) {
                        results.add(nulls != null && nulls[i] ? null : longs[i]);
                    }
                    break;
                case DOUBLE:
                    // special case to test floats just to get coverage on getFloatVector
                    if ("float2".equals(expression)) {
                        nulls = selector.getNullVector();
                        float[] floats = selector.getFloatVector();
                        for (int i = 0; i < selector.getCurrentVectorSize(); i++, rowCount++) {
                            results.add(nulls != null && nulls[i] ? null : (double) floats[i]);
                        }
                    } else {
                        nulls = selector.getNullVector();
                        double[] doubles = selector.getDoubleVector();
                        for (int i = 0; i < selector.getCurrentVectorSize(); i++, rowCount++) {
                            results.add(nulls != null && nulls[i] ? null : doubles[i]);
                        }
                    }
                    break;
                case STRING:
                    Object[] objects = objectSelector.getObjectVector();
                    for (int i = 0; i < objectSelector.getCurrentVectorSize(); i++, rowCount++) {
                        results.add(objects[i]);
                    }
                    break;
            }
            cursor.advance();
        }
    }
    closer.register(cursor);
    Sequence<Cursor> cursors = new QueryableIndexStorageAdapter(index).makeCursors(null, index.getDataInterval(), virtualColumns, Granularities.ALL, false, null);
    int rowCountCursor = cursors.map(nonVectorized -> {
        final ColumnValueSelector nonSelector = nonVectorized.getColumnSelectorFactory().makeColumnValueSelector("v");
        int rows = 0;
        while (!nonVectorized.isDone()) {
            Assert.assertEquals(StringUtils.format("Failed at row %s", rows), nonSelector.getObject(), results.get(rows));
            rows++;
            nonVectorized.advance();
        }
        return rows;
    }).accumulate(0, (acc, in) -> acc + in);
    Assert.assertTrue(rowCountCursor > 0);
    Assert.assertEquals(rowCountCursor, rowCount);
}
Also used : BeforeClass(org.junit.BeforeClass) SegmentGenerator(org.apache.druid.segment.generator.SegmentGenerator) RunWith(org.junit.runner.RunWith) ColumnValueSelector(org.apache.druid.segment.ColumnValueSelector) Parser(org.apache.druid.math.expr.Parser) ArrayList(java.util.ArrayList) DefaultDimensionSpec(org.apache.druid.query.dimension.DefaultDimensionSpec) GeneratorBasicSchemas(org.apache.druid.segment.generator.GeneratorBasicSchemas) VectorCursor(org.apache.druid.segment.vector.VectorCursor) ImmutableList(com.google.common.collect.ImmutableList) ExpressionType(org.apache.druid.math.expr.ExpressionType) Expr(org.apache.druid.math.expr.Expr) SingleValueDimensionVectorSelector(org.apache.druid.segment.vector.SingleValueDimensionVectorSelector) Parameterized(org.junit.runners.Parameterized) Nullable(javax.annotation.Nullable) Before(org.junit.Before) Sequence(org.apache.druid.java.util.common.guava.Sequence) ColumnInspector(org.apache.druid.segment.ColumnInspector) AfterClass(org.junit.AfterClass) QueryableIndexStorageAdapter(org.apache.druid.segment.QueryableIndexStorageAdapter) VirtualColumns(org.apache.druid.segment.VirtualColumns) Closer(org.apache.druid.java.util.common.io.Closer) QueryableIndex(org.apache.druid.segment.QueryableIndex) StringUtils(org.apache.druid.java.util.common.StringUtils) GeneratorSchemaInfo(org.apache.druid.segment.generator.GeneratorSchemaInfo) VectorObjectSelector(org.apache.druid.segment.vector.VectorObjectSelector) Test(org.junit.Test) IOException(java.io.IOException) TestExprMacroTable(org.apache.druid.query.expression.TestExprMacroTable) VectorValueSelector(org.apache.druid.segment.vector.VectorValueSelector) Collectors(java.util.stream.Collectors) Granularities(org.apache.druid.java.util.common.granularity.Granularities) ExprMacroTable(org.apache.druid.math.expr.ExprMacroTable) List(java.util.List) Cursor(org.apache.druid.segment.Cursor) LinearShardSpec(org.apache.druid.timeline.partition.LinearShardSpec) DataSegment(org.apache.druid.timeline.DataSegment) ColumnCapabilities(org.apache.druid.segment.column.ColumnCapabilities) Assert(org.junit.Assert) ArrayList(java.util.ArrayList) QueryableIndexStorageAdapter(org.apache.druid.segment.QueryableIndexStorageAdapter) VectorCursor(org.apache.druid.segment.vector.VectorCursor) Cursor(org.apache.druid.segment.Cursor) VectorCursor(org.apache.druid.segment.vector.VectorCursor) ColumnCapabilities(org.apache.druid.segment.column.ColumnCapabilities) VectorValueSelector(org.apache.druid.segment.vector.VectorValueSelector) SingleValueDimensionVectorSelector(org.apache.druid.segment.vector.SingleValueDimensionVectorSelector) VectorObjectSelector(org.apache.druid.segment.vector.VectorObjectSelector) VirtualColumns(org.apache.druid.segment.VirtualColumns) ColumnValueSelector(org.apache.druid.segment.ColumnValueSelector)

Example 3 with ExpressionType

use of org.apache.druid.math.expr.ExpressionType in project druid by druid-io.

the class ExpressionFilter method makeVectorMatcher.

@Override
public VectorValueMatcher makeVectorMatcher(VectorColumnSelectorFactory factory) {
    final Expr theExpr = expr.get();
    DruidPredicateFactory predicateFactory = new DruidPredicateFactory() {

        @Override
        public Predicate<String> makeStringPredicate() {
            return Evals::asBoolean;
        }

        @Override
        public DruidLongPredicate makeLongPredicate() {
            return Evals::asBoolean;
        }

        @Override
        public DruidFloatPredicate makeFloatPredicate() {
            return Evals::asBoolean;
        }

        @Override
        public DruidDoublePredicate makeDoublePredicate() {
            return Evals::asBoolean;
        }

        // The hashcode and equals are to make SubclassesMustOverrideEqualsAndHashCodeTest stop complaining..
        // DruidPredicateFactory currently doesn't really need equals or hashcode since 'toString' method that is actually
        // called when testing equality of DimensionPredicateFilter, so it's the truly required method, but that seems
        // a bit strange. DimensionPredicateFilter should probably be reworked to use equals from DruidPredicateFactory
        // instead of using toString.
        @Override
        public int hashCode() {
            return super.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            return super.equals(obj);
        }
    };
    final ExpressionType outputType = theExpr.getOutputType(factory);
    // effectively constant
    if (outputType == null) {
        // false matcher
        if (NullHandling.sqlCompatible()) {
            return BooleanVectorValueMatcher.of(factory.getReadableVectorInspector(), false);
        }
        // or not.
        return BooleanVectorValueMatcher.of(factory.getReadableVectorInspector(), theExpr.eval(InputBindings.nilBindings()).asBoolean());
    }
    // if we got here, we really have to evaluate the expressions to match
    switch(outputType.getType()) {
        case LONG:
            return VectorValueMatcherColumnProcessorFactory.instance().makeLongProcessor(ColumnCapabilitiesImpl.createSimpleNumericColumnCapabilities(ColumnType.LONG), ExpressionVectorSelectors.makeVectorValueSelector(factory, theExpr)).makeMatcher(predicateFactory);
        case DOUBLE:
            return VectorValueMatcherColumnProcessorFactory.instance().makeDoubleProcessor(ColumnCapabilitiesImpl.createSimpleNumericColumnCapabilities(ColumnType.DOUBLE), ExpressionVectorSelectors.makeVectorValueSelector(factory, theExpr)).makeMatcher(predicateFactory);
        case STRING:
            return VectorValueMatcherColumnProcessorFactory.instance().makeObjectProcessor(ColumnCapabilitiesImpl.createSimpleSingleValueStringColumnCapabilities(), ExpressionVectorSelectors.makeVectorObjectSelector(factory, theExpr)).makeMatcher(predicateFactory);
        default:
            throw new UOE("Vectorized expression matchers not implemented for type: [%s]", outputType);
    }
}
Also used : Expr(org.apache.druid.math.expr.Expr) UOE(org.apache.druid.java.util.common.UOE) ExpressionType(org.apache.druid.math.expr.ExpressionType) DruidPredicateFactory(org.apache.druid.query.filter.DruidPredicateFactory)

Example 4 with ExpressionType

use of org.apache.druid.math.expr.ExpressionType in project druid by druid-io.

the class VectorProcessors method not.

public static <T> ExprVectorProcessor<T> not(Expr.VectorInputBindingInspector inspector, Expr expr) {
    final ExpressionType inputType = expr.getOutputType(inspector);
    final int maxVectorSize = inspector.getMaxVectorSize();
    ExprVectorProcessor<?> processor = null;
    if (Types.is(inputType, ExprType.STRING)) {
        processor = new LongOutStringInFunctionVectorProcessor(expr.buildVectorized(inspector), maxVectorSize) {

            @Override
            public void processIndex(String[] strings, long[] longs, boolean[] outputNulls, int i) {
                outputNulls[i] = strings[i] == null;
                if (!outputNulls[i]) {
                    longs[i] = Evals.asLong(!Evals.asBoolean(strings[i]));
                }
            }
        };
    } else if (Types.is(inputType, ExprType.LONG)) {
        processor = new LongOutLongInFunctionVectorValueProcessor(expr.buildVectorized(inspector), maxVectorSize) {

            @Override
            public long apply(long input) {
                return Evals.asLong(!Evals.asBoolean(input));
            }
        };
    } else if (Types.is(inputType, ExprType.DOUBLE)) {
        if (!ExpressionProcessing.useStrictBooleans()) {
            processor = new DoubleOutDoubleInFunctionVectorValueProcessor(expr.buildVectorized(inspector), maxVectorSize) {

                @Override
                public double apply(double input) {
                    return Evals.asDouble(!Evals.asBoolean(input));
                }
            };
        } else {
            processor = new LongOutDoubleInFunctionVectorValueProcessor(expr.buildVectorized(inspector), maxVectorSize) {

                @Override
                public long apply(double input) {
                    return Evals.asLong(!Evals.asBoolean(input));
                }
            };
        }
    }
    if (processor == null) {
        throw Exprs.cannotVectorize();
    }
    return (ExprVectorProcessor<T>) processor;
}
Also used : ExpressionType(org.apache.druid.math.expr.ExpressionType)

Example 5 with ExpressionType

use of org.apache.druid.math.expr.ExpressionType in project druid by druid-io.

the class VectorProcessors method isNotNull.

public static <T> ExprVectorProcessor<T> isNotNull(Expr.VectorInputBindingInspector inspector, Expr expr) {
    final ExpressionType type = expr.getOutputType(inspector);
    if (type == null) {
        return constant(0L, inspector.getMaxVectorSize());
    }
    final long[] outputValues = new long[inspector.getMaxVectorSize()];
    ExprVectorProcessor<?> processor = null;
    if (Types.is(type, ExprType.STRING)) {
        final ExprVectorProcessor<String[]> input = expr.buildVectorized(inspector);
        processor = new ExprVectorProcessor<long[]>() {

            @Override
            public ExprEvalVector<long[]> evalVector(Expr.VectorInputBinding bindings) {
                final ExprEvalVector<String[]> inputEval = input.evalVector(bindings);
                final int currentSize = bindings.getCurrentVectorSize();
                final String[] values = inputEval.values();
                for (int i = 0; i < currentSize; i++) {
                    if (values[i] == null) {
                        outputValues[i] = 0L;
                    } else {
                        outputValues[i] = 1L;
                    }
                }
                return new ExprEvalLongVector(outputValues, null);
            }

            @Override
            public ExpressionType getOutputType() {
                return ExpressionType.LONG;
            }
        };
    } else if (Types.is(type, ExprType.LONG)) {
        final ExprVectorProcessor<long[]> input = expr.buildVectorized(inspector);
        processor = new ExprVectorProcessor<long[]>() {

            @Override
            public ExprEvalVector<long[]> evalVector(Expr.VectorInputBinding bindings) {
                final ExprEvalVector<long[]> inputEval = input.evalVector(bindings);
                final int currentSize = bindings.getCurrentVectorSize();
                final boolean[] nulls = inputEval.getNullVector();
                if (nulls == null) {
                    Arrays.fill(outputValues, 1L);
                } else {
                    for (int i = 0; i < currentSize; i++) {
                        if (nulls[i]) {
                            outputValues[i] = 0L;
                        } else {
                            outputValues[i] = 1L;
                        }
                    }
                }
                return new ExprEvalLongVector(outputValues, null);
            }

            @Override
            public ExpressionType getOutputType() {
                return ExpressionType.LONG;
            }
        };
    } else if (Types.is(type, ExprType.DOUBLE)) {
        final ExprVectorProcessor<double[]> input = expr.buildVectorized(inspector);
        processor = new ExprVectorProcessor<long[]>() {

            @Override
            public ExprEvalVector<long[]> evalVector(Expr.VectorInputBinding bindings) {
                final ExprEvalVector<double[]> inputEval = input.evalVector(bindings);
                final int currentSize = bindings.getCurrentVectorSize();
                final boolean[] nulls = inputEval.getNullVector();
                if (nulls == null) {
                    Arrays.fill(outputValues, 1L);
                } else {
                    for (int i = 0; i < currentSize; i++) {
                        if (nulls[i]) {
                            outputValues[i] = 0L;
                        } else {
                            outputValues[i] = 1L;
                        }
                    }
                }
                return new ExprEvalLongVector(outputValues, null);
            }

            @Override
            public ExpressionType getOutputType() {
                return ExpressionType.LONG;
            }
        };
    }
    if (processor == null) {
        throw Exprs.cannotVectorize();
    }
    return (ExprVectorProcessor<T>) processor;
}
Also used : Expr(org.apache.druid.math.expr.Expr) ExpressionType(org.apache.druid.math.expr.ExpressionType)

Aggregations

ExpressionType (org.apache.druid.math.expr.ExpressionType)23 Expr (org.apache.druid.math.expr.Expr)9 Nullable (javax.annotation.Nullable)3 ColumnCapabilities (org.apache.druid.segment.column.ColumnCapabilities)3 ArrayList (java.util.ArrayList)2 DefaultDimensionSpec (org.apache.druid.query.dimension.DefaultDimensionSpec)2 ColumnValueSelector (org.apache.druid.segment.ColumnValueSelector)2 ColumnType (org.apache.druid.segment.column.ColumnType)2 VectorCursor (org.apache.druid.segment.vector.VectorCursor)2 VectorObjectSelector (org.apache.druid.segment.vector.VectorObjectSelector)2 VectorValueSelector (org.apache.druid.segment.vector.VectorValueSelector)2 ImmutableList (com.google.common.collect.ImmutableList)1 IOException (java.io.IOException)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Collectors (java.util.stream.Collectors)1 IAE (org.apache.druid.java.util.common.IAE)1 ISE (org.apache.druid.java.util.common.ISE)1 NonnullPair (org.apache.druid.java.util.common.NonnullPair)1