// 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.impala.analysis;

import static org.apache.impala.analysis.ToSqlOptions.DEFAULT;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import org.apache.impala.authorization.Privilege;
import org.apache.impala.catalog.FeFsTable;
import org.apache.impala.catalog.FeTable;
import org.apache.impala.common.AnalysisException;
import org.apache.impala.planner.JoinNode.DistributionMode;
import org.apache.impala.rewrite.ExprRewriter;
import org.apache.impala.thrift.TReplicaPreference;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;

/**
 * Superclass of all table references, including references to views, base tables
 * (Hdfs, HBase or DataSource tables), and nested collections. Contains the join
 * specification. An instance of a TableRef (and not a subclass thereof) represents
 * an unresolved table reference that must be resolved during analysis. All resolved
 * table references are subclasses of TableRef.
 *
 * The analysis of table refs follows a two-step process:
 *
 * 1. Resolution: A table ref's path is resolved and then the generic TableRef is
 * replaced by a concrete table ref (a BaseTableRef, CollectionTabeRef or ViewRef)
 * in the originating stmt and that is given the resolved path. This step is driven by
 * Analyzer.resolveTableRef().
 *
 * 2. Analysis/registration: After resolution, the concrete table ref is analyzed
 * to register a tuple descriptor for its resolved path and register other table-ref
 * specific state with the analyzer (e.g., whether it is outer/semi joined, etc.).
 *
 * Therefore, subclasses of TableRef should never call the analyze() of its superclass.
 *
 * TODO for 2.3: The current TableRef class hierarchy and the related two-phase analysis
 * feels convoluted and is hard to follow. We should reorganize the TableRef class
 * structure for clarity of analysis and avoid a table ref 'switching genders' in between
 * resolution and registration.
 *
 * TODO for 2.3: Rename this class to CollectionRef and re-consider the naming and
 * structure of all subclasses.
 */
public class TableRef extends StmtNode {
  // Path to a collection type. Not set for inline views.
  protected List<String> rawPath_;

  // Legal aliases of this table ref. Contains the explicit alias as its sole element if
  // there is one. Otherwise, contains the two implicit aliases. Implicit aliases are set
  // in the c'tor of the corresponding resolved table ref (subclasses of TableRef) during
  // analysis. By convention, for table refs with multiple implicit aliases, aliases_[0]
  // contains the fully-qualified implicit alias to ensure that aliases_[0] always
  // uniquely identifies this table ref regardless of whether it has an explicit alias.
  protected String[] aliases_;

  // Indicates whether this table ref is given an explicit alias,
  protected boolean hasExplicitAlias_;

  // Analysis registers privilege and/or audit requests based on this privilege.
  protected final Privilege priv_;
  protected final boolean requireGrantOption_;

  // Optional TABLESAMPLE clause. Null if not specified.
  protected TableSampleClause sampleParams_;

  protected JoinOperator joinOp_;
  protected List<PlanHint> joinHints_ = new ArrayList<>();
  protected List<String> usingColNames_;

  protected List<PlanHint> tableHints_ = new ArrayList<>();
  protected TReplicaPreference replicaPreference_;
  protected boolean randomReplica_;

  // Hinted distribution mode for this table ref; set after analyzeJoinHints()
  // TODO: Move join-specific members out of TableRef.
  private DistributionMode distrMode_ = DistributionMode.NONE;

  /////////////////////////////////////////
  // BEGIN: Members that need to be reset()

  // Resolution of rawPath_ if applicable. Result of analysis.
  protected Path resolvedPath_;

  protected Expr onClause_;

  // the ref to the left of us, if we're part of a JOIN clause
  protected TableRef leftTblRef_;

  // true if this TableRef has been analyzed; implementing subclass should set it to true
  // at the end of analyze() call.
  protected boolean isAnalyzed_;

  // Lists of table ref ids and materialized tuple ids of the full sequence of table
  // refs up to and including this one. These ids are cached during analysis because
  // we may alter the chain of table refs during plan generation, but we still rely
  // on the original list of ids for correct predicate assignment.
  // Populated in analyzeJoin().
  protected List<TupleId> allTableRefIds_ = new ArrayList<>();
  protected List<TupleId> allMaterializedTupleIds_ = new ArrayList<>();

  // All physical tuple ids that this table ref is correlated with:
  // Tuple ids of root descriptors from outer query blocks that this table ref
  // (if a CollectionTableRef) or contained CollectionTableRefs (if an InlineViewRef)
  // are rooted at. Populated during analysis.
  protected List<TupleId> correlatedTupleIds_ = new ArrayList<>();

  // analysis output
  protected TupleDescriptor desc_;

  // END: Members that need to be reset()
  /////////////////////////////////////////

  public TableRef(List<String> path, String alias) {
    this(path, alias, Privilege.SELECT);
  }

  public TableRef(List<String> path, String alias, TableSampleClause tableSample) {
    this(path, alias, tableSample, Privilege.SELECT, false);
  }

  public TableRef(List<String> path, String alias, Privilege priv) {
    this(path, alias, null, priv, false);
  }

  public TableRef(List<String> path, String alias, Privilege priv,
      boolean requireGrantOption) {
    this(path, alias, null, priv, requireGrantOption);
  }

  public TableRef(List<String> path, String alias, TableSampleClause sampleParams,
      Privilege priv, boolean requireGrantOption) {
    rawPath_ = path;
    if (alias != null) {
      aliases_ = new String[] { alias.toLowerCase() };
      hasExplicitAlias_ = true;
    } else {
      hasExplicitAlias_ = false;
    }
    sampleParams_ = sampleParams;
    priv_ = priv;
    requireGrantOption_ = requireGrantOption;
    isAnalyzed_ = false;
    replicaPreference_ = null;
    randomReplica_ = false;
  }

  /**
   * C'tor for cloning.
   */
  protected TableRef(TableRef other) {
    rawPath_ = other.rawPath_;
    resolvedPath_ = other.resolvedPath_;
    aliases_ = other.aliases_;
    hasExplicitAlias_ = other.hasExplicitAlias_;
    sampleParams_ = other.sampleParams_;
    priv_ = other.priv_;
    requireGrantOption_ = other.requireGrantOption_;
    joinOp_ = other.joinOp_;
    joinHints_ = Lists.newArrayList(other.joinHints_);
    onClause_ = (other.onClause_ != null) ? other.onClause_.clone() : null;
    usingColNames_ =
        (other.usingColNames_ != null) ? Lists.newArrayList(other.usingColNames_) : null;
    tableHints_ = Lists.newArrayList(other.tableHints_);
    replicaPreference_ = other.replicaPreference_;
    randomReplica_ = other.randomReplica_;
    distrMode_ = other.distrMode_;
    // The table ref links are created at the statement level, so cloning a set of linked
    // table refs is the responsibility of the statement.
    leftTblRef_ = null;
    isAnalyzed_ = other.isAnalyzed_;
    allTableRefIds_ = Lists.newArrayList(other.allTableRefIds_);
    allMaterializedTupleIds_ = Lists.newArrayList(other.allMaterializedTupleIds_);
    correlatedTupleIds_ = Lists.newArrayList(other.correlatedTupleIds_);
    desc_ = other.desc_;
  }

  @Override
  public void analyze(Analyzer analyzer) throws AnalysisException {
    throw new IllegalStateException(
        "Should not call analyze() on an unresolved TableRef.");
  }

  /**
   * Creates and returns a empty TupleDescriptor registered with the analyzer
   * based on the resolvedPath_.
   * This method is called from the analyzer when registering this table reference.
   */
  public TupleDescriptor createTupleDescriptor(Analyzer analyzer)
      throws AnalysisException {
    TupleDescriptor result = analyzer.getDescTbl().createTupleDescriptor(
        getClass().getSimpleName() + " " + getUniqueAlias());
    result.setPath(resolvedPath_);
    return result;
  }

  /**
   * Set this table's context-dependent join attributes from the given table.
   * Does not clone the attributes.
   */
  protected void setJoinAttrs(TableRef other) {
    this.joinOp_ = other.joinOp_;
    this.joinHints_ = other.joinHints_;
    this.tableHints_ = other.tableHints_;
    this.onClause_ = other.onClause_;
    this.usingColNames_ = other.usingColNames_;
  }

  public JoinOperator getJoinOp() {
    // if it's not explicitly set, we're doing an inner join
    return (joinOp_ == null ? JoinOperator.INNER_JOIN : joinOp_);
  }

  public TReplicaPreference getReplicaPreference() { return replicaPreference_; }
  public boolean getRandomReplica() { return randomReplica_; }

  /**
   * Returns true if this table ref has a resolved path that is rooted at a registered
   * tuple descriptor, false otherwise.
   */
  public boolean isRelative() { return false; }

  /**
   * Indicates if this TableRef directly or indirectly references another TableRef from
   * an outer query block.
   */
  public boolean isCorrelated() { return !correlatedTupleIds_.isEmpty(); }

  public List<String> getPath() { return rawPath_; }
  public Path getResolvedPath() { return resolvedPath_; }

  /**
   * Returns all legal aliases of this table ref.
   */
  public String[] getAliases() { return aliases_; }

  /**
   * Returns the explicit alias or the fully-qualified implicit alias. The returned alias
   * is guaranteed to be unique (i.e., column/field references against the alias cannot
   * be ambiguous).
   */
  public String getUniqueAlias() { return aliases_[0]; }

  /**
   * Returns true if this table ref has an explicit alias.
   * Note that getAliases().length() == 1 does not imply an explicit alias because
   * nested collection refs have only a single implicit alias.
   */
  public boolean hasExplicitAlias() { return hasExplicitAlias_; }

  /**
   * Returns the explicit alias if this table ref has one, null otherwise.
   */
  public String getExplicitAlias() {
    if (hasExplicitAlias()) return getUniqueAlias();
    return null;
  }

  public FeTable getTable() {
    Preconditions.checkNotNull(resolvedPath_);
    return resolvedPath_.getRootTable();
  }
  public TableSampleClause getSampleParams() { return sampleParams_; }
  public Privilege getPrivilege() { return priv_; }
  public boolean requireGrantOption() { return requireGrantOption_; }
  public List<PlanHint> getJoinHints() { return joinHints_; }
  public List<PlanHint> getTableHints() { return tableHints_; }
  public Expr getOnClause() { return onClause_; }
  public void setJoinOp(JoinOperator op) { this.joinOp_ = op; }
  public void setOnClause(Expr e) { this.onClause_ = e; }
  public void setUsingClause(List<String> colNames) { this.usingColNames_ = colNames; }
  public TableRef getLeftTblRef() { return leftTblRef_; }
  public void setLeftTblRef(TableRef leftTblRef) { this.leftTblRef_ = leftTblRef; }

  public void setJoinHints(List<PlanHint> hints) {
    Preconditions.checkNotNull(hints);
    joinHints_ = hints;
  }

  public void setTableHints(List<PlanHint> hints) {
    Preconditions.checkNotNull(hints);
    tableHints_ = hints;
  }

  public boolean isBroadcastJoin() { return distrMode_ == DistributionMode.BROADCAST; }

  public boolean isPartitionedJoin() {
    return distrMode_ == DistributionMode.PARTITIONED;
  }

  public DistributionMode getDistributionMode() { return distrMode_; }
  public List<TupleId> getCorrelatedTupleIds() { return correlatedTupleIds_; }
  public boolean isAnalyzed() { return isAnalyzed_; }
  public boolean isResolved() { return !getClass().equals(TableRef.class); }

  /**
   * This method should only be called after the TableRef has been analyzed.
   */
  public TupleDescriptor getDesc() {
    Preconditions.checkState(isAnalyzed_);
    // after analyze(), desc should be set.
    Preconditions.checkState(desc_ != null);
    return desc_;
  }

  /**
   * This method should only be called after the TableRef has been analyzed.
   */
  public TupleId getId() {
    Preconditions.checkState(isAnalyzed_);
    // after analyze(), desc should be set.
    Preconditions.checkNotNull(desc_);
    return desc_.getId();
  }

  public List<TupleId> getMaterializedTupleIds() {
    // This function should only be called after analyze().
    Preconditions.checkState(isAnalyzed_);
    Preconditions.checkNotNull(desc_);
    return desc_.getId().asList();
  }

  /**
   * Returns the list of tuple ids materialized by the full sequence of
   * table refs up to and including this one.
   */
  public List<TupleId> getAllMaterializedTupleIds() {
    Preconditions.checkState(isAnalyzed_);
    return allMaterializedTupleIds_;
  }

  /**
   * Return the list of table ref ids of the full sequence of table refs up to
   * and including this one.
   */
  public List<TupleId> getAllTableRefIds() {
    Preconditions.checkState(isAnalyzed_);
    return allTableRefIds_;
  }

  protected void analyzeTableSample(Analyzer analyzer) throws AnalysisException {
    if (sampleParams_ == null) return;
    sampleParams_.analyze(analyzer);
    if (!(this instanceof BaseTableRef)
        || !(resolvedPath_.destTable() instanceof FeFsTable)) {
      throw new AnalysisException(
          "TABLESAMPLE is only supported on HDFS tables: " + getUniqueAlias());
    }
  }

  protected void analyzeHints(Analyzer analyzer) throws AnalysisException {
    // We prefer adding warnings over throwing exceptions here to maintain view
    // compatibility with Hive.
    Preconditions.checkState(isResolved());
    analyzeTableHints(analyzer);
    analyzeJoinHints(analyzer);
  }

  private void analyzeTableHints(Analyzer analyzer) {
    if (tableHints_.isEmpty()) return;
    if (!(this instanceof BaseTableRef)) {
      analyzer.addWarning("Table hints not supported for inline view and collections");
      return;
    }
    // BaseTableRef will always have their path resolved at this point.
    Preconditions.checkState(getResolvedPath() != null);
    if (getResolvedPath().destTable() != null &&
        !(getResolvedPath().destTable() instanceof FeFsTable)) {
      analyzer.addWarning("Table hints only supported for Hdfs tables");
    }
    for (PlanHint hint: tableHints_) {
      if (hint.is("SCHEDULE_CACHE_LOCAL")) {
        analyzer.setHasPlanHints();
        replicaPreference_ = TReplicaPreference.CACHE_LOCAL;
      } else if (hint.is("SCHEDULE_DISK_LOCAL")) {
        analyzer.setHasPlanHints();
        replicaPreference_ = TReplicaPreference.DISK_LOCAL;
      } else if (hint.is("SCHEDULE_REMOTE")) {
        analyzer.setHasPlanHints();
        replicaPreference_ = TReplicaPreference.REMOTE;
      } else if (hint.is("SCHEDULE_RANDOM_REPLICA")) {
        analyzer.setHasPlanHints();
        randomReplica_ = true;
      } else {
        Preconditions.checkState(getAliases() != null && getAliases().length > 0);
        analyzer.addWarning("Table hint not recognized for table " + getUniqueAlias() +
            ": " + hint);
      }
    }
  }

  private void analyzeJoinHints(Analyzer analyzer) throws AnalysisException {
    if (joinHints_.isEmpty()) return;
    for (PlanHint hint: joinHints_) {
      if (hint.is("BROADCAST")) {
        if (joinOp_ == JoinOperator.RIGHT_OUTER_JOIN
            || joinOp_ == JoinOperator.FULL_OUTER_JOIN
            || joinOp_ == JoinOperator.RIGHT_SEMI_JOIN
            || joinOp_ == JoinOperator.RIGHT_ANTI_JOIN) {
          throw new AnalysisException(
              joinOp_.toString() + " does not support BROADCAST.");
        }
        if (isPartitionedJoin()) {
          throw new AnalysisException("Conflicting JOIN hint: " + hint);
        }
        distrMode_ = DistributionMode.BROADCAST;
        analyzer.setHasPlanHints();
      } else if (hint.is("SHUFFLE")) {
        if (joinOp_ == JoinOperator.CROSS_JOIN) {
          throw new AnalysisException("CROSS JOIN does not support SHUFFLE.");
        }
        if (isBroadcastJoin()) {
          throw new AnalysisException("Conflicting JOIN hint: " + hint);
        }
        distrMode_ = DistributionMode.PARTITIONED;
        analyzer.setHasPlanHints();
      } else {
        analyzer.addWarning("JOIN hint not recognized: " + hint);
      }
    }
  }

  /**
   * Analyzes the join clause. Populates allTableRefIds_ and allMaterializedTupleIds_.
   * The join clause can only be analyzed after the left table has been analyzed
   * and the TupleDescriptor (desc) of this table has been created.
   */
  public void analyzeJoin(Analyzer analyzer) throws AnalysisException {
    Preconditions.checkState(leftTblRef_ == null || leftTblRef_.isAnalyzed_);
    Preconditions.checkState(desc_ != null);

    // Populate the lists of all table ref and materialized tuple ids.
    allTableRefIds_.clear();
    allMaterializedTupleIds_.clear();
    if (leftTblRef_ != null) {
      allTableRefIds_.addAll(leftTblRef_.getAllTableRefIds());
      allMaterializedTupleIds_.addAll(leftTblRef_.getAllMaterializedTupleIds());
    }
    allTableRefIds_.add(getId());
    allMaterializedTupleIds_.addAll(getMaterializedTupleIds());

    if (joinOp_ == JoinOperator.CROSS_JOIN) {
      // A CROSS JOIN is always a broadcast join, regardless of the join hints
      distrMode_ = DistributionMode.BROADCAST;
    }

    if (usingColNames_ != null) {
      Preconditions.checkState(joinOp_ != JoinOperator.CROSS_JOIN);
      // Turn USING clause into equivalent ON clause.
      onClause_ = null;
      for (String colName: usingColNames_) {
        // check whether colName exists both for our table and the one
        // to the left of us
        Path leftColPath = new Path(leftTblRef_.getDesc(),
            Lists.newArrayList(colName.toLowerCase()));
        if (!leftColPath.resolve()) {
          throw new AnalysisException(
              "unknown column " + colName + " for alias "
              + leftTblRef_.getUniqueAlias() + " (in \"" + this.toSql() + "\")");
        }
        Path rightColPath = new Path(desc_,
            Lists.newArrayList(colName.toLowerCase()));
        if (!rightColPath.resolve()) {
          throw new AnalysisException(
              "unknown column " + colName + " for alias "
              + getUniqueAlias() + " (in \"" + this.toSql() + "\")");
        }

        // create predicate "<left>.colName = <right>.colName"
        BinaryPredicate eqPred =
            new BinaryPredicate(BinaryPredicate.Operator.EQ,
              new SlotRef(Path.createRawPath(leftTblRef_.getUniqueAlias(), colName)),
              new SlotRef(Path.createRawPath(getUniqueAlias(), colName)));
        onClause_ = CompoundPredicate.createConjunction(eqPred, onClause_);
      }
    }

    // at this point, both 'this' and leftTblRef have been analyzed and registered;
    // register the tuple ids of the TableRefs on the nullable side of an outer join
    if (joinOp_ == JoinOperator.LEFT_OUTER_JOIN
        || joinOp_ == JoinOperator.FULL_OUTER_JOIN) {
      analyzer.registerOuterJoinedTids(getId().asList(), this);
    }
    if (joinOp_ == JoinOperator.RIGHT_OUTER_JOIN
        || joinOp_ == JoinOperator.FULL_OUTER_JOIN) {
      analyzer.registerOuterJoinedTids(leftTblRef_.getAllTableRefIds(), this);
    }
    // register the tuple ids of a full outer join
    if (joinOp_ == JoinOperator.FULL_OUTER_JOIN) {
      analyzer.registerFullOuterJoinedTids(leftTblRef_.getAllTableRefIds(), this);
      analyzer.registerFullOuterJoinedTids(getId().asList(), this);
    }
    // register the tuple id of the rhs of a left semi join
    TupleId semiJoinedTupleId = null;
    if (joinOp_ == JoinOperator.LEFT_SEMI_JOIN
        || joinOp_ == JoinOperator.LEFT_ANTI_JOIN
        || joinOp_ == JoinOperator.NULL_AWARE_LEFT_ANTI_JOIN) {
      analyzer.registerSemiJoinedTid(getId(), this);
      semiJoinedTupleId = getId();
    }
    // register the tuple id of the lhs of a right semi join
    if (joinOp_ == JoinOperator.RIGHT_SEMI_JOIN
        || joinOp_ == JoinOperator.RIGHT_ANTI_JOIN) {
      analyzer.registerSemiJoinedTid(leftTblRef_.getId(), this);
      semiJoinedTupleId = leftTblRef_.getId();
    }

    if (onClause_ != null) {
      Preconditions.checkState(joinOp_ != JoinOperator.CROSS_JOIN);
      analyzer.setVisibleSemiJoinedTuple(semiJoinedTupleId);
      onClause_.analyze(analyzer);
      analyzer.setVisibleSemiJoinedTuple(null);
      onClause_.checkReturnsBool("ON clause", true);
        if (onClause_.contains(Expr.IS_AGGREGATE)) {
          throw new AnalysisException(
              "aggregate function not allowed in ON clause: " + toSql());
      }
      if (onClause_.contains(AnalyticExpr.class)) {
        throw new AnalysisException(
            "analytic expression not allowed in ON clause: " + toSql());
      }
      if (onClause_.contains(Subquery.class)) {
        throw new AnalysisException(
            "Subquery is not allowed in ON clause: " + toSql());
      }
      Set<TupleId> onClauseTupleIds = new HashSet<>();
      List<Expr> conjuncts = onClause_.getConjuncts();
      // Outer join clause conjuncts are registered for this particular table ref
      // (ie, can only be evaluated by the plan node that implements this join).
      // The exception are conjuncts that only pertain to the nullable side
      // of the outer join; those can be evaluated directly when materializing tuples
      // without violating outer join semantics.
      analyzer.registerOnClauseConjuncts(conjuncts, this);
      for (Expr e: conjuncts) {
        List<TupleId> tupleIds = new ArrayList<>();
        e.getIds(tupleIds, null);
        onClauseTupleIds.addAll(tupleIds);
      }
    } else if (!isRelative() && !isCorrelated()
        && (getJoinOp().isOuterJoin() || getJoinOp().isSemiJoin())) {
      throw new AnalysisException(
          joinOp_.toString() + " requires an ON or USING clause.");
    } else {
      // Indicate that this table ref has an empty ON-clause.
      analyzer.registerOnClauseConjuncts(Collections.<Expr>emptyList(), this);
    }
  }

  public void rewriteExprs(ExprRewriter rewriter, Analyzer analyzer)
      throws AnalysisException {
    Preconditions.checkState(isAnalyzed_);
    if (onClause_ != null) onClause_ = rewriter.rewrite(onClause_, analyzer);
  }

  public String debugString() { return tableRefToSql(); }

  protected String tableRefToSql() { return tableRefToSql(DEFAULT); }

  protected String tableRefToSql(ToSqlOptions options) {
    String aliasSql = null;
    String alias = getExplicitAlias();
    if (alias != null) aliasSql = ToSqlUtils.getIdentSql(alias);
    List<String> path = rawPath_;
    if (resolvedPath_ != null) path = resolvedPath_.getFullyQualifiedRawPath();
    return ToSqlUtils.getPathSql(path) + ((aliasSql != null) ? " " + aliasSql : "");
  }

  @Override
  public final String toSql() {
    return toSql(DEFAULT);
  }

  @Override
  public String toSql(ToSqlOptions options) {
    if (joinOp_ == null) {
      // prepend "," if we're part of a sequence of table refs w/o an
      // explicit JOIN clause
      return (leftTblRef_ != null ? ", " : "") + tableRefToSql(options);
    }

    StringBuilder output = new StringBuilder(" " + joinOp_.toString() + " ");
    if (!joinHints_.isEmpty())
      output.append(ToSqlUtils.getPlanHintsSql(options, joinHints_)).append(" ");
    output.append(tableRefToSql(options));
    if (usingColNames_ != null) {
      output.append(" USING (").append(Joiner.on(", ").join(usingColNames_)).append(")");
    } else if (onClause_ != null) {
      output.append(" ON ").append(onClause_.toSql(options));
    }
    return output.toString();
  }

  /**
   * Returns a deep clone of this table ref without also cloning the chain of table refs.
   * Sets leftTblRef_ in the returned clone to null.
   */
  @Override
  protected TableRef clone() { return new TableRef(this); }

  public void reset() {
    isAnalyzed_ = false;
    resolvedPath_ = null;
    if (usingColNames_ != null) {
      // The using col names are converted into an on-clause predicate during analysis,
      // so unset the on-clause here.
      onClause_ = null;
    } else if (onClause_ != null) {
      onClause_.reset();
    }
    leftTblRef_ = null;
    allTableRefIds_.clear();
    allMaterializedTupleIds_.clear();
    correlatedTupleIds_.clear();
    desc_ = null;
  }

  public boolean isTableMaskingView() { return false; }

  void migratePropertiesTo(TableRef other) {
    other.aliases_ = aliases_;
    other.onClause_ = onClause_;
    other.usingColNames_ = usingColNames_;
    other.joinOp_ = joinOp_;
    other.joinHints_ = joinHints_;
    other.tableHints_ = tableHints_;
    // Clear properties. Don't clear aliases_ since it's still used in resolving slots
    // in the query block of 'other'.
    onClause_ = null;
    usingColNames_ = null;
    joinOp_ = null;
    joinHints_ = new ArrayList<>();
    tableHints_ = new ArrayList<>();
  }
}
