JoinTable joinTable = getJoinTable(query, pconn); assertEquals(1, joinTable.getTable().getPreFilters().size()); assertEquals(1, joinTable.getJoinSpecs().get(0).getJoinTable().getTable().getPreFilters().size()); assertEquals(1, joinTable.getJoinSpecs().get(1).getJoinTable().getTable().getPreFilters().size()); assertEquals(1, joinTable.getJoinSpecs().get(0).getJoinTable().getTable().getPreFilters().size()); assertEquals(0, joinTable.getJoinSpecs().get(1).getJoinTable().getTable().getPreFilters().size()); assertEquals(0, joinTable.getJoinSpecs().get(0).getJoinTable().getTable().getPreFilters().size()); assertEquals(1, joinTable.getJoinSpecs().get(1).getJoinTable().getTable().getPreFilters().size()); assertEquals(0, joinTable.getJoinSpecs().get(0).getJoinTable().getTable().getPreFilters().size()); assertEquals(1, joinTable.getJoinSpecs().get(1).getJoinTable().getTable().getPreFilters().size()); assertEquals(0, joinTable.getJoinSpecs().get(0).getJoinTable().getTable().getPreFilters().size()); assertEquals(0, joinTable.getJoinSpecs().get(1).getJoinTable().getTable().getPreFilters().size()); assertEquals(0, joinTable.getJoinSpecs().get(0).getJoinTable().getTable().getPreFilters().size()); assertEquals(1, joinTable.getJoinSpecs().get(1).getJoinTable().getTable().getPreFilters().size()); assertEquals(1, joinTable.getJoinSpecs().get(0).getJoinTable().getTable().getPreFilters().size()); assertEquals(1, joinTable.getJoinSpecs().get(1).getJoinTable().getTable().getPreFilters().size()); assertEquals(0, joinTable.getJoinSpecs().get(0).getJoinTable().getTable().getPreFilters().size()); assertEquals(1, joinTable.getJoinSpecs().get(1).getJoinTable().getTable().getPreFilters().size());
@Override public Pair<Table, List<JoinSpec>> visit(JoinTableNode joinNode) throws SQLException { Pair<Table, List<JoinSpec>> lhs = joinNode.getLHS().accept(this); Pair<Table, List<JoinSpec>> rhs = joinNode.getRHS().accept(this); JoinTable joinTable = rhs.getSecond() == null ? new JoinTable(rhs.getFirst()) : new JoinTable(rhs.getFirst(), rhs.getSecond()); List<JoinSpec> joinSpecs = lhs.getSecond(); if (joinSpecs == null) { joinSpecs = new ArrayList<JoinSpec>(); } joinSpecs.add(new JoinSpec(joinNode.getType(), joinNode.getOnNode(), joinTable, joinNode.isSingleValueOnly(), origResolver)); return new Pair<Table, List<JoinSpec>>(lhs.getFirst(), joinSpecs); }
@Override public Void visitLeave(ComparisonParseNode node, List<Void> l) throws SQLException { if (!(node instanceof EqualParseNode)) return leaveBooleanNode(node, l); ListIterator<JoinSpec> iter = prefilterAcceptedTables.listIterator(prefilterAcceptedTables.size()); while (iter.hasPrevious()) { JoinSpec joinSpec = iter.previous(); if (joinSpec.getType() != JoinType.Inner || joinSpec.isSingleValueOnly()) { continue; } try { joinSpec.addOnCondition(node); return null; } catch (SQLException e) { } } return leaveBooleanNode(node, l); } }
Scan subScan = ScanUtil.newScan(originalScan); subContexts[i] = new StatementContext(statement, context.getResolver(), subScan, new SequenceManager(statement)); subPlans[i] = compileJoinQuery(subContexts[i], binds, joinSpec.getJoinTable(), true, true, null); boolean hasPostReference = joinSpec.getJoinTable().hasPostReference(); if (hasPostReference) { tables[i] = subContexts[i].getResolver().getTables().get(0).getTable(); projectedTable = JoinCompiler.joinProjectedTables(projectedTable, tables[i], joinSpec.getType()); } else { tables[i] = null; context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), query.getUdfParseNodes())); joinIds[i] = new ImmutableBytesPtr(emptyByteArray); // place-holder Pair<List<Expression>, List<Expression>> joinConditions = joinSpec.compileJoinConditions(context, subContexts[i], strategy); joinExpressions[i] = joinConditions.getFirst(); List<Expression> hashExpressions = joinConditions.getSecond(); Pair<Expression, Expression> keyRangeExpressions = new Pair<Expression, Expression>(null, null); boolean optimized = getKeyExpressionCombinations(keyRangeExpressions, context, joinTable.getStatement(), tableRef, joinSpec.getType(), joinExpressions[i], hashExpressions); Expression keyRangeLhsExpression = keyRangeExpressions.getFirst(); Expression keyRangeRhsExpression = keyRangeExpressions.getSecond(); joinTypes[i] = joinSpec.getType(); if (i < count - 1) { fieldPositions[i + 1] = fieldPositions[i] + (tables[i] == null ? 0 : (tables[i].getColumns().size() - tables[i].getPKColumns().size())); hashPlans[i] = new HashSubPlan(i, subPlans[i], optimized ? null : hashExpressions, joinSpec.isSingleValueOnly(), usePersistentCache, keyRangeLhsExpression, keyRangeRhsExpression); JoinType type = lastJoinSpec.getType(); JoinTable rhsJoinTable = lastJoinSpec.getJoinTable(); Table rhsTable = rhsJoinTable.getTable(); JoinTable lhsJoin = joinTable.getSubJoinTableWithoutPostFilters();
Scan subScan = ScanUtil.newScan(originalScan); subContexts[i] = new StatementContext(statement, context.getResolver(), subScan, new SequenceManager(statement)); subPlans[i] = compileJoinQuery(subContexts[i], binds, joinSpec.getJoinTable(), true, true, null); boolean hasPostReference = joinSpec.getJoinTable().hasPostReference(); if (hasPostReference) { tables[i] = subContexts[i].getResolver().getTables().get(0).getTable(); projectedTable = JoinCompiler.joinProjectedTables(projectedTable, tables[i], joinSpec.getType()); } else { tables[i] = null; context.setResolver(FromCompiler.getResolverForProjectedTable(projectedTable, context.getConnection(), query.getUdfParseNodes())); joinIds[i] = new ImmutableBytesPtr(emptyByteArray); // place-holder Pair<List<Expression>, List<Expression>> joinConditions = joinSpec.compileJoinConditions(context, subContexts[i], strategy); joinExpressions[i] = joinConditions.getFirst(); List<Expression> hashExpressions = joinConditions.getSecond(); Pair<Expression, Expression> keyRangeExpressions = new Pair<Expression, Expression>(null, null); boolean optimized = getKeyExpressionCombinations(keyRangeExpressions, context, joinTable.getStatement(), tableRef, joinSpec.getType(), joinExpressions[i], hashExpressions); Expression keyRangeLhsExpression = keyRangeExpressions.getFirst(); Expression keyRangeRhsExpression = keyRangeExpressions.getSecond(); joinTypes[i] = joinSpec.getType(); if (i < count - 1) { fieldPositions[i + 1] = fieldPositions[i] + (tables[i] == null ? 0 : (tables[i].getColumns().size() - tables[i].getPKColumns().size())); hashPlans[i] = new HashSubPlan(i, subPlans[i], optimized ? null : hashExpressions, joinSpec.isSingleValueOnly(), keyRangeLhsExpression, keyRangeRhsExpression); JoinType type = lastJoinSpec.getType(); JoinTable rhsJoinTable = lastJoinSpec.getJoinTable(); Table rhsTable = rhsJoinTable.getTable(); JoinTable lhsJoin = joinTable.getSubJoinTableWithoutPostFilters();
rhsCompiler.reset(); Expression right = condition.getRHS().accept(rhsCompiler); PDataType toType = getCommonType(left.getDataType(), right.getDataType()); SortOrder toSortOrder = strategy == Strategy.SORT_MERGE ? SortOrder.ASC : (strategy == Strategy.HASH_BUILD_LEFT ? right.getSortOrder() : left.getSortOrder()); if (left.getDataType() != toType || left.getSortOrder() != toSortOrder) {
rhsCompiler.reset(); Expression right = condition.getRHS().accept(rhsCompiler); PDataType toType = getCommonType(left.getDataType(), right.getDataType()); SortOrder toSortOrder = strategy == Strategy.SORT_MERGE ? SortOrder.ASC : (strategy == Strategy.HASH_BUILD_LEFT ? right.getSortOrder() : left.getSortOrder()); if (left.getDataType() != toType || left.getSortOrder() != toSortOrder) {
(!useStarJoin && count > 1 && joinSpecs.get(count - 1).getType() != JoinType.Left && joinSpecs.get(count - 1).getType() != JoinType.Semi && joinSpecs.get(count - 1).getType() != JoinType.Anti && !joinSpecs.get(count - 1).isSingleValueOnly())) return null; for (int i = 0; i < count; i++) { JoinSpec joinSpec = joinSpecs.get(i); if (joinSpec.getType() != JoinType.Left && joinSpec.getType() != JoinType.Inner && joinSpec.getType() != JoinType.Semi && joinSpec.getType() != JoinType.Anti) return null; vector[i] = true; Iterator<TableRef> iter = joinSpec.getDependencies().iterator(); while (vector[i] == true && iter.hasNext()) { TableRef tableRef = iter.next();
(!useStarJoin && count > 1 && joinSpecs.get(count - 1).getType() != JoinType.Left && joinSpecs.get(count - 1).getType() != JoinType.Semi && joinSpecs.get(count - 1).getType() != JoinType.Anti && !joinSpecs.get(count - 1).isSingleValueOnly())) return null; for (int i = 0; i < count; i++) { JoinSpec joinSpec = joinSpecs.get(i); if (joinSpec.getType() != JoinType.Left && joinSpec.getType() != JoinType.Inner && joinSpec.getType() != JoinType.Semi && joinSpec.getType() != JoinType.Anti) return null; vector[i] = true; Iterator<TableRef> iter = joinSpec.getDependencies().iterator(); while (vector[i] == true && iter.hasNext()) { TableRef tableRef = iter.next();
JoinTable matched = null; for (JoinSpec joinSpec : prefilterAcceptedTables) { if (columnRefVisitor.getContentType(joinSpec.getJoinTable().getTableRefs()) == ColumnRefParseNodeVisitor.ColumnRefType.SELF_ONLY) { matched = joinSpec.getJoinTable(); break;
for (int i = 0; i < joinSpecs.size(); i++) { JoinSpec joinSpec = joinSpecs.get(i); this.tables.addAll(joinSpec.getJoinTable().getTables()); allLeftJoin = allLeftJoin && joinSpec.getType() == JoinType.Left; hasFullJoin = hasFullJoin || joinSpec.getType() == JoinType.Full; if (joinSpec.getType() == JoinType.Right) { lastRightJoinIndex = i; for (int i = lastRightJoinIndex == -1 ? 0 : lastRightJoinIndex; i < joinSpecs.size(); i++) { JoinSpec joinSpec = joinSpecs.get(i); if (joinSpec.getType() != JoinType.Left && joinSpec.getType() != JoinType.Anti && joinSpec.getType() != JoinType.Full) { prefilterAcceptedTables.add(joinSpec);
JoinType type = lastJoinSpec.getType(); if ((type == JoinType.Right || type == JoinType.Inner) && lastJoinSpec.getJoinTable().getJoinSpecs().isEmpty() && lastJoinSpec.getJoinTable().getTable().isFlat()) { strategies.add(Strategy.HASH_BUILD_LEFT);
JoinType type = lastJoinSpec.getType(); if ((type == JoinType.Right || type == JoinType.Inner) && lastJoinSpec.getJoinTable().getJoinSpecs().isEmpty() && lastJoinSpec.getJoinTable().getTable().isFlat()) { strategies.add(Strategy.HASH_BUILD_LEFT);
for (int i = 0; i < joinSpecs.size(); i++) { JoinSpec joinSpec = joinSpecs.get(i); this.tables.addAll(joinSpec.getJoinTable().getTables()); allLeftJoin = allLeftJoin && joinSpec.getType() == JoinType.Left; hasFullJoin = hasFullJoin || joinSpec.getType() == JoinType.Full; if (joinSpec.getType() == JoinType.Right) { lastRightJoinIndex = i; for (int i = lastRightJoinIndex == -1 ? 0 : lastRightJoinIndex; i < joinSpecs.size(); i++) { JoinSpec joinSpec = joinSpecs.get(i); if (joinSpec.getType() != JoinType.Left && joinSpec.getType() != JoinType.Anti && joinSpec.getType() != JoinType.Full) { prefilterAcceptedTables.add(joinSpec);
JoinTable matched = null; for (JoinSpec joinSpec : prefilterAcceptedTables) { if (columnRefVisitor.getContentType(joinSpec.getJoinTable().getTableRefs()) == ColumnRefParseNodeVisitor.ColumnRefType.SELF_ONLY) { matched = joinSpec.getJoinTable(); break;
public void pushDownColumnRefVisitors(ColumnRefParseNodeVisitor generalRefVisitor, ColumnRefParseNodeVisitor joinLocalRefVisitor, ColumnRefParseNodeVisitor prefilterRefVisitor) throws SQLException { for (ParseNode node : table.getPreFilters()) { node.accept(prefilterRefVisitor); } for (ParseNode node : table.getPostFilters()) { node.accept(generalRefVisitor); } for (ParseNode node : postFilters) { node.accept(generalRefVisitor); } for (JoinSpec joinSpec : joinSpecs) { JoinTable joinTable = joinSpec.getJoinTable(); boolean hasSubJoin = !joinTable.getJoinSpecs().isEmpty(); for (EqualParseNode node : joinSpec.getOnConditions()) { node.getLHS().accept(generalRefVisitor); if (hasSubJoin) { node.getRHS().accept(generalRefVisitor); } else { node.getRHS().accept(joinLocalRefVisitor); } } joinTable.pushDownColumnRefVisitors(generalRefVisitor, joinLocalRefVisitor, prefilterRefVisitor); } }
public void pushDownColumnRefVisitors(ColumnRefParseNodeVisitor generalRefVisitor, ColumnRefParseNodeVisitor joinLocalRefVisitor, ColumnRefParseNodeVisitor prefilterRefVisitor) throws SQLException { for (ParseNode node : table.getPreFilters()) { node.accept(prefilterRefVisitor); } for (ParseNode node : table.getPostFilters()) { node.accept(generalRefVisitor); } for (ParseNode node : postFilters) { node.accept(generalRefVisitor); } for (JoinSpec joinSpec : joinSpecs) { JoinTable joinTable = joinSpec.getJoinTable(); boolean hasSubJoin = !joinTable.getJoinSpecs().isEmpty(); for (EqualParseNode node : joinSpec.getOnConditions()) { node.getLHS().accept(generalRefVisitor); if (hasSubJoin) { node.getRHS().accept(generalRefVisitor); } else { node.getRHS().accept(joinLocalRefVisitor); } } joinTable.pushDownColumnRefVisitors(generalRefVisitor, joinLocalRefVisitor, prefilterRefVisitor); } }
@Override public Void visitLeave(ComparisonParseNode node, List<Void> l) throws SQLException { if (!(node instanceof EqualParseNode)) return leaveBooleanNode(node, l); ListIterator<JoinSpec> iter = prefilterAcceptedTables.listIterator(prefilterAcceptedTables.size()); while (iter.hasPrevious()) { JoinSpec joinSpec = iter.previous(); if (joinSpec.getType() != JoinType.Inner || joinSpec.isSingleValueOnly()) { continue; } try { joinSpec.addOnCondition(node); return null; } catch (SQLException e) { } } return leaveBooleanNode(node, l); } }
@Override public Void visitLeave(ComparisonParseNode node, List<Void> l) throws SQLException { if (!(node instanceof EqualParseNode)) return leaveBooleanNode(node, l); ListIterator<JoinSpec> iter = prefilterAcceptedTables.listIterator(prefilterAcceptedTables.size()); while (iter.hasPrevious()) { JoinSpec joinSpec = iter.previous(); if (joinSpec.getType() != JoinType.Inner || joinSpec.isSingleValueOnly()) { continue; } try { joinSpec.addOnCondition(node); return null; } catch (SQLException e) { } } return leaveBooleanNode(node, l); } }
@Override public Pair<Table, List<JoinSpec>> visit(JoinTableNode joinNode) throws SQLException { Pair<Table, List<JoinSpec>> lhs = joinNode.getLHS().accept(this); Pair<Table, List<JoinSpec>> rhs = joinNode.getRHS().accept(this); JoinTable joinTable = rhs.getSecond() == null ? new JoinTable(rhs.getFirst()) : new JoinTable(rhs.getFirst(), rhs.getSecond()); List<JoinSpec> joinSpecs = lhs.getSecond(); if (joinSpecs == null) { joinSpecs = new ArrayList<JoinSpec>(); } joinSpecs.add(new JoinSpec(joinNode.getType(), joinNode.getOnNode(), joinTable, joinNode.isSingleValueOnly(), origResolver)); return new Pair<Table, List<JoinSpec>>(lhs.getFirst(), joinSpecs); }