use of org.apache.druid.sql.calcite.expression.DruidExpression in project druid by druid-io.
the class BloomFilterOperatorConversion method toDruidFilter.
@Nullable
@Override
public DimFilter toDruidFilter(final PlannerContext plannerContext, RowSignature rowSignature, @Nullable VirtualColumnRegistry virtualColumnRegistry, final RexNode rexNode) {
final List<RexNode> operands = ((RexCall) rexNode).getOperands();
final DruidExpression druidExpression = Expressions.toDruidExpression(plannerContext, rowSignature, operands.get(0));
if (druidExpression == null) {
return null;
}
String base64EncodedBloomKFilter = RexLiteral.stringValue(operands.get(1));
final byte[] decoded = StringUtils.decodeBase64String(base64EncodedBloomKFilter);
BloomKFilter filter;
BloomKFilterHolder holder;
try {
filter = BloomFilterSerializersModule.bloomKFilterFromBytes(decoded);
holder = BloomKFilterHolder.fromBloomKFilter(filter);
} catch (IOException ioe) {
throw new RuntimeException("Failed to deserialize bloom filter", ioe);
}
if (druidExpression.isSimpleExtraction()) {
return new BloomDimFilter(druidExpression.getSimpleExtraction().getColumn(), holder, druidExpression.getSimpleExtraction().getExtractionFn(), null);
} else if (virtualColumnRegistry != null) {
String virtualColumnName = virtualColumnRegistry.getOrCreateVirtualColumnForExpression(druidExpression, operands.get(0).getType());
if (virtualColumnName == null) {
return null;
}
return new BloomDimFilter(virtualColumnName, holder, null, null);
} else {
return null;
}
}
use of org.apache.druid.sql.calcite.expression.DruidExpression in project druid by druid-io.
the class DruidJoinQueryRel method toDruidQuery.
@Override
public DruidQuery toDruidQuery(final boolean finalizeAggregations) {
final DruidRel<?> leftDruidRel = (DruidRel<?>) left;
final DruidQuery leftQuery = Preconditions.checkNotNull((leftDruidRel).toDruidQuery(false), "leftQuery");
final RowSignature leftSignature = leftQuery.getOutputRowSignature();
final DataSource leftDataSource;
final DruidRel<?> rightDruidRel = (DruidRel<?>) right;
final DruidQuery rightQuery = Preconditions.checkNotNull(rightDruidRel.toDruidQuery(false), "rightQuery");
final RowSignature rightSignature = rightQuery.getOutputRowSignature();
final DataSource rightDataSource;
if (computeLeftRequiresSubquery(leftDruidRel)) {
leftDataSource = new QueryDataSource(leftQuery.getQuery());
if (leftFilter != null) {
throw new ISE("Filter on left table is supposed to be null if left child is a query source");
}
} else {
leftDataSource = leftQuery.getDataSource();
}
if (computeRightRequiresSubquery(rightDruidRel)) {
rightDataSource = new QueryDataSource(rightQuery.getQuery());
} else {
rightDataSource = rightQuery.getDataSource();
}
final Pair<String, RowSignature> prefixSignaturePair = computeJoinRowSignature(leftSignature, rightSignature);
VirtualColumnRegistry virtualColumnRegistry = VirtualColumnRegistry.create(prefixSignaturePair.rhs, getPlannerContext().getExprMacroTable());
getPlannerContext().setJoinExpressionVirtualColumnRegistry(virtualColumnRegistry);
// Generate the condition for this join as a Druid expression.
final DruidExpression condition = Expressions.toDruidExpression(getPlannerContext(), prefixSignaturePair.rhs, joinRel.getCondition());
// Unsetting it to avoid any VC Registry leaks incase there are multiple druid quries for the SQL
// It should be fixed soon with changes in interface for SqlOperatorConversion and Expressions bridge class
getPlannerContext().setJoinExpressionVirtualColumnRegistry(null);
// quiets static code analysis.
if (condition == null) {
throw new CannotBuildQueryException(joinRel, joinRel.getCondition());
}
return partialQuery.build(JoinDataSource.create(leftDataSource, rightDataSource, prefixSignaturePair.lhs, condition.getExpression(), toDruidJoinType(joinRel.getJoinType()), getDimFilter(getPlannerContext(), leftSignature, leftFilter), getPlannerContext().getExprMacroTable()), prefixSignaturePair.rhs, getPlannerContext(), getCluster().getRexBuilder(), finalizeAggregations, virtualColumnRegistry);
}
use of org.apache.druid.sql.calcite.expression.DruidExpression in project druid by druid-io.
the class SubstringOperatorConversion method toDruidExpression.
@Override
public DruidExpression toDruidExpression(final PlannerContext plannerContext, final RowSignature rowSignature, final RexNode rexNode) {
// Can't simply pass-through operands, since SQL standard args don't match what Druid's expression language wants.
// SQL is 1-indexed, Druid is 0-indexed.
final RexCall call = (RexCall) rexNode;
final DruidExpression input = Expressions.toDruidExpression(plannerContext, rowSignature, call.getOperands().get(0));
if (input == null) {
return null;
}
final int index = RexLiteral.intValue(call.getOperands().get(1)) - 1;
final int length;
if (call.getOperands().size() > 2) {
length = RexLiteral.intValue(call.getOperands().get(2));
} else {
length = -1;
}
return input.map(simpleExtraction -> simpleExtraction.cascade(new SubstringDimExtractionFn(index, length < 0 ? null : length)), expression -> StringUtils.format("substring(%s, %s, %s)", expression, DruidExpression.numberLiteral(index), DruidExpression.numberLiteral(length)));
}
use of org.apache.druid.sql.calcite.expression.DruidExpression in project druid by druid-io.
the class TimeExtractOperatorConversion method toDruidExpression.
@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 = OperatorConversions.getOperandWithDefault(call.getOperands(), 2, operand -> DateTimes.inferTzFromString(RexLiteral.stringValue(operand)), plannerContext.getTimeZone());
return applyTimeExtract(timeExpression, unit, timeZone);
}
use of org.apache.druid.sql.calcite.expression.DruidExpression in project druid by druid-io.
the class TrimOperatorConversion method toDruidExpression.
@Override
public DruidExpression toDruidExpression(final PlannerContext plannerContext, final RowSignature rowSignature, final RexNode rexNode) {
// TRIM(<style> <chars> FROM <arg>)
final RexCall call = (RexCall) rexNode;
final RexLiteral flag = (RexLiteral) call.getOperands().get(0);
final SqlTrimFunction.Flag trimStyle = (SqlTrimFunction.Flag) flag.getValue();
final DruidExpression charsExpression = Expressions.toDruidExpression(plannerContext, rowSignature, call.getOperands().get(1));
final DruidExpression stringExpression = Expressions.toDruidExpression(plannerContext, rowSignature, call.getOperands().get(2));
if (charsExpression == null || stringExpression == null) {
return null;
}
return makeTrimExpression(trimStyle, stringExpression, charsExpression, Calcites.getColumnTypeForRelDataType(rexNode.getType()));
}
Aggregations