@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())); } }
@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())); } }
/** * 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; }
/** * Translates to an "expression" type leaf filter. Used as a fallback if we can't use a simple leaf filter. */ @Nullable private static DimFilter toExpressionLeafFilter( final PlannerContext plannerContext, final RowSignature rowSignature, final RexNode rexNode ) { final DruidExpression druidExpression = toDruidExpression(plannerContext, rowSignature, rexNode); return druidExpression == null ? null : new ExpressionDimFilter(druidExpression.getExpression(), plannerContext.getExprMacroTable()); }
final SqlTrimFunction.Flag trimStyle = (SqlTrimFunction.Flag) flag.getValue(); final DruidExpression charsExpression = Expressions.toDruidExpression( plannerContext, rowSignature, ); final DruidExpression stringExpression = Expressions.toDruidExpression( plannerContext, rowSignature,
@Override public DruidExpression toDruidExpression( final PlannerContext plannerContext, final RowSignature rowSignature, final RexNode rexNode ) { // EXTRACT(timeUnit FROM arg) final RexCall call = (RexCall) rexNode; final RexLiteral flag = (RexLiteral) call.getOperands().get(0); final TimeUnitRange calciteUnit = (TimeUnitRange) flag.getValue(); final RexNode arg = call.getOperands().get(1); final DruidExpression input = Expressions.toDruidExpression(plannerContext, rowSignature, arg); if (input == null) { return null; } final TimestampExtractExprMacro.Unit druidUnit = EXTRACT_UNIT_MAP.get(calciteUnit); if (druidUnit == null) { // Don't know how to extract this time unit. return null; } return TimeExtractOperatorConversion.applyTimeExtract(input, druidUnit, plannerContext.getTimeZone()); } }
@Nullable @Override public DimFilter toDruidFilter( PlannerContext plannerContext, RowSignature rowSignature, RexNode rexNode ) { final List<RexNode> operands = ((RexCall) rexNode).getOperands(); final DruidExpression druidExpression = Expressions.toDruidExpression( plannerContext, rowSignature, operands.get(0) ); if (druidExpression == null || !druidExpression.isSimpleExtraction()) { return null; } return new LikeDimFilter( druidExpression.getSimpleExtraction().getColumn(), RexLiteral.stringValue(operands.get(1)), operands.size() > 2 ? RexLiteral.stringValue(operands.get(2)) : null, druidExpression.getSimpleExtraction().getExtractionFn() ); } }
private static DruidExpression toDruidExpressionForSimpleAggregator( final PlannerContext plannerContext, final RowSignature rowSignature, final RexNode rexNode ) { final DruidExpression druidExpression = Expressions.toDruidExpression(plannerContext, rowSignature, rexNode); if (druidExpression == null) { return null; } if (druidExpression.isSimpleExtraction() && (!druidExpression.isDirectColumnAccess() || rowSignature.getColumnType(druidExpression.getDirectColumn()) == ValueType.STRING)) { // Aggregators are unable to implicitly cast strings to numbers. So remove the simple extraction in this case. return druidExpression.map(simpleExtraction -> null, Function.identity()); } else { return druidExpression; } } }
final DruidExpression timeExpression = Expressions.toDruidExpression(plannerContext, rowSignature, timeArg); if (timeExpression == null) { return null;
@Override public DruidExpression toDruidExpression( final PlannerContext plannerContext, final RowSignature rowSignature, final RexNode rexNode ) { final RexCall call = (RexCall) rexNode; final RexNode timeArg = call.getOperands().get(0); final DruidExpression timeExpression = Expressions.toDruidExpression(plannerContext, rowSignature, timeArg); if (timeExpression == null) { return null; } final TimestampExtractExprMacro.Unit unit = TimestampExtractExprMacro.Unit.valueOf( StringUtils.toUpperCase(RexLiteral.stringValue(call.getOperands().get(1))) ); final DateTimeZone timeZone = call.getOperands().size() > 2 && !RexLiteral.isNullLiteral(call.getOperands().get(2)) ? DateTimes.inferTzFromString(RexLiteral.stringValue(call.getOperands().get(2))) : plannerContext.getTimeZone(); return applyTimeExtract(timeExpression, unit, timeZone); } }
final DruidExpression expression = Expressions.toDruidExpression( plannerContext, sourceRowSignature,
for (final RexNode postAggregatorRexNode : project.getChildExps()) { final DruidExpression postAggregatorExpression = Expressions.toDruidExpression( plannerContext, inputRowSignature,
final DruidExpression operandExpression = Expressions.toDruidExpression( plannerContext, rowSignature,
final DruidExpression druidExpression = Expressions.toDruidExpression( plannerContext, rowSignature,
final DruidExpression druidExpression = Expressions.toDruidExpression( plannerContext, rowSignature,
final DruidExpression input = Expressions.toDruidExpression( plannerContext, rowSignature,
final DruidExpression druidExpression = Expressions.toDruidExpression( plannerContext, sourceRowSignature,
final DruidExpression druidExpression = Expressions.toDruidExpression( plannerContext, rowSignature,
final RexNode shiftRexNode = operands.get(1); final DruidExpression timeExpr = Expressions.toDruidExpression(plannerContext, rowSignature, timeRexNode); final DruidExpression shiftExpr = Expressions.toDruidExpression(plannerContext, rowSignature, shiftRexNode);
private void testExpression( final RexNode rexNode, final DruidExpression expectedExpression, final Object expectedResult ) { final DruidExpression expression = Expressions.toDruidExpression(plannerContext, rowSignature, rexNode); Assert.assertEquals("Expression for: " + rexNode, expectedExpression, expression); final ExprEval result = Parser.parse(expression.getExpression(), plannerContext.getExprMacroTable()) .eval(Parser.withMap(bindings)); Assert.assertEquals("Result for: " + rexNode, expectedResult, result.value()); } }