org.apache.calcite.rel.logical.LogicalProject Java Examples

The following examples show how to use org.apache.calcite.rel.logical.LogicalProject. 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: OLAPProjectRule.java    From kylin-on-parquet-v2 with Apache License 2.0 6 votes vote down vote up
@Override
public RelNode convert(final RelNode rel) {

    //  KYLIN-3281
    //  OLAPProjectRule can't normal working with projectRel[input=sortRel]
    final LogicalProject project = (LogicalProject) rel;
    final RelNode convertChild = convert(project.getInput(),
            project.getInput().getTraitSet().replace(OLAPRel.CONVENTION));
    final RelOptCluster cluster = convertChild.getCluster();
    final RelTraitSet traitSet = cluster.traitSet().replace(OLAPRel.CONVENTION)
            .replaceIfs(RelCollationTraitDef.INSTANCE, new Supplier<List<RelCollation>>() {
                public List<RelCollation> get() {
                    //  CALCITE-88
                    return RelMdCollation.project(cluster.getMetadataQuery(), convertChild, project.getProjects());
                }
            });
    return new OLAPProjectRel(convertChild.getCluster(), traitSet, convertChild, project.getProjects(),
            project.getRowType());
}
 
Example #2
Source File: FlinkSemiAntiJoinProjectTransposeRule.java    From flink with Apache License 2.0 6 votes vote down vote up
@Override
public boolean matches(RelOptRuleCall call) {
	LogicalJoin join = call.rel(0);
	LogicalProject project = call.rel(1);

	// only accept SEMI/ANTI join
	JoinRelType joinType = join.getJoinType();
	if (joinType != JoinRelType.SEMI && joinType != JoinRelType.ANTI) {
		return false;
	}
	// all expressions in Project should be RexInputRef
	for (RexNode p : project.getProjects()) {
		if (!(p instanceof RexInputRef)) {
			return false;
		}
	}
	return true;
}
 
Example #3
Source File: MockCatalogReader.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Override public RelNode toRel(ToRelContext context) {
  RelNode rel = LogicalTableScan.create(context.getCluster(), fromTable,
      context.getTableHints());
  final RexBuilder rexBuilder = context.getCluster().getRexBuilder();
  rel = LogicalFilter.create(
      rel, getConstraint(rexBuilder, rel.getRowType()));
  final List<RelDataTypeField> fieldList =
      rel.getRowType().getFieldList();
  final List<Pair<RexNode, String>> projects =
      new AbstractList<Pair<RexNode, String>>() {
        @Override public Pair<RexNode, String> get(int index) {
          return RexInputRef.of2(mapping.get(index), fieldList);
        }

        @Override public int size() {
          return mapping.size();
        }
      };
  return LogicalProject.create(rel,
      ImmutableList.of(),
      Pair.left(projects),
      Pair.right(projects));
}
 
Example #4
Source File: FlinkSemiAntiJoinProjectTransposeRule.java    From flink with Apache License 2.0 6 votes vote down vote up
@Override
public boolean matches(RelOptRuleCall call) {
	LogicalJoin join = call.rel(0);
	LogicalProject project = call.rel(1);

	// only accept SEMI/ANTI join
	JoinRelType joinType = join.getJoinType();
	if (joinType != JoinRelType.SEMI && joinType != JoinRelType.ANTI) {
		return false;
	}
	// all expressions in Project should be RexInputRef
	for (RexNode p : project.getProjects()) {
		if (!(p instanceof RexInputRef)) {
			return false;
		}
	}
	return true;
}
 
Example #5
Source File: SqlExprToRexConverterImpl.java    From flink with Apache License 2.0 6 votes vote down vote up
@Override
public RexNode[] convertToRexNodes(String[] exprs) {
	String query = String.format(QUERY_FORMAT, String.join(",", exprs));
	SqlNode parsed = planner.parser().parse(query);
	SqlNode validated = planner.validate(parsed);
	RelNode rel = planner.rel(validated).rel;
	// The plan should in the following tree
	// LogicalProject
	// +- TableScan
	if (rel instanceof LogicalProject
		&& rel.getInput(0) != null
		&& rel.getInput(0) instanceof TableScan) {
		return ((LogicalProject) rel).getProjects().toArray(new RexNode[0]);
	} else {
		throw new IllegalStateException("The root RelNode should be LogicalProject, but is " + rel.toString());
	}
}
 
Example #6
Source File: JoinTranslator.java    From samza with Apache License 2.0 6 votes vote down vote up
private JoinInputNode.InputType getInputType(RelNode relNode, TranslatorContext context) {

    // NOTE: Any intermediate form of a join is always a stream. Eg: For the second level join of
    // stream-table-table join, the left side of the join is join output, which we always
    // assume to be a stream. The intermediate stream won't be an instance of TableScan.
    // The join key(s) for the table could be an udf in which case the relNode would be LogicalProject.

    if (relNode instanceof TableScan || relNode instanceof LogicalProject) {
      SqlIOConfig sourceTableConfig = resolveSQlIOForTable(relNode, context);
      if (sourceTableConfig == null || !sourceTableConfig.getTableDescriptor().isPresent()) {
        return JoinInputNode.InputType.STREAM;
      } else if (sourceTableConfig.getTableDescriptor().get() instanceof RemoteTableDescriptor ||
          sourceTableConfig.getTableDescriptor().get() instanceof CachingTableDescriptor) {
        return JoinInputNode.InputType.REMOTE_TABLE;
      } else {
        return JoinInputNode.InputType.LOCAL_TABLE;
      }
    } else {
      return JoinInputNode.InputType.STREAM;
    }
  }
 
Example #7
Source File: ProcessorStatusProjectTableScanRule.java    From nifi with Apache License 2.0 6 votes vote down vote up
@Override
public void onMatch(RelOptRuleCall call) {
    final LogicalProject project = call.rel(0);
    final ProcessorStatusTableScan scan = call.rel(1);
    final int[] fields = getProjectFields(project.getProjects());

    if (fields == null) {
        // Project contains expressions more complex than just field references.
        return;
    }

    call.transformTo(
        new ProcessorStatusTableScan(
            scan.getCluster(),
            scan.getTable(),
            scan.processorStatusTable,
            fields));
}
 
Example #8
Source File: MultiJoinProjectTransposeRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
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 #9
Source File: ReflectionUtils.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
public static RelNode removeColumns(RelNode node, Predicate<RelDataTypeField> predicate) {
  if (node.getTraitSet() == null) {
    // for test purposes.
    return node;
  }

  // identify all fields that match passed predicate
  Set<RelDataTypeField> toRemove = FluentIterable.from(node.getRowType().getFieldList()).filter(predicate).toSet();

  if (toRemove.isEmpty()) {
    return node;
  }

  final RexBuilder rexBuilder = node.getCluster().getRexBuilder();
  final RelDataTypeFactory.FieldInfoBuilder rowTypeBuilder = new RelDataTypeFactory.FieldInfoBuilder(node.getCluster().getTypeFactory());
  final List<RexNode> projects = FluentIterable.from(node.getRowType().getFieldList())
    .filter(Predicates.not(toRemove::contains))
    .transform((RelDataTypeField field) -> {
      rowTypeBuilder.add(field);
      return (RexNode) rexBuilder.makeInputRef(field.getType(), field.getIndex());
    }).toList();

  return new LogicalProject(node.getCluster(), node.getTraitSet(), node, projects, rowTypeBuilder.build());
}
 
Example #10
Source File: TraitPropagationTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  LogicalProject rel = call.rel(0);
  RelNode rawInput = call.rel(1);
  RelNode input = convert(rawInput, PHYSICAL);

  if (subsetHack && input instanceof RelSubset) {
    RelSubset subset = (RelSubset) input;
    for (RelNode child : subset.getRels()) {
      // skip logical nodes
      if (child.getTraitSet().getTrait(ConventionTraitDef.INSTANCE)
          == Convention.NONE) {
        continue;
      } else {
        RelTraitSet outcome = child.getTraitSet().replace(PHYSICAL);
        call.transformTo(
            new PhysProj(rel.getCluster(), outcome, convert(child, outcome),
                rel.getProjects(), rel.getRowType()));
      }
    }
  } else {
    call.transformTo(
        PhysProj.create(input, rel.getProjects(), rel.getRowType()));
  }

}
 
Example #11
Source File: IncrementalUpdateUtils.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override
public RelNode visit(LogicalProject project) {
  RelNode input = project.getInput().accept(this);
  RelDataType incomingRowType = input.getRowType();
  List<RexNode> newProjects;
  RelDataTypeField modField = incomingRowType.getField(UPDATE_COLUMN, false, false);
  if (modField == null) {
    return project;
  }
  newProjects = FluentIterable.from(project.getProjects())
    .append(new RexInputRef(modField.getIndex(), modField.getType()))
    .toList();
  FieldInfoBuilder fieldInfoBuilder = new FieldInfoBuilder(project.getCluster().getTypeFactory());
  for (RelDataTypeField field : project.getRowType().getFieldList()) {
    fieldInfoBuilder.add(field);
  }
  fieldInfoBuilder.add(UPDATE_COLUMN, modField.getType());
  return new LogicalProject(
    project.getCluster(),
    project.getTraitSet(),
    input,
    newProjects,
    fieldInfoBuilder.build()
  );
}
 
Example #12
Source File: SubQueryDecorrelator.java    From flink with Apache License 2.0 6 votes vote down vote up
/**
 * Adds Projection to adjust the field index for join condition.
 *
 * <p>e.g. SQL: SELECT * FROM l WHERE b IN (SELECT COUNT(*) FROM r WHERE l.c = r.f
 * the rel in SubQuery is `LogicalAggregate(group=[{}], EXPR$1=[COUNT()])`.
 * After decorrelated, it was changed to `LogicalAggregate(group=[{0}], EXPR$0=[COUNT()])`,
 * and the output index of `COUNT()` was changed from 0 to 1.
 * So, add a project (`LogicalProject(EXPR$0=[$1], f=[$0])`) to adjust output fields order.
 */
private RelNode addProjectionForIn(RelNode relNode) {
	if (relNode instanceof LogicalProject) {
		return relNode;
	}

	RelDataType rowType = relNode.getRowType();
	final List<RexNode> projects = new ArrayList<>();
	for (int i = 0; i < rowType.getFieldCount(); ++i) {
		projects.add(RexInputRef.of(i, rowType));
	}

	relBuilder.clear();
	relBuilder.push(relNode);
	relBuilder.project(projects, rowType.getFieldNames(), true);
	return relBuilder.build();
}
 
Example #13
Source File: SubQueryDecorrelator.java    From flink with Apache License 2.0 6 votes vote down vote up
@Override
public RelNode visit(LogicalProject project) {
	hasOverNode = RexOver.containsOver(project.getProjects(), null);
	final boolean hasSubQuery = RexUtil.SubQueryFinder.find(project.getProjects()) != null;
	try {
		if (!corNodeStack.isEmpty()) {
			mapSubQueryNodeToCorSet.put(project, corNodeStack.peek().getVariablesSet());
		}
		if (hasSubQuery) {
			corNodeStack.push(project);
		}
		checkCorCondition(project);
		for (RexNode node : project.getProjects()) {
			node.accept(rexVisitor(project));
		}
	} finally {
		if (hasSubQuery) {
			corNodeStack.pop();
		}
	}
	return super.visit(project);
}
 
Example #14
Source File: JoinTranslator.java    From samza with Apache License 2.0 6 votes vote down vote up
/**
 * Helper method to check if the join condition can be evaluated by the remote table.
 * It does follow single path  using the index ref path checking if it is a simple reference all the way to table scan.
 * In case any RexCall is encountered will stop an return null as a marker otherwise will return Column Name.
 *
 * @param inputRexIndex rex ref index
 * @param relNode current Rel Node
 * @return false if any Relational Expression is encountered on the path, true if is simple ref to __key__ column.
 */
private static boolean isValidRemoteJoinRef(int inputRexIndex, RelNode relNode) {
  if (relNode instanceof TableScan) {
    return relNode.getRowType().getFieldList().get(inputRexIndex).getName().equals(SamzaSqlRelMessage.KEY_NAME);
  }
  // has to be a single rel kind filter/project/table scan
  Preconditions.checkState(relNode.getInputs().size() == 1,
      "Has to be single input RelNode and got " + relNode.getDigest());
  if (relNode instanceof LogicalFilter) {
    return isValidRemoteJoinRef(inputRexIndex, relNode.getInput(0));
  }
  RexNode inputRef = ((LogicalProject) relNode).getProjects().get(inputRexIndex);
  if (inputRef instanceof RexCall) {
    return false; // we can not push any expression as of now stop and return null.
  }
  return isValidRemoteJoinRef(((RexInputRef) inputRef).getIndex(), relNode.getInput(0));
}
 
Example #15
Source File: SamzaSqlValidator.java    From samza with Apache License 2.0 6 votes vote down vote up
private void validateOutput(RelRoot relRoot, RelSchemaProvider outputRelSchemaProvider)
    throws SamzaSqlValidatorException {
  LogicalProject project = (LogicalProject) relRoot.rel;

  RelRecordType projectRecord = (RelRecordType) project.getRowType();
  RelRecordType outputRecord = (RelRecordType) QueryPlanner.getSourceRelSchema(outputRelSchemaProvider,
      new RelSchemaConverter());

  // Handle any DELETE ops.
  if (projectRecord.getFieldList().stream().anyMatch(f -> f.getName().equalsIgnoreCase(SamzaSqlRelMessage.OP_NAME))) {
    validateDeleteOp(relRoot);
    return;
  }

  // Get Samza Sql schema along with Calcite schema. The reason is that the Calcite schema does not have a way
  // to represent optional fields while Samza Sql schema can represent optional fields. This is the reason that
  // we use SqlSchema in validating output.
  SqlSchema outputSqlSchema = QueryPlanner.getSourceSqlSchema(outputRelSchemaProvider);

  validateOutputRecords(outputSqlSchema, outputRecord, projectRecord, outputRelSchemaProvider);
  LOG.info("Samza Sql Validation finished successfully.");
}
 
Example #16
Source File: RelDecorrelator.java    From Bats with Apache License 2.0 5 votes vote down vote up
AdjustProjectForCountAggregateRule(boolean flavor, RelBuilderFactory relBuilderFactory) {
    super(flavor
            ? operand(LogicalCorrelate.class, operand(RelNode.class, any()),
                    operand(LogicalProject.class, operand(LogicalAggregate.class, any())))
            : operand(LogicalCorrelate.class, operand(RelNode.class, any()),
                    operand(LogicalAggregate.class, any())),
            relBuilderFactory, null);
    this.flavor = flavor;
}
 
Example #17
Source File: PreProcessRel.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public RelNode visit(LogicalProject project) {
  final RenameConvertToConvertFromVisitor renameVisitor = new RenameConvertToConvertFromVisitor(project.getCluster().getRexBuilder(), table);
  final List<RexNode> projExpr = Lists.newArrayList();
  for(RexNode rexNode : project.getChildExps()) {
    projExpr.add(rexNode.accept(unwrappingExpressionVisitor));
  }

  project =  project.copy(project.getTraitSet(),
      project.getInput(),
      projExpr,
      project.getRowType());

  List<RexNode> exprList = new ArrayList<>();
  boolean rewrite = false;

  for (RexNode rex : project.getChildExps()) {
    RexNode newExpr = rex.accept(renameVisitor);
    if (newExpr != rex) {
      rewrite = true;
    }
    exprList.add(newExpr);
  }

  if (rewrite == true) {
    LogicalProject newProject = project.copy(project.getTraitSet(), project.getInput(0), exprList, project.getRowType());
    return visitChild(newProject, 0, project.getInput());
  }

  return visitChild(project, 0, project.getInput());
}
 
Example #18
Source File: ProjectCalcMergeRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a ProjectCalcMergeRule.
 *
 * @param relBuilderFactory Builder for relational expressions
 */
public ProjectCalcMergeRule(RelBuilderFactory relBuilderFactory) {
  super(
      operand(
          LogicalProject.class,
          operand(LogicalCalc.class, any())),
      relBuilderFactory, null);
}
 
Example #19
Source File: RelDecorrelator.java    From Bats with Apache License 2.0 5 votes vote down vote up
RemoveCorrelationForScalarAggregateRule(RelBuilderFactory relBuilderFactory) {
    super(operand(LogicalCorrelate.class, operand(RelNode.class, any()),
            operand(LogicalProject.class,
                    operandJ(LogicalAggregate.class, null, Aggregate::isSimple,
                            operand(LogicalProject.class, operand(RelNode.class, any()))))),
            relBuilderFactory, null);
}
 
Example #20
Source File: RelStructuredTypeFlattener.java    From Bats with Apache License 2.0 5 votes vote down vote up
public void rewriteRel(LogicalProject rel) {
    final List<Pair<RexNode, String>> flattenedExpList = new ArrayList<>();
    flattenProjections(new RewriteRexShuttle(), rel.getProjects(), rel.getRowType().getFieldNames(), "",
            flattenedExpList);
    relBuilder.push(getNewForOldRel(rel.getInput())).projectNamed(Pair.left(flattenedExpList),
            Pair.right(flattenedExpList), true);
    setNewForOldRel(rel, relBuilder.build());
}
 
Example #21
Source File: CsvProjectTableScanRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public void onMatch(RelOptRuleCall call) {
  final LogicalProject project = call.rel(0);
  final CsvTableScan scan = call.rel(1);
  int[] fields = getProjectFields(project.getProjects());
  if (fields == null) {
    // Project contains expressions more complex than just field references.
    return;
  }
  call.transformTo(
      new CsvTableScan(
          scan.getCluster(),
          scan.getTable(),
          scan.csvTable,
          fields));
}
 
Example #22
Source File: RelDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
@Override public RelNode visit(LogicalProject project) {
  try {
    stack.push(project);
    for (RexNode node : project.getProjects()) {
      node.accept(rexVisitor(project));
    }
  } finally {
    stack.pop();
  }
  return super.visit(project);
}
 
Example #23
Source File: SamzaSqlValidator.java    From samza with Apache License 2.0 5 votes vote down vote up
private void validateDeleteOp(RelRoot relRoot) throws SamzaSqlValidatorException {
  LogicalProject project = (LogicalProject) relRoot.rel;
  RelRecordType projectRecord = (RelRecordType) project.getRowType();

  // In the case of DELETE op, only the key and DELETE op are required.

  if (projectRecord.getFieldCount() != 2) {
    throw new SamzaSqlValidatorException(String.format("Only two select query fields are expected for DELETE op."
        + " But there are %d fields given in the query.", projectRecord.getFieldCount()));
  }

  RelDataTypeField keyField = projectRecord.getField(SamzaSqlRelMessage.KEY_NAME, true, true);
  if (keyField == null) {
    throw new SamzaSqlValidatorException(String.format("Select query needs to specify '%s' field while using DELETE"
            + " op. Eg: 'SELECT myKey AS %s, '%s' AS %s FROM myTable'", SamzaSqlRelMessage.KEY_NAME,
        SamzaSqlRelMessage.KEY_NAME, SamzaSqlRelMessage.DELETE_OP, SamzaSqlRelMessage.OP_NAME));
  }
  int keyIdx = projectRecord.getFieldList().indexOf(keyField);
  // Get the node corresponding to the special op.
  RexNode node = project.getProjects().get(1 - keyIdx);
  if (!node.toString().equals(String.format("'%s'", SamzaSqlRelMessage.DELETE_OP))) {
    throw new SamzaSqlValidatorException(String.format("%s op is not supported. Please note that only '%s' op is"
            + " currently supported. Eg:'SELECT myKey AS %s, '%s' AS %s FROM myStream'", node.toString(),
        SamzaSqlRelMessage.DELETE_OP, SamzaSqlRelMessage.KEY_NAME, SamzaSqlRelMessage.DELETE_OP,
        SamzaSqlRelMessage.OP_NAME));
  }
}
 
Example #24
Source File: ProjectWindowTransposeRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Creates ProjectWindowTransposeRule.
 *
 * @param relBuilderFactory Builder for relational expressions
 */
public ProjectWindowTransposeRule(RelBuilderFactory relBuilderFactory) {
  super(
      operand(LogicalProject.class,
          operand(LogicalWindow.class, any())),
      relBuilderFactory, null);
}
 
Example #25
Source File: RelDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
AdjustProjectForCountAggregateRule(boolean flavor,
    RelBuilderFactory relBuilderFactory) {
  super(
      flavor
          ? operand(LogicalCorrelate.class,
              operand(RelNode.class, any()),
                  operand(LogicalProject.class,
                      operand(LogicalAggregate.class, any())))
          : operand(LogicalCorrelate.class,
              operand(RelNode.class, any()),
                  operand(LogicalAggregate.class, any())),
      relBuilderFactory, null);
  this.flavor = flavor;
}
 
Example #26
Source File: AggJoinFinder.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public RelNode visit(LogicalProject project) {
  if(state == State.AGG) {
    toState(project, State.AGG_PROJECT);
  } else if(state == State.AGG_PROJECT) {
    // treat one or many projects the same.
  } else {
    toState(project, State.OUT);
  }
  return visitChildren(project);
}
 
Example #27
Source File: ShortenJdbcColumnAliases.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
public RelNode visit(RelNode other) {
  if (other instanceof JdbcCrel) {
    final JdbcCrel logical = (JdbcCrel) other;

    // Eliminate subsets to enforce that all nodes in the Jdbc subtree are JdbcRelImpl nodes.
    final RelNode subsetRemoved = logical.getInput().accept(new MoreRelOptUtil.SubsetRemover());
    logical.replaceInput(0, subsetRemoved);

    if (logical.getPluginId() == null) {
      return logical;
    }

    final RelNode updatedJdbcRoot = super.visitChildren(logical);

    // Add a LogicalProject to map the original set of column aliases if necessary.
    if (logical.getRowType().equals(updatedJdbcRoot.getRowType())) {
      return updatedJdbcRoot;
    }

    final LogicalProject logicalProject = LogicalProject.create(updatedJdbcRoot,
      updatedJdbcRoot.getCluster().getRexBuilder().identityProjects(updatedJdbcRoot.getRowType()), other.getRowType());

    return logicalProject;

  } else if (other instanceof JdbcRelImpl) {
    final RelNode updatedNode = super.visitChildren(other);

    final JdbcRelImpl jdbcNode = (JdbcRelImpl) updatedNode;
    return jdbcNode.shortenAliases(SHORT_ALIAS_SUGGESTER, usedAliases);
  }
  return super.visit(other);
}
 
Example #28
Source File: RelDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * Pulls a {@link Project} above a {@link Correlate} from its RHS input.
 * Enforces nullability for join output.
 *
 * @param correlate  Correlate
 * @param project the original project as the RHS input of the join
 * @param isCount Positions which are calls to the <code>COUNT</code>
 *                aggregation function
 * @return the subtree with the new Project at the root
 */
private RelNode aggregateCorrelatorOutput(
    Correlate correlate,
    LogicalProject project,
    Set<Integer> isCount) {
  final RelNode left = correlate.getLeft();
  final JoinRelType joinType = correlate.getJoinType();

  // now create the new project
  final List<Pair<RexNode, String>> newProjects = new ArrayList<>();

  // Project everything from the LHS and then those from the original
  // project
  final List<RelDataTypeField> leftInputFields =
      left.getRowType().getFieldList();

  for (int i = 0; i < leftInputFields.size(); i++) {
    newProjects.add(RexInputRef.of2(i, leftInputFields));
  }

  // Marked where the projected expr is coming from so that the types will
  // become nullable for the original projections which are now coming out
  // of the nullable side of the OJ.
  boolean projectPulledAboveLeftCorrelator =
      joinType.generatesNullsOnRight();

  for (Pair<RexNode, String> pair : project.getNamedProjects()) {
    RexNode newProjExpr =
        removeCorrelationExpr(
            pair.left,
            projectPulledAboveLeftCorrelator,
            isCount);
    newProjects.add(Pair.of(newProjExpr, pair.right));
  }

  return relBuilder.push(correlate)
      .projectNamed(Pair.left(newProjects), Pair.right(newProjects), true)
      .build();
}
 
Example #29
Source File: RelDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  LogicalAggregate singleAggregate = call.rel(0);
  LogicalProject project = call.rel(1);
  LogicalAggregate aggregate = call.rel(2);

  // check singleAggRel is single_value agg
  if ((!singleAggregate.getGroupSet().isEmpty())
      || (singleAggregate.getAggCallList().size() != 1)
      || !(singleAggregate.getAggCallList().get(0).getAggregation()
      instanceof SqlSingleValueAggFunction)) {
    return;
  }

  // check projRel only projects one expression
  // check this project only projects one expression, i.e. scalar
  // sub-queries.
  List<RexNode> projExprs = project.getProjects();
  if (projExprs.size() != 1) {
    return;
  }

  // check the input to project is an aggregate on the entire input
  if (!aggregate.getGroupSet().isEmpty()) {
    return;
  }

  // singleAggRel produces a nullable type, so create the new
  // projection that casts proj expr to a nullable type.
  final RelBuilder relBuilder = call.builder();
  final RelDataType type =
      relBuilder.getTypeFactory()
          .createTypeWithNullability(projExprs.get(0).getType(), true);
  final RexNode cast =
      relBuilder.getRexBuilder().makeCast(type, projExprs.get(0));
  relBuilder.push(aggregate)
      .project(cast);
  call.transformTo(relBuilder.build());
}
 
Example #30
Source File: RelDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
RemoveCorrelationForScalarProjectRule(RelBuilderFactory relBuilderFactory) {
  super(
      operand(LogicalCorrelate.class,
          operand(RelNode.class, any()),
          operand(LogicalAggregate.class,
              operand(LogicalProject.class,
                  operand(RelNode.class, any())))),
      relBuilderFactory, null);
}