org.apache.impala.catalog.IncompleteTable.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.impala.catalog.IncompleteTable.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 org.apache.impala.catalog;

import java.util.List;
import java.util.Set;

import org.apache.hadoop.hive.metastore.IMetaStoreClient;

import org.apache.impala.common.ImpalaException;
import org.apache.impala.common.JniUtil;
import org.apache.impala.thrift.TCatalogObjectType;
import org.apache.impala.thrift.TErrorCode;
import org.apache.impala.thrift.TStatus;
import org.apache.impala.thrift.TTable;
import org.apache.impala.thrift.TTableDescriptor;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;

/**
 * Represents a table with incomplete metadata. The metadata may be incomplete because
 * it has not yet been loaded or because of errors encountered during the loading
 * process.
 */
public class IncompleteTable extends Table {
    // The cause for the incomplete metadata. If there is no cause given (cause_ = null),
    // then this is assumed to be an uninitialized table (table that does not have
    // its metadata loaded).
    private ImpalaException cause_;

    private IncompleteTable(Db db, String name, ImpalaException cause) {
        super(null, db, name, null);
        cause_ = cause;
    }

    /**
     * Returns the cause (ImpalaException) which led to this table's metadata being
     * incomplete.
     */
    public ImpalaException getCause() {
        return cause_;
    }

    /**
     * See comment on cause_.
     */
    @Override
    public boolean isLoaded() {
        return cause_ != null;
    }

    @Override
    public TCatalogObjectType getCatalogObjectType() {
        return TCatalogObjectType.TABLE;
    }

    @Override
    public TTableDescriptor toThriftDescriptor(int tableId, Set<Long> referencedPartitions) {
        throw new IllegalStateException(cause_);
    }

    @Override
    public void load(boolean reuseMetadata, IMetaStoreClient client,
            org.apache.hadoop.hive.metastore.api.Table msTbl) throws TableLoadingException {
        if (cause_ instanceof TableLoadingException) {
            throw (TableLoadingException) cause_;
        } else {
            throw new TableLoadingException("Table metadata incomplete: ", cause_);
        }
    }

    @Override
    public TTable toThrift() {
        TTable table = new TTable(db_.getName(), name_);
        if (cause_ != null) {
            table.setLoad_status(new TStatus(TErrorCode.INTERNAL_ERROR,
                    Lists.newArrayList(JniUtil.throwableToString(cause_), JniUtil.throwableToStackTrace(cause_))));
        }
        return table;
    }

    @Override
    protected void loadFromThrift(TTable thriftTable) throws TableLoadingException {
        if (thriftTable.isSetLoad_status()) {
            // Since the load status is set, it indicates the table is incomplete due to
            // an error loading the table metadata. The error message in the load status
            // should provide details on why. By convention, the final error message should
            // be the remote (Catalog Server) call stack. This shouldn't be displayed to the
            // user under normal circumstances, but needs to be recorded somewhere so append
            // it to the call stack of the local TableLoadingException created here.
            // TODO: Provide a mechanism (query option?) to optionally allow returning more
            // detailed errors (including the full call stack(s)) to the user.
            List<String> errorMsgs = thriftTable.getLoad_status().getError_msgs();
            String callStackStr = "<None available>";
            if (errorMsgs.size() > 1)
                callStackStr = errorMsgs.remove(errorMsgs.size() - 1);

            String errorMsg = Joiner.on("\n").join(errorMsgs);
            // The errorMsg will always be prefixed with "ExceptionClassName: ". Since we treat
            // all errors as TableLoadingExceptions, the prefix "TableLoadingException" is
            // redundant and can be stripped out.
            errorMsg = errorMsg.replaceFirst("^TableLoadingException: ", "");
            TableLoadingException loadingException = new TableLoadingException(errorMsg);
            List<StackTraceElement> stackTrace = Lists.newArrayList(loadingException.getStackTrace());
            stackTrace.add(
                    new StackTraceElement("========", "<Remote stack trace on catalogd>: " + callStackStr, "", -1));
            loadingException.setStackTrace(stackTrace.toArray(new StackTraceElement[stackTrace.size()]));
            this.cause_ = loadingException;
        }
    }

    public static IncompleteTable createUninitializedTable(Db db, String name) {
        return new IncompleteTable(db, name, null);
    }

    public static IncompleteTable createFailedMetadataLoadTable(Db db, String name, ImpalaException e) {
        return new IncompleteTable(db, name, e);
    }
}