All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.tajo.plan.nameresolver.ResolverByLegacy 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 org.apache.tajo.plan.nameresolver;

import org.apache.tajo.algebra.ColumnReferenceExpr;
import org.apache.tajo.catalog.CatalogUtil;
import org.apache.tajo.catalog.Column;
import org.apache.tajo.catalog.Schema;
import org.apache.tajo.exception.AmbiguousColumnException;
import org.apache.tajo.exception.TajoException;
import org.apache.tajo.exception.UndefinedColumnException;
import org.apache.tajo.plan.LogicalPlan;
import org.apache.tajo.plan.logical.LogicalNode;
import org.apache.tajo.plan.logical.NodeType;
import org.apache.tajo.plan.logical.RelationNode;
import org.apache.tajo.util.Pair;
import org.apache.tajo.util.TUtil;

import java.util.List;

public class ResolverByLegacy extends NameResolver {
  @Override
  public Column resolve(LogicalPlan plan,
                        LogicalPlan.QueryBlock block,
                        ColumnReferenceExpr columnRef,
                        boolean includeSeflDescTable)
      throws TajoException {

    if (columnRef.hasQualifier()) {
      return resolveColumnWithQualifier(plan, block, columnRef, includeSeflDescTable);
    } else {
      return resolveColumnWithoutQualifier(plan, block, columnRef, includeSeflDescTable);
    }
  }

  private static Column resolveColumnWithQualifier(LogicalPlan plan, LogicalPlan.QueryBlock block,
                                                   ColumnReferenceExpr columnRef, boolean includeSeflDescTable)
      throws TajoException {
    final String qualifier;
    final String qualifiedName;

    Pair normalized = lookupQualifierAndCanonicalName(block, columnRef, includeSeflDescTable);
    qualifier = normalized.getFirst();
    qualifiedName = CatalogUtil.buildFQName(qualifier, columnRef.getName());

    Column found = resolveFromRelsWithinBlock(plan, block, columnRef, includeSeflDescTable);
    if (found == null) {
      throw new UndefinedColumnException(columnRef.getCanonicalName());
    }

    // If code reach here, a column is found.
    // But, it may be aliased from bottom logical node.
    // If the column is aliased, the found name may not be used in upper node.

    // Here, we try to check if column reference is already aliased.
    // If so, it replaces the name with aliased name.
    LogicalNode currentNode = block.getCurrentNode();

    // The condition (currentNode.getInSchema().contains(column)) means
    // the column can be used at the current node. So, we don't need to find aliase name.
    Schema currentNodeSchema = null;
    if (currentNode != null) {
      if (currentNode instanceof RelationNode) {
        currentNodeSchema = ((RelationNode) currentNode).getLogicalSchema();
      } else {
        currentNodeSchema = currentNode.getInSchema();
      }
    }

    if (currentNode != null && !currentNodeSchema.contains(found)
        && currentNode.getType() != NodeType.TABLE_SUBQUERY) {
      List candidates = TUtil.newList();
      if (block.getNamedExprsManager().isAliased(qualifiedName)) {
        String alias = block.getNamedExprsManager().getAlias(qualifiedName);
        found = resolve(plan, block, new ColumnReferenceExpr(alias), NameResolvingMode.LEGACY, includeSeflDescTable);
        if (found != null) {
          candidates.add(found);
        }
      }
      if (!candidates.isEmpty()) {
        return ensureUniqueColumn(candidates);
      }
    }

    return found;
  }

  static Column resolveColumnWithoutQualifier(LogicalPlan plan, LogicalPlan.QueryBlock block,
                                              ColumnReferenceExpr columnRef, boolean includeSeflDescTable)
      throws AmbiguousColumnException, UndefinedColumnException {

    Column found = lookupColumnFromAllRelsInBlock(block, columnRef.getName(), includeSeflDescTable);
    if (found != null) {
      return found;
    }

    found = resolveAliasedName(block, columnRef);
    if (found != null) {
      return found;
    }

    found = resolveFromCurrentAndChildNode(block, columnRef);
    if (found != null) {
      return found;
    }

    found = resolveFromAllRelsInAllBlocks(plan, columnRef);
    if (found != null) {
      return found;
    }

    throw new UndefinedColumnException(columnRef.getCanonicalName());
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy