SourceColumnKey.java
// 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 org.apache.doris.nereids.processor.post.materialize;
import org.apache.doris.analysis.ColumnAccessPath;
import org.apache.doris.catalog.Column;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.plans.RelationId;
import org.apache.doris.nereids.trees.plans.algebra.Relation;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/** Stable identity of one physical source column used by TopN lazy materialization. */
public final class SourceColumnKey implements Comparable<SourceColumnKey> {
private final RelationId relationId;
private final int columnUniqueId;
private final String columnName;
private final List<ColumnAccessPath> accessPaths;
private SourceColumnKey(RelationId relationId, int columnUniqueId, String columnName,
List<ColumnAccessPath> accessPaths) {
this.relationId = Objects.requireNonNull(relationId, "relationId must not be null");
this.columnUniqueId = columnUniqueId;
this.columnName = Objects.requireNonNull(columnName, "columnName must not be null");
this.accessPaths = ImmutableList.copyOf(accessPaths);
}
/** Build a key from resolved relation and base slot metadata. */
public static SourceColumnKey from(Relation relation, SlotReference baseSlot) {
Objects.requireNonNull(relation, "relation must not be null");
Objects.requireNonNull(baseSlot, "baseSlot must not be null");
Preconditions.checkArgument(baseSlot.getOriginalColumn().isPresent(),
"baseSlot must have an original column: %s", baseSlot);
Column column = baseSlot.getOriginalColumn().get();
List<ColumnAccessPath> normalizedPaths = new ArrayList<>(
baseSlot.getAllAccessPaths().orElse(ImmutableList.of()));
Collections.sort(normalizedPaths);
return new SourceColumnKey(relation.getRelationId(), column.getUniqueId(), column.getName(), normalizedPaths);
}
public RelationId getRelationId() {
return relationId;
}
public int getColumnUniqueId() {
return columnUniqueId;
}
public String getColumnName() {
return columnName;
}
public List<ColumnAccessPath> getAccessPaths() {
return accessPaths;
}
@Override
public int compareTo(SourceColumnKey other) {
int result = Integer.compare(relationId.asInt(), other.relationId.asInt());
if (result != 0) {
return result;
}
result = Integer.compare(columnUniqueId, other.columnUniqueId);
if (result != 0) {
return result;
}
result = columnName.compareTo(other.columnName);
if (result != 0) {
return result;
}
int commonSize = Math.min(accessPaths.size(), other.accessPaths.size());
for (int i = 0; i < commonSize; i++) {
result = accessPaths.get(i).compareTo(other.accessPaths.get(i));
if (result != 0) {
return result;
}
}
return Integer.compare(accessPaths.size(), other.accessPaths.size());
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (!(object instanceof SourceColumnKey)) {
return false;
}
SourceColumnKey other = (SourceColumnKey) object;
return columnUniqueId == other.columnUniqueId
&& relationId.equals(other.relationId)
&& columnName.equals(other.columnName)
&& accessPaths.equals(other.accessPaths);
}
@Override
public int hashCode() {
return Objects.hash(relationId, columnUniqueId, columnName, accessPaths);
}
@Override
public String toString() {
return relationId + ":" + columnUniqueId + ":" + columnName + accessPaths;
}
}