@Override public DruidExpression toDruidExpression( final PlannerContext plannerContext, final RowSignature rowSignature, final RexNode rexNode ) { // Nothing to do, just leave the operand unchanged. Druid treats millis and timestamps the same internally. final RexCall call = (RexCall) rexNode; return Expressions.toDruidExpression(plannerContext, rowSignature, Iterables.getOnlyElement(call.getOperands())); } }
final RexNode rexNode = Expressions.fromFieldAccess(sourceRowSignature, partialQuery.getSelectProject(), i); final DruidExpression druidExpression = Expressions.toDruidExpression( plannerContext, sourceRowSignature,
/** * Converts an expression to a Granularity, if possible. This is possible if, and only if, the expression * is a timestamp_floor function on the __time column with literal parameters for period, origin, and timeZone. * * @return granularity or null if not possible */ @Nullable public static Granularity toQueryGranularity(final DruidExpression expression, final ExprMacroTable macroTable) { final TimestampFloorExprMacro.TimestampFloorExpr expr = asTimestampFloorExpr(expression, macroTable); if (expr == null) { return null; } final Expr arg = expr.getArg(); final Granularity granularity = expr.getGranularity(); if (ColumnHolder.TIME_COLUMN_NAME.equals(Parser.getIdentifierIfIdentifier(arg))) { return granularity; } else { return null; } }
return toSimpleLeafFilter( plannerContext, rowSignature, } else if (kind == SqlKind.IS_FALSE || kind == SqlKind.IS_NOT_TRUE) { return new NotDimFilter( toSimpleLeafFilter( plannerContext, rowSignature, final DruidExpression druidExpression = toDruidExpression(plannerContext, rowSignature, operand); if (druidExpression == null || !druidExpression.isSimpleExtraction()) { return null; final DruidExpression lhsExpression = toDruidExpression(plannerContext, rowSignature, lhs); if (lhsExpression == null) { return null; final Granularity queryGranularity = toQueryGranularity(lhsExpression, plannerContext.getExprMacroTable()); if (queryGranularity != null) { return buildTimeFloorFilter(ColumnHolder.TIME_COLUMN_NAME, queryGranularity, flippedKind, rhsMillis); return getBoundTimeDimFilter(flippedKind, boundRefKey, rhsInterval, rhsAligned);
final RexNode rexNode = Expressions.fromFieldAccess( rowSignature, project, final DimFilter nonNullFilter = Expressions.toFilter( plannerContext, rowSignature,
@Nullable public static List<DruidExpression> getArgumentsForSimpleAggregator( final PlannerContext plannerContext, final RowSignature rowSignature, final AggregateCall call, final Project project ) { return call.getArgList().stream() .map(i -> Expressions.fromFieldAccess(rowSignature, project, i)) .map(rexNode -> toDruidExpressionForSimpleAggregator(plannerContext, rowSignature, rexNode)) .collect(Collectors.toList()); }
@Nullable public static DruidExpression convertCall( final PlannerContext plannerContext, final RowSignature rowSignature, final RexNode rexNode, final Function<List<DruidExpression>, DruidExpression> expressionFunction ) { final RexCall call = (RexCall) rexNode; final List<DruidExpression> druidExpressions = Expressions.toDruidExpressions( plannerContext, rowSignature, call.getOperands() ); if (druidExpressions == null) { return null; } return expressionFunction.apply(druidExpressions); }
/** * 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; } // Check if a cast is necessary. final ExprType toExprType = Expressions.exprTypeForValueType( aggregateRowSignature.getColumnType(expression.getDirectColumn()) ); final ExprType fromExprType = Expressions.exprTypeForValueType( Calcites.getValueTypeForSqlTypeName(rexNode.getType().getSqlTypeName()) ); return toExprType.equals(fromExprType); }
/** * Build a filter for an expression like FLOOR(column TO granularity) [operator] rhsMillis */ private static DimFilter buildTimeFloorFilter( final String column, final Granularity granularity, final SqlKind operatorKind, final long rhsMillis ) { final BoundRefKey boundRefKey = new BoundRefKey(column, null, StringComparators.NUMERIC); final Interval rhsInterval = granularity.bucket(DateTimes.utc(rhsMillis)); // Is rhs aligned on granularity boundaries? final boolean rhsAligned = rhsInterval.getStartMillis() == rhsMillis; return getBoundTimeDimFilter(operatorKind, boundRefKey, rhsInterval, rhsAligned); }
return toSimpleLeafFilter( plannerContext, rowSignature, } else if (kind == SqlKind.IS_FALSE || kind == SqlKind.IS_NOT_TRUE) { return new NotDimFilter( toSimpleLeafFilter( plannerContext, rowSignature, final DruidExpression druidExpression = toDruidExpression(plannerContext, rowSignature, operand); if (druidExpression == null || !druidExpression.isSimpleExtraction()) { return null; final DruidExpression lhsExpression = toDruidExpression(plannerContext, rowSignature, lhs); if (lhsExpression == null) { return null; final Granularity queryGranularity = toQueryGranularity(lhsExpression, plannerContext.getExprMacroTable()); if (queryGranularity != null) { return buildTimeFloorFilter(ColumnHolder.TIME_COLUMN_NAME, queryGranularity, flippedKind, rhsMillis); } else if (kind == SqlKind.LIKE) { final List<RexNode> operands = ((RexCall) rexNode).getOperands(); final DruidExpression druidExpression = toDruidExpression( plannerContext, rowSignature,
final RexNode rexNode = Expressions.fromFieldAccess( rowSignature, project, final DimFilter nonNullFilter = Expressions.toFilter( plannerContext, rowSignature,
@Nullable public static List<DruidExpression> getArgumentsForSimpleAggregator( final PlannerContext plannerContext, final RowSignature rowSignature, final AggregateCall call, final Project project ) { return call.getArgList().stream() .map(i -> Expressions.fromFieldAccess(rowSignature, project, i)) .map(rexNode -> toDruidExpressionForSimpleAggregator(plannerContext, rowSignature, rexNode)) .collect(Collectors.toList()); }
final List<DruidExpression> druidExpressions = Expressions.toDruidExpressions( plannerContext, rowSignature,
/** * 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; } // Check if a cast is necessary. final ExprType toExprType = Expressions.exprTypeForValueType( aggregateRowSignature.getColumnType(expression.getDirectColumn()) ); final ExprType fromExprType = Expressions.exprTypeForValueType( Calcites.getValueTypeForSqlTypeName(rexNode.getType().getSqlTypeName()) ); return toExprType.equals(fromExprType); }
@Override public DruidExpression toDruidExpression( final PlannerContext plannerContext, final RowSignature rowSignature, final RexNode rexNode ) { // Nothing to do, just leave the operand unchanged. Druid treats millis and timestamps the same internally. final RexCall call = (RexCall) rexNode; return Expressions.toDruidExpression(plannerContext, rowSignature, Iterables.getOnlyElement(call.getOperands())); } }
final DruidExpression input = Expressions.toDruidExpression( plannerContext, rowSignature, Expressions.fromFieldAccess( rowSignature, project, final RexNode probabilityArg = Expressions.fromFieldAccess( rowSignature, project, final RexNode resolutionArg = Expressions.fromFieldAccess( rowSignature, project,
@Nullable public static DruidExpression convertCall( final PlannerContext plannerContext, final RowSignature rowSignature, final RexNode rexNode, final Function<List<DruidExpression>, DruidExpression> expressionFunction ) { final RexCall call = (RexCall) rexNode; final List<DruidExpression> druidExpressions = Expressions.toDruidExpressions( plannerContext, rowSignature, call.getOperands() ); if (druidExpressions == null) { return null; } return expressionFunction.apply(druidExpressions); }
final TimestampFloorExprMacro.TimestampFloorExpr floorExpr = Expressions.asTimestampFloorExpr( input, macroTable
/** * Translate a list of Calcite {@code RexNode} to Druid expressions. * * @param plannerContext SQL planner context * @param rowSignature signature of the rows to be extracted from * @param rexNodes list of Calcite expressions meant to be applied on top of the rows * * @return list of Druid expressions in the same order as rexNodes, or null if not possible. * If a non-null list is returned, all elements will be non-null. */ @Nullable public static List<DruidExpression> toDruidExpressions( final PlannerContext plannerContext, final RowSignature rowSignature, final List<RexNode> rexNodes ) { final List<DruidExpression> retVal = new ArrayList<>(rexNodes.size()); for (RexNode rexNode : rexNodes) { final DruidExpression druidExpression = toDruidExpression(plannerContext, rowSignature, rexNode); if (druidExpression == null) { return null; } retVal.add(druidExpression); } return retVal; }
final RexNode rexNode = Expressions.fromFieldAccess( rowSignature, project, ); final DruidExpression arg = Expressions.toDruidExpression(plannerContext, rowSignature, rexNode); if (arg == null) { return null;