use of org.apache.calcite.rel.core.CorrelationId in project Mycat2 by MyCATApache.
the class MycatValuesJoinRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
Join join = call.rel(0);
RelHint lastJoinHint = HintTools.getLastJoinHint(join.getHints());
if (lastJoinHint != null) {
if (!"use_values_join".equalsIgnoreCase(lastJoinHint.hintName)) {
return;
}
} else {
return;
}
RelOptCluster cluster = join.getCluster();
RelNode left = call.rel(1);
RelNode right = call.rel(2);
JoinInfo joinInfo = join.analyzeCondition();
if (!joinInfo.isEqui()) {
return;
}
if (!(right instanceof MycatView)) {
return;
}
MycatView mycatView = (MycatView) right;
if (mycatView.banPushdown()) {
return;
}
JoinRelType joinType = join.getJoinType();
switch(joinType) {
case INNER:
case SEMI:
case LEFT:
case RIGHT:
break;
default:
return;
}
if (RelOptUtil.countJoins(mycatView.getRelNode()) > 1) {
return;
}
RexBuilder rexBuilder = MycatCalciteSupport.RexBuilder;
RelDataTypeFactory typeFactory = cluster.getTypeFactory();
List<RexNode> leftExprs = new ArrayList<>();
List<CorrelationId> correlationIds = new ArrayList<>();
{
for (Integer leftKey : join.analyzeCondition().leftSet()) {
CorrelationId correl = cluster.createCorrel();
correlationIds.add(correl);
RelDataType type = left.getRowType().getFieldList().get(leftKey).getType();
RexNode rexNode = rexBuilder.makeCorrel(typeFactory.createSqlType(SqlTypeName.VARCHAR), correl);
leftExprs.add(rexBuilder.makeCast(type, rexNode));
}
}
switch(mycatView.getDistribution().type()) {
case PHY:
case BROADCAST:
RelBuilder builder = call.builder();
builder.push(MycatTableLookupValues.create(cluster, left.getRowType(), leftExprs, left.getTraitSet())).push(mycatView.getRelNode()).join(joinType, join.getCondition());
MycatView view = mycatView.changeTo(builder.build());
MycatSQLTableLookup mycatSQLTableLookup = new MycatSQLTableLookup(cluster, join.getTraitSet(), left, view, joinType, join.getCondition(), correlationIds, MycatSQLTableLookup.Type.NONE);
call.transformTo(mycatSQLTableLookup);
break;
default:
}
}
use of org.apache.calcite.rel.core.CorrelationId in project Mycat2 by MyCATApache.
the class HBTQueryConvertor method correlate.
private RelNode correlate(CorrelateSchema input) {
RelNode left = handle(input.getLeft());
Holder<RexCorrelVariable> of = Holder.of(null);
relBuilder.push(left);
relBuilder.variable(of);
correlVariableMap.put(input.getRefName(), of.get());
RelNode right = handle(input.getRight());
relBuilder.clear();
final CorrelationId id = of.get().id;
final ImmutableBitSet requiredColumns = RelOptUtil.correlationColumns(id, right);
relBuilder.push(left);
List<RexInputRef> collect = requiredColumns.asList().stream().map(i -> relBuilder.field(i)).collect(Collectors.toList());
relBuilder.clear();
relBuilder.push(left);
relBuilder.push(right);
return relBuilder.correlate(joinOp(input.getOp()), of.get().id, collect).build();
}
use of org.apache.calcite.rel.core.CorrelationId in project Mycat2 by MyCATApache.
the class HBTQueryConvertor method correlateJoin.
private RelNode correlateJoin(JoinSchema input) {
List<Schema> schemas = input.getSchemas();
joinCount = schemas.size();
try {
ArrayList<RelNode> nodes = new ArrayList<>(schemas.size());
HashSet<String> set = new HashSet<>();
for (Schema schema : schemas) {
HBTQueryConvertor queryOp = new HBTQueryConvertor(params, relBuilder);
RelNode relNode = queryOp.complie(schema);
List<String> fieldNames = relNode.getRowType().getFieldNames();
if (!set.addAll(fieldNames)) {
log.warn("dup fieldNames:" + fieldNames);
}
nodes.add(relNode);
}
for (RelNode relNode : nodes) {
relBuilder.push(relNode);
}
if (input.getCondition() != null) {
RexNode rexNode = null;
try {
rexNode = toRex(input.getCondition());
} catch (Exception e) {
e.printStackTrace();
}
Set<CorrelationId> collect = correlVariableMap.values().stream().filter(i -> i instanceof RexCorrelVariable).map(i -> i.id).collect(Collectors.toSet());
return relBuilder.join(joinOp(input.getOp()), rexNode, collect).build();
} else {
return relBuilder.join(joinOp(input.getOp())).build();
}
} finally {
joinCount = 0;
}
}
use of org.apache.calcite.rel.core.CorrelationId in project hive by apache.
the class HiveSubQRemoveRelBuilder method join.
/** Creates a {@link org.apache.calcite.rel.core.Join} with correlating
* variables. */
public HiveSubQRemoveRelBuilder join(JoinRelType joinType, RexNode condition, Set<CorrelationId> variablesSet) {
Frame right = stack.pop();
final Frame left = stack.pop();
final RelNode join;
final boolean correlate = variablesSet.size() == 1;
RexNode postCondition = literal(true);
if (correlate) {
final CorrelationId id = Iterables.getOnlyElement(variablesSet);
final ImmutableBitSet requiredColumns = RelOptUtil.correlationColumns(id, right.rel);
if (!RelOptUtil.notContainsCorrelation(left.rel, id, Litmus.IGNORE)) {
throw new IllegalArgumentException("variable " + id + " must not be used by left input to correlation");
}
switch(joinType) {
case LEFT:
// Correlate does not have an ON clause.
// For a LEFT correlate, predicate must be evaluated first.
// For INNER, we can defer.
stack.push(right);
filter(condition.accept(new Shifter(left.rel, id, right.rel)));
right = stack.pop();
break;
default:
postCondition = condition;
}
join = correlateFactory.createCorrelate(left.rel, right.rel, id, requiredColumns, SemiJoinType.of(joinType));
} else {
join = joinFactory.createJoin(left.rel, right.rel, condition, variablesSet, joinType, false);
}
final List<Pair<String, RelDataType>> pairs = new ArrayList<>();
pairs.addAll(left.right);
pairs.addAll(right.right);
stack.push(new Frame(join, ImmutableList.copyOf(pairs)));
filter(postCondition);
return this;
}
use of org.apache.calcite.rel.core.CorrelationId in project flink by apache.
the class FlinkRelDecorrelator method createValueGenerator.
/**
* Create RelNode tree that produces a list of correlated variables.
*
* @param correlations correlated variables to generate
* @param valueGenFieldOffset offset in the output that generated columns
* will start
* @param mapCorVarToOutputPos output positions for the correlated variables
* generated
* @return RelNode the root of the resultant RelNode tree
*/
private RelNode createValueGenerator(Iterable<Correlation> correlations, int valueGenFieldOffset, SortedMap<Correlation, Integer> mapCorVarToOutputPos) {
final Map<RelNode, List<Integer>> mapNewInputToOutputPos = new HashMap<>();
final Map<RelNode, Integer> mapNewInputToNewOffset = new HashMap<>();
// Add to map all the referenced positions (relative to each input rel).
for (Correlation corVar : correlations) {
final int oldCorVarOffset = corVar.field;
final RelNode oldInput = getCorRel(corVar);
assert oldInput != null;
final Frame frame = map.get(oldInput);
assert frame != null;
final RelNode newInput = frame.r;
final List<Integer> newLocalOutputPosList;
if (!mapNewInputToOutputPos.containsKey(newInput)) {
newLocalOutputPosList = Lists.newArrayList();
} else {
newLocalOutputPosList = mapNewInputToOutputPos.get(newInput);
}
final int newCorVarOffset = frame.oldToNewOutputPos.get(oldCorVarOffset);
// Add all unique positions referenced.
if (!newLocalOutputPosList.contains(newCorVarOffset)) {
newLocalOutputPosList.add(newCorVarOffset);
}
mapNewInputToOutputPos.put(newInput, newLocalOutputPosList);
}
int offset = 0;
// Project only the correlated fields out of each inputRel
// and join the projectRel together.
// To make sure the plan does not change in terms of join order,
// join these rels based on their occurrence in cor var list which
// is sorted.
final Set<RelNode> joinedInputRelSet = Sets.newHashSet();
RelNode r = null;
for (Correlation corVar : correlations) {
final RelNode oldInput = getCorRel(corVar);
assert oldInput != null;
final RelNode newInput = map.get(oldInput).r;
assert newInput != null;
if (!joinedInputRelSet.contains(newInput)) {
RelNode project = RelOptUtil.createProject(newInput, mapNewInputToOutputPos.get(newInput));
RelNode distinct = RelOptUtil.createDistinctRel(project);
RelOptCluster cluster = distinct.getCluster();
joinedInputRelSet.add(newInput);
mapNewInputToNewOffset.put(newInput, offset);
offset += distinct.getRowType().getFieldCount();
if (r == null) {
r = distinct;
} else {
r = LogicalJoin.create(r, distinct, cluster.getRexBuilder().makeLiteral(true), ImmutableSet.<CorrelationId>of(), JoinRelType.INNER);
}
}
}
// referencing correlated variables.
for (Correlation corVar : correlations) {
// The first input of a Correlator is always the rel defining
// the correlated variables.
final RelNode oldInput = getCorRel(corVar);
assert oldInput != null;
final Frame frame = map.get(oldInput);
final RelNode newInput = frame.r;
assert newInput != null;
final List<Integer> newLocalOutputPosList = mapNewInputToOutputPos.get(newInput);
final int newLocalOutputPos = frame.oldToNewOutputPos.get(corVar.field);
// newOutputPos is the index of the cor var in the referenced
// position list plus the offset of referenced position list of
// each newInput.
final int newOutputPos = newLocalOutputPosList.indexOf(newLocalOutputPos) + mapNewInputToNewOffset.get(newInput) + valueGenFieldOffset;
if (mapCorVarToOutputPos.containsKey(corVar)) {
assert mapCorVarToOutputPos.get(corVar) == newOutputPos;
}
mapCorVarToOutputPos.put(corVar, newOutputPos);
}
return r;
}
Aggregations