org.apache.calcite.plan.RelOptUtil Java Examples
The following examples show how to use
org.apache.calcite.plan.RelOptUtil.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: FlinkJoinToMultiJoinRule.java From flink with Apache License 2.0 | 6 votes |
/** * Shifts a filter originating from the right child of the LogicalJoin to the * right, to reflect the filter now being applied on the resulting * MultiJoin. * * @param joinRel the original LogicalJoin * @param left the left child of the LogicalJoin * @param right the right child of the LogicalJoin * @param rightFilter the filter originating from the right child * @return the adjusted right filter */ private RexNode shiftRightFilter( Join joinRel, RelNode left, MultiJoin right, RexNode rightFilter) { if (rightFilter == null) { return null; } int nFieldsOnLeft = left.getRowType().getFieldList().size(); int nFieldsOnRight = right.getRowType().getFieldList().size(); int[] adjustments = new int[nFieldsOnRight]; for (int i = 0; i < nFieldsOnRight; i++) { adjustments[i] = nFieldsOnLeft; } rightFilter = rightFilter.accept( new RelOptUtil.RexInputConverter( joinRel.getCluster().getRexBuilder(), right.getRowType().getFieldList(), joinRel.getRowType().getFieldList(), adjustments)); return rightFilter; }
Example #2
Source File: RexSimplify.java From Bats with Apache License 2.0 | 6 votes |
RexNode simplifyAnd(RexCall e, RexUnknownAs unknownAs) { List<RexNode> operands = RelOptUtil.conjunctions(e); if (unknownAs == FALSE && predicateElimination) { simplifyAndTerms(operands, FALSE); } else { simplifyList(operands, unknownAs); } final List<RexNode> terms = new ArrayList<>(); final List<RexNode> notTerms = new ArrayList<>(); for (RexNode o : operands) { RelOptUtil.decomposeConjunction(o, terms, notTerms); } switch (unknownAs) { case FALSE: return simplifyAnd2ForUnknownAsFalse(terms, notTerms, Comparable.class); } return simplifyAnd2(terms, notTerms); }
Example #3
Source File: LoptOptimizeJoinRule.java From Bats with Apache License 2.0 | 6 votes |
/** * Determines whether any additional filters are applicable to a join tree. * If there are any, creates a filter node on top of the join tree with the * additional filters. * * @param relBuilder Builder holding current join tree * @param multiJoin join factors being optimized * @param left left side of join tree * @param right right side of join tree * @param filtersToAdd remaining filters */ private void addAdditionalFilters( RelBuilder relBuilder, LoptMultiJoin multiJoin, LoptJoinTree left, LoptJoinTree right, List<RexNode> filtersToAdd) { RexNode filterCond = addFilters(multiJoin, left, -1, right, filtersToAdd, false); if (!filterCond.isAlwaysTrue()) { // adjust the filter to reflect the outer join output int [] adjustments = new int[multiJoin.getNumTotalFields()]; if (needsAdjustment(multiJoin, adjustments, left, right, false)) { RexBuilder rexBuilder = multiJoin.getMultiJoinRel().getCluster().getRexBuilder(); filterCond = filterCond.accept( new RelOptUtil.RexInputConverter( rexBuilder, multiJoin.getMultiJoinFields(), relBuilder.peek().getRowType().getFieldList(), adjustments)); relBuilder.filter(filterCond); } } }
Example #4
Source File: Lattice.java From calcite with Apache License 2.0 | 6 votes |
private static boolean populate(List<RelNode> nodes, List<int[][]> tempLinks, RelNode rel) { if (nodes.isEmpty() && rel instanceof LogicalProject) { return populate(nodes, tempLinks, ((LogicalProject) rel).getInput()); } if (rel instanceof TableScan) { nodes.add(rel); return true; } if (rel instanceof LogicalJoin) { LogicalJoin join = (LogicalJoin) rel; if (join.getJoinType().isOuterJoin()) { throw new RuntimeException("only non nulls-generating join allowed, but got " + join.getJoinType()); } populate(nodes, tempLinks, join.getLeft()); populate(nodes, tempLinks, join.getRight()); for (RexNode rex : RelOptUtil.conjunctions(join.getCondition())) { tempLinks.add(grab(nodes, rex)); } return true; } throw new RuntimeException("Invalid node type " + rel.getClass().getSimpleName() + " in lattice query"); }
Example #5
Source File: MaterializedViewFilterScanRule.java From Bats with Apache License 2.0 | 6 votes |
protected void apply(RelOptRuleCall call, Filter filter, TableScan scan) { final RelOptPlanner planner = call.getPlanner(); final List<RelOptMaterialization> materializations = planner.getMaterializations(); if (!materializations.isEmpty()) { RelNode root = filter.copy(filter.getTraitSet(), Collections.singletonList((RelNode) scan)); List<RelOptMaterialization> applicableMaterializations = RelOptMaterializations.getApplicableMaterializations(root, materializations); for (RelOptMaterialization materialization : applicableMaterializations) { if (RelOptUtil.areRowTypesEqual(scan.getRowType(), materialization.queryRel.getRowType(), false)) { RelNode target = materialization.queryRel; final HepPlanner hepPlanner = new HepPlanner(program, planner.getContext()); hepPlanner.setRoot(target); target = hepPlanner.findBestExp(); List<RelNode> subs = new MaterializedViewSubstitutionVisitor(target, root) .go(materialization.tableRel); for (RelNode s : subs) { call.transformTo(s); } } } } }
Example #6
Source File: MultiJoinProjectTransposeRule.java From Bats with Apache License 2.0 | 6 votes |
protected RelNode getProjectChild( RelOptRuleCall call, LogicalProject project, boolean leftChild) { // locate the appropriate MultiJoin based on which rule was fired // and which projection we're dealing with MultiJoin multiJoin; if (leftChild) { multiJoin = call.rel(2); } else if (call.rels.length == 4) { multiJoin = call.rel(3); } else { multiJoin = call.rel(4); } // create a new MultiJoin that reflects the columns in the projection // above the MultiJoin return RelOptUtil.projectMultiJoin(multiJoin, project); }
Example #7
Source File: Prepare.java From calcite with Apache License 2.0 | 6 votes |
public final RelOptTable extend(List<RelDataTypeField> extendedFields) { final Table table = unwrap(Table.class); // Get the set of extended columns that do not have the same name as a column // in the base table. final List<RelDataTypeField> baseColumns = getRowType().getFieldList(); final List<RelDataTypeField> dedupedFields = RelOptUtil.deduplicateColumns(baseColumns, extendedFields); final List<RelDataTypeField> dedupedExtendedFields = dedupedFields.subList(baseColumns.size(), dedupedFields.size()); if (table instanceof ExtensibleTable) { final Table extendedTable = ((ExtensibleTable) table).extend(dedupedExtendedFields); return extend(extendedTable); } else if (table instanceof ModifiableViewTable) { final ModifiableViewTable modifiableViewTable = (ModifiableViewTable) table; final ModifiableViewTable extendedView = modifiableViewTable.extend(dedupedExtendedFields, getRelOptSchema().getTypeFactory()); return extend(extendedView); } throw new RuntimeException("Cannot extend " + table); }
Example #8
Source File: ElasticsearchJoin.java From dk-fitting with Apache License 2.0 | 6 votes |
public void implement(Implementor implementor) { implementor.visitChild(0, getLeft()); implementor.visitChild(0, getRight()); if (!getCondition().isA(SqlKind.EQUALS)) { throw new IllegalArgumentException("Only equi-join are supported"); } List<RexNode> operands = ((RexCall) getCondition()).getOperands(); if (operands.size() != 2) { throw new IllegalArgumentException("Only equi-join are supported"); } List<Integer> leftKeys = new ArrayList<Integer>(1); List<Integer> rightKeys = new ArrayList<Integer>(1); List<Boolean> filterNulls = new ArrayList<Boolean>(1); RexNode rexNode = RelOptUtil.splitJoinCondition(getLeft(), getRight(), getCondition(), leftKeys, rightKeys, filterNulls); String leftRelAlias = implementor.getElasticsearchRelationAlias((ElasticsearchRelNode) getLeft()); String rightRelAlias = implementor.getElasticsearchRelationAlias((ElasticsearchRelNode) getRight()); String leftJoinFieldName = implementor.getFieldName((ElasticsearchRelNode) getLeft(), leftKeys.get(0)); String rightJoinFieldName = implementor.getFieldName((ElasticsearchRelNode) getRight(), rightKeys.get(0)); String result = implementor.getElasticsearchRelationAlias((ElasticsearchRelNode) getLeft()) + " = JOIN " + leftRelAlias + " BY "+ leftJoinFieldName + ' ' + getElasticsearchJoinType() + ", " + rightRelAlias + " BY "+ rightJoinFieldName + ';'; System.out.println("implementor = " + result); }
Example #9
Source File: JoinCommuteRule.java From Bats with Apache License 2.0 | 6 votes |
/** * Returns a relational expression with the inputs switched round. Does not * modify <code>join</code>. Returns null if the join cannot be swapped (for * example, because it is an outer join). * * @param join join to be swapped * @param swapOuterJoins whether outer joins should be swapped * @param relBuilder Builder for relational expressions * @return swapped join if swapping possible; else null */ public static RelNode swap(Join join, boolean swapOuterJoins, RelBuilder relBuilder) { final JoinRelType joinType = join.getJoinType(); if (!swapOuterJoins && joinType != JoinRelType.INNER) { return null; } final RexBuilder rexBuilder = join.getCluster().getRexBuilder(); final RelDataType leftRowType = join.getLeft().getRowType(); final RelDataType rightRowType = join.getRight().getRowType(); final VariableReplacer variableReplacer = new VariableReplacer(rexBuilder, leftRowType, rightRowType); final RexNode oldCondition = join.getCondition(); RexNode condition = variableReplacer.go(oldCondition); // NOTE jvs 14-Mar-2006: We preserve attribute semiJoinDone after the // swap. This way, we will generate one semijoin for the original // join, and one for the swapped join, and no more. This // doesn't prevent us from seeing any new combinations assuming // that the planner tries the desired order (semijoins after swaps). Join newJoin = join.copy(join.getTraitSet(), condition, join.getRight(), join.getLeft(), joinType.swap(), join.isSemiJoinDone()); final List<RexNode> exps = RelOptUtil.createSwappedJoinExprs(newJoin, join, true); return relBuilder.push(newJoin).project(exps, join.getRowType().getFieldNames()).build(); }
Example #10
Source File: JoinPrel.java From Bats with Apache License 2.0 | 6 votes |
/** * Build the list of join conditions for this join. * A join condition is built only for equality and IS NOT DISTINCT FROM comparisons. The difference is: * null == null is FALSE whereas null IS NOT DISTINCT FROM null is TRUE * For a use case of the IS NOT DISTINCT FROM comparison, see * {@link org.apache.calcite.rel.rules.AggregateRemoveRule} * @param conditions populated list of join conditions * @param leftFields join fields from the left input * @param rightFields join fields from the right input */ protected void buildJoinConditions(List<JoinCondition> conditions, List<String> leftFields, List<String> rightFields, List<Integer> leftKeys, List<Integer> rightKeys) { List<RexNode> conjuncts = RelOptUtil.conjunctions(this.getCondition()); short i=0; for (Pair<Integer, Integer> pair : Pair.zip(leftKeys, rightKeys)) { final RexNode conditionExpr = conjuncts.get(i++); final SqlKind kind = conditionExpr.getKind(); if (kind != SqlKind.EQUALS && kind != SqlKind.IS_NOT_DISTINCT_FROM) { throw UserException.unsupportedError() .message("Unsupported comparator in join condition %s", conditionExpr) .build(logger); } conditions.add(new JoinCondition(kind.toString(), FieldReference.getWithQuotedRef(leftFields.get(pair.left)), FieldReference.getWithQuotedRef(rightFields.get(pair.right)))); } }
Example #11
Source File: RelMdPredicates.java From Bats with Apache License 2.0 | 6 votes |
private void infer(RexNode predicates, Set<RexNode> allExprs, List<RexNode> inferredPredicates, boolean includeEqualityInference, ImmutableBitSet inferringFields) { for (RexNode r : RelOptUtil.conjunctions(predicates)) { if (!includeEqualityInference && equalityPredicates.contains(r)) { continue; } for (Mapping m : mappings(r)) { RexNode tr = r.accept( new RexPermuteInputsShuttle(m, joinRel.getInput(0), joinRel.getInput(1))); // Filter predicates can be already simplified, so we should work with // simplified RexNode versions as well. It also allows prevent of having // some duplicates in in result pulledUpPredicates RexNode simplifiedTarget = simplify.simplifyFilterPredicates(RelOptUtil.conjunctions(tr)); if (checkTarget(inferringFields, allExprs, tr) && checkTarget(inferringFields, allExprs, simplifiedTarget)) { inferredPredicates.add(simplifiedTarget); allExprs.add(simplifiedTarget); } } } }
Example #12
Source File: RelFieldTrimmer.java From calcite with Apache License 2.0 | 6 votes |
/** Creates a project with a dummy column, to protect the parts of the system * that cannot handle a relational expression with no columns. * * @param fieldCount Number of fields in the original relational expression * @param input Trimmed input * @param originalRelNode Source RelNode for hint propagation (or null if no propagation needed) * @return Dummy project */ protected TrimResult dummyProject(int fieldCount, RelNode input, RelNode originalRelNode) { final RelOptCluster cluster = input.getCluster(); final Mapping mapping = Mappings.create(MappingType.INVERSE_SURJECTION, fieldCount, 1); if (input.getRowType().getFieldCount() == 1) { // Input already has one field (and may in fact be a dummy project we // created for the child). We can't do better. return result(input, mapping); } final RexLiteral expr = cluster.getRexBuilder().makeExactLiteral(BigDecimal.ZERO); relBuilder.push(input); relBuilder.project(ImmutableList.of(expr), ImmutableList.of("DUMMY")); RelNode newProject = relBuilder.build(); if (originalRelNode != null) { newProject = RelOptUtil.propagateRelHints(originalRelNode, newProject); } return result(newProject, mapping); }
Example #13
Source File: RexProgramTest.java From calcite with Apache License 2.0 | 6 votes |
@Test void testIsDeterministic() { SqlOperator ndc = new SqlSpecialOperator( "NDC", SqlKind.OTHER_FUNCTION, 0, false, ReturnTypes.BOOLEAN, null, null) { @Override public boolean isDeterministic() { return false; } }; RexNode n = rexBuilder.makeCall(ndc); assertFalse(RexUtil.isDeterministic(n)); assertEquals(0, RexUtil.retainDeterministic(RelOptUtil.conjunctions(n)).size()); }
Example #14
Source File: DruidRules.java From calcite with Apache License 2.0 | 6 votes |
private static Pair<List<RexNode>, List<RexNode>> splitProjects( final RexBuilder rexBuilder, final RelNode input, List<RexNode> nodes) { final RelOptUtil.InputReferencedVisitor visitor = new RelOptUtil.InputReferencedVisitor(); visitor.visitEach(nodes); if (visitor.inputPosReferenced.size() == input.getRowType().getFieldCount()) { // All inputs are referenced return null; } final List<RexNode> belowNodes = new ArrayList<>(); final List<RelDataType> belowTypes = new ArrayList<>(); final List<Integer> positions = Lists.newArrayList(visitor.inputPosReferenced); for (int i : positions) { final RexNode node = rexBuilder.makeInputRef(input, i); belowNodes.add(node); belowTypes.add(node.getType()); } final List<RexNode> aboveNodes = new RexShuttle() { @Override public RexNode visitInputRef(RexInputRef ref) { final int index = positions.indexOf(ref.getIndex()); return rexBuilder.makeInputRef(belowTypes.get(index), index); } }.visitList(nodes); return Pair.of(aboveNodes, belowNodes); }
Example #15
Source File: BatsOptimizerTest.java From Bats with Apache License 2.0 | 6 votes |
static void testVolcanoPlanner() throws Exception { VolcanoPlanner volcanoPlanner = createVolcanoPlanner(); volcanoPlanner.addRelTraitDef(ConventionTraitDef.INSTANCE); // volcanoPlanner.addRelTraitDef(RelCollationTraitDef.INSTANCE); // addRules(volcanoPlanner); volcanoPlanner.addRule(ReduceExpressionsRule.PROJECT_INSTANCE); // volcanoPlanner.addRule(EnumerableRules.ENUMERABLE_PROJECT_RULE); RelNode relNode = testSqlToRelConverter(volcanoPlanner); volcanoPlanner.setRoot(relNode); relNode = volcanoPlanner.findBestExp(); // 在这一步出错 String plan = RelOptUtil.toString(relNode); System.out.println("Volcano Plan:"); System.out.println("------------------------------------------------------------------"); System.out.println(plan); }
Example #16
Source File: SqlToRelConverterTest.java From calcite with Apache License 2.0 | 5 votes |
@Test void testLarge() { // Size factor used to be 400, but lambdas use a lot of stack final int x = 300; SqlValidatorTest.checkLarge(x, input -> { final RelRoot root = tester.convertSqlToRel(input); final String s = RelOptUtil.toString(root.project()); assertThat(s, notNullValue()); }); }
Example #17
Source File: IndexConditionInfo.java From Bats with Apache License 2.0 | 5 votes |
/** * Given a list of Index Expressions(usually indexed fields/functions from one or a set of indexes), * separate a filter condition into * 1), relevant subset of conditions (by relevant, it means at least one given index Expression was found) and, * 2), the rest in remainderCondition * @param relevantPaths * @param condition * @return */ public IndexConditionInfo indexConditionRelatedToFields(List<LogicalExpression> relevantPaths, RexNode condition) { // Use the same filter analyzer that is used for partitioning columns RewriteCombineBinaryOperators reverseVisitor = new RewriteCombineBinaryOperators(true, builder); condition = condition.accept(reverseVisitor); RexSeparator separator = new RexSeparator(relevantPaths, scan, builder); RexNode indexCondition = separator.getSeparatedCondition(condition); if (indexCondition == null) { return new IndexConditionInfo(null, null, false); } List<RexNode> conjuncts = RelOptUtil.conjunctions(condition); List<RexNode> indexConjuncts = RelOptUtil.conjunctions(indexCondition); for (RexNode indexConjunction: indexConjuncts) { RexUtil.removeAll(conjuncts, indexConjunction); } RexNode remainderCondition = RexUtil.composeConjunction(builder, conjuncts, false); indexCondition = indexCondition.accept(reverseVisitor); return new IndexConditionInfo(indexCondition, remainderCondition, true); }
Example #18
Source File: JoinUtils.java From dremio-oss with Apache License 2.0 | 5 votes |
/** * Check if the given RelNode contains any Cartesian join. * Return true if find one. Otherwise, return false. * * @param relNode the RelNode to be inspected. * @param leftKeys a list used for the left input into the join which has * equi-join keys. It can be empty or not (but not null), * this method will clear this list before using it. * @param rightKeys a list used for the right input into the join which has * equi-join keys. It can be empty or not (but not null), * this method will clear this list before using it. * @param filterNulls The join key positions for which null values will not * match. null values only match for the "is not distinct * from" condition. * @return Return true if the given relNode contains Cartesian join. * Otherwise, return false */ public static boolean checkCartesianJoin(RelNode relNode, List<Integer> leftKeys, List<Integer> rightKeys, List<Boolean> filterNulls) { if (relNode instanceof Join) { leftKeys.clear(); rightKeys.clear(); Join joinRel = (Join) relNode; RelNode left = joinRel.getLeft(); RelNode right = joinRel.getRight(); RexNode remaining = RelOptUtil.splitJoinCondition(left, right, joinRel.getCondition(), leftKeys, rightKeys, filterNulls); if(joinRel.getJoinType() == JoinRelType.INNER) { if(leftKeys.isEmpty() || rightKeys.isEmpty()) { return true; } } else { if(!remaining.isAlwaysTrue() || leftKeys.isEmpty() || rightKeys.isEmpty()) { return true; } } } for (RelNode child : relNode.getInputs()) { if(checkCartesianJoin(child, leftKeys, rightKeys, filterNulls)) { return true; } } return false; }
Example #19
Source File: SqlValidatorImpl.java From flink with Apache License 2.0 | 5 votes |
/** * Validates updates against the constraint of a modifiable view. * * @param validatorTable A {@link SqlValidatorTable} that may wrap a * ModifiableViewTable * @param update The UPDATE parse tree node * @param targetRowType The target type */ private void checkConstraint( SqlValidatorTable validatorTable, SqlUpdate update, RelDataType targetRowType) { final ModifiableViewTable modifiableViewTable = validatorTable.unwrap(ModifiableViewTable.class); if (modifiableViewTable != null) { final Table table = modifiableViewTable.unwrap(Table.class); final RelDataType tableRowType = table.getRowType(typeFactory); final Map<Integer, RexNode> projectMap = RelOptUtil.getColumnConstraints(modifiableViewTable, targetRowType, typeFactory); final Map<String, Integer> nameToIndex = SqlValidatorUtil.mapNameToIndex(tableRowType.getFieldList()); // Validate update values against the view constraint. final List<SqlNode> targets = update.getTargetColumnList().getList(); final List<SqlNode> sources = update.getSourceExpressionList().getList(); for (final Pair<SqlNode, SqlNode> column : Pair.zip(targets, sources)) { final String columnName = ((SqlIdentifier) column.left).getSimple(); final Integer columnIndex = nameToIndex.get(columnName); if (projectMap.containsKey(columnIndex)) { final RexNode columnConstraint = projectMap.get(columnIndex); final ValidationError validationError = new ValidationError(column.right, RESOURCE.viewConstraintNotSatisfied(columnName, Util.last(validatorTable.getQualifiedName()))); RelOptUtil.validateValueAgainstConstraint(column.right, columnConstraint, validationError); } } } }
Example #20
Source File: RexSubQuery.java From calcite with Apache License 2.0 | 5 votes |
@Override protected @Nonnull String computeDigest(boolean withType) { final StringBuilder sb = new StringBuilder(op.getName()); sb.append("("); for (RexNode operand : operands) { sb.append(operand); sb.append(", "); } sb.append("{\n"); sb.append(RelOptUtil.toString(rel)); sb.append("})"); return sb.toString(); }
Example #21
Source File: ProjectMultiJoinMergeRule.java From calcite with Apache License 2.0 | 5 votes |
public void onMatch(RelOptRuleCall call) { Project project = call.rel(0); MultiJoin multiJoin = call.rel(1); // if all inputs have their projFields set, then projection information // has already been pushed into each input boolean allSet = true; for (int i = 0; i < multiJoin.getInputs().size(); i++) { if (multiJoin.getProjFields().get(i) == null) { allSet = false; break; } } if (allSet) { return; } // create a new MultiJoin that reflects the columns in the projection // above the MultiJoin final RelBuilder relBuilder = call.builder(); MultiJoin newMultiJoin = RelOptUtil.projectMultiJoin(multiJoin, project); relBuilder.push(newMultiJoin) .project(project.getProjects(), project.getRowType().getFieldNames()); call.transformTo(relBuilder.build()); }
Example #22
Source File: JoinCommuteRule.java From calcite with Apache License 2.0 | 5 votes |
public void onMatch(final RelOptRuleCall call) { Join join = call.rel(0); final RelNode swapped = swap(join, this.swapOuter, call.builder()); if (swapped == null) { return; } // The result is either a Project or, if the project is trivial, a // raw Join. final Join newJoin = swapped instanceof Join ? (Join) swapped : (Join) swapped.getInput(0); call.transformTo(swapped); // We have converted join='a join b' into swapped='select // a0,a1,a2,b0,b1 from b join a'. Now register that project='select // b0,b1,a0,a1,a2 from (select a0,a1,a2,b0,b1 from b join a)' is the // same as 'b join a'. If we didn't do this, the swap join rule // would fire on the new join, ad infinitum. final RelBuilder relBuilder = call.builder(); final List<RexNode> exps = RelOptUtil.createSwappedJoinExprs(newJoin, join, false); relBuilder.push(swapped) .project(exps, newJoin.getRowType().getFieldNames()); call.getPlanner().ensureRegistered(relBuilder.build(), newJoin); }
Example #23
Source File: JoinCommuteRule.java From calcite with Apache License 2.0 | 5 votes |
/** * Returns a relational expression with the inputs switched round. Does not * modify <code>join</code>. Returns null if the join cannot be swapped (for * example, because it is an outer join). * * @param join join to be swapped * @param swapOuterJoins whether outer joins should be swapped * @param relBuilder Builder for relational expressions * @return swapped join if swapping possible; else null */ public static RelNode swap(Join join, boolean swapOuterJoins, RelBuilder relBuilder) { final JoinRelType joinType = join.getJoinType(); if (!swapOuterJoins && joinType != JoinRelType.INNER) { return null; } final RexBuilder rexBuilder = join.getCluster().getRexBuilder(); final RelDataType leftRowType = join.getLeft().getRowType(); final RelDataType rightRowType = join.getRight().getRowType(); final VariableReplacer variableReplacer = new VariableReplacer(rexBuilder, leftRowType, rightRowType); final RexNode oldCondition = join.getCondition(); RexNode condition = variableReplacer.apply(oldCondition); // NOTE jvs 14-Mar-2006: We preserve attribute semiJoinDone after the // swap. This way, we will generate one semijoin for the original // join, and one for the swapped join, and no more. This // doesn't prevent us from seeing any new combinations assuming // that the planner tries the desired order (semijoins after swaps). Join newJoin = join.copy(join.getTraitSet(), condition, join.getRight(), join.getLeft(), joinType.swap(), join.isSemiJoinDone()); final List<RexNode> exps = RelOptUtil.createSwappedJoinExprs(newJoin, join, true); return relBuilder.push(newJoin) .project(exps, join.getRowType().getFieldNames()) .build(); }
Example #24
Source File: LoptOptimizeJoinRule.java From calcite with Apache License 2.0 | 5 votes |
/** * Adjusts a filter to reflect swapping of join inputs * * @param rexBuilder rexBuilder * @param multiJoin join factors being optimized * @param origLeft original LHS of the join tree (before swap) * @param origRight original RHS of the join tree (before swap) * @param condition original join condition * * @return join condition reflect swap of join inputs */ private RexNode swapFilter( RexBuilder rexBuilder, LoptMultiJoin multiJoin, LoptJoinTree origLeft, LoptJoinTree origRight, RexNode condition) { int nFieldsOnLeft = origLeft.getJoinTree().getRowType().getFieldCount(); int nFieldsOnRight = origRight.getJoinTree().getRowType().getFieldCount(); int [] adjustments = new int[nFieldsOnLeft + nFieldsOnRight]; for (int i = 0; i < nFieldsOnLeft; i++) { adjustments[i] = nFieldsOnRight; } for (int i = nFieldsOnLeft; i < (nFieldsOnLeft + nFieldsOnRight); i++) { adjustments[i] = -nFieldsOnLeft; } condition = condition.accept( new RelOptUtil.RexInputConverter( rexBuilder, multiJoin.getJoinFields(origLeft, origRight), multiJoin.getJoinFields(origRight, origLeft), adjustments)); return condition; }
Example #25
Source File: TpchTest.java From calcite with Apache License 2.0 | 5 votes |
@Disabled("Infinite planning") @Test void testQuery02Conversion() { query(2) .convertMatches(relNode -> { String s = RelOptUtil.toString(relNode); assertThat(s, not(containsString("Correlator"))); return null; }); }
Example #26
Source File: QuarkTileTable.java From quark with Apache License 2.0 | 5 votes |
public RelNode toRel( RelOptTable.ToRelContext context, RelOptTable relOptTable) { // Request all fields. RelNode rel = new QuarkTileScan(context.getCluster(), this.relOptTable, this.quarkTile, this.backingTable); //Create a filter RexBuilder rexBuilder = rel.getCluster().getRexBuilder(); List<RexNode> filterArgs = Lists.newArrayList(); filterArgs.add(rexBuilder.makeInputRef(rel, this.quarkTile.groupingColumn)); filterArgs.add(rexBuilder.makeLiteral(bitSetToString(this.quarkTile.groupingValue))); rel = LogicalFilter.create(rel, rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, filterArgs)); //Create a project list List<Integer> posList = Lists.newArrayList(); for (QuarkTile.Column quarkColumn : this.quarkTile.cubeColumns) { posList.add(quarkColumn.cubeOrdinal); } for (Lattice.Measure measure : this.quarkTile.measures) { posList.add(((QuarkTile.Measure) measure).ordinal); } return RelOptUtil.createProject(rel, posList); }
Example #27
Source File: FilterRemoveIsNotDistinctFromRule.java From calcite with Apache License 2.0 | 5 votes |
public RexNode visitCall(RexCall call) { RexNode newCall = super.visitCall(call); if (call.getOperator() == SqlStdOperatorTable.IS_NOT_DISTINCT_FROM) { RexCall tmpCall = (RexCall) newCall; newCall = RelOptUtil.isDistinctFrom( rexBuilder, tmpCall.operands.get(0), tmpCall.operands.get(1), true); } return newCall; }
Example #28
Source File: LogicalProjectDigestTest.java From calcite with Apache License 2.0 | 5 votes |
@Test void testProjectDigestWithOneTrivialField() { final FrameworkConfig config = RelBuilderTest.config().build(); final RelBuilder builder = RelBuilder.create(config); final RelNode rel = builder .scan("EMP") .project(builder.field("EMPNO")) .build(); String digest = RelOptUtil.toString(rel, SqlExplainLevel.DIGEST_ATTRIBUTES); final String expected = "" + "LogicalProject(inputs=[0])\n" + " LogicalTableScan(table=[[scott, EMP]])\n"; assertThat(digest, isLinux(expected)); }
Example #29
Source File: Aggregate.java From Bats with Apache License 2.0 | 5 votes |
/** * Returns whether the inferred type of an {@link AggregateCall} matches the * type it was given when it was created. * * @param aggCall Aggregate call * @param litmus What to do if an error is detected (types do not match) * @return Whether the inferred and declared types match */ private boolean typeMatchesInferred( final AggregateCall aggCall, final Litmus litmus) { SqlAggFunction aggFunction = aggCall.getAggregation(); AggCallBinding callBinding = aggCall.createBinding(this); RelDataType type = aggFunction.inferReturnType(callBinding); RelDataType expectedType = aggCall.type; return RelOptUtil.eq("aggCall type", expectedType, "inferred type", type, litmus); }
Example #30
Source File: Programs.java From calcite with Apache License 2.0 | 5 votes |
/** Creates a program that invokes heuristic join-order optimization * (via {@link org.apache.calcite.rel.rules.JoinToMultiJoinRule}, * {@link org.apache.calcite.rel.rules.MultiJoin} and * {@link org.apache.calcite.rel.rules.LoptOptimizeJoinRule}) * if there are 6 or more joins (7 or more relations). */ public static Program heuristicJoinOrder( final Iterable<? extends RelOptRule> rules, final boolean bushy, final int minJoinCount) { return (planner, rel, requiredOutputTraits, materializations, lattices) -> { final int joinCount = RelOptUtil.countJoins(rel); final Program program; if (joinCount < minJoinCount) { program = ofRules(rules); } else { // Create a program that gathers together joins as a MultiJoin. final HepProgram hep = new HepProgramBuilder() .addRuleInstance(FilterJoinRule.FILTER_ON_JOIN) .addMatchOrder(HepMatchOrder.BOTTOM_UP) .addRuleInstance(JoinToMultiJoinRule.INSTANCE) .build(); final Program program1 = of(hep, false, DefaultRelMetadataProvider.INSTANCE); // Create a program that contains a rule to expand a MultiJoin // into heuristically ordered joins. // We use the rule set passed in, but remove JoinCommuteRule and // JoinPushThroughJoinRule, because they cause exhaustive search. final List<RelOptRule> list = Lists.newArrayList(rules); list.removeAll( ImmutableList.of(JoinCommuteRule.INSTANCE, JoinAssociateRule.INSTANCE, JoinPushThroughJoinRule.LEFT, JoinPushThroughJoinRule.RIGHT)); list.add(bushy ? MultiJoinOptimizeBushyRule.INSTANCE : LoptOptimizeJoinRule.INSTANCE); final Program program2 = ofRules(list); program = sequence(program1, program2); } return program.run( planner, rel, requiredOutputTraits, materializations, lattices); }; }