use of org.apache.calcite.rex.RexInputRef in project calcite by apache.
the class RelMdAllPredicates method getAllPredicates.
/**
* Add the Join condition to the list obtained from the input.
*/
public RelOptPredicateList getAllPredicates(Join join, RelMetadataQuery mq) {
if (join.getJoinType() != JoinRelType.INNER) {
// We cannot map origin of this expression.
return null;
}
final RexBuilder rexBuilder = join.getCluster().getRexBuilder();
final RexNode pred = join.getCondition();
final Multimap<List<String>, RelTableRef> qualifiedNamesToRefs = HashMultimap.create();
RelOptPredicateList newPreds = RelOptPredicateList.EMPTY;
for (RelNode input : join.getInputs()) {
final RelOptPredicateList inputPreds = mq.getAllPredicates(input);
if (inputPreds == null) {
// Bail out
return null;
}
// Gather table references
final Set<RelTableRef> tableRefs = mq.getTableReferences(input);
if (input == join.getLeft()) {
// Left input references remain unchanged
for (RelTableRef leftRef : tableRefs) {
qualifiedNamesToRefs.put(leftRef.getQualifiedName(), leftRef);
}
newPreds = newPreds.union(rexBuilder, inputPreds);
} else {
// Right input references might need to be updated if there are table name
// clashes with left input
final Map<RelTableRef, RelTableRef> currentTablesMapping = new HashMap<>();
for (RelTableRef rightRef : tableRefs) {
int shift = 0;
Collection<RelTableRef> lRefs = qualifiedNamesToRefs.get(rightRef.getQualifiedName());
if (lRefs != null) {
shift = lRefs.size();
}
currentTablesMapping.put(rightRef, RelTableRef.of(rightRef.getTable(), shift + rightRef.getEntityNumber()));
}
final List<RexNode> updatedPreds = Lists.newArrayList(Iterables.transform(inputPreds.pulledUpPredicates, new Function<RexNode, RexNode>() {
@Override
public RexNode apply(RexNode e) {
return RexUtil.swapTableReferences(rexBuilder, e, currentTablesMapping);
}
}));
newPreds = newPreds.union(rexBuilder, RelOptPredicateList.of(rexBuilder, updatedPreds));
}
}
// Extract input fields referenced by Join condition
final Set<RelDataTypeField> inputExtraFields = new LinkedHashSet<>();
final RelOptUtil.InputFinder inputFinder = new RelOptUtil.InputFinder(inputExtraFields);
pred.accept(inputFinder);
final ImmutableBitSet inputFieldsUsed = inputFinder.inputBitSet.build();
// Infer column origin expressions for given references
final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>();
for (int idx : inputFieldsUsed) {
final RexInputRef inputRef = RexInputRef.of(idx, join.getRowType().getFieldList());
final Set<RexNode> originalExprs = mq.getExpressionLineage(join, inputRef);
if (originalExprs == null) {
// Bail out
return null;
}
final RexInputRef ref = RexInputRef.of(idx, join.getRowType().getFieldList());
mapping.put(ref, originalExprs);
}
// Replace with new expressions and return union of predicates
return newPreds.union(rexBuilder, RelOptPredicateList.of(rexBuilder, RelMdExpressionLineage.createAllPossibleExpressions(rexBuilder, pred, mapping)));
}
use of org.apache.calcite.rex.RexInputRef in project calcite by apache.
the class RelMdAllPredicates method getAllPredicates.
/**
* Add the Filter condition to the list obtained from the input.
*/
public RelOptPredicateList getAllPredicates(Filter filter, RelMetadataQuery mq) {
final RelNode input = filter.getInput();
final RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
final RexNode pred = filter.getCondition();
final RelOptPredicateList predsBelow = mq.getAllPredicates(input);
if (predsBelow == null) {
// Safety check
return null;
}
// Extract input fields referenced by Filter condition
final Set<RelDataTypeField> inputExtraFields = new LinkedHashSet<>();
final RelOptUtil.InputFinder inputFinder = new RelOptUtil.InputFinder(inputExtraFields);
pred.accept(inputFinder);
final ImmutableBitSet inputFieldsUsed = inputFinder.inputBitSet.build();
// Infer column origin expressions for given references
final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>();
for (int idx : inputFieldsUsed) {
final RexInputRef ref = RexInputRef.of(idx, filter.getRowType().getFieldList());
final Set<RexNode> originalExprs = mq.getExpressionLineage(filter, ref);
if (originalExprs == null) {
// Bail out
return null;
}
mapping.put(ref, originalExprs);
}
// Replace with new expressions and return union of predicates
return predsBelow.union(rexBuilder, RelOptPredicateList.of(rexBuilder, RelMdExpressionLineage.createAllPossibleExpressions(rexBuilder, pred, mapping)));
}
use of org.apache.calcite.rex.RexInputRef in project calcite by apache.
the class RelBuilderTest method testBadFieldName.
@Test
public void testBadFieldName() {
final RelBuilder builder = RelBuilder.create(config().build());
try {
RexInputRef ref = builder.scan("EMP").field("deptno");
fail("expected error, got " + ref);
} catch (IllegalArgumentException e) {
assertThat(e.getMessage(), is("field [deptno] not found; input fields are: [EMPNO, ENAME, JOB, " + "MGR, HIREDATE, SAL, COMM, DEPTNO]"));
}
}
use of org.apache.calcite.rex.RexInputRef in project calcite by apache.
the class RelBuilderTest method testBadFieldOrdinal.
@Test
public void testBadFieldOrdinal() {
final RelBuilder builder = RelBuilder.create(config().build());
try {
RexInputRef ref = builder.scan("DEPT").field(20);
fail("expected error, got " + ref);
} catch (IllegalArgumentException e) {
assertThat(e.getMessage(), is("field ordinal [20] out of range; " + "input fields are: [DEPTNO, DNAME, LOC]"));
}
}
use of org.apache.calcite.rex.RexInputRef 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);
}
}
Aggregations