use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef in project calcite by apache.
the class RelOptUtil method splitCorrelatedFilterCondition.
private static void splitCorrelatedFilterCondition(LogicalFilter filter, RexNode condition, List<RexNode> joinKeys, List<RexNode> correlatedJoinKeys, List<RexNode> nonEquiList, boolean extractCorrelatedFieldAccess) {
if (condition instanceof RexCall) {
RexCall call = (RexCall) condition;
if (call.getOperator().getKind() == SqlKind.AND) {
for (RexNode operand : call.getOperands()) {
splitCorrelatedFilterCondition(filter, operand, joinKeys, correlatedJoinKeys, nonEquiList, extractCorrelatedFieldAccess);
}
return;
}
if (call.getOperator().getKind() == SqlKind.EQUALS) {
final List<RexNode> operands = call.getOperands();
RexNode op0 = operands.get(0);
RexNode op1 = operands.get(1);
if (extractCorrelatedFieldAccess) {
if (!RexUtil.containsFieldAccess(op0) && (op1 instanceof RexFieldAccess)) {
joinKeys.add(op0);
correlatedJoinKeys.add(op1);
return;
} else if ((op0 instanceof RexFieldAccess) && !RexUtil.containsFieldAccess(op1)) {
correlatedJoinKeys.add(op0);
joinKeys.add(op1);
return;
}
} else {
if (!(RexUtil.containsInputRef(op0)) && (op1 instanceof RexInputRef)) {
correlatedJoinKeys.add(op0);
joinKeys.add(op1);
return;
} else if ((op0 instanceof RexInputRef) && !(RexUtil.containsInputRef(op1))) {
joinKeys.add(op0);
correlatedJoinKeys.add(op1);
return;
}
}
}
}
// The operator is not of RexCall type
// So we fail. Fall through.
// Add this condition to the list of non-equi-join conditions.
nonEquiList.add(condition);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef in project calcite by apache.
the class RexProgramTest method testSimplifyIsNotNull.
@Test
public void testSimplifyIsNotNull() {
RelDataType intType = typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.INTEGER), false);
RelDataType intNullableType = typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.INTEGER), true);
final RexInputRef i0 = rexBuilder.makeInputRef(intNullableType, 0);
final RexInputRef i1 = rexBuilder.makeInputRef(intNullableType, 1);
final RexInputRef i2 = rexBuilder.makeInputRef(intType, 2);
final RexInputRef i3 = rexBuilder.makeInputRef(intType, 3);
final RexLiteral one = rexBuilder.makeExactLiteral(BigDecimal.ONE);
final RexLiteral null_ = rexBuilder.makeNullLiteral(intType);
checkSimplify(isNotNull(lt(i0, i1)), "AND(IS NOT NULL($0), IS NOT NULL($1))");
checkSimplify(isNotNull(lt(i0, i2)), "IS NOT NULL($0)");
checkSimplify(isNotNull(lt(i2, i3)), "true");
checkSimplify(isNotNull(lt(i0, one)), "IS NOT NULL($0)");
checkSimplify(isNotNull(lt(i0, null_)), "false");
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef in project calcite by apache.
the class DruidExpressions method toDruidExpression.
/**
* Translates Calcite rexNode to Druid Expression when possible
* @param rexNode rexNode to convert to a Druid Expression
* @param inputRowType input row type of the rexNode to translate
* @param druidRel Druid query
*
* @return Druid Expression or null when can not convert the RexNode
*/
@Nullable
public static String toDruidExpression(final RexNode rexNode, final RelDataType inputRowType, final DruidQuery druidRel) {
SqlKind kind = rexNode.getKind();
SqlTypeName sqlTypeName = rexNode.getType().getSqlTypeName();
if (kind == SqlKind.INPUT_REF) {
final RexInputRef ref = (RexInputRef) rexNode;
final String columnName = inputRowType.getFieldNames().get(ref.getIndex());
if (columnName == null) {
return null;
}
if (druidRel.getDruidTable().timestampFieldName.equals(columnName)) {
return DruidExpressions.fromColumn(DruidTable.DEFAULT_TIMESTAMP_COLUMN);
}
return DruidExpressions.fromColumn(columnName);
}
if (rexNode instanceof RexCall) {
final SqlOperator operator = ((RexCall) rexNode).getOperator();
final DruidSqlOperatorConverter conversion = druidRel.getOperatorConversionMap().get(operator);
if (conversion == null) {
// unknown operator can not translate
return null;
} else {
return conversion.toDruidExpression(rexNode, inputRowType, druidRel);
}
}
if (kind == SqlKind.LITERAL) {
// Translate literal.
if (RexLiteral.isNullLiteral(rexNode)) {
// case the filter/project might yield to unknown let Calcite deal with this for now
return null;
} else if (SqlTypeName.NUMERIC_TYPES.contains(sqlTypeName)) {
return DruidExpressions.numberLiteral((Number) RexLiteral.value(rexNode));
} else if (SqlTypeFamily.INTERVAL_DAY_TIME == sqlTypeName.getFamily()) {
// Calcite represents DAY-TIME intervals in milliseconds.
final long milliseconds = ((Number) RexLiteral.value(rexNode)).longValue();
return DruidExpressions.numberLiteral(milliseconds);
} else if (SqlTypeFamily.INTERVAL_YEAR_MONTH == sqlTypeName.getFamily()) {
// Calcite represents YEAR-MONTH intervals in months.
final long months = ((Number) RexLiteral.value(rexNode)).longValue();
return DruidExpressions.numberLiteral(months);
} else if (SqlTypeName.STRING_TYPES.contains(sqlTypeName)) {
return DruidExpressions.stringLiteral(RexLiteral.stringValue(rexNode));
} else if (SqlTypeName.TIMESTAMP == sqlTypeName || SqlTypeName.DATE == sqlTypeName || SqlTypeName.TIME_WITH_LOCAL_TIME_ZONE == sqlTypeName) {
return DruidExpressions.numberLiteral(DruidDateTimeUtils.literalValue(rexNode, TimeZone.getTimeZone(druidRel.getConnectionConfig().timeZone())).getMillisSinceEpoch());
} else if (SqlTypeName.BOOLEAN == sqlTypeName) {
return DruidExpressions.numberLiteral(RexLiteral.booleanValue(rexNode) ? 1 : 0);
}
}
// Not Literal/InputRef/RexCall or unknown type?
return null;
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef in project calcite by apache.
the class ProjectWindowTransposeRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final LogicalProject project = call.rel(0);
final LogicalWindow window = call.rel(1);
final RelOptCluster cluster = window.getCluster();
final List<RelDataTypeField> rowTypeWindowInput = window.getInput().getRowType().getFieldList();
final int windowInputColumn = rowTypeWindowInput.size();
// Record the window input columns which are actually referred
// either in the LogicalProject above LogicalWindow or LogicalWindow itself
// (Note that the constants used in LogicalWindow are not considered here)
final ImmutableBitSet beReferred = findReference(project, window);
// it is impossible to trim anyone of them out
if (beReferred.cardinality() == windowInputColumn) {
return;
}
// Put a DrillProjectRel below LogicalWindow
final List<RexNode> exps = new ArrayList<>();
final RelDataTypeFactory.Builder builder = cluster.getTypeFactory().builder();
// Keep only the fields which are referred
for (int index : BitSets.toIter(beReferred)) {
final RelDataTypeField relDataTypeField = rowTypeWindowInput.get(index);
exps.add(new RexInputRef(index, relDataTypeField.getType()));
builder.add(relDataTypeField);
}
final LogicalProject projectBelowWindow = new LogicalProject(cluster, window.getTraitSet(), window.getInput(), exps, builder.build());
// Create a new LogicalWindow with necessary inputs only
final List<Window.Group> groups = new ArrayList<>();
// As the un-referred columns are trimmed by the LogicalProject,
// the indices specified in LogicalWindow would need to be adjusted
final RexShuttle indexAdjustment = new RexShuttle() {
@Override
public RexNode visitInputRef(RexInputRef inputRef) {
final int newIndex = getAdjustedIndex(inputRef.getIndex(), beReferred, windowInputColumn);
return new RexInputRef(newIndex, inputRef.getType());
}
@Override
public RexNode visitCall(final RexCall call) {
if (call instanceof Window.RexWinAggCall) {
boolean[] update = { false };
final List<RexNode> clonedOperands = visitList(call.operands, update);
if (update[0]) {
return new Window.RexWinAggCall((SqlAggFunction) call.getOperator(), call.getType(), clonedOperands, ((Window.RexWinAggCall) call).ordinal, ((Window.RexWinAggCall) call).distinct);
} else {
return call;
}
} else {
return super.visitCall(call);
}
}
};
int aggCallIndex = windowInputColumn;
final RelDataTypeFactory.Builder outputBuilder = cluster.getTypeFactory().builder();
outputBuilder.addAll(projectBelowWindow.getRowType().getFieldList());
for (Window.Group group : window.groups) {
final ImmutableBitSet.Builder keys = ImmutableBitSet.builder();
final List<RelFieldCollation> orderKeys = new ArrayList<>();
final List<Window.RexWinAggCall> aggCalls = new ArrayList<>();
// Adjust keys
for (int index : group.keys) {
keys.set(getAdjustedIndex(index, beReferred, windowInputColumn));
}
// Adjust orderKeys
for (RelFieldCollation relFieldCollation : group.orderKeys.getFieldCollations()) {
final int index = relFieldCollation.getFieldIndex();
orderKeys.add(relFieldCollation.copy(getAdjustedIndex(index, beReferred, windowInputColumn)));
}
// Adjust Window Functions
for (Window.RexWinAggCall rexWinAggCall : group.aggCalls) {
aggCalls.add((Window.RexWinAggCall) rexWinAggCall.accept(indexAdjustment));
final RelDataTypeField relDataTypeField = window.getRowType().getFieldList().get(aggCallIndex);
outputBuilder.add(relDataTypeField);
++aggCallIndex;
}
groups.add(new Window.Group(keys.build(), group.isRows, group.lowerBound, group.upperBound, RelCollations.of(orderKeys), aggCalls));
}
final LogicalWindow newLogicalWindow = LogicalWindow.create(window.getTraitSet(), projectBelowWindow, window.constants, outputBuilder.build(), groups);
// Modify the top LogicalProject
final List<RexNode> topProjExps = new ArrayList<>();
for (RexNode rexNode : project.getChildExps()) {
topProjExps.add(rexNode.accept(indexAdjustment));
}
final LogicalProject newTopProj = project.copy(newLogicalWindow.getTraitSet(), newLogicalWindow, topProjExps, project.getRowType());
if (ProjectRemoveRule.isTrivial(newTopProj)) {
call.transformTo(newLogicalWindow);
} else {
call.transformTo(newTopProj);
}
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexInputRef in project calcite by apache.
the class SemiJoinProjectTransposeRule method onMatch.
// ~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
SemiJoin semiJoin = call.rel(0);
LogicalProject project = call.rel(1);
// Convert the LHS semi-join keys to reference the child projection
// expression; all projection expressions must be RexInputRefs,
// otherwise, we wouldn't have created this semi-join.
final List<Integer> newLeftKeys = new ArrayList<>();
final List<Integer> leftKeys = semiJoin.getLeftKeys();
final List<RexNode> projExprs = project.getProjects();
for (int leftKey : leftKeys) {
RexInputRef inputRef = (RexInputRef) projExprs.get(leftKey);
newLeftKeys.add(inputRef.getIndex());
}
// convert the semijoin condition to reflect the LHS with the project
// pulled up
RexNode newCondition = adjustCondition(project, semiJoin);
SemiJoin newSemiJoin = SemiJoin.create(project.getInput(), semiJoin.getRight(), newCondition, ImmutableIntList.copyOf(newLeftKeys), semiJoin.getRightKeys());
// Create the new projection. Note that the projection expressions
// are the same as the original because they only reference the LHS
// of the semijoin and the semijoin only projects out the LHS
final RelBuilder relBuilder = call.builder();
relBuilder.push(newSemiJoin);
relBuilder.project(projExprs, project.getRowType().getFieldNames());
call.transformTo(relBuilder.build());
}
Aggregations