Java源码示例:org.apache.calcite.rel.core.Values

示例1
public List<Double> averageColumnSizes(Values rel, RelMetadataQuery mq) {
  final List<RelDataTypeField> fields = rel.getRowType().getFieldList();
  final ImmutableList.Builder<Double> list = ImmutableList.builder();
  for (int i = 0; i < fields.size(); i++) {
    RelDataTypeField field = fields.get(i);
    double d;
    if (rel.getTuples().isEmpty()) {
      d = averageTypeValueSize(field.getType());
    } else {
      d = 0;
      for (ImmutableList<RexLiteral> literals : rel.getTuples()) {
        d += typeValueSize(field.getType(),
            literals.get(i).getValueAs(Comparable.class));
      }
      d /= rel.getTuples().size();
    }
    list.add(d);
  }
  return list.build();
}
 
示例2
public Boolean areColumnsUnique(Values rel, RelMetadataQuery mq,
    ImmutableBitSet columns, boolean ignoreNulls) {
  if (rel.tuples.size() < 2) {
    return true;
  }
  final Set<List<Comparable>> set = new HashSet<>();
  final List<Comparable> values = new ArrayList<>();
  for (ImmutableList<RexLiteral> tuple : rel.tuples) {
    for (int column : columns) {
      final RexLiteral literal = tuple.get(column);
      values.add(literal.isNull()
          ? NullSentinel.INSTANCE
          : literal.getValueAs(Comparable.class));
    }
    if (!set.add(ImmutableList.copyOf(values))) {
      return false;
    }
    values.clear();
  }
  return true;
}
 
示例3
public Boolean areColumnsUnique(RelSubset rel, RelMetadataQuery mq,
    ImmutableBitSet columns, boolean ignoreNulls) {
  int nullCount = 0;
  for (RelNode rel2 : rel.getRels()) {
    if (rel2 instanceof Aggregate
        || rel2 instanceof Filter
        || rel2 instanceof Values
        || rel2 instanceof TableScan
        || simplyProjects(rel2, columns)) {
      try {
        final Boolean unique = mq.areColumnsUnique(rel2, columns, ignoreNulls);
        if (unique != null) {
          if (unique) {
            return true;
          }
        } else {
          ++nullCount;
        }
      } catch (CyclicMetadataException e) {
        // Ignore this relational expression; there will be non-cyclic ones
        // in this set.
      }
    }
  }
  return nullCount == 0 ? false : null;
}
 
示例4
/** Ensures that the field names match those given.
 *
 * <p>If all fields have the same name, adds nothing;
 * if any fields do not have the same name, adds a {@link Project}.
 *
 * <p>Note that the names can be short-lived. Other {@code RelBuilder}
 * operations make no guarantees about the field names of the rows they
 * produce.
 *
 * @param fieldNames List of desired field names; may contain null values or
 * have fewer fields than the current row type
 */
public RelBuilder rename(List<String> fieldNames) {
    final List<String> oldFieldNames = peek().getRowType().getFieldNames();
    Preconditions.checkArgument(fieldNames.size() <= oldFieldNames.size(), "More names than fields");
    final List<String> newFieldNames = new ArrayList<>(oldFieldNames);
    for (int i = 0; i < fieldNames.size(); i++) {
        final String s = fieldNames.get(i);
        if (s != null) {
            newFieldNames.set(i, s);
        }
    }
    if (oldFieldNames.equals(newFieldNames)) {
        return this;
    }
    if (peek() instanceof Values) {
        // Special treatment for VALUES. Re-build it rather than add a project.
        final Values v = (Values) build();
        final RelDataTypeFactory.Builder b = getTypeFactory().builder();
        for (Pair<String, RelDataTypeField> p : Pair.zip(newFieldNames, v.getRowType().getFieldList())) {
            b.add(p.left, p.right.getType());
        }
        return values(v.tuples, b.build());
    }

    return project(fields(), newFieldNames, true);
}
 
示例5
public List<Double> averageColumnSizes(Values rel, RelMetadataQuery mq) {
  final List<RelDataTypeField> fields = rel.getRowType().getFieldList();
  final ImmutableList.Builder<Double> list = ImmutableList.builder();
  for (int i = 0; i < fields.size(); i++) {
    RelDataTypeField field = fields.get(i);
    double d;
    if (rel.getTuples().isEmpty()) {
      d = averageTypeValueSize(field.getType());
    } else {
      d = 0;
      for (ImmutableList<RexLiteral> literals : rel.getTuples()) {
        d += typeValueSize(field.getType(),
            literals.get(i).getValueAs(Comparable.class));
      }
      d /= rel.getTuples().size();
    }
    list.add(d);
  }
  return list.build();
}
 
示例6
public Boolean areColumnsUnique(Values rel, RelMetadataQuery mq,
    ImmutableBitSet columns, boolean ignoreNulls) {
  columns = decorateWithConstantColumnsFromPredicates(columns, rel, mq);
  if (rel.tuples.size() < 2) {
    return true;
  }
  final Set<List<Comparable>> set = new HashSet<>();
  final List<Comparable> values = new ArrayList<>();
  for (ImmutableList<RexLiteral> tuple : rel.tuples) {
    for (int column : columns) {
      final RexLiteral literal = tuple.get(column);
      values.add(literal.isNull()
          ? NullSentinel.INSTANCE
          : literal.getValueAs(Comparable.class));
    }
    if (!set.add(ImmutableList.copyOf(values))) {
      return false;
    }
    values.clear();
  }
  return true;
}
 
示例7
private static boolean isEmpty(RelNode node) {
  if (node instanceof Values) {
    return ((Values) node).getTuples().isEmpty();
  }
  if (node instanceof HepRelVertex) {
    return isEmpty(((HepRelVertex) node).getCurrentRel());
  }
  // Note: relation input might be a RelSubset, so we just iterate over the relations
  // in order to check if the subset is equivalent to an empty relation.
  if (!(node instanceof RelSubset)) {
    return false;
  }
  RelSubset subset = (RelSubset) node;
  for (RelNode rel : subset.getRels()) {
    if (isEmpty(rel)) {
      return true;
    }
  }
  return false;
}
 
示例8
public Double getDistinctRowCount(Values rel, RelMetadataQuery mq,
    ImmutableBitSet groupKey, RexNode predicate) {
  if (predicate == null || predicate.isAlwaysTrue()) {
    if (groupKey.isEmpty()) {
      return 1D;
    }
  }
  double selectivity = RelMdUtil.guessSelectivity(predicate);

  // assume half the rows are duplicates
  double nRows = rel.estimateRowCount(mq) / 2;
  return RelMdUtil.numDistinctVals(nRows, nRows * selectivity);
}
 
示例9
/**
 * Creates an AggregateValuesRule.
 *
 * @param relBuilderFactory Builder for relational expressions
 */
public AggregateValuesRule(RelBuilderFactory relBuilderFactory) {
  super(
      operandJ(Aggregate.class, null,
          aggregate -> aggregate.getGroupCount() == 0,
          operandJ(Values.class, null,
              values -> values.getTuples().isEmpty(), none())),
      relBuilderFactory, null);
}
 
示例10
@Override public void onMatch(RelOptRuleCall call) {
  final Aggregate aggregate = call.rel(0);
  final Values values = call.rel(1);
  Util.discard(values);
  final RelBuilder relBuilder = call.builder();
  final RexBuilder rexBuilder = relBuilder.getRexBuilder();

  final List<RexLiteral> literals = new ArrayList<>();
  for (final AggregateCall aggregateCall : aggregate.getAggCallList()) {
    switch (aggregateCall.getAggregation().getKind()) {
    case COUNT:
    case SUM0:
      literals.add((RexLiteral) rexBuilder.makeLiteral(
          BigDecimal.ZERO, aggregateCall.getType(), false));
      break;

    case MIN:
    case MAX:
    case SUM:
      literals.add((RexLiteral) rexBuilder.makeCast(
          aggregateCall.getType(), rexBuilder.constantNull()));
      break;

    default:
      // Unknown what this aggregate call should do on empty Values. Bail out to be safe.
      return;
    }
  }

  call.transformTo(
      relBuilder.values(ImmutableList.of(literals), aggregate.getRowType())
          .build());

  // New plan is absolutely better than old plan.
  call.getPlanner().setImportance(aggregate, 0.0);
}
 
示例11
/** Creates a RemoveEmptySingleRule. */
public <R extends SingleRel> RemoveEmptySingleRule(Class<R> clazz,
    Predicate<R> predicate, RelBuilderFactory relBuilderFactory,
    String description) {
  super(
      operandJ(clazz, null, predicate,
          operandJ(Values.class, null, Values::isEmpty, none())),
      relBuilderFactory, description);
}
 
示例12
@Override
public boolean matches(RelOptRuleCall call) {
  if(!checkChild) {
    return true;
  }
  // Make sure that we do not push filter past project onto things that it can't go past (filter/aggregate).
  // Also, do not push filter past project if there is yet another project.  Just make the projects merge first.
  return !(call.rel(2) instanceof Project || call.rel(2) instanceof Aggregate || call.rel(2) instanceof Values);
}
 
示例13
public Result visitValues(Values e) {
  final List<String> fields = e.getRowType().getFieldNames();
  final List<Clause> clauses = Collections.singletonList(Clause.SELECT);
  final Context context =
      new AliasContext(Collections.<Pair<String, RelDataType>>emptyList(), false);
  final List<SqlSelect> selects = new ArrayList<>();
  for (List<RexLiteral> tuple : e.getTuples()) {
    final List<SqlNode> selectList = new ArrayList<>();
    for (Pair<RexLiteral, String> literal : Pair.zip(tuple, fields)) {
      selectList.add(
          SqlStdOperatorTable.AS.createCall(
              POS,
              context.toSql(null, literal.left),
              new SqlIdentifier(literal.right, POS)));
    }
    selects.add(
        new SqlSelect(POS, SqlNodeList.EMPTY,
            new SqlNodeList(selectList, POS), null, null, null,
            null, null, null, null, null));
  }
  SqlNode query = null;
  for (SqlSelect select : selects) {
    if (query == null) {
      query = select;
    } else {
      query = SqlStdOperatorTable.UNION_ALL.createCall(POS, query,
          select);
    }
  }
  return result(query, clauses, e);
}
 
示例14
public Double getDistinctRowCount(Values rel, RelMetadataQuery mq,
    ImmutableBitSet groupKey, RexNode predicate) {
  if (predicate == null || predicate.isAlwaysTrue()) {
    if (groupKey.isEmpty()) {
      return 1D;
    }
  }
  double selectivity = RelMdUtil.guessSelectivity(predicate);

  // assume half the rows are duplicates
  double nRows = rel.estimateRowCount(mq) / 2;
  return RelMdUtil.numDistinctVals(nRows, nRows * selectivity);
}
 
示例15
public Boolean areColumnsUnique(RelSubset rel, RelMetadataQuery mq,
    ImmutableBitSet columns, boolean ignoreNulls) {
  columns = decorateWithConstantColumnsFromPredicates(columns, rel, mq);
  int nullCount = 0;
  for (RelNode rel2 : rel.getRels()) {
    if (rel2 instanceof Aggregate
        || rel2 instanceof Filter
        || rel2 instanceof Values
        || rel2 instanceof Sort
        || rel2 instanceof TableScan
        || simplyProjects(rel2, columns)) {
      try {
        final Boolean unique = mq.areColumnsUnique(rel2, columns, ignoreNulls);
        if (unique != null) {
          if (unique) {
            return true;
          }
        } else {
          ++nullCount;
        }
      } catch (CyclicMetadataException e) {
        // Ignore this relational expression; there will be non-cyclic ones
        // in this set.
      }
    }
  }
  return nullCount == 0 ? false : null;
}
 
示例16
/**
 * Creates an AggregateValuesRule.
 *
 * @param relBuilderFactory Builder for relational expressions
 */
public AggregateValuesRule(RelBuilderFactory relBuilderFactory) {
  super(
      operandJ(Aggregate.class, null,
          aggregate -> aggregate.getGroupCount() == 0,
          operandJ(Values.class, null,
              values -> values.getTuples().isEmpty(), none())),
      relBuilderFactory, null);
}
 
示例17
@Override public void onMatch(RelOptRuleCall call) {
  final Aggregate aggregate = call.rel(0);
  final Values values = call.rel(1);
  Util.discard(values);
  final RelBuilder relBuilder = call.builder();
  final RexBuilder rexBuilder = relBuilder.getRexBuilder();

  final List<RexLiteral> literals = new ArrayList<>();
  for (final AggregateCall aggregateCall : aggregate.getAggCallList()) {
    switch (aggregateCall.getAggregation().getKind()) {
    case COUNT:
    case SUM0:
      literals.add(
          (RexLiteral) rexBuilder.makeLiteral(
              BigDecimal.ZERO, aggregateCall.getType(), false));
      break;

    case MIN:
    case MAX:
    case SUM:
      literals.add(rexBuilder.makeNullLiteral(aggregateCall.getType()));
      break;

    default:
      // Unknown what this aggregate call should do on empty Values. Bail out to be safe.
      return;
    }
  }

  call.transformTo(
      relBuilder.values(ImmutableList.of(literals), aggregate.getRowType())
          .build());

  // New plan is absolutely better than old plan.
  call.getPlanner().prune(aggregate);
}
 
示例18
/** Creates a RemoveEmptySingleRule. */
public <R extends SingleRel> RemoveEmptySingleRule(Class<R> clazz,
    Predicate<R> predicate, RelBuilderFactory relBuilderFactory,
    String description) {
  super(
      operandJ(clazz, null, predicate,
          operandJ(Values.class, null, Values::isEmpty, none())),
      relBuilderFactory, description);
}
 
示例19
/** Ensures that the field names match those given.
 *
 * <p>If all fields have the same name, adds nothing;
 * if any fields do not have the same name, adds a {@link Project}.
 *
 * <p>Note that the names can be short-lived. Other {@code RelBuilder}
 * operations make no guarantees about the field names of the rows they
 * produce.
 *
 * @param fieldNames List of desired field names; may contain null values or
 * have fewer fields than the current row type
 */
public RelBuilder rename(List<String> fieldNames) {
  final List<String> oldFieldNames = peek().getRowType().getFieldNames();
  Preconditions.checkArgument(fieldNames.size() <= oldFieldNames.size(),
      "More names than fields");
  final List<String> newFieldNames = new ArrayList<>(oldFieldNames);
  for (int i = 0; i < fieldNames.size(); i++) {
    final String s = fieldNames.get(i);
    if (s != null) {
      newFieldNames.set(i, s);
    }
  }
  if (oldFieldNames.equals(newFieldNames)) {
    return this;
  }
  if (peek() instanceof Values) {
    // Special treatment for VALUES. Re-build it rather than add a project.
    final Values v = (Values) build();
    final RelDataTypeFactory.Builder b = getTypeFactory().builder();
    for (Pair<String, RelDataTypeField> p
        : Pair.zip(newFieldNames, v.getRowType().getFieldList())) {
      b.add(p.left, p.right.getType());
    }
    return values(v.tuples, b.build());
  }

  return project(fields(), newFieldNames, true);
}
 
示例20
@Test void testNodeTypeCountValues() {
  final String sql = "select * from (values (1), (2)) as t(c)";
  final Map<Class<? extends RelNode>, Integer> expected = new HashMap<>();
  expected.put(Values.class, 1);
  expected.put(Project.class, 1);
  checkNodeTypeCount(sql, expected);
}
 
示例21
private MutableValues(Values rel) {
  super(MutableRelType.VALUES, rel);
}
 
示例22
@Override public StringBuilder digest(StringBuilder buf) {
  return buf.append("Values(tuples: ")
      .append(((Values) rel).getTuples()).append(")");
}
 
示例23
@Override public MutableRel clone() {
  return MutableValues.of((Values) rel);
}
 
示例24
public Multimap<Class<? extends RelNode>, RelNode> getNodeTypes(Values rel,
    RelMetadataQuery mq) {
  return getNodeTypes(rel, Values.class, mq);
}
 
示例25
public RelDistribution distribution(Values values, RelMetadataQuery mq) {
  return values(values.getRowType(), values.getTuples());
}
 
示例26
public Double getPopulationSize(Values rel, RelMetadataQuery mq,
    ImmutableBitSet groupKey) {
  // assume half the rows are duplicates
  return rel.estimateRowCount(mq) / 2;
}
 
示例27
public ImmutableList<RelCollation> collations(Values values,
    RelMetadataQuery mq) {
  return ImmutableList.copyOf(
      values(mq, values.getRowType(), values.getTuples()));
}
 
示例28
public Double getMaxRowCount(Values values, RelMetadataQuery mq) {
  // For Values, the maximum row count is the actual row count.
  // This is especially useful if Values is empty.
  return (double) values.getTuples().size();
}
 
示例29
public Double getMinRowCount(Values values, RelMetadataQuery mq) {
  // For Values, the minimum row count is the actual row count.
  return (double) values.getTuples().size();
}
 
示例30
public Double getRowCount(Values rel, RelMetadataQuery mq) {
  return rel.estimateRowCount(mq);
}