com.hazelcast.org.apache.calcite.materialize.LatticeNode Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.org.apache.calcite.materialize;
import com.hazelcast.org.apache.calcite.plan.RelOptTable;
import com.hazelcast.org.apache.calcite.util.mapping.IntPair;
import com.hazelcast.com.google.common.base.Preconditions;
import com.hazelcast.com.google.common.collect.ImmutableList;
import com.hazelcast.org.checkerframework.checker.initialization.qual.Initialized;
import com.hazelcast.org.checkerframework.checker.nullness.qual.Nullable;
import java.util.List;
import static java.util.Objects.requireNonNull;
/** Source relation of a lattice.
*
* Relations form a tree; all relations except the root relation
* (the fact table) have precisely one parent and an equi-join
* condition on one or more pairs of columns linking to it. */
public abstract class LatticeNode {
public final LatticeTable table;
final int startCol;
final int endCol;
public final @Nullable String alias;
private final ImmutableList children;
public final String digest;
/** Creates a LatticeNode.
*
* The {@code parent} and {@code mutableNode} arguments are used only
* during construction. */
LatticeNode(LatticeSpace space, @Nullable LatticeNode parent, MutableNode mutableNode) {
this.table = requireNonNull(mutableNode.table);
this.startCol = mutableNode.startCol;
this.endCol = mutableNode.endCol;
this.alias = mutableNode.alias;
Preconditions.checkArgument(startCol >= 0);
Preconditions.checkArgument(endCol > startCol);
final StringBuilder sb = new StringBuilder()
.append(space.simpleName(table));
if (parent != null) {
sb.append(':');
int i = 0;
for (IntPair p : requireNonNull(mutableNode.step, "mutableNode.step").keys) {
if (i++ > 0) {
sb.append(",");
}
sb.append(space.fieldName(parent.table, p.source));
}
}
if (mutableNode.children.isEmpty()) {
this.children = ImmutableList.of();
} else {
sb.append(" (");
final ImmutableList.Builder b = ImmutableList.builder();
int i = 0;
for (MutableNode mutableChild : mutableNode.children) {
if (i++ > 0) {
sb.append(' ');
}
@SuppressWarnings({"argument.type.incompatible", "assignment.type.incompatible"})
final @Initialized LatticeChildNode node =
new LatticeChildNode(space, this, mutableChild);
sb.append(node.digest);
b.add(node);
}
this.children = b.build();
sb.append(")");
}
this.digest = sb.toString();
}
@Override public String toString() {
return digest;
}
public RelOptTable relOptTable() {
return table.t;
}
abstract void use(List usedNodes);
void flattenTo(ImmutableList.Builder builder) {
builder.add(this);
for (LatticeChildNode child : children) {
child.flattenTo(builder);
}
}
void createPathsRecurse(LatticeSpace space, List steps,
List paths) {
paths.add(space.addPath(steps));
for (LatticeChildNode child : children) {
steps.add(space.addEdge(table, child.table, child.link));
child.createPathsRecurse(space, steps, paths);
steps.remove(steps.size() - 1);
}
}
}