@Override public List<Double> averageColumnSizes(SemiJoin rel, RelMetadataQuery mq) { final RelNode left = rel.getLeft(); final List<Double> lefts = mq.getAverageColumnSizes(left); if (lefts == null) { return null; } final int fieldCount = rel.getRowType().getFieldCount(); Double[] sizes = new Double[fieldCount]; if (lefts != null) { lefts.toArray(sizes); } return ImmutableNullableList.copyOf(sizes); }
final ImmutableIntList leftKeys = semiJoin.getLeftKeys(); final ImmutableIntList rightKeys = semiJoin.getRightKeys(); int nFieldsZ = semiJoin.getRight().getRowType().getFieldList().size(); int nTotalFields = nFieldsX + nFieldsY + nFieldsZ; List<RelDataTypeField> fields = new ArrayList<>(); semiJoin.getRowType().getFieldList(); for (int i = 0; i < (nFieldsX + nFieldsY); i++) { fields.add(joinFields.get(i)); joinFields = semiJoin.getRight().getRowType().getFieldList(); for (int i = 0; i < nFieldsZ; i++) { fields.add(joinFields.get(i)); -nFieldsY); newSemiJoinFilter = semiJoin.getCondition().accept( new RelOptUtil.RexInputConverter( semiJoin.getCluster().getRexBuilder(), fields, adjustments)); -nFieldsX); newSemiJoinFilter = semiJoin.getCondition().accept( new RelOptUtil.RexInputConverter( semiJoin.getCluster().getRexBuilder(), fields,
public void onMatch(RelOptRuleCall call) { SemiJoin semiJoin = call.rel(0); LogicalFilter filter = call.rel(1); RelNode newSemiJoin = SemiJoin.create(filter.getInput(), semiJoin.getRight(), semiJoin.getCondition(), semiJoin.getLeftKeys(), semiJoin.getRightKeys()); final RelFactories.FilterFactory factory = RelFactories.DEFAULT_FILTER_FACTORY; RelNode newFilter = factory.createFilter(newSemiJoin, filter.getCondition()); call.transformTo(newFilter); } }
final MutableRel left = toMutable(semiJoin.getLeft()); final MutableRel right = toMutable(semiJoin.getRight()); return MutableSemiJoin.of(semiJoin.getRowType(), left, right, semiJoin.getCondition(), semiJoin.getLeftKeys(), semiJoin.getRightKeys());
OpAttr dispatch(RelNode rn) throws SemanticException { if (rn instanceof HiveTableScan) { return visit((HiveTableScan) rn); } else if (rn instanceof HiveProject) { return visit((HiveProject) rn); } else if (rn instanceof MultiJoin) { return visit((MultiJoin) rn); } else if (rn instanceof HiveJoin) { return visit((HiveJoin) rn); } else if (rn instanceof SemiJoin) { SemiJoin sj = (SemiJoin) rn; HiveJoin hj = HiveJoin.getJoin(sj.getCluster(), sj.getLeft(), sj.getRight(), sj.getCondition(), sj.getJoinType(), true); return visit(hj); } else if (rn instanceof HiveFilter) { return visit((HiveFilter) rn); } else if (rn instanceof HiveSort) { return visit((HiveSort) rn); } else if (rn instanceof HiveUnion) { return visit((HiveUnion) rn); } else if (rn instanceof HiveSortExchange) { return visit((HiveSortExchange) rn); } else if (rn instanceof HiveAggregate) { return visit((HiveAggregate) rn); } LOG.error(rn.getClass().getCanonicalName() + "operator translation not supported" + " yet in return path."); return null; }
/** * Computes the selectivity of a semijoin filter if it is applied on a fact * table. The computation is based on the selectivity of the dimension * table/columns and the number of distinct values in the fact table * columns. * * @param rel semijoin rel * @return calculated selectivity */ public static double computeSemiJoinSelectivity(RelMetadataQuery mq, SemiJoin rel) { return computeSemiJoinSelectivity(mq, rel.getLeft(), rel.getRight(), rel.getLeftKeys(), rel.getRightKeys()); }
public Double getSelectivity(SemiJoin rel, RelMetadataQuery mq, RexNode predicate) { // create a RexNode representing the selectivity of the // semijoin filter and pass it to getSelectivity RexBuilder rexBuilder = rel.getCluster().getRexBuilder(); RexNode newPred = RelMdUtil.makeSemiJoinSelectivityRexNode(mq, rel); if (predicate != null) { newPred = rexBuilder.makeCall( SqlStdOperatorTable.AND, newPred, predicate); } return mq.getSelectivity(rel.getLeft(), newPred); }
/** * Creates a RexNode that stores a selectivity value corresponding to the * selectivity of a semijoin. This can be added to a filter to simulate the * effect of the semijoin during costing, but should never appear in a real * plan since it has no physical implementation. * * @param rel the semijoin of interest * @return constructed rexnode */ public static RexNode makeSemiJoinSelectivityRexNode(RelMetadataQuery mq, SemiJoin rel) { RexBuilder rexBuilder = rel.getCluster().getRexBuilder(); double selectivity = computeSemiJoinSelectivity(mq, rel.getLeft(), rel.getRight(), rel); return rexBuilder.makeCall(ARTIFICIAL_SELECTIVITY_FUNC, rexBuilder.makeApproxLiteral(new BigDecimal(selectivity))); }
RelNode rightChild = semiJoin.getRight(); typeFactory, null, semiJoin.getSystemFieldList()); RexProgramBuilder bottomProgramBuilder = new RexProgramBuilder(bottomInputRowType, rexBuilder); typeFactory, null, semiJoin.getSystemFieldList()); RexProgramBuilder topProgramBuilder = new RexProgramBuilder( rexBuilder); topProgramBuilder.addIdentity(); topProgramBuilder.addCondition(semiJoin.getCondition()); RexProgram topProgram = topProgramBuilder.getProgram();
public Set<ImmutableBitSet> getUniqueKeys(SemiJoin rel, RelMetadataQuery mq, boolean ignoreNulls) { // only return the unique keys from the LHS since a semijoin only // returns the LHS return mq.getUniqueKeys(rel.getLeft(), ignoreNulls); }
/** * Computes the selectivity of a semijoin filter if it is applied on a fact * table. The computation is based on the selectivity of the dimension * table/columns and the number of distinct values in the fact table * columns. * * @param factRel fact table participating in the semijoin * @param dimRel dimension table participating in the semijoin * @param rel semijoin rel * @return calculated selectivity */ public static double computeSemiJoinSelectivity(RelMetadataQuery mq, RelNode factRel, RelNode dimRel, SemiJoin rel) { return computeSemiJoinSelectivity(mq, factRel, dimRel, rel.getLeftKeys(), rel.getRightKeys()); }
private Pair<ImmutableBitSet, ImmutableBitSet> getSemiJoinConditionInputRefs(SemiJoin semiJoin) { final int leftInputFieldCount = semiJoin.getLeft().getRowType().getFieldCount(); final ImmutableBitSet.Builder leftInputBitSet = ImmutableBitSet.builder(); final ImmutableBitSet.Builder rightInputBitSet = ImmutableBitSet.builder(); semiJoin.getCondition().accept(new RexVisitorImpl<Void>(true) { public Void visitInputRef(RexInputRef inputRef) { int index = inputRef.getIndex(); if (index < leftInputFieldCount) { leftInputBitSet.set(index); } else { rightInputBitSet.set(index); } return null; } }); return new Pair<>(leftInputBitSet.build(), rightInputBitSet.build()); } }
@Override public SemiJoin copy(RelTraitSet traitSet, RexNode condition, RelNode left, RelNode right, JoinRelType joinType, boolean semiJoinDone) { assert joinType == JoinRelType.INNER; final JoinInfo joinInfo = JoinInfo.of(left, right, condition); assert joinInfo.isEqui(); return new SemiJoin(getCluster(), traitSet, left, right, condition, joinInfo.leftKeys, joinInfo.rightKeys); }
@Override public RelNode convert(RelNode rel) { final SemiJoin semiJoin = (SemiJoin) rel; final List<RelNode> newInputs = new ArrayList<>(); for (RelNode input : semiJoin.getInputs()) { if (!(input.getConvention() instanceof EnumerableConvention)) { input = convert(input, input.getTraitSet().replace(EnumerableConvention.INSTANCE)); } newInputs.add(input); } return EnumerableSemiJoin.create(newInputs.get(0), newInputs.get(1), semiJoin.getCondition(), semiJoin.leftKeys, semiJoin.rightKeys); } }
public RelNode createSemiJoin(RelNode left, RelNode right, RexNode condition) { final JoinInfo joinInfo = JoinInfo.of(left, right, condition); return SemiJoin.create(left, right, condition, joinInfo.leftKeys, joinInfo.rightKeys); } }
/** * {@inheritDoc} * * <p>In the case of semi-join, the row type consists of columns from left * input only. */ @Override public RelDataType deriveRowType() { return SqlValidatorUtil.deriveJoinRowType( left.getRowType(), null, JoinRelType.INNER, getCluster().getTypeFactory(), null, ImmutableList.of()); } }
/** Creates a SemiJoin. */ public static SemiJoin create(RelNode left, RelNode right, RexNode condition, ImmutableIntList leftKeys, ImmutableIntList rightKeys) { final RelOptCluster cluster = left.getCluster(); return new SemiJoin(cluster, cluster.traitSetOf(Convention.NONE), left, right, condition, leftKeys, rightKeys); }
final ImmutableBitSet dimCols = ImmutableBitSet.of(semiJoin.getRightKeys()); final double selectivity = RelMdUtil.computeSemiJoinSelectivity(mq, factRel, dimRel, semiJoin);
final ImmutableIntList leftKeys = semiJoin.getLeftKeys(); final ImmutableIntList rightKeys = semiJoin.getRightKeys(); int nFieldsZ = semiJoin.getRight().getRowType().getFieldList().size(); int nTotalFields = nFieldsX + nFieldsY + nFieldsZ; List<RelDataTypeField> fields = new ArrayList<>(); semiJoin.getRowType().getFieldList(); for (int i = 0; i < (nFieldsX + nFieldsY); i++) { fields.add(joinFields.get(i)); joinFields = semiJoin.getRight().getRowType().getFieldList(); for (int i = 0; i < nFieldsZ; i++) { fields.add(joinFields.get(i)); -nFieldsY); newSemiJoinFilter = semiJoin.getCondition().accept( new RelOptUtil.RexInputConverter( semiJoin.getCluster().getRexBuilder(), fields, adjustments)); -nFieldsX); newSemiJoinFilter = semiJoin.getCondition().accept( new RelOptUtil.RexInputConverter( semiJoin.getCluster().getRexBuilder(), fields,
public void onMatch(RelOptRuleCall call) { SemiJoin semiJoin = call.rel(0); LogicalFilter filter = call.rel(1); RelNode newSemiJoin = SemiJoin.create(filter.getInput(), semiJoin.getRight(), semiJoin.getCondition(), semiJoin.getLeftKeys(), semiJoin.getRightKeys()); final RelFactories.FilterFactory factory = RelFactories.DEFAULT_FILTER_FACTORY; RelNode newFilter = factory.createFilter(newSemiJoin, filter.getCondition()); call.transformTo(newFilter); } }