use of io.mycat.calcite.physical.MycatSQLTableLookup in project Mycat2 by MyCATApache.
the class MycatJoinTableLookupTransposeRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
Join join = call.rel(0);
RelDataType originalRowType = join.getRowType();
RelOptCluster cluster = join.getCluster();
RelNode outerLeft = call.rel(1);
RelNode outerRight = call.rel(2);
if (outerLeft instanceof MycatSQLTableLookup) {
MycatSQLTableLookup mycatSQLTableLookup = (MycatSQLTableLookup) outerLeft;
if (mycatSQLTableLookup.getType() == MycatSQLTableLookup.Type.BACK) {
int fieldCount = mycatSQLTableLookup.getInput().getRowType().getFieldCount();
if (join.analyzeCondition().leftSet().asList().stream().allMatch(i -> i < fieldCount)) {
// 与最左表无关
RelNode bottomInput = mycatSQLTableLookup.getInput();
MycatView indexRightView = (MycatView) mycatSQLTableLookup.getRight();
RelNode newInputJoin = join.copy(bottomInput.getTraitSet(), ImmutableList.of(bottomInput, outerRight));
MycatSQLTableLookup newMycatSQLTableLookup = new MycatSQLTableLookup(join.getCluster(), join.getTraitSet(), newInputJoin, indexRightView, mycatSQLTableLookup.getJoinType(), mycatSQLTableLookup.getCondition(), mycatSQLTableLookup.getCorrelationIds(), mycatSQLTableLookup.getType());
fixProject(originalRowType, newMycatSQLTableLookup, call.builder()).ifPresent(res -> {
call.transformTo(res);
});
return;
}
}
}
if (outerRight instanceof MycatSQLTableLookup) {
MycatSQLTableLookup mycatSQLTableLookup = (MycatSQLTableLookup) outerRight;
MycatView indexRightView = (MycatView) mycatSQLTableLookup.getRight();
RelNode newInputJoin = join.copy(outerLeft.getTraitSet(), ImmutableList.of(mycatSQLTableLookup.getInput(), indexRightView));
if (mycatSQLTableLookup.getType() == MycatSQLTableLookup.Type.BACK) {
int fieldCount = mycatSQLTableLookup.getInput().getRowType().getFieldCount();
if (join.analyzeCondition().rightSet().asList().stream().allMatch(i -> i > fieldCount)) {
// 最右回表无关
MycatSQLTableLookup newMycatSQLTableLookup = new MycatSQLTableLookup(join.getCluster(), join.getTraitSet(), newInputJoin, indexRightView, mycatSQLTableLookup.getJoinType(), mycatSQLTableLookup.getCondition(), mycatSQLTableLookup.getCorrelationIds(), mycatSQLTableLookup.getType());
fixProject(originalRowType, newMycatSQLTableLookup, call.builder()).ifPresent(res -> {
call.transformTo(res);
});
return;
}
}
}
}
use of io.mycat.calcite.physical.MycatSQLTableLookup 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 io.mycat.calcite.physical.MycatSQLTableLookup in project Mycat2 by MyCATApache.
the class PlanImpl method specificSql.
@NotNull
public List<SpecificSql> specificSql(DrdsSqlWithParams drdsSql, int mergeUnionSize) {
List<SpecificSql> res = new ArrayList<>();
getMycatRel().accept(new RelShuttleImpl() {
@Override
protected RelNode visitChildren(RelNode relNode) {
List<Each> sqls = new ArrayList<>();
String parameterizedSql = "";
if (relNode instanceof MycatView) {
MycatView view = (MycatView) relNode;
SqlNode sqlTemplate = view.getSQLTemplate(false);
ImmutableMultimap<String, SqlString> apply = view.apply(mergeUnionSize, sqlTemplate, AsyncMycatDataContextImpl.getSqlMap(executerContext.getConstantMap(), view, drdsSql, drdsSql.getHintDataNodeFilter()), drdsSql.getParams());
ImmutableMultimap<String, SqlString> stringImmutableMultimap = apply;
for (Map.Entry<String, SqlString> entry : (stringImmutableMultimap.entries())) {
SqlString sqlString = new SqlString(entry.getValue().getDialect(), (Util.toLinux(entry.getValue().getSql())), entry.getValue().getDynamicParameters());
sqls.add(new Each(entry.getKey(), sqlString.getSql()));
}
if (relNode instanceof MycatView) {
parameterizedSql = ((MycatView) relNode).getSql();
}
if (relNode instanceof MycatTransientSQLTableScan) {
parameterizedSql = ((MycatTransientSQLTableScan) relNode).getSql();
}
res.add(new SpecificSql(relNode.getDigest(), parameterizedSql, sqls));
} else if (relNode instanceof MycatSQLTableLookup) {
MycatView right = ((MycatSQLTableLookup) relNode).getRight();
right.accept(this);
}
return super.visitChildren(relNode);
}
});
return res;
}
use of io.mycat.calcite.physical.MycatSQLTableLookup in project Mycat2 by MyCATApache.
the class MycatTableLookupSemiJoinRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
Join join = call.rel(0);
RelOptCluster cluster = join.getCluster();
RelNode left = call.rel(1);
RelNode right = call.rel(2);
RelMetadataQuery metadataQuery = cluster.getMetadataQuery();
RelHint lastJoinHint = HintTools.getLastJoinHint(join.getHints());
// if (lastJoinHint == null){
// return;
// }
boolean hint = false;
if (lastJoinHint != null && "use_bka_join".equalsIgnoreCase(lastJoinHint.hintName)) {
hint = true;
} else {
double leftRowCount = Optional.ofNullable(metadataQuery.getRowCount(left)).orElse(0.0);
if (leftRowCount > BKA_JOIN_LEFT_ROW_COUNT_LIMIT) {
return;
}
}
if (!join.analyzeCondition().isEqui()) {
return;
}
if (!(right instanceof MycatView)) {
return;
}
MycatView mycatView = (MycatView) right;
if (mycatView.banPushdown()) {
return;
}
if (!hint) {
if (!isGisView(mycatView))
return;
}
JoinRelType joinType = join.getJoinType();
switch(joinType) {
case LEFT:
case INNER:
case SEMI:
break;
default:
return;
}
if (RelOptUtil.countJoins(mycatView.getRelNode()) > 1) {
return;
}
RelBuilder relBuilder = MycatCalciteSupport.relBuilderFactory.create(cluster, null);
//
// ImmutableList.Builder<RelDataTypeField> listBuilder = ImmutableList.builder();
// Map<Integer, Integer> sourcePosToTargetPos = new HashMap<>();
// extractedTrimJoinLeftKeys(join, listBuilder, sourcePosToTargetPos);
// RelRecordType argTypeListRecordType = new RelRecordType(listBuilder.build());
// Mapping mapping = Mappings.bijection(sourcePosToTargetPos);
// RexNode equiCondition = RexUtil.apply(mapping, RelOptUtil.createEquiJoinCondition(right, join.analyzeCondition().rightKeys, left, join.analyzeCondition().leftKeys,
// MycatCalciteSupport.RexBuilder));
RexBuilder rexBuilder = MycatCalciteSupport.RexBuilder;
RelDataTypeFactory typeFactory = cluster.getTypeFactory();
relBuilder.push(right);
List<RexNode> rightExprs = new ArrayList<>();
{
for (Integer rightKey : join.analyzeCondition().rightSet()) {
rightExprs.add(relBuilder.field(rightKey));
}
}
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.createUnknownType(), correl);
leftExprs.add(rexBuilder.makeCast(type, rexNode));
}
}
RexNode condition = relBuilder.call(MYCAT_SQL_LOOKUP_IN, rexBuilder.makeCall(SqlStdOperatorTable.ROW, rightExprs), rexBuilder.makeCall(SqlStdOperatorTable.ROW, leftExprs));
Distribution.Type type = mycatView.getDistribution().type();
switch(type) {
case PHY:
case BROADCAST:
{
RelNode relNode = mycatView.getRelNode();
relBuilder.push(relNode);
relBuilder.filter(condition);
relBuilder.rename(mycatView.getRowType().getFieldNames());
MycatView view = mycatView.changeTo(relBuilder.build());
call.transformTo(new MycatSQLTableLookup(cluster, join.getTraitSet(), left, view, joinType, join.getCondition(), correlationIds, MycatSQLTableLookup.Type.BACK));
return;
}
case SHARDING:
{
RelNode innerRelNode = mycatView.getRelNode();
boolean bottomFilter = innerRelNode instanceof TableScan;
relBuilder.push(mycatView.getRelNode());
relBuilder.filter(condition);
RelNode innerDataNode = relBuilder.rename(mycatView.getRowType().getFieldNames()).build();
Optional<RexNode> viewConditionOptional = mycatView.getCondition();
RexNode finalCondition = null;
if (!viewConditionOptional.isPresent() && bottomFilter) {
finalCondition = condition;
} else if (bottomFilter) {
finalCondition = viewConditionOptional.map(i -> RexUtil.composeConjunction(MycatCalciteSupport.RexBuilder, ImmutableList.of(i, condition))).orElse(condition);
}
MycatView resView = MycatView.ofCondition(innerDataNode, mycatView.getDistribution(), finalCondition);
call.transformTo(new MycatSQLTableLookup(cluster, join.getTraitSet(), left, resView, joinType, join.getCondition(), correlationIds, MycatSQLTableLookup.Type.BACK));
break;
}
default:
}
}
use of io.mycat.calcite.physical.MycatSQLTableLookup in project Mycat2 by MyCATApache.
the class MycatTableLookupCombineRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
Join join = call.rel(0);
RelOptCluster cluster = join.getCluster();
MycatSQLTableLookup left = call.rel(1);
if (left.getType() != MycatSQLTableLookup.Type.NONE) {
return;
}
RelNode right = call.rel(2);
JoinInfo joinInfo = join.analyzeCondition();
if (!(right instanceof MycatView)) {
return;
}
MycatView inneRightMycatView = (MycatView) left.getRight();
MycatView outerRightmycatView = (MycatView) right;
if (outerRightmycatView.banPushdown()) {
return;
}
JoinRelType joinType = join.getJoinType();
switch(joinType) {
case INNER:
case SEMI:
break;
default:
return;
}
if (RelOptUtil.countJoins(outerRightmycatView.getRelNode()) > 1) {
return;
}
switch(outerRightmycatView.getDistribution().type()) {
case PHY:
case BROADCAST:
{
RelBuilder builder = call.builder();
inneRightMycatView.getDistribution().join(outerRightmycatView.getDistribution()).ifPresent(c -> {
RelBuilder relBuilder = builder.push(inneRightMycatView.getRelNode()).push(outerRightmycatView.getRelNode()).join(joinType, join.getCondition());
RelNode relNode = relBuilder.build();
MycatView view = MycatView.ofCondition(relNode, c, null);
call.transformTo(left.changeTo(left.getInput(0), view));
});
break;
}
case SHARDING:
{
SQLRBORewriter.bottomJoin(inneRightMycatView, outerRightmycatView, join).ifPresent(relNode1 -> {
call.transformTo(left.changeTo(left.getInput(0), (MycatView) relNode1));
});
break;
}
default:
}
}
Aggregations