use of org.apache.calcite.rex.RexFieldAccess in project flink by apache.
the class FlinkRelDecorrelator method checkCorVars.
/**
* Checks whether the correlations in projRel and filter are related to
* the correlated variables provided by corRel.
*
* @param correlate Correlate
* @param project The original Project as the RHS input of the join
* @param filter Filter
* @param correlatedJoinKeys Correlated join keys
* @return true if filter and proj only references corVar provided by corRel
*/
private boolean checkCorVars(LogicalCorrelate correlate, LogicalProject project, LogicalFilter filter, List<RexFieldAccess> correlatedJoinKeys) {
if (filter != null) {
assert correlatedJoinKeys != null;
// check that all correlated refs in the filter condition are
// used in the join(as field access).
Set<Correlation> corVarInFilter = Sets.newHashSet(cm.mapRefRelToCorVar.get(filter));
for (RexFieldAccess correlatedJoinKey : correlatedJoinKeys) {
corVarInFilter.remove(cm.mapFieldAccessToCorVar.get(correlatedJoinKey));
}
if (!corVarInFilter.isEmpty()) {
return false;
}
// Check that the correlated variables referenced in these
// comparisons do come from the correlatorRel.
corVarInFilter.addAll(cm.mapRefRelToCorVar.get(filter));
for (Correlation corVar : corVarInFilter) {
if (cm.mapCorVarToCorRel.get(corVar.corr) != correlate) {
return false;
}
}
}
// of the correlate.
if ((project != null) && cm.mapRefRelToCorVar.containsKey(project)) {
for (Correlation corVar : cm.mapRefRelToCorVar.get(project)) {
if (cm.mapCorVarToCorRel.get(corVar.corr) != correlate) {
return false;
}
}
}
return true;
}
use of org.apache.calcite.rex.RexFieldAccess in project calcite by apache.
the class RexToLixTranslator method translate0.
/**
* Translates an expression that is not in the cache.
*
* @param expr Expression
* @param nullAs If false, if expression is definitely not null at
* runtime. Therefore we can optimize. For example, we can cast to int
* using x.intValue().
* @return Translated expression
*/
private Expression translate0(RexNode expr, RexImpTable.NullAs nullAs, Type storageType) {
if (nullAs == RexImpTable.NullAs.NULL && !expr.getType().isNullable()) {
nullAs = RexImpTable.NullAs.NOT_POSSIBLE;
}
switch(expr.getKind()) {
case INPUT_REF:
final int index = ((RexInputRef) expr).getIndex();
Expression x = inputGetter.field(list, index, storageType);
// safe to share
Expression input = list.append("inp" + index + "_", x);
if (nullAs == RexImpTable.NullAs.NOT_POSSIBLE && input.type.equals(storageType)) {
// unboxing via nullAs.handle below.
return input;
}
return handleNull(input, nullAs);
case LOCAL_REF:
return translate(deref(expr), nullAs, storageType);
case LITERAL:
return translateLiteral((RexLiteral) expr, nullifyType(expr.getType(), isNullable(expr) && nullAs != RexImpTable.NullAs.NOT_POSSIBLE), typeFactory, nullAs);
case DYNAMIC_PARAM:
return translateParameter((RexDynamicParam) expr, nullAs, storageType);
case CORREL_VARIABLE:
throw new RuntimeException("Cannot translate " + expr + ". Correlated" + " variables should always be referenced by field access");
case FIELD_ACCESS:
RexFieldAccess fieldAccess = (RexFieldAccess) expr;
RexNode target = deref(fieldAccess.getReferenceExpr());
// only $cor.field access is supported
if (!(target instanceof RexCorrelVariable)) {
throw new RuntimeException("cannot translate expression " + expr);
}
if (correlates == null) {
throw new RuntimeException("Cannot translate " + expr + " since " + "correlate variables resolver is not defined");
}
InputGetter getter = correlates.apply(((RexCorrelVariable) target).getName());
return getter.field(list, fieldAccess.getField().getIndex(), storageType);
default:
if (expr instanceof RexCall) {
return translateCall((RexCall) expr, nullAs);
}
throw new RuntimeException("cannot translate expression " + expr);
}
}
use of org.apache.calcite.rex.RexFieldAccess in project calcite by apache.
the class SqlToRelConverter method convertIdentifier.
/**
* Converts an identifier into an expression in a given scope. For example,
* the "empno" in "select empno from emp join dept" becomes "emp.empno".
*/
private RexNode convertIdentifier(Blackboard bb, SqlIdentifier identifier) {
// first check for reserved identifiers like CURRENT_USER
final SqlCall call = SqlUtil.makeCall(opTab, identifier);
if (call != null) {
return bb.convertExpression(call);
}
String pv = null;
if (bb.isPatternVarRef && identifier.names.size() > 1) {
pv = identifier.names.get(0);
}
final SqlQualified qualified;
if (bb.scope != null) {
qualified = bb.scope.fullyQualify(identifier);
} else {
qualified = SqlQualified.create(null, 1, null, identifier);
}
final Pair<RexNode, Map<String, Integer>> e0 = bb.lookupExp(qualified);
RexNode e = e0.left;
for (String name : qualified.suffix()) {
if (e == e0.left && e0.right != null) {
int i = e0.right.get(name);
e = rexBuilder.makeFieldAccess(e, i);
} else {
// name already fully-qualified
final boolean caseSensitive = true;
if (identifier.isStar() && bb.scope instanceof MatchRecognizeScope) {
e = rexBuilder.makeFieldAccess(e, 0);
} else {
e = rexBuilder.makeFieldAccess(e, name, caseSensitive);
}
}
}
if (e instanceof RexInputRef) {
// adjust the type to account for nulls introduced by outer joins
e = adjustInputRef(bb, (RexInputRef) e);
if (pv != null) {
e = RexPatternFieldRef.of(pv, (RexInputRef) e);
}
}
if (e0.left instanceof RexCorrelVariable) {
assert e instanceof RexFieldAccess;
final RexNode prev = bb.mapCorrelateToRex.put(((RexCorrelVariable) e0.left).id, (RexFieldAccess) e);
assert prev == null;
}
return e;
}
use of org.apache.calcite.rex.RexFieldAccess in project calcite by apache.
the class RelFieldTrimmer method trimChild.
/**
* Trims the fields of an input relational expression.
*
* @param rel Relational expression
* @param input Input relational expression, whose fields to trim
* @param fieldsUsed Bitmap of fields needed by the consumer
* @return New relational expression and its field mapping
*/
protected TrimResult trimChild(RelNode rel, RelNode input, final ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
final ImmutableBitSet.Builder fieldsUsedBuilder = fieldsUsed.rebuild();
// Fields that define the collation cannot be discarded.
final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
final ImmutableList<RelCollation> collations = mq.collations(input);
for (RelCollation collation : collations) {
for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
fieldsUsedBuilder.set(fieldCollation.getFieldIndex());
}
}
// fields.
for (final CorrelationId correlation : rel.getVariablesSet()) {
rel.accept(new CorrelationReferenceFinder() {
protected RexNode handle(RexFieldAccess fieldAccess) {
final RexCorrelVariable v = (RexCorrelVariable) fieldAccess.getReferenceExpr();
if (v.id.equals(correlation)) {
fieldsUsedBuilder.set(fieldAccess.getField().getIndex());
}
return fieldAccess;
}
});
}
return dispatchTrimFields(input, fieldsUsedBuilder.build(), extraFields);
}
use of org.apache.calcite.rex.RexFieldAccess 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);
}
Aggregations