Alias.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.trees.expressions;
import org.apache.doris.nereids.exceptions.UnboundException;
import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DataType;
import com.google.common.base.Preconditions;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
/**
* Expression for alias, such as col1 as c1.
*/
public class Alias extends NamedExpression implements UnaryExpression {
private final ExprId exprId;
private final Supplier<String> name;
private final List<String> qualifier;
private final boolean nameFromChild;
/**
* constructor of Alias.
*
* @param child expression that alias represents for
* @param name alias name
*/
public Alias(Expression child, String name) {
this(child, name, false);
}
public Alias(Expression child, String name, boolean nameFromChild) {
this(StatementScopeIdGenerator.newExprId(), child, name, nameFromChild);
}
public Alias(Expression child) {
this(StatementScopeIdGenerator.newExprId(), ImmutableList.of(child),
Suppliers.memoize(child::toSql), ImmutableList.of(), true);
}
public Alias(ExprId exprId, Expression child, String name) {
this(exprId, ImmutableList.of(child), name, ImmutableList.of(), false);
}
public Alias(Expression child, String name, List<String> qualifier) {
this(StatementScopeIdGenerator.newExprId(), ImmutableList.of(child), name, qualifier, false);
}
public Alias(ExprId exprId, Expression child, String name, boolean nameFromChild) {
this(exprId, ImmutableList.of(child), name, ImmutableList.of(), nameFromChild);
}
public Alias(ExprId exprId, List<Expression> child, String name, List<String> qualifier, boolean nameFromChild) {
this(exprId, child, Suppliers.memoize(() -> name), qualifier, nameFromChild);
}
private Alias(ExprId exprId, List<Expression> child, Supplier<String> name,
List<String> qualifier, boolean nameFromChild) {
super(child);
this.exprId = exprId;
this.name = name;
this.qualifier = qualifier;
this.nameFromChild = nameFromChild;
}
@Override
public Slot toSlot() throws UnboundException {
SlotReference slotReference = child() instanceof SlotReference
? (SlotReference) child() : null;
return new SlotReference(exprId, name, child().getDataType(), child().nullable(), qualifier,
slotReference != null ? ((SlotReference) child()).getOriginalTable().orElse(null) : null,
slotReference != null ? slotReference.getOriginalColumn().orElse(null) : null,
slotReference != null ? ((SlotReference) child()).getOneLevelTable().orElse(null) : null,
slotReference != null ? slotReference.getOriginalColumn().orElse(null) : null,
slotReference != null ? slotReference.getSubPath() : ImmutableList.of(), Optional.empty()
);
}
@Override
public String getName() throws UnboundException {
return name.get();
}
@Override
public ExprId getExprId() throws UnboundException {
return exprId;
}
@Override
public List<String> getQualifier() {
return qualifier;
}
@Override
public DataType getDataType() throws UnboundException {
return child().getDataType();
}
@Override
public String computeToSql() {
return child().toSql() + " AS `" + name.get() + "`";
}
@Override
public boolean nullable() throws UnboundException {
return child().nullable();
}
@Override
protected boolean extraEquals(Expression other) {
Alias that = (Alias) other;
if (!exprId.equals(that.exprId) || !qualifier.equals(that.qualifier)) {
return false;
}
return nameFromChild || name.get().equals(that.name.get());
}
@Override
public int computeHashCode() {
return Objects.hash(exprId, qualifier);
}
@Override
public String toString() {
return child().toString() + " AS `" + name.get() + "`#" + exprId;
}
@Override
public Alias withChildren(List<Expression> children) {
Preconditions.checkArgument(children.size() == 1);
return new Alias(exprId, children, name, qualifier, nameFromChild);
}
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitAlias(this, context);
}
public boolean isNameFromChild() {
return nameFromChild;
}
}