// 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 org.apache.impala.authorization.Privilege;
import org.apache.impala.authorization.PrivilegeRequestBuilder;
import org.apache.impala.common.AnalysisException;
import com.google.common.base.Preconditions;

/**
 * Reference to a MAP or ARRAY collection type that implies its
 * flattening during execution.
 * TODO: We currently create a new slot in the root tuple descriptor for every
 * relative collection ref, even if they have the same path. The BE currently relies on
 * this behavior for setting collection slots to NULL after they have been unnested
 * inside a SubplanNode. We could instead share the slot and the corresponding item tuple
 * descriptor among all collection table refs with the same path. This change will
 * require decoupling tuple descriptors from table aliases, i.e., a tuple descriptor
 * should be able to back multiple aliases.
 */
public class CollectionTableRef extends TableRef {
  /////////////////////////////////////////
  // BEGIN: Members that need to be reset()

  // Expr that returns the referenced collection. Typically a SlotRef into the
  // parent scan's tuple. Result of analysis. Fully resolved against base tables.
  private Expr collectionExpr_;

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

  /**
   * Create a CollectionTableRef from the original unresolved table ref as well as
   * its resolved path. Sets table aliases and join-related attributes.
   */
  public CollectionTableRef(TableRef tableRef, Path resolvedPath) {
    super(tableRef);
    Preconditions.checkState(resolvedPath.isResolved());
    resolvedPath_ = resolvedPath;
    // Use the last path element as an implicit alias if no explicit alias was given.
    if (hasExplicitAlias()) return;
    String implicitAlias = rawPath_.get(rawPath_.size() - 1).toLowerCase();
    aliases_ = new String[] { implicitAlias };
  }

  /**
   * C'tor for cloning.
   */
  public CollectionTableRef(CollectionTableRef other) {
    super(other);
    collectionExpr_ =
        (other.collectionExpr_ != null) ? other.collectionExpr_.clone() : null;
  }

  /**
   * Registers this collection table ref with the given analyzer and adds a slot
   * descriptor for the materialized collection to be populated by parent scan.
   * Also determines whether this collection table ref is correlated or not.
   *
   * If this function is called in the context of analyzing a WITH clause, then
   * no slot is added to the parent descriptor so as to not pollute the analysis
   * state of the parent block (the WITH-clause analyzer is discarded, and the
   * parent analyzer could have an entirely different global state).
   */
  @Override
  public void analyze(Analyzer analyzer) throws AnalysisException {
    if (isAnalyzed_) return;
    desc_ = analyzer.registerTableRef(this);
    if (isRelative() && !analyzer.isWithClause()) {
      SlotDescriptor parentSlotDesc = analyzer.registerSlotRef(resolvedPath_);
      parentSlotDesc.setItemTupleDesc(desc_);
      collectionExpr_ = new SlotRef(parentSlotDesc);
      // Must always be materialized to ensure the correct cardinality after unnesting.
      analyzer.materializeSlots(collectionExpr_);
      Analyzer parentAnalyzer =
          analyzer.findAnalyzer(resolvedPath_.getRootDesc().getId());
      Preconditions.checkNotNull(parentAnalyzer);
      if (parentAnalyzer != analyzer) {
        TableRef parentRef =
            parentAnalyzer.getTableRef(resolvedPath_.getRootDesc().getId());
        Preconditions.checkNotNull(parentRef);
        // InlineViews are currently not supported as a parent ref.
        Preconditions.checkState(!(parentRef instanceof InlineViewRef));
        correlatedTupleIds_.add(parentRef.getId());
      }
    }
    if (!isRelative()) {
      // Register a table-level privilege request as well as a column-level privilege request
      // for the collection-typed column.
      Preconditions.checkNotNull(resolvedPath_.getRootTable());
      analyzer.registerAuthAndAuditEvent(resolvedPath_.getRootTable(), priv_);
      analyzer.registerPrivReq(new PrivilegeRequestBuilder().
          allOf(Privilege.SELECT).onColumn(desc_.getTableName().getDb(),
          desc_.getTableName().getTbl(), desc_.getPath().getRawPath().get(0))
          .toRequest());
    }
    isAnalyzed_ = true;
    analyzeTableSample(analyzer);
    analyzeHints(analyzer);

    // TODO: For joins on nested collections some join ops can be simplified
    // due to the containment relationship of the parent and child. For example,
    // a FULL OUTER JOIN would become a LEFT OUTER JOIN, or a RIGHT SEMI JOIN
    // would become an INNER or CROSS JOIN.
    analyzeJoin(analyzer);
  }

  @Override
  public boolean isRelative() {
    Preconditions.checkNotNull(resolvedPath_);
    return resolvedPath_.getRootDesc() != null;
  }

  public Expr getCollectionExpr() { return collectionExpr_; }

  @Override
  protected CollectionTableRef clone() { return new CollectionTableRef(this); }

  @Override
  public void reset() {
    super.reset();
    collectionExpr_ = null;
  }
}
