RexNodeAndFieldIndex.java
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.calcite.rex;
import org.apache.calcite.rel.type.RelDataType;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Objects;
/**
* RexNodeAndFieldIndex has the same meaning as {@link RexInputRef}, they are both reference a
* field of an input relational expression. The difference is that, RexNodeAndFieldIndex uses the
* input index and the relative position of field in input rowType.
*
* <p> For example, if the inputs to a join are
*
* <ul>
* <li>Input #0: EMP(EMPNO, ENAME, DEPTNO) and</li>
* <li>Input #1: DEPT(DEPTNO AS DEPTNO2, DNAME)</li>
* </ul>
*
* <p>then the fields are:
*
* <ul>
* <li>Node #0, Field #0: EMPNO</li>
* <li>Node #0, Field #1: ENAME</li>
* <li>Node #0, Field #2: DEPTNO (from EMP)</li>
* <li>Node #1, Field #0: DEPTNO2 (from DEPT)</li>
* <li>Node #1, Field #1: DNAME</li>
* </ul>
*
* <p> If in some cases, the inputs order of a relation is frequently adjusted and it is difficult
* to maintain the correct RexInputRef, you can consider temporarily replacing RexInputRef with
* RexNodeAndFieldIndex.
*
* @see org.apache.calcite.rel.rules.JoinToHyperGraphRule
* @see org.apache.calcite.rel.rules.HyperGraph#extractJoinCond
* @see org.apache.calcite.rel.rules.HyperEdge#createHyperEdgesFromJoinConds
*/
public class RexNodeAndFieldIndex extends RexVariable {
// the index of the node in relation inputs
private final int nodeIndex;
// the index of the field in the rowType of the node
private final int fieldIndex;
public RexNodeAndFieldIndex(int nodeIndex, int fieldIndex, String name, RelDataType type) {
super(name, type);
this.nodeIndex = nodeIndex;
this.fieldIndex = fieldIndex;
}
public int getNodeIndex() {
return nodeIndex;
}
public int getFieldIndex() {
return fieldIndex;
}
@Override public <R> R accept(RexVisitor<R> visitor) {
return visitor.visitNodeAndFieldIndex(this);
}
@Override public <R, P> R accept(RexBiVisitor<R, P> visitor, P arg) {
return visitor.visitNodeAndFieldIndex(this, arg);
}
@Override public boolean equals(@Nullable Object obj) {
return this == obj
|| obj instanceof RexNodeAndFieldIndex
&& nodeIndex == ((RexNodeAndFieldIndex) obj).nodeIndex
&& fieldIndex == ((RexNodeAndFieldIndex) obj).fieldIndex;
}
@Override public int hashCode() {
return Objects.hash(nodeIndex, fieldIndex);
}
@Override public String toString() {
return "node(" + nodeIndex + ")_field(" + fieldIndex + ")";
}
}