Search in sources :

Example 21 with SqlKind

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project druid by druid-io.

the class OperatorConversions method toPostAggregator.

/**
 * Translate a Calcite {@code RexNode} to a Druid PostAggregator
 *
 * @param plannerContext        SQL planner context
 * @param rowSignature          signature of the rows to be extracted from
 * @param rexNode               expression meant to be applied on top of the rows
 * @param postAggregatorVisitor visitor that manages postagg names and tracks postaggs that were created
 *                              by the translation
 *
 * @return rexNode referring to fields in rowOrder, or null if not possible
 */
@Nullable
public static PostAggregator toPostAggregator(final PlannerContext plannerContext, final RowSignature rowSignature, final RexNode rexNode, final PostAggregatorVisitor postAggregatorVisitor) {
    final SqlKind kind = rexNode.getKind();
    if (kind == SqlKind.INPUT_REF) {
        // Translate field references.
        final RexInputRef ref = (RexInputRef) rexNode;
        final String columnName = rowSignature.getColumnName(ref.getIndex());
        if (columnName == null) {
            throw new ISE("PostAggregator referred to nonexistent index[%d]", ref.getIndex());
        }
        return new FieldAccessPostAggregator(postAggregatorVisitor.getOutputNamePrefix() + postAggregatorVisitor.getAndIncrementCounter(), columnName);
    } else if (rexNode instanceof RexCall) {
        final SqlOperator operator = ((RexCall) rexNode).getOperator();
        final SqlOperatorConversion conversion = plannerContext.getOperatorTable().lookupOperatorConversion(operator);
        if (conversion == null) {
            return null;
        } else {
            return conversion.toPostAggregator(plannerContext, rowSignature, rexNode, postAggregatorVisitor);
        }
    } else if (kind == SqlKind.LITERAL) {
        return null;
    } else {
        throw new IAE("Unknown rexnode kind: " + kind);
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) FieldAccessPostAggregator(org.apache.druid.query.aggregation.post.FieldAccessPostAggregator) SqlOperator(org.apache.calcite.sql.SqlOperator) RexInputRef(org.apache.calcite.rex.RexInputRef) ISE(org.apache.druid.java.util.common.ISE) SqlKind(org.apache.calcite.sql.SqlKind) IAE(org.apache.druid.java.util.common.IAE) Nullable(javax.annotation.Nullable)

Example 22 with SqlKind

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project hazelcast by hazelcast.

the class AggregateAbstractPhysicalRule method aggregateOperation.

protected static AggregateOperation<?, JetSqlRow> aggregateOperation(RelDataType inputType, ImmutableBitSet groupSet, List<AggregateCall> aggregateCalls) {
    List<QueryDataType> operandTypes = OptUtils.schema(inputType).getTypes();
    List<SupplierEx<SqlAggregation>> aggregationProviders = new ArrayList<>();
    List<FunctionEx<JetSqlRow, Object>> valueProviders = new ArrayList<>();
    for (Integer groupIndex : groupSet.toList()) {
        aggregationProviders.add(ValueSqlAggregation::new);
        // getMaybeSerialized is safe for ValueAggr because it only passes the value on
        valueProviders.add(new RowGetMaybeSerializedFn(groupIndex));
    }
    for (AggregateCall aggregateCall : aggregateCalls) {
        boolean distinct = aggregateCall.isDistinct();
        List<Integer> aggregateCallArguments = aggregateCall.getArgList();
        SqlKind kind = aggregateCall.getAggregation().getKind();
        switch(kind) {
            case COUNT:
                if (distinct) {
                    int countIndex = aggregateCallArguments.get(0);
                    aggregationProviders.add(new AggregateCountSupplier(true, true));
                    // getMaybeSerialized is safe for COUNT because the aggregation only looks whether it is null or not
                    valueProviders.add(new RowGetMaybeSerializedFn(countIndex));
                } else if (aggregateCallArguments.size() == 1) {
                    int countIndex = aggregateCallArguments.get(0);
                    aggregationProviders.add(new AggregateCountSupplier(true, false));
                    valueProviders.add(new RowGetMaybeSerializedFn(countIndex));
                } else {
                    aggregationProviders.add(new AggregateCountSupplier(false, false));
                    valueProviders.add(NullFunction.INSTANCE);
                }
                break;
            case MIN:
                int minIndex = aggregateCallArguments.get(0);
                aggregationProviders.add(MinSqlAggregation::new);
                valueProviders.add(new RowGetFn(minIndex));
                break;
            case MAX:
                int maxIndex = aggregateCallArguments.get(0);
                aggregationProviders.add(MaxSqlAggregation::new);
                valueProviders.add(new RowGetFn(maxIndex));
                break;
            case SUM:
                int sumIndex = aggregateCallArguments.get(0);
                QueryDataType sumOperandType = operandTypes.get(sumIndex);
                aggregationProviders.add(new AggregateSumSupplier(distinct, sumOperandType));
                valueProviders.add(new RowGetFn(sumIndex));
                break;
            case AVG:
                int avgIndex = aggregateCallArguments.get(0);
                QueryDataType avgOperandType = operandTypes.get(avgIndex);
                aggregationProviders.add(new AggregateAvgSupplier(distinct, avgOperandType));
                valueProviders.add(new RowGetFn(avgIndex));
                break;
            default:
                throw QueryException.error("Unsupported aggregation function: " + kind);
        }
    }
    return AggregateOperation.withCreate(new AggregateCreateSupplier(aggregationProviders)).andAccumulate(new AggregateAccumulateFunction(valueProviders)).andCombine(AggregateCombineFunction.INSTANCE).andExportFinish(AggregateExportFinishFunction.INSTANCE);
}
Also used : MaxSqlAggregation(com.hazelcast.jet.sql.impl.aggregate.MaxSqlAggregation) QueryDataType(com.hazelcast.sql.impl.type.QueryDataType) ArrayList(java.util.ArrayList) SupplierEx(com.hazelcast.function.SupplierEx) SqlKind(org.apache.calcite.sql.SqlKind) ValueSqlAggregation(com.hazelcast.jet.sql.impl.aggregate.ValueSqlAggregation) AggregateCall(org.apache.calcite.rel.core.AggregateCall) MinSqlAggregation(com.hazelcast.jet.sql.impl.aggregate.MinSqlAggregation) FunctionEx(com.hazelcast.function.FunctionEx)

Example 23 with SqlKind

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project hive by apache.

the class JDBCAggregationPushDownRule method matches.

@Override
public boolean matches(RelOptRuleCall call) {
    final HiveAggregate agg = call.rel(0);
    final HiveJdbcConverter converter = call.rel(1);
    if (agg.getGroupType() != Group.SIMPLE) {
        // TODO: Grouping sets not supported yet
        return false;
    }
    for (AggregateCall relOptRuleOperand : agg.getAggCallList()) {
        SqlAggFunction f = relOptRuleOperand.getAggregation();
        if (f instanceof HiveSqlCountAggFunction) {
            // count distinct with more that one argument is not supported
            HiveSqlCountAggFunction countAgg = (HiveSqlCountAggFunction) f;
            if (countAgg.isDistinct() && 1 < relOptRuleOperand.getArgList().size()) {
                return false;
            }
        }
        SqlKind kind = f.getKind();
        if (!converter.getJdbcDialect().supportsAggregateFunction(kind)) {
            return false;
        }
    }
    return true;
}
Also used : AggregateCall(org.apache.calcite.rel.core.AggregateCall) HiveAggregate(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.HiveAggregate) HiveSqlCountAggFunction(org.apache.hadoop.hive.ql.optimizer.calcite.functions.HiveSqlCountAggFunction) HiveJdbcConverter(org.apache.hadoop.hive.ql.optimizer.calcite.reloperators.jdbc.HiveJdbcConverter) SqlAggFunction(org.apache.calcite.sql.SqlAggFunction) SqlKind(org.apache.calcite.sql.SqlKind)

Example 24 with SqlKind

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project hive by apache.

the class HiveAggregateReduceFunctionsRule method reduceAgg.

private RexNode reduceAgg(Aggregate oldAggRel, AggregateCall oldCall, List<AggregateCall> newCalls, Map<AggregateCall, RexNode> aggCallMapping, List<RexNode> inputExprs) {
    final SqlKind kind = oldCall.getAggregation().getKind();
    if (isReducible(kind)) {
        switch(kind) {
            case SUM0:
                // replace original SUM0(x) with COALESCE(SUM(x), 0)
                return reduceSum0(oldAggRel, oldCall, newCalls, aggCallMapping, inputExprs);
            case AVG:
                // replace original AVG(x) with SUM(x) / COUNT(x)
                return reduceAvg(oldAggRel, oldCall, newCalls, aggCallMapping, inputExprs);
            case STDDEV_POP:
                // / COUNT(x))
                return reduceStddev(oldAggRel, oldCall, true, true, newCalls, aggCallMapping, inputExprs);
            case STDDEV_SAMP:
                // / CASE COUNT(x) WHEN 1 THEN NULL ELSE COUNT(x) - 1 END)
                return reduceStddev(oldAggRel, oldCall, false, true, newCalls, aggCallMapping, inputExprs);
            case VAR_POP:
                // / COUNT(x)
                return reduceStddev(oldAggRel, oldCall, true, false, newCalls, aggCallMapping, inputExprs);
            case VAR_SAMP:
                // / CASE COUNT(x) WHEN 1 THEN NULL ELSE COUNT(x) - 1 END
                return reduceStddev(oldAggRel, oldCall, false, false, newCalls, aggCallMapping, inputExprs);
            default:
                throw Util.unexpected(kind);
        }
    } else {
        // anything else:  preserve original call
        RexBuilder rexBuilder = oldAggRel.getCluster().getRexBuilder();
        final int nGroups = oldAggRel.getGroupCount();
        List<RelDataType> oldArgTypes = SqlTypeUtil.projectTypes(oldAggRel.getInput().getRowType(), oldCall.getArgList());
        return rexBuilder.addAggCall(oldCall, nGroups, oldAggRel.indicator, newCalls, aggCallMapping, oldArgTypes);
    }
}
Also used : RexBuilder(org.apache.calcite.rex.RexBuilder) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlKind(org.apache.calcite.sql.SqlKind)

Example 25 with SqlKind

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlKind in project druid by druid-io.

the class Expressions method toLeafFilter.

/**
   * Translates "condition" to a Druid filter, assuming it does not contain any boolean expressions. Returns null
   * if we cannot translate the condition.
   *
   * @param plannerContext planner context
   * @param rowSignature   row signature of the dataSource to be filtered
   * @param expression     Calcite row expression
   */
private static DimFilter toLeafFilter(final DruidOperatorTable operatorTable, final PlannerContext plannerContext, final RowSignature rowSignature, final RexNode expression) {
    if (expression.isAlwaysTrue()) {
        return Filtration.matchEverything();
    } else if (expression.isAlwaysFalse()) {
        return Filtration.matchNothing();
    }
    final SqlKind kind = expression.getKind();
    if (kind == SqlKind.LIKE) {
        final List<RexNode> operands = ((RexCall) expression).getOperands();
        final RowExtraction rex = toRowExtraction(operatorTable, plannerContext, rowSignature.getRowOrder(), operands.get(0));
        if (rex == null || !rex.isFilterable(rowSignature)) {
            return null;
        }
        return new LikeDimFilter(rex.getColumn(), RexLiteral.stringValue(operands.get(1)), operands.size() > 2 ? RexLiteral.stringValue(operands.get(2)) : null, rex.getExtractionFn());
    } else if (kind == SqlKind.EQUALS || kind == SqlKind.NOT_EQUALS || kind == SqlKind.GREATER_THAN || kind == SqlKind.GREATER_THAN_OR_EQUAL || kind == SqlKind.LESS_THAN || kind == SqlKind.LESS_THAN_OR_EQUAL) {
        final List<RexNode> operands = ((RexCall) expression).getOperands();
        Preconditions.checkState(operands.size() == 2, "WTF?! Expected 2 operands, got[%,d]", operands.size());
        boolean flip = false;
        RexNode lhs = operands.get(0);
        RexNode rhs = operands.get(1);
        if (lhs.getKind() == SqlKind.LITERAL && rhs.getKind() != SqlKind.LITERAL) {
            // swap lhs, rhs
            RexNode x = lhs;
            lhs = rhs;
            rhs = x;
            flip = true;
        }
        // rhs must be a literal
        if (rhs.getKind() != SqlKind.LITERAL) {
            return null;
        }
        // lhs must be translatable to a RowExtraction to be filterable
        final RowExtraction rex = toRowExtraction(operatorTable, plannerContext, rowSignature.getRowOrder(), lhs);
        if (rex == null || !rex.isFilterable(rowSignature)) {
            return null;
        }
        final String column = rex.getColumn();
        final ExtractionFn extractionFn = rex.getExtractionFn();
        if (column.equals(Column.TIME_COLUMN_NAME) && extractionFn instanceof TimeFormatExtractionFn) {
            // Check if we can strip the extractionFn and convert the filter to a direct filter on __time.
            // This allows potential conversion to query-level "intervals" later on, which is ideal for Druid queries.
            final Granularity granularity = ExtractionFns.toQueryGranularity(extractionFn);
            if (granularity != null) {
                // lhs is FLOOR(__time TO granularity); rhs must be a timestamp
                final long rhsMillis = toMillisLiteral(rhs, plannerContext.getTimeZone());
                final Interval rhsInterval = granularity.bucket(new DateTime(rhsMillis));
                // Is rhs aligned on granularity boundaries?
                final boolean rhsAligned = rhsInterval.getStartMillis() == rhsMillis;
                // Create a BoundRefKey that strips the extractionFn and compares __time as a number.
                final BoundRefKey boundRefKey = new BoundRefKey(column, null, StringComparators.NUMERIC);
                if (kind == SqlKind.EQUALS) {
                    return rhsAligned ? Bounds.interval(boundRefKey, rhsInterval) : Filtration.matchNothing();
                } else if (kind == SqlKind.NOT_EQUALS) {
                    return rhsAligned ? new NotDimFilter(Bounds.interval(boundRefKey, rhsInterval)) : Filtration.matchEverything();
                } else if ((!flip && kind == SqlKind.GREATER_THAN) || (flip && kind == SqlKind.LESS_THAN)) {
                    return Bounds.greaterThanOrEqualTo(boundRefKey, String.valueOf(rhsInterval.getEndMillis()));
                } else if ((!flip && kind == SqlKind.GREATER_THAN_OR_EQUAL) || (flip && kind == SqlKind.LESS_THAN_OR_EQUAL)) {
                    return rhsAligned ? Bounds.greaterThanOrEqualTo(boundRefKey, String.valueOf(rhsInterval.getStartMillis())) : Bounds.greaterThanOrEqualTo(boundRefKey, String.valueOf(rhsInterval.getEndMillis()));
                } else if ((!flip && kind == SqlKind.LESS_THAN) || (flip && kind == SqlKind.GREATER_THAN)) {
                    return rhsAligned ? Bounds.lessThan(boundRefKey, String.valueOf(rhsInterval.getStartMillis())) : Bounds.lessThan(boundRefKey, String.valueOf(rhsInterval.getEndMillis()));
                } else if ((!flip && kind == SqlKind.LESS_THAN_OR_EQUAL) || (flip && kind == SqlKind.GREATER_THAN_OR_EQUAL)) {
                    return Bounds.lessThan(boundRefKey, String.valueOf(rhsInterval.getEndMillis()));
                } else {
                    throw new IllegalStateException("WTF?! Shouldn't have got here...");
                }
            }
        }
        final String val;
        final RexLiteral rhsLiteral = (RexLiteral) rhs;
        if (SqlTypeName.NUMERIC_TYPES.contains(rhsLiteral.getTypeName())) {
            val = String.valueOf(RexLiteral.value(rhsLiteral));
        } else if (SqlTypeName.CHAR_TYPES.contains(rhsLiteral.getTypeName())) {
            val = String.valueOf(RexLiteral.stringValue(rhsLiteral));
        } else if (SqlTypeName.TIMESTAMP == rhsLiteral.getTypeName() || SqlTypeName.DATE == rhsLiteral.getTypeName()) {
            val = String.valueOf(toMillisLiteral(rhsLiteral, plannerContext.getTimeZone()));
        } else {
            // Don't know how to filter on this kind of literal.
            return null;
        }
        // Numeric lhs needs a numeric comparison.
        final boolean lhsIsNumeric = SqlTypeName.NUMERIC_TYPES.contains(lhs.getType().getSqlTypeName()) || SqlTypeName.TIMESTAMP == lhs.getType().getSqlTypeName() || SqlTypeName.DATE == lhs.getType().getSqlTypeName();
        final StringComparator comparator = lhsIsNumeric ? StringComparators.NUMERIC : StringComparators.LEXICOGRAPHIC;
        final BoundRefKey boundRefKey = new BoundRefKey(column, extractionFn, comparator);
        final DimFilter filter;
        // Always use BoundDimFilters, to simplify filter optimization later (it helps to remember the comparator).
        if (kind == SqlKind.EQUALS) {
            filter = Bounds.equalTo(boundRefKey, val);
        } else if (kind == SqlKind.NOT_EQUALS) {
            filter = new NotDimFilter(Bounds.equalTo(boundRefKey, val));
        } else if ((!flip && kind == SqlKind.GREATER_THAN) || (flip && kind == SqlKind.LESS_THAN)) {
            filter = Bounds.greaterThan(boundRefKey, val);
        } else if ((!flip && kind == SqlKind.GREATER_THAN_OR_EQUAL) || (flip && kind == SqlKind.LESS_THAN_OR_EQUAL)) {
            filter = Bounds.greaterThanOrEqualTo(boundRefKey, val);
        } else if ((!flip && kind == SqlKind.LESS_THAN) || (flip && kind == SqlKind.GREATER_THAN)) {
            filter = Bounds.lessThan(boundRefKey, val);
        } else if ((!flip && kind == SqlKind.LESS_THAN_OR_EQUAL) || (flip && kind == SqlKind.GREATER_THAN_OR_EQUAL)) {
            filter = Bounds.lessThanOrEqualTo(boundRefKey, val);
        } else {
            throw new IllegalStateException("WTF?! Shouldn't have got here...");
        }
        return filter;
    } else {
        return null;
    }
}
Also used : TimeFormatExtractionFn(io.druid.query.extraction.TimeFormatExtractionFn) RexLiteral(org.apache.calcite.rex.RexLiteral) NotDimFilter(io.druid.query.filter.NotDimFilter) SqlKind(org.apache.calcite.sql.SqlKind) Granularity(io.druid.java.util.common.granularity.Granularity) StringComparator(io.druid.query.ordering.StringComparator) DateTime(org.joda.time.DateTime) RexCall(org.apache.calcite.rex.RexCall) ExtractionFn(io.druid.query.extraction.ExtractionFn) TimeFormatExtractionFn(io.druid.query.extraction.TimeFormatExtractionFn) LikeDimFilter(io.druid.query.filter.LikeDimFilter) List(java.util.List) BoundRefKey(io.druid.sql.calcite.filtration.BoundRefKey) LikeDimFilter(io.druid.query.filter.LikeDimFilter) OrDimFilter(io.druid.query.filter.OrDimFilter) DimFilter(io.druid.query.filter.DimFilter) NotDimFilter(io.druid.query.filter.NotDimFilter) AndDimFilter(io.druid.query.filter.AndDimFilter) RexNode(org.apache.calcite.rex.RexNode) Interval(org.joda.time.Interval)

Aggregations

SqlKind (org.apache.calcite.sql.SqlKind)44 RexNode (org.apache.calcite.rex.RexNode)21 ArrayList (java.util.ArrayList)16 SqlOperator (org.apache.calcite.sql.SqlOperator)14 RelDataType (org.apache.calcite.rel.type.RelDataType)11 RexCall (org.apache.calcite.rex.RexCall)10 RexInputRef (org.apache.calcite.rex.RexInputRef)8 List (java.util.List)7 AggregateCall (org.apache.calcite.rel.core.AggregateCall)7 RexBuilder (org.apache.calcite.rex.RexBuilder)7 SqlNode (org.apache.calcite.sql.SqlNode)6 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)6 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)5 SqlAggFunction (org.apache.calcite.sql.SqlAggFunction)5 SqlCall (org.apache.calcite.sql.SqlCall)5 ImmutableList (com.google.common.collect.ImmutableList)4 SqlBasicCall (org.apache.calcite.sql.SqlBasicCall)4 Aggregate (org.apache.calcite.rel.core.Aggregate)3 LogicalAggregate (org.apache.calcite.rel.logical.LogicalAggregate)3 SqlTypeName (org.apache.calcite.sql.type.SqlTypeName)3