Search in sources :

Example 86 with ImmutableBitSet

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);
}
Also used : AggregateCall(org.apache.calcite.rel.core.AggregateCall) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet)

Example 87 with ImmutableBitSet

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);
    }
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ImmutableList(com.google.common.collect.ImmutableList) ArrayList(java.util.ArrayList) AbstractList(java.util.AbstractList) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) Constructor(java.lang.reflect.Constructor) RelInput(org.apache.calcite.rel.RelInput) InvocationTargetException(java.lang.reflect.InvocationTargetException) AggregateCall(org.apache.calcite.rel.core.AggregateCall) RelNode(org.apache.calcite.rel.RelNode) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) RexNode(org.apache.calcite.rex.RexNode)

Example 88 with ImmutableBitSet

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);
}
Also used : RelCollation(org.apache.calcite.rel.RelCollation) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RexLocalRef(org.apache.calcite.rex.RexLocalRef) RexWindow(org.apache.calcite.rex.RexWindow)

Example 89 with ImmutableBitSet

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;
}
Also used : ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 90 with ImmutableBitSet

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();
}
Also used : JoinInfo(org.apache.calcite.rel.core.JoinInfo) RelNode(org.apache.calcite.rel.RelNode) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Aggregations

ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)365 RexNode (org.apache.calcite.rex.RexNode)196 RelNode (org.apache.calcite.rel.RelNode)183 ArrayList (java.util.ArrayList)179 AggregateCall (org.apache.calcite.rel.core.AggregateCall)116 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)98 RexBuilder (org.apache.calcite.rex.RexBuilder)92 RelDataType (org.apache.calcite.rel.type.RelDataType)89 RexInputRef (org.apache.calcite.rex.RexInputRef)79 HashMap (java.util.HashMap)68 Aggregate (org.apache.calcite.rel.core.Aggregate)62 RelBuilder (org.apache.calcite.tools.RelBuilder)59 Pair (org.apache.calcite.util.Pair)57 List (java.util.List)49 ImmutableList (com.google.common.collect.ImmutableList)48 HashSet (java.util.HashSet)45 LinkedHashSet (java.util.LinkedHashSet)45 Join (org.apache.calcite.rel.core.Join)45 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)45 Nullable (org.checkerframework.checker.nullness.qual.Nullable)43