use of org.apache.calcite.rex.RexNode in project druid by druid-io.
the class QuantileSqlAggregator method toDruidAggregation.
@Override
public Aggregation toDruidAggregation(final String name, final RowSignature rowSignature, final DruidOperatorTable operatorTable, final PlannerContext plannerContext, final List<Aggregation> existingAggregations, final Project project, final AggregateCall aggregateCall, final DimFilter filter) {
final RowExtraction rex = Expressions.toRowExtraction(operatorTable, plannerContext, rowSignature.getRowOrder(), Expressions.fromFieldAccess(rowSignature, project, aggregateCall.getArgList().get(0)));
if (rex == null) {
return null;
}
final AggregatorFactory aggregatorFactory;
final String histogramName = String.format("%s:agg", name);
final RexNode probabilityArg = Expressions.fromFieldAccess(rowSignature, project, aggregateCall.getArgList().get(1));
final float probability = ((Number) RexLiteral.value(probabilityArg)).floatValue();
final int resolution;
if (aggregateCall.getArgList().size() >= 3) {
final RexNode resolutionArg = Expressions.fromFieldAccess(rowSignature, project, aggregateCall.getArgList().get(2));
resolution = ((Number) RexLiteral.value(resolutionArg)).intValue();
} else {
resolution = ApproximateHistogram.DEFAULT_HISTOGRAM_SIZE;
}
final int numBuckets = ApproximateHistogram.DEFAULT_BUCKET_SIZE;
final float lowerLimit = Float.NEGATIVE_INFINITY;
final float upperLimit = Float.POSITIVE_INFINITY;
// Look for existing matching aggregatorFactory.
for (final Aggregation existing : existingAggregations) {
for (AggregatorFactory factory : existing.getAggregatorFactories()) {
final boolean matches = Aggregations.aggregatorMatches(factory, filter, ApproximateHistogramAggregatorFactory.class, new Predicate<ApproximateHistogramAggregatorFactory>() {
@Override
public boolean apply(final ApproximateHistogramAggregatorFactory theFactory) {
return theFactory.getFieldName().equals(rex.getColumn()) && theFactory.getResolution() == resolution && theFactory.getNumBuckets() == numBuckets && theFactory.getLowerLimit() == lowerLimit && theFactory.getUpperLimit() == upperLimit;
}
});
if (matches) {
// Found existing one. Use this.
return Aggregation.create(ImmutableList.<AggregatorFactory>of(), new QuantilePostAggregator(name, factory.getName(), probability));
}
}
}
if (rowSignature.getColumnType(rex.getColumn()) == ValueType.COMPLEX) {
aggregatorFactory = new ApproximateHistogramFoldingAggregatorFactory(histogramName, rex.getColumn(), resolution, numBuckets, lowerLimit, upperLimit);
} else {
aggregatorFactory = new ApproximateHistogramAggregatorFactory(histogramName, rex.getColumn(), resolution, numBuckets, lowerLimit, upperLimit);
}
return Aggregation.create(ImmutableList.of(aggregatorFactory), new QuantilePostAggregator(name, histogramName, probability)).filter(filter);
}
use of org.apache.calcite.rex.RexNode in project drill by apache.
the class MongoPushDownFilterForScan method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final ScanPrel scan = (ScanPrel) call.rel(1);
final FilterPrel filter = (FilterPrel) call.rel(0);
final RexNode condition = filter.getCondition();
MongoGroupScan groupScan = (MongoGroupScan) scan.getGroupScan();
if (groupScan.isFilterPushedDown()) {
return;
}
LogicalExpression conditionExp = DrillOptiq.toDrill(new DrillParseContext(PrelUtil.getPlannerSettings(call.getPlanner())), scan, condition);
MongoFilterBuilder mongoFilterBuilder = new MongoFilterBuilder(groupScan, conditionExp);
MongoScanSpec newScanSpec = mongoFilterBuilder.parseTree();
if (newScanSpec == null) {
// no filter pushdown so nothing to apply.
return;
}
MongoGroupScan newGroupsScan = null;
try {
newGroupsScan = new MongoGroupScan(groupScan.getUserName(), groupScan.getStoragePlugin(), newScanSpec, groupScan.getColumns());
} catch (IOException e) {
logger.error(e.getMessage(), e);
throw new DrillRuntimeException(e.getMessage(), e);
}
newGroupsScan.setFilterPushedDown(true);
final ScanPrel newScanPrel = ScanPrel.create(scan, filter.getTraitSet(), newGroupsScan, scan.getRowType());
if (mongoFilterBuilder.isAllExpressionsConverted()) {
/*
* Since we could convert the entire filter condition expression into an
* Mongo filter, we can eliminate the filter operator altogether.
*/
call.transformTo(newScanPrel);
} else {
call.transformTo(filter.copy(filter.getTraitSet(), ImmutableList.of((RelNode) newScanPrel)));
}
}
use of org.apache.calcite.rex.RexNode in project drill by apache.
the class DrillConstExecutor method reduce.
@Override
public void reduce(final RexBuilder rexBuilder, List<RexNode> constExps, final List<RexNode> reducedValues) {
for (final RexNode newCall : constExps) {
LogicalExpression logEx = DrillOptiq.toDrill(new DrillParseContext(plannerSettings), (RelNode) null, /* input rel */
newCall);
ErrorCollectorImpl errors = new ErrorCollectorImpl();
final LogicalExpression materializedExpr = ExpressionTreeMaterializer.materialize(logEx, null, errors, funcImplReg);
if (errors.getErrorCount() != 0) {
String message = String.format("Failure while materializing expression in constant expression evaluator [%s]. Errors: %s", newCall.toString(), errors.toString());
throw UserException.planError().message(message).build(logger);
}
if (NON_REDUCIBLE_TYPES.contains(materializedExpr.getMajorType().getMinorType())) {
logger.debug("Constant expression not folded due to return type {}, complete expression: {}", materializedExpr.getMajorType(), ExpressionStringBuilder.toString(materializedExpr));
reducedValues.add(newCall);
continue;
}
ValueHolder output = InterpreterEvaluator.evaluateConstantExpr(udfUtilities, materializedExpr);
final RelDataTypeFactory typeFactory = rexBuilder.getTypeFactory();
if (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL && TypeHelper.isNull(output)) {
SqlTypeName sqlTypeName = TypeInferenceUtils.getCalciteTypeFromDrillType(materializedExpr.getMajorType().getMinorType());
if (sqlTypeName == null) {
String message = String.format("Error reducing constant expression, unsupported type: %s.", materializedExpr.getMajorType().getMinorType());
throw UserException.unsupportedError().message(message).build(logger);
}
reducedValues.add(rexBuilder.makeNullLiteral(sqlTypeName));
continue;
}
Function<ValueHolder, RexNode> literator = new Function<ValueHolder, RexNode>() {
@Override
public RexNode apply(ValueHolder output) {
switch(materializedExpr.getMajorType().getMinorType()) {
case INT:
{
int value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? ((NullableIntHolder) output).value : ((IntHolder) output).value;
return rexBuilder.makeLiteral(new BigDecimal(value), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.INTEGER, newCall.getType().isNullable()), false);
}
case BIGINT:
{
long value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? ((NullableBigIntHolder) output).value : ((BigIntHolder) output).value;
return rexBuilder.makeLiteral(new BigDecimal(value), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.BIGINT, newCall.getType().isNullable()), false);
}
case FLOAT4:
{
float value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? ((NullableFloat4Holder) output).value : ((Float4Holder) output).value;
return rexBuilder.makeLiteral(new BigDecimal(value), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.FLOAT, newCall.getType().isNullable()), false);
}
case FLOAT8:
{
double value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? ((NullableFloat8Holder) output).value : ((Float8Holder) output).value;
return rexBuilder.makeLiteral(new BigDecimal(value), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.DOUBLE, newCall.getType().isNullable()), false);
}
case VARCHAR:
{
String value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? StringFunctionHelpers.getStringFromVarCharHolder((NullableVarCharHolder) output) : StringFunctionHelpers.getStringFromVarCharHolder((VarCharHolder) output);
return rexBuilder.makeLiteral(value, TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.VARCHAR, newCall.getType().isNullable()), false);
}
case BIT:
{
boolean value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? ((NullableBitHolder) output).value == 1 : ((BitHolder) output).value == 1;
return rexBuilder.makeLiteral(value, TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.BOOLEAN, newCall.getType().isNullable()), false);
}
case DATE:
{
Calendar value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? new DateTime(((NullableDateHolder) output).value, DateTimeZone.UTC).toCalendar(null) : new DateTime(((DateHolder) output).value, DateTimeZone.UTC).toCalendar(null);
return rexBuilder.makeLiteral(value, TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.DATE, newCall.getType().isNullable()), false);
}
case DECIMAL9:
{
long value;
int scale;
if (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) {
NullableDecimal9Holder decimal9Out = (NullableDecimal9Holder) output;
value = decimal9Out.value;
scale = decimal9Out.scale;
} else {
Decimal9Holder decimal9Out = (Decimal9Holder) output;
value = decimal9Out.value;
scale = decimal9Out.scale;
}
return rexBuilder.makeLiteral(new BigDecimal(BigInteger.valueOf(value), scale), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.DECIMAL, newCall.getType().isNullable()), false);
}
case DECIMAL18:
{
long value;
int scale;
if (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) {
NullableDecimal18Holder decimal18Out = (NullableDecimal18Holder) output;
value = decimal18Out.value;
scale = decimal18Out.scale;
} else {
Decimal18Holder decimal18Out = (Decimal18Holder) output;
value = decimal18Out.value;
scale = decimal18Out.scale;
}
return rexBuilder.makeLiteral(new BigDecimal(BigInteger.valueOf(value), scale), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.DECIMAL, newCall.getType().isNullable()), false);
}
case DECIMAL28SPARSE:
{
DrillBuf buffer;
int start;
int scale;
if (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) {
NullableDecimal28SparseHolder decimal28Out = (NullableDecimal28SparseHolder) output;
buffer = decimal28Out.buffer;
start = decimal28Out.start;
scale = decimal28Out.scale;
} else {
Decimal28SparseHolder decimal28Out = (Decimal28SparseHolder) output;
buffer = decimal28Out.buffer;
start = decimal28Out.start;
scale = decimal28Out.scale;
}
return rexBuilder.makeLiteral(org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(buffer, start * 20, 5, scale), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.DECIMAL, newCall.getType().isNullable()), false);
}
case DECIMAL38SPARSE:
{
DrillBuf buffer;
int start;
int scale;
if (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) {
NullableDecimal38SparseHolder decimal38Out = (NullableDecimal38SparseHolder) output;
buffer = decimal38Out.buffer;
start = decimal38Out.start;
scale = decimal38Out.scale;
} else {
Decimal38SparseHolder decimal38Out = (Decimal38SparseHolder) output;
buffer = decimal38Out.buffer;
start = decimal38Out.start;
scale = decimal38Out.scale;
}
return rexBuilder.makeLiteral(org.apache.drill.exec.util.DecimalUtility.getBigDecimalFromSparse(buffer, start * 24, 6, scale), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.DECIMAL, newCall.getType().isNullable()), false);
}
case TIME:
{
Calendar value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? new DateTime(((NullableTimeHolder) output).value, DateTimeZone.UTC).toCalendar(null) : new DateTime(((TimeHolder) output).value, DateTimeZone.UTC).toCalendar(null);
return rexBuilder.makeLiteral(value, TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.TIME, newCall.getType().isNullable()), false);
}
case TIMESTAMP:
{
Calendar value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? new DateTime(((NullableTimeStampHolder) output).value, DateTimeZone.UTC).toCalendar(null) : new DateTime(((TimeStampHolder) output).value, DateTimeZone.UTC).toCalendar(null);
return rexBuilder.makeLiteral(value, TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.TIMESTAMP, newCall.getType().isNullable()), false);
}
case INTERVALYEAR:
{
BigDecimal value = (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) ? new BigDecimal(((NullableIntervalYearHolder) output).value) : new BigDecimal(((IntervalYearHolder) output).value);
return rexBuilder.makeLiteral(value, TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.INTERVAL_YEAR_MONTH, newCall.getType().isNullable()), false);
}
case INTERVALDAY:
{
int days;
int milliseconds;
if (materializedExpr.getMajorType().getMode() == TypeProtos.DataMode.OPTIONAL) {
NullableIntervalDayHolder intervalDayOut = (NullableIntervalDayHolder) output;
days = intervalDayOut.days;
milliseconds = intervalDayOut.milliseconds;
} else {
IntervalDayHolder intervalDayOut = (IntervalDayHolder) output;
days = intervalDayOut.days;
milliseconds = intervalDayOut.milliseconds;
}
return rexBuilder.makeLiteral(new BigDecimal(days * DateUtility.daysToStandardMillis + milliseconds), TypeInferenceUtils.createCalciteTypeWithNullability(typeFactory, SqlTypeName.INTERVAL_DAY_TIME, newCall.getType().isNullable()), false);
}
// as new types may be added in the future.
default:
logger.debug("Constant expression not folded due to return type {}, complete expression: {}", materializedExpr.getMajorType(), ExpressionStringBuilder.toString(materializedExpr));
return newCall;
}
}
};
reducedValues.add(literator.apply(output));
}
}
use of org.apache.calcite.rex.RexNode in project drill by apache.
the class DrillProjectRelBase method getProjectExpressions.
protected List<NamedExpression> getProjectExpressions(DrillParseContext context) {
List<NamedExpression> expressions = Lists.newArrayList();
HashMap<String, String> starColPrefixes = new HashMap<String, String>();
// This will allow us to differentiate the regular expanded from *, and the regular column referenced in the query.
for (Pair<RexNode, String> pair : projects()) {
if (StarColumnHelper.isPrefixedStarColumn(pair.right)) {
String prefix = StarColumnHelper.extractStarColumnPrefix(pair.right);
if (!starColPrefixes.containsKey(prefix)) {
starColPrefixes.put(prefix, pair.right);
}
}
}
for (Pair<RexNode, String> pair : projects()) {
if (!StarColumnHelper.subsumeColumn(starColPrefixes, pair.right)) {
LogicalExpression expr = DrillOptiq.toDrill(context, getInput(), pair.left);
expressions.add(new NamedExpression(expr, FieldReference.getWithQuotedRef(pair.right)));
}
}
return expressions;
}
use of org.apache.calcite.rex.RexNode in project drill by apache.
the class DrillProjectRelBase method getSimpleFieldCount.
private int getSimpleFieldCount() {
int cnt = 0;
final ComplexFieldWithNamedSegmentIdentifier complexFieldIdentifer = new ComplexFieldWithNamedSegmentIdentifier();
// a + b, a * 10 + b, etc are not simple fields, since they are expressions.
for (RexNode expr : this.getProjects()) {
if (expr instanceof RexInputRef) {
// Simple Field reference.
cnt++;
} else if (expr instanceof RexCall && expr.accept(complexFieldIdentifer)) {
// Complex field with named segments only.
cnt++;
}
}
return cnt;
}
Aggregations