com.cloudera.impala.analysis.DescribeTableStmt.java Source code

Java tutorial

Introduction

Here is the source code for com.cloudera.impala.analysis.DescribeTableStmt.java

Source

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

import java.util.ArrayList;

import org.apache.commons.lang3.StringUtils;

import parquet.Strings;

import com.cloudera.impala.analysis.Path.PathType;
import com.cloudera.impala.authorization.Privilege;
import com.cloudera.impala.authorization.PrivilegeRequestBuilder;
import com.cloudera.impala.catalog.StructType;
import com.cloudera.impala.catalog.TableLoadingException;
import com.cloudera.impala.common.AnalysisException;
import com.cloudera.impala.thrift.TDescribeOutputStyle;
import com.cloudera.impala.thrift.TDescribeTableParams;
import com.google.common.base.Preconditions;

/**
 * Representation of a DESCRIBE table statement which returns metadata on
 * a specified table:
 * Syntax: DESCRIBE <path>
 *         DESCRIBE FORMATTED|EXTENDED <table>
 *
 * If FORMATTED|EXTENDED is not specified and the path refers to a table, the statement
 * only returns info on the given table's column definition (column name, data type, and
 * comment). If the path refers to a complex typed field within a column, the statement
 * returns the field names, types, and comments.
 * If FORMATTED|EXTENDED is specified, extended metadata on the table is returned
 * (in addition to the column definitions). This metadata includes info about the table
 * properties, SerDe properties, StorageDescriptor properties, and more.
 */
public class DescribeTableStmt extends StatementBase {
    private final TDescribeOutputStyle outputStyle_;

    /// "."-separated path from the describe statement.
    private ArrayList<String> rawPath_;

    /// The resolved path to describe, set after analysis.
    private Path path_;

    /// The fully qualified name of the root table, set after analysis.
    private TableName tableName_;

    /// Struct type with the fields to display for the described path.
    private StructType resultStruct_;

    public DescribeTableStmt(ArrayList<String> rawPath, TDescribeOutputStyle outputStyle) {
        Preconditions.checkNotNull(rawPath);
        Preconditions.checkArgument(!rawPath.isEmpty());
        rawPath_ = rawPath;
        outputStyle_ = outputStyle;
        path_ = null;
        tableName_ = null;
        resultStruct_ = null;
    }

    @Override
    public String toSql() {
        StringBuilder sb = new StringBuilder("DESCRIBE ");
        if (outputStyle_ != TDescribeOutputStyle.MINIMAL) {
            sb.append(outputStyle_.toString() + " ");
        }
        return sb.toString() + StringUtils.join(rawPath_, ".");
    }

    public TableName getTableName() {
        return tableName_;
    }

    public TDescribeOutputStyle getOutputStyle() {
        return outputStyle_;
    }

    /**
     * Get the privilege requirement, which depends on the output style.
     */
    private Privilege getPrivilegeRequirement() {
        switch (outputStyle_) {
        case MINIMAL:
            return Privilege.ANY;
        case FORMATTED:
        case EXTENDED:
            return Privilege.VIEW_METADATA;
        default:
            Preconditions.checkArgument(false);
            return null;
        }
    }

    @Override
    public void analyze(Analyzer analyzer) throws AnalysisException {
        try {
            path_ = analyzer.resolvePath(rawPath_, PathType.ANY);
        } catch (AnalysisException ae) {
            // Register privilege requests to prefer reporting an authorization error over
            // an analysis error. We should not accidentally reveal the non-existence of a
            // table/database if the user is not authorized.
            if (analyzer.hasMissingTbls())
                throw ae;
            if (rawPath_.size() > 1) {
                analyzer.registerPrivReq(new PrivilegeRequestBuilder().onTable(rawPath_.get(0), rawPath_.get(1))
                        .allOf(getPrivilegeRequirement()).toRequest());
            }
            analyzer.registerPrivReq(new PrivilegeRequestBuilder().onTable(analyzer.getDefaultDb(), rawPath_.get(0))
                    .allOf(getPrivilegeRequirement()).toRequest());
            throw ae;
        } catch (TableLoadingException tle) {
            throw new AnalysisException(tle.getMessage(), tle);
        }

        tableName_ = analyzer.getFqTableName(path_.getRootTable().getTableName());
        analyzer.getTable(tableName_, getPrivilegeRequirement());

        if (path_.destTable() != null) {
            resultStruct_ = path_.getRootTable().getHiveColumnsAsStruct();
        } else if (path_.destType().isComplexType()) {
            if (outputStyle_ == TDescribeOutputStyle.FORMATTED || outputStyle_ == TDescribeOutputStyle.EXTENDED) {
                throw new AnalysisException("DESCRIBE FORMATTED|EXTENDED must refer to a table");
            }
            Preconditions.checkState(outputStyle_ == TDescribeOutputStyle.MINIMAL);
            resultStruct_ = Path.getTypeAsStruct(path_.destType());
        } else {
            throw new AnalysisException("Cannot describe path '" + Strings.join(rawPath_, ".")
                    + "' targeting scalar type: " + path_.destType().toSql());
        }
    }

    public TDescribeTableParams toThrift() {
        TDescribeTableParams params = new TDescribeTableParams();
        params.setTable_name(getTableName().getTbl());
        params.setDb(getTableName().getDb());
        params.setOutput_style(outputStyle_);
        params.setResult_struct(resultStruct_.toThrift());
        return params;
    }
}