use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class SubstitutionVisitor method permute.
public static MutableAggregate permute(MutableAggregate aggregate, MutableRel input, Mapping mapping) {
ImmutableBitSet groupSet = Mappings.apply(mapping, aggregate.groupSet);
ImmutableList<ImmutableBitSet> groupSets = Mappings.apply2(mapping, aggregate.groupSets);
List<AggregateCall> aggregateCalls = Util.transform(aggregate.aggCalls, call -> call.transform(mapping));
return MutableAggregate.of(input, groupSet, groupSets, aggregateCalls);
}
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) requireNonNull(jsonRel.get("id"), "jsonRel.id");
String type = (String) requireNonNull(jsonRel.get("relOp"), "jsonRel.relOp");
Constructor constructor = relJson.getConstructor(type);
RelInput input = new RelInput() {
@Override
public RelOptCluster getCluster() {
return cluster;
}
@Override
public RelTraitSet getTraitSet() {
return cluster.traitSetOf(Convention.NONE);
}
@Override
public RelOptTable getTable(String table) {
final List<String> list = requireNonNull(getStringList(table), () -> "getStringList for " + table);
return requireNonNull(relOptSchema.getTableForMember(list), () -> "table " + table + " is not found in schema " + relOptSchema.toString());
}
@Override
public RelNode getInput() {
final List<RelNode> inputs = getInputs();
assert inputs.size() == 1;
return inputs.get(0);
}
@Override
public List<RelNode> getInputs() {
final List<String> jsonInputs = getStringList("inputs");
if (jsonInputs == null) {
return ImmutableList.of(requireNonNull(lastRel, "lastRel"));
}
final ImmutableList.Builder<RelNode> inputs = new ImmutableList.Builder<>();
for (String jsonInput : jsonInputs) {
inputs.add(lookupInput(jsonInput));
}
return inputs.build();
}
@Override
@Nullable
public RexNode getExpression(String tag) {
return relJson.toRex(this, jsonRel.get(tag));
}
@Override
public ImmutableBitSet getBitSet(String tag) {
return ImmutableBitSet.of(requireNonNull(getIntegerList(tag), tag));
}
@Override
@Nullable
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();
}
@Override
@Nullable
public List<String> getStringList(String tag) {
// noinspection unchecked
return (List<String>) jsonRel.get(tag);
}
@Override
@Nullable
public List<Integer> getIntegerList(String tag) {
// noinspection unchecked
return (List<Integer>) jsonRel.get(tag);
}
@Override
@Nullable
public List<List<Integer>> getIntegerListList(String tag) {
// noinspection unchecked
return (List<List<Integer>>) jsonRel.get(tag);
}
@Override
public List<AggregateCall> getAggregateCalls(String tag) {
@SuppressWarnings("unchecked") final List<Map<String, Object>> jsonAggs = (List) getNonNull(tag);
final List<AggregateCall> inputs = new ArrayList<>();
for (Map<String, Object> jsonAggCall : jsonAggs) {
inputs.add(toAggCall(jsonAggCall));
}
return inputs;
}
@Override
@Nullable
public Object get(String tag) {
return jsonRel.get(tag);
}
private Object getNonNull(String tag) {
return requireNonNull(get(tag), () -> "no entry for tag " + tag);
}
@Override
@Nullable
public String getString(String tag) {
return (String) get(tag);
}
@Override
public float getFloat(String tag) {
return ((Number) getNonNull(tag)).floatValue();
}
@Override
public boolean getBoolean(String tag, boolean default_) {
final Boolean b = (Boolean) get(tag);
return b != null ? b : default_;
}
@Override
@Nullable
public <E extends Enum<E>> E getEnum(String tag, Class<E> enumClass) {
return Util.enumVal(enumClass, ((String) getNonNull(tag)).toUpperCase(Locale.ROOT));
}
@Override
@Nullable
public List<RexNode> getExpressionList(String tag) {
@SuppressWarnings("unchecked") final List<Object> jsonNodes = (List) jsonRel.get(tag);
if (jsonNodes == null) {
return null;
}
final List<RexNode> nodes = new ArrayList<>();
for (Object jsonNode : jsonNodes) {
nodes.add(relJson.toRex(this, jsonNode));
}
return nodes;
}
@Override
public RelDataType getRowType(String tag) {
final Object o = getNonNull(tag);
return relJson.toType(cluster.getTypeFactory(), o);
}
@Override
public RelDataType getRowType(String expressionsTag, String fieldsTag) {
final List<RexNode> expressionList = getExpressionList(expressionsTag);
@SuppressWarnings("unchecked") final List<String> names = (List<String>) getNonNull(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), requireNonNull(expressionList, "expressionList").get(index).getType());
}
@Override
public int size() {
return names.size();
}
});
}
@Override
public RelCollation getCollation() {
// noinspection unchecked
return relJson.toCollation((List) getNonNull("collation"));
}
@Override
public RelDistribution getDistribution() {
// noinspection unchecked
return relJson.toDistribution((Map<String, Object>) getNonNull("distribution"));
}
@Override
public ImmutableList<ImmutableList<RexLiteral>> getTuples(String tag) {
// noinspection unchecked
final List<List> jsonTuples = (List) getNonNull(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 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(Util.filter(aggWindow.orderKeys, rexFieldCollation -> 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);
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelMdColumnUniqueness method areColumnsUnique.
@Nullable
public Boolean areColumnsUnique(Aggregate rel, RelMetadataQuery mq, ImmutableBitSet columns, boolean ignoreNulls) {
if (Aggregate.isSimple(rel) || ignoreNulls) {
columns = decorateWithConstantColumnsFromPredicates(columns, rel, mq);
// group by keys form a unique key
ImmutableBitSet groupKey = ImmutableBitSet.range(rel.getGroupCount());
return columns.contains(groupKey);
}
return null;
}
use of org.apache.calcite.util.ImmutableBitSet in project calcite by apache.
the class RelMdColumnUniqueness method areColumnsUnique.
@Nullable
public Boolean areColumnsUnique(Join rel, RelMetadataQuery mq, ImmutableBitSet columns, boolean ignoreNulls) {
columns = decorateWithConstantColumnsFromPredicates(columns, rel, mq);
if (columns.cardinality() == 0) {
return false;
}
final RelNode left = rel.getLeft();
final RelNode right = rel.getRight();
// Semi or anti join should ignore uniqueness of the right input.
if (!rel.getJoinType().projectsRight()) {
return mq.areColumnsUnique(left, columns, ignoreNulls);
}
// Divide up the input column mask into column masks for the left and
// right sides of the join
final Pair<ImmutableBitSet, ImmutableBitSet> leftAndRightColumns = splitLeftAndRightColumns(rel.getLeft().getRowType().getFieldCount(), columns);
final ImmutableBitSet leftColumns = leftAndRightColumns.left;
final ImmutableBitSet rightColumns = leftAndRightColumns.right;
// guaranteed that the result will be unique
if (!ignoreNulls && rel.getJoinType() == JoinRelType.FULL && leftColumns.cardinality() > 0 && rightColumns.cardinality() > 0) {
return false;
}
// If the original column mask contains columns from both the left and
// right hand side, then the columns are unique if and only if they're
// unique for their respective join inputs
Boolean leftUnique = mq.areColumnsUnique(left, leftColumns, ignoreNulls);
Boolean rightUnique = mq.areColumnsUnique(right, rightColumns, ignoreNulls);
if ((leftColumns.cardinality() > 0) && (rightColumns.cardinality() > 0)) {
if ((leftUnique == null) || (rightUnique == null)) {
return null;
} else {
return leftUnique && rightUnique;
}
}
// If we're only trying to determine uniqueness for columns that
// originate from one join input, then determine if the equijoin
// columns from the other join input are unique. If they are, then
// the columns are unique for the entire join if they're unique for
// the corresponding join input, provided that input is not null
// generating.
final JoinInfo joinInfo = rel.analyzeCondition();
if (leftColumns.cardinality() > 0) {
if (rel.getJoinType().generatesNullsOnLeft()) {
return false;
}
Boolean rightJoinColsUnique = mq.areColumnsUnique(right, joinInfo.rightSet(), ignoreNulls);
if ((rightJoinColsUnique == null) || (leftUnique == null)) {
return null;
}
return rightJoinColsUnique && leftUnique;
} else if (rightColumns.cardinality() > 0) {
if (rel.getJoinType().generatesNullsOnRight()) {
return false;
}
Boolean leftJoinColsUnique = mq.areColumnsUnique(left, joinInfo.leftSet(), ignoreNulls);
if ((leftJoinColsUnique == null) || (rightUnique == null)) {
return null;
}
return leftJoinColsUnique && rightUnique;
}
throw new AssertionError();
}
Aggregations