private static double pkSelectivity(Join joinRel, RelMetadataQuery mq, boolean leftChild, RelNode child, double childRowCount) { if ((leftChild && joinRel.getJoinType().generatesNullsOnRight()) || (!leftChild && joinRel.getJoinType().generatesNullsOnLeft())) { return 1.0; } else { HiveTableScan tScan = EstimateUniqueKeys.getTableScan(child, true); if (tScan != null) { double tRowCount = mq.getRowCount(tScan); return childRowCount / tRowCount; } else { return 1.0; } } }
private static double pkSelectivity(Join joinRel, RelMetadataQuery mq, boolean leftChild, RelNode child, double childRowCount) { if ((leftChild && joinRel.getJoinType().generatesNullsOnRight()) || (!leftChild && joinRel.getJoinType().generatesNullsOnLeft())) { return 1.0; } else { HiveTableScan tScan = HiveRelMdUniqueKeys.getTableScan(child, true); if (tScan != null) { double tRowCount = mq.getRowCount(tScan); return childRowCount / tRowCount; } else { return 1.0; } } }
&& rightUnique && (leftSet != null) && !(rel.getJoinType().generatesNullsOnLeft())) { retSet.addAll(leftSet);
final List<RexNode> rightFilters = new ArrayList<>(); RelOptUtil.classifyFilters(join, joinFilters, join.getJoinType(),false, !join.getJoinType().generatesNullsOnRight(), !join.getJoinType().generatesNullsOnLeft(), joinFilters, leftFilters, rightFilters); PKSideInfo pkInfo = new PKSideInfo(rightRowCount, rightNDV, join.getJoinType().generatesNullsOnLeft() ? 1.0 : pkSelectivity); double ndvScalingFactor = isPKSideSimpleTree ? rightNDV/leftNDV : 1.0;
.getJoinType().generatesNullsOnLeft(), joinFilters, leftFilters, rightFilters); PKSideInfo pkInfo = new PKSideInfo(rightRowCount, rightNDV, joinRel.getJoinType().generatesNullsOnLeft() ? 1.0 : pkSelectivity);
.getJoinType().generatesNullsOnLeft(), joinFilters, leftFilters, rightFilters); PKSideInfo pkInfo = new PKSideInfo(rightRowCount, rightNDV, joinRel.getJoinType().generatesNullsOnLeft() ? 1.0 : pkSelectivity);
/** Returns whether this join type generates nulls on side #{@code i}. */ public boolean generatesNullsOn(int i) { switch (i) { case 0: return generatesNullsOnLeft(); case 1: return generatesNullsOnRight(); default: throw new IllegalArgumentException("invalid: " + i); } }
/** Returns whether this join type generates nulls on side #{@code i}. */ public boolean generatesNullsOn(int i) { switch (i) { case 0: return generatesNullsOnLeft(); case 1: return generatesNullsOnRight(); default: throw new IllegalArgumentException("invalid: " + i); } }
filters.add(joinRel.getCondition()); if (canCombine(left, joinType.generatesNullsOnLeft())) { filters.add(((MultiJoin) left).getJoinFilter());
filters.add(joinRel.getCondition()); if (canCombine(left, joinType.generatesNullsOnLeft())) { filters.add(((MultiJoin) left).getJoinFilter());
private static double pkSelectivity(Join joinRel, boolean leftChild, RelNode child, double childRowCount) { if ((leftChild && joinRel.getJoinType().generatesNullsOnRight()) || (!leftChild && joinRel.getJoinType().generatesNullsOnLeft())) { return 1.0; } else { HiveTableScan tScan = HiveRelMdUniqueKeys.getTableScan(child, true); if (tScan != null) { double tRowCount = RelMetadataQuery.getRowCount(tScan); return childRowCount / tRowCount; } else { return 1.0; } } }
@Override public void onMatch(RelOptRuleCall call) { Join join = call.rel(0); if (join.getJoinType().generatesNullsOnLeft()) { // "select * from emp right join dept" is not necessarily empty if // emp is empty return; } call.transformTo(call.builder().push(join).empty().build()); } };
@Override public void onMatch(RelOptRuleCall call) { Join join = call.rel(0); if (join.getJoinType().generatesNullsOnLeft()) { // "select * from emp right join dept" is not necessarily empty if // emp is empty return; } call.transformTo(call.builder().push(join).empty().build()); } };
public Double getMaxRowCount(Join rel, RelMetadataQuery mq) { Double left = mq.getMaxRowCount(rel.getLeft()); Double right = mq.getMaxRowCount(rel.getRight()); if (left == null || right == null) { return null; } if (left < 1D && rel.getJoinType().generatesNullsOnLeft()) { left = 1D; } if (right < 1D && rel.getJoinType().generatesNullsOnRight()) { right = 1D; } return left * right; }
public Double getMaxRowCount(Join rel, RelMetadataQuery mq) { Double left = mq.getMaxRowCount(rel.getLeft()); Double right = mq.getMaxRowCount(rel.getRight()); if (left == null || right == null) { return null; } if (left < 1D && rel.getJoinType().generatesNullsOnLeft()) { left = 1D; } if (right < 1D && rel.getJoinType().generatesNullsOnRight()) { right = 1D; } return left * right; }
public Set<RelColumnOrigin> getColumnOrigins(Join rel, RelMetadataQuery mq, int iOutputColumn) { int nLeftColumns = rel.getLeft().getRowType().getFieldList().size(); Set<RelColumnOrigin> set; boolean derived = false; if (iOutputColumn < nLeftColumns) { set = mq.getColumnOrigins(rel.getLeft(), iOutputColumn); if (rel.getJoinType().generatesNullsOnLeft()) { derived = true; } } else { set = mq.getColumnOrigins(rel.getRight(), iOutputColumn - nLeftColumns); if (rel.getJoinType().generatesNullsOnRight()) { derived = true; } } if (derived) { // nulls are generated due to outer join; that counts // as derivation set = createDerivedColumnOrigins(set); } return set; }
public Set<RelColumnOrigin> getColumnOrigins(Join rel, RelMetadataQuery mq, int iOutputColumn) { int nLeftColumns = rel.getLeft().getRowType().getFieldList().size(); Set<RelColumnOrigin> set; boolean derived = false; if (iOutputColumn < nLeftColumns) { set = mq.getColumnOrigins(rel.getLeft(), iOutputColumn); if (rel.getJoinType().generatesNullsOnLeft()) { derived = true; } } else { set = mq.getColumnOrigins(rel.getRight(), iOutputColumn - nLeftColumns); if (rel.getJoinType().generatesNullsOnRight()) { derived = true; } } if (derived) { // nulls are generated due to outer join; that counts // as derivation set = createDerivedColumnOrigins(set); } return set; }
private PlannerOp planEnumerableThetaJoin(EnumerableThetaJoin op, RelDataType rowType) { PlannerOp left = convertRelNode(op.getLeft(), null, false); PlannerOp right = convertRelNode(op.getRight(), null, false); CompiledSQLExpression condition = SQLExpressionCompiler.compileExpression(op.getCondition()); boolean generateNullsOnLeft = op.getJoinType().generatesNullsOnLeft(); boolean generateNullsOnRight = op.getJoinType().generatesNullsOnRight(); final RelDataType _rowType = rowType == null ? op.getRowType() : rowType; List<RelDataTypeField> fieldList = _rowType.getFieldList(); Column[] columns = new Column[fieldList.size()]; String[] fieldNames = new String[columns.length]; int i = 0; for (RelDataTypeField field : fieldList) { Column col = Column.column(field.getName().toLowerCase(), convertToHerdType(field.getType())); fieldNames[i] = col.name; columns[i++] = col; } return new ThetaJoinOp(fieldNames, columns, left, right, condition, generateNullsOnLeft, generateNullsOnRight, false); }
private PlannerOp planEnumerableJoin(EnumerableJoin op, RelDataType rowType) { // please note that EnumerableJoin has a condition field which actually is not useful PlannerOp left = convertRelNode(op.getLeft(), null, false); PlannerOp right = convertRelNode(op.getRight(), null, false); int[] leftKeys = op.getLeftKeys().toIntArray(); int[] rightKeys = op.getRightKeys().toIntArray(); boolean generateNullsOnLeft = op.getJoinType().generatesNullsOnLeft(); boolean generateNullsOnRight = op.getJoinType().generatesNullsOnRight(); final RelDataType _rowType = rowType == null ? op.getRowType() : rowType; List<RelDataTypeField> fieldList = _rowType.getFieldList(); Column[] columns = new Column[fieldList.size()]; String[] fieldNames = new String[columns.length]; int i = 0; for (RelDataTypeField field : fieldList) { Column col = Column.column(field.getName().toLowerCase(), convertToHerdType(field.getType())); fieldNames[i] = col.name; columns[i++] = col; } return new JoinOp(fieldNames, columns, leftKeys, left, rightKeys, right, generateNullsOnLeft, generateNullsOnRight, false); }
private PlannerOp planEnumerableMergeJoin(EnumerableMergeJoin op, RelDataType rowType) { // please note that EnumerableMergeJoin has a condition field which actually is not useful PlannerOp left = convertRelNode(op.getLeft(), null, false); PlannerOp right = convertRelNode(op.getRight(), null, false); int[] leftKeys = op.getLeftKeys().toIntArray(); int[] rightKeys = op.getRightKeys().toIntArray(); boolean generateNullsOnLeft = op.getJoinType().generatesNullsOnLeft(); boolean generateNullsOnRight = op.getJoinType().generatesNullsOnRight(); final RelDataType _rowType = rowType == null ? op.getRowType() : rowType; List<RelDataTypeField> fieldList = _rowType.getFieldList(); Column[] columns = new Column[fieldList.size()]; String[] fieldNames = new String[columns.length]; int i = 0; for (RelDataTypeField field : fieldList) { Column col = Column.column(field.getName().toLowerCase(), convertToHerdType(field.getType())); fieldNames[i] = col.name; columns[i++] = col; } return new JoinOp(fieldNames, columns, leftKeys, left, rightKeys, right, generateNullsOnLeft, generateNullsOnRight, true); }