use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelMdDistinctRowCount method getDistinctRowCount.
public Double getDistinctRowCount(Project rel, RelMetadataQuery mq, ImmutableBitSet groupKey, RexNode predicate) {
if (predicate == null || predicate.isAlwaysTrue()) {
if (groupKey.isEmpty()) {
return 1D;
}
}
ImmutableBitSet.Builder baseCols = ImmutableBitSet.builder();
ImmutableBitSet.Builder projCols = ImmutableBitSet.builder();
List<RexNode> projExprs = rel.getProjects();
RelMdUtil.splitCols(projExprs, groupKey, baseCols, projCols);
final List<RexNode> notPushable = new ArrayList<>();
final List<RexNode> pushable = new ArrayList<>();
RelOptUtil.splitFilters(ImmutableBitSet.range(rel.getRowType().getFieldCount()), predicate, pushable, notPushable);
final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
// get the distinct row count of the child input, passing in the
// columns and filters that only reference the child; convert the
// filter to reference the children projection expressions
RexNode childPred = RexUtil.composeConjunction(rexBuilder, pushable, true);
RexNode modifiedPred;
if (childPred == null) {
modifiedPred = null;
} else {
modifiedPred = RelOptUtil.pushPastProject(childPred, rel);
}
Double distinctRowCount = mq.getDistinctRowCount(rel.getInput(), baseCols.build(), modifiedPred);
if (distinctRowCount == null) {
return null;
} else if (!notPushable.isEmpty()) {
RexNode preds = RexUtil.composeConjunction(rexBuilder, notPushable, true);
distinctRowCount *= RelMdUtil.guessSelectivity(preds);
}
// are all column references
if (projCols.cardinality() == 0) {
return distinctRowCount;
}
// multiply by the cardinality of the non-child projection expressions
for (int bit : projCols.build()) {
Double subRowCount = RelMdUtil.cardOfProjExpr(mq, rel, projExprs.get(bit));
if (subRowCount == null) {
return null;
}
distinctRowCount *= subRowCount;
}
return RelMdUtil.numDistinctVals(distinctRowCount, mq.getRowCount(rel));
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelJsonReader method readRel.
private void readRel(final Map<String, Object> jsonRel) {
String id = (String) jsonRel.get("id");
String type = (String) jsonRel.get("relOp");
Constructor constructor = relJson.getConstructor(type);
RelInput input = new RelInput() {
public RelOptCluster getCluster() {
return cluster;
}
public RelTraitSet getTraitSet() {
return cluster.traitSetOf(Convention.NONE);
}
public RelOptTable getTable(String table) {
final List<String> list = getStringList(table);
return relOptSchema.getTableForMember(list);
}
public RelNode getInput() {
final List<RelNode> inputs = getInputs();
assert inputs.size() == 1;
return inputs.get(0);
}
public List<RelNode> getInputs() {
final List<String> jsonInputs = getStringList("inputs");
if (jsonInputs == null) {
return ImmutableList.of(lastRel);
}
final List<RelNode> inputs = new ArrayList<>();
for (String jsonInput : jsonInputs) {
inputs.add(lookupInput(jsonInput));
}
return inputs;
}
public RexNode getExpression(String tag) {
return relJson.toRex(this, jsonRel.get(tag));
}
public ImmutableBitSet getBitSet(String tag) {
return ImmutableBitSet.of(getIntegerList(tag));
}
public List<ImmutableBitSet> getBitSetList(String tag) {
List<List<Integer>> list = getIntegerListList(tag);
if (list == null) {
return null;
}
final ImmutableList.Builder<ImmutableBitSet> builder = ImmutableList.builder();
for (List<Integer> integers : list) {
builder.add(ImmutableBitSet.of(integers));
}
return builder.build();
}
public List<String> getStringList(String tag) {
// noinspection unchecked
return (List<String>) jsonRel.get(tag);
}
public List<Integer> getIntegerList(String tag) {
// noinspection unchecked
return (List<Integer>) jsonRel.get(tag);
}
public List<List<Integer>> getIntegerListList(String tag) {
// noinspection unchecked
return (List<List<Integer>>) jsonRel.get(tag);
}
public List<AggregateCall> getAggregateCalls(String tag) {
@SuppressWarnings("unchecked") final List<Map<String, Object>> jsonAggs = (List) jsonRel.get(tag);
final List<AggregateCall> inputs = new ArrayList<>();
for (Map<String, Object> jsonAggCall : jsonAggs) {
inputs.add(toAggCall(jsonAggCall));
}
return inputs;
}
public Object get(String tag) {
return jsonRel.get(tag);
}
public String getString(String tag) {
return (String) jsonRel.get(tag);
}
public float getFloat(String tag) {
return ((Number) jsonRel.get(tag)).floatValue();
}
public boolean getBoolean(String tag, boolean default_) {
final Boolean b = (Boolean) jsonRel.get(tag);
return b != null ? b : default_;
}
public <E extends Enum<E>> E getEnum(String tag, Class<E> enumClass) {
return Util.enumVal(enumClass, getString(tag).toUpperCase(Locale.ROOT));
}
public List<RexNode> getExpressionList(String tag) {
@SuppressWarnings("unchecked") final List<Object> jsonNodes = (List) jsonRel.get(tag);
final List<RexNode> nodes = new ArrayList<>();
for (Object jsonNode : jsonNodes) {
nodes.add(relJson.toRex(this, jsonNode));
}
return nodes;
}
public RelDataType getRowType(String tag) {
final Object o = jsonRel.get(tag);
return relJson.toType(cluster.getTypeFactory(), o);
}
public RelDataType getRowType(String expressionsTag, String fieldsTag) {
final List<RexNode> expressionList = getExpressionList(expressionsTag);
@SuppressWarnings("unchecked") final List<String> names = (List<String>) get(fieldsTag);
return cluster.getTypeFactory().createStructType(new AbstractList<Map.Entry<String, RelDataType>>() {
@Override
public Map.Entry<String, RelDataType> get(int index) {
return Pair.of(names.get(index), expressionList.get(index).getType());
}
@Override
public int size() {
return names.size();
}
});
}
public RelCollation getCollation() {
// noinspection unchecked
return relJson.toCollation((List) get("collation"));
}
public RelDistribution getDistribution() {
return relJson.toDistribution(get("distribution"));
}
public ImmutableList<ImmutableList<RexLiteral>> getTuples(String tag) {
// noinspection unchecked
final List<List> jsonTuples = (List) get(tag);
final ImmutableList.Builder<ImmutableList<RexLiteral>> builder = ImmutableList.builder();
for (List jsonTuple : jsonTuples) {
builder.add(getTuple(jsonTuple));
}
return builder.build();
}
public ImmutableList<RexLiteral> getTuple(List jsonTuple) {
final ImmutableList.Builder<RexLiteral> builder = ImmutableList.builder();
for (Object jsonValue : jsonTuple) {
builder.add((RexLiteral) relJson.toRex(this, jsonValue));
}
return builder.build();
}
};
try {
final RelNode rel = (RelNode) constructor.newInstance(input);
relMap.put(id, rel);
lastRel = rel;
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
final Throwable e2 = e.getCause();
if (e2 instanceof RuntimeException) {
throw (RuntimeException) e2;
}
throw new RuntimeException(e2);
}
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelMdPredicates method getPredicates.
/**
* Infers predicates for an Aggregate.
*
* <p>Pulls up predicates that only contains references to columns in the
* GroupSet. For e.g.
*
* <blockquote><pre>
* inputPullUpExprs : { a > 7, b + c < 10, a + e = 9}
* groupSet : { a, b}
* pulledUpExprs : { a > 7}
* </pre></blockquote>
*/
public RelOptPredicateList getPredicates(Aggregate agg, RelMetadataQuery mq) {
final RelNode input = agg.getInput();
final RexBuilder rexBuilder = agg.getCluster().getRexBuilder();
final RelOptPredicateList inputInfo = mq.getPulledUpPredicates(input);
final List<RexNode> aggPullUpPredicates = new ArrayList<>();
ImmutableBitSet groupKeys = agg.getGroupSet();
if (groupKeys.isEmpty()) {
// no rows!) but not on the output (there is one row).
return RelOptPredicateList.EMPTY;
}
Mapping m = Mappings.create(MappingType.PARTIAL_FUNCTION, input.getRowType().getFieldCount(), agg.getRowType().getFieldCount());
int i = 0;
for (int j : groupKeys) {
m.set(j, i++);
}
for (RexNode r : inputInfo.pulledUpPredicates) {
ImmutableBitSet rCols = RelOptUtil.InputFinder.bits(r);
if (groupKeys.contains(rCols)) {
r = r.accept(new RexPermuteInputsShuttle(m, input));
aggPullUpPredicates.add(r);
}
}
return RelOptPredicateList.of(rexBuilder, aggPullUpPredicates);
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelMdRowCount method getRowCount.
public Double getRowCount(Aggregate rel, RelMetadataQuery mq) {
// .range(rel.getGroupCount());
ImmutableBitSet groupKey = rel.getGroupSet();
// rowCount is the cardinality of the group by columns
Double distinctRowCount = mq.getDistinctRowCount(rel.getInput(), groupKey, null);
if (distinctRowCount == null) {
distinctRowCount = mq.getRowCount(rel.getInput()) / 10;
}
// Grouping sets multiply
distinctRowCount *= rel.getGroupSets().size();
return distinctRowCount;
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class LogicalWindow method addWindows.
private static void addWindows(Multimap<WindowKey, RexOver> windowMap, RexOver over, final int inputFieldCount) {
final RexWindow aggWindow = over.getWindow();
// Look up or create a window.
RelCollation orderKeys = getCollation(Lists.newArrayList(Iterables.filter(aggWindow.orderKeys, new PredicateImpl<RexFieldCollation>() {
public boolean test(RexFieldCollation rexFieldCollation) {
// then we can ignore such ORDER BY key.
return rexFieldCollation.left instanceof RexLocalRef;
}
})));
ImmutableBitSet groupSet = ImmutableBitSet.of(getProjectOrdinals(aggWindow.partitionKeys));
final int groupLength = groupSet.length();
if (inputFieldCount < groupLength) {
// If PARTITION BY references constant, we can ignore such partition key.
// All the inputs after inputFieldCount are literals, thus we can clear.
groupSet = groupSet.except(ImmutableBitSet.range(inputFieldCount, groupLength));
}
WindowKey windowKey = new WindowKey(groupSet, orderKeys, aggWindow.isRows(), aggWindow.getLowerBound(), aggWindow.getUpperBound());
windowMap.put(windowKey, over);
}
Aggregations