/** * 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.hadoop.hive.ql.metadata; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import com.google.common.base.Preconditions; import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hive.common.FileUtils; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.conf.HiveConf.ConfVars; import org.apache.hadoop.hive.metastore.MetaStoreUtils; import org.apache.hadoop.hive.metastore.TableType; import org.apache.hadoop.hive.metastore.api.FieldSchema; import org.apache.hadoop.hive.metastore.api.MetaException; import org.apache.hadoop.hive.metastore.api.Order; import org.apache.hadoop.hive.metastore.api.SerDeInfo; import org.apache.hadoop.hive.metastore.api.SkewedInfo; import org.apache.hadoop.hive.metastore.api.StorageDescriptor; import org.apache.hadoop.hive.metastore.api.hive_metastoreConstants; import org.apache.hadoop.hive.ql.exec.Utilities; import org.apache.hadoop.hive.ql.io.HiveFileFormatUtils; import org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat; import org.apache.hadoop.hive.ql.parse.BaseSemanticAnalyzer.TableSpec; import org.apache.hadoop.hive.ql.parse.SemanticAnalyzer; import org.apache.hadoop.hive.ql.parse.SemanticException; import org.apache.hadoop.hive.ql.session.SessionState; import org.apache.hadoop.hive.serde.serdeConstants; import org.apache.hadoop.hive.serde2.AbstractSerDe; import org.apache.hadoop.hive.serde2.Deserializer; import org.apache.hadoop.hive.serde2.MetadataTypedColumnsetSerDe; import org.apache.hadoop.hive.serde2.SerDeException; import org.apache.hadoop.hive.serde2.objectinspector.StructField; import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector; import org.apache.hadoop.io.Writable; import org.apache.hadoop.io.WritableComparable; import org.apache.hadoop.mapred.InputFormat; import org.apache.hadoop.mapred.OutputFormat; import org.apache.hadoop.mapred.SequenceFileInputFormat; import org.apache.hive.common.util.ReflectionUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A Hive Table: is a fundamental unit of data in Hive that shares a common schema/DDL. * * Please note that the ql code should always go through methods of this class to access the * metadata, instead of directly accessing org.apache.hadoop.hive.metastore.api.Table. This * helps to isolate the metastore code and the ql code. */ public class Table implements Serializable { private static final long serialVersionUID = 1L; static final private Logger LOG = LoggerFactory.getLogger("hive.ql.metadata.Table"); private org.apache.hadoop.hive.metastore.api.Table tTable; /** * These fields are all cached fields. The information comes from tTable. */ private Deserializer deserializer; private Class<? extends OutputFormat> outputFormatClass; private Class<? extends InputFormat> inputFormatClass; private Path path; private transient HiveStorageHandler storageHandler; private transient TableSpec tableSpec; private transient boolean materializedTable; /** * Used only for serialization. */ public Table() { } public Table(org.apache.hadoop.hive.metastore.api.Table table) { initialize(table); } // Do initialization here, so as to keep the ctor minimal. protected void initialize(org.apache.hadoop.hive.metastore.api.Table table) { tTable = table; // Note that we do not set up fields like inputFormatClass, outputFormatClass // and deserializer because the Partition needs to be accessed from across // the metastore side as well, which will result in attempting to load // the class associated with them, which might not be available, and // the main reason to instantiate them would be to pre-cache them for // performance. Since those fields are null/cache-check by their accessors // anyway, that's not a concern. } public Table(String databaseName, String tableName) { this(getEmptyTable(databaseName, tableName)); } public boolean isDummyTable() { return tTable.getTableName().equals(SemanticAnalyzer.DUMMY_TABLE); } /** * This function should only be used in serialization. * We should never call this function to modify the fields, because * the cached fields will become outdated. */ public org.apache.hadoop.hive.metastore.api.Table getTTable() { return tTable; } /** * This function should only be called by Java serialization. */ public void setTTable(org.apache.hadoop.hive.metastore.api.Table tTable) { this.tTable = tTable; } /** * Initialize an empty table. */ public static org.apache.hadoop.hive.metastore.api.Table getEmptyTable(String databaseName, String tableName) { StorageDescriptor sd = new StorageDescriptor(); { sd.setSerdeInfo(new SerDeInfo()); sd.setNumBuckets(-1); sd.setBucketCols(new ArrayList<String>()); sd.setCols(new ArrayList<FieldSchema>()); sd.setParameters(new HashMap<String, String>()); sd.setSortCols(new ArrayList<Order>()); sd.getSerdeInfo().setParameters(new HashMap<String, String>()); // We have to use MetadataTypedColumnsetSerDe because LazySimpleSerDe does // not support a table with no columns. sd.getSerdeInfo().setSerializationLib(MetadataTypedColumnsetSerDe.class.getName()); sd.getSerdeInfo().getParameters().put(serdeConstants.SERIALIZATION_FORMAT, "1"); sd.setInputFormat(SequenceFileInputFormat.class.getName()); sd.setOutputFormat(HiveSequenceFileOutputFormat.class.getName()); SkewedInfo skewInfo = new SkewedInfo(); skewInfo.setSkewedColNames(new ArrayList<String>()); skewInfo.setSkewedColValues(new ArrayList<List<String>>()); skewInfo.setSkewedColValueLocationMaps(new HashMap<List<String>, String>()); sd.setSkewedInfo(skewInfo); } org.apache.hadoop.hive.metastore.api.Table t = new org.apache.hadoop.hive.metastore.api.Table(); { t.setSd(sd); t.setPartitionKeys(new ArrayList<FieldSchema>()); t.setParameters(new HashMap<String, String>()); t.setTableType(TableType.MANAGED_TABLE.toString()); t.setDbName(databaseName); t.setTableName(tableName); t.setOwner(SessionState.getUserFromAuthenticator()); // set create time t.setCreateTime((int) (System.currentTimeMillis() / 1000)); } return t; } public void checkValidity(Configuration conf) throws HiveException { // check for validity String name = tTable.getTableName(); if (null == name || name.length() == 0 || !MetaStoreUtils.validateName(name, conf)) { throw new HiveException("[" + name + "]: is not a valid table name"); } if (0 == getCols().size()) { throw new HiveException( "at least one column must be specified for the table"); } if (!isView()) { if (null == getDeserializerFromMetaStore(false)) { throw new HiveException("must specify a non-null serDe"); } if (null == getInputFormatClass()) { throw new HiveException("must specify an InputFormat class"); } if (null == getOutputFormatClass()) { throw new HiveException("must specify an OutputFormat class"); } } if (isView()) { assert (getViewOriginalText() != null); assert (getViewExpandedText() != null); } else if (isMaterializedView()) { assert(getViewOriginalText() != null); assert(getViewExpandedText() == null); } else { assert(getViewOriginalText() == null); assert(getViewExpandedText() == null); } validateColumns(getCols(), getPartCols()); } public StorageDescriptor getSd() { return tTable.getSd(); } public void setInputFormatClass(Class<? extends InputFormat> inputFormatClass) { this.inputFormatClass = inputFormatClass; tTable.getSd().setInputFormat(inputFormatClass.getName()); } public void setOutputFormatClass(Class<? extends OutputFormat> outputFormatClass) { this.outputFormatClass = outputFormatClass; tTable.getSd().setOutputFormat(outputFormatClass.getName()); } final public Properties getMetadata() { return MetaStoreUtils.getTableMetadata(tTable); } final public Path getPath() { String location = tTable.getSd().getLocation(); if (location == null) { return null; } return new Path(location); } final public String getTableName() { return tTable.getTableName(); } final public Path getDataLocation() { if (path == null) { path = getPath(); } return path; } final public Deserializer getDeserializer() { if (deserializer == null) { deserializer = getDeserializerFromMetaStore(false); } return deserializer; } final public Class<? extends Deserializer> getDeserializerClass() throws Exception { return MetaStoreUtils.getDeserializerClass(SessionState.getSessionConf(), tTable); } final public Deserializer getDeserializer(boolean skipConfError) { if (deserializer == null) { deserializer = getDeserializerFromMetaStore(skipConfError); } return deserializer; } final public Deserializer getDeserializerFromMetaStore(boolean skipConfError) { try { return MetaStoreUtils.getDeserializer(SessionState.getSessionConf(), tTable, skipConfError); } catch (MetaException e) { throw new RuntimeException(e); } } public HiveStorageHandler getStorageHandler() { if (storageHandler != null || !isNonNative()) { return storageHandler; } try { storageHandler = HiveUtils.getStorageHandler( SessionState.getSessionConf(), getProperty( org.apache.hadoop.hive.metastore.api.hive_metastoreConstants.META_TABLE_STORAGE)); } catch (Exception e) { throw new RuntimeException(e); } return storageHandler; } final public Class<? extends InputFormat> getInputFormatClass() { if (inputFormatClass == null) { try { String className = tTable.getSd().getInputFormat(); if (className == null) { if (getStorageHandler() == null) { return null; } inputFormatClass = getStorageHandler().getInputFormatClass(); } else { inputFormatClass = (Class<? extends InputFormat>) Class.forName(className, true, Utilities.getSessionSpecifiedClassLoader()); } } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } return inputFormatClass; } final public Class<? extends OutputFormat> getOutputFormatClass() { if (outputFormatClass == null) { try { String className = tTable.getSd().getOutputFormat(); Class<?> c; if (className == null) { if (getStorageHandler() == null) { return null; } c = getStorageHandler().getOutputFormatClass(); } else { c = Class.forName(className, true, Utilities.getSessionSpecifiedClassLoader()); } // Replace FileOutputFormat for backward compatibility outputFormatClass = HiveFileFormatUtils.getOutputFormatSubstitute(c); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } return outputFormatClass; } public boolean isMaterializedTable() { return materializedTable; } public void setMaterializedTable(boolean materializedTable) { this.materializedTable = materializedTable; } /** * Marker SemanticException, so that processing that allows for table validation failures * and appropriately handles them can recover from these types of SemanticExceptions */ public class ValidationFailureSemanticException extends SemanticException{ public ValidationFailureSemanticException(String s) { super(s); } }; final public void validatePartColumnNames( Map<String, String> spec, boolean shouldBeFull) throws SemanticException { List<FieldSchema> partCols = tTable.getPartitionKeys(); if (partCols == null || (partCols.size() == 0)) { if (spec != null) { throw new ValidationFailureSemanticException("table is not partitioned but partition spec exists: " + spec); } return; } else if (spec == null) { if (shouldBeFull) { throw new ValidationFailureSemanticException("table is partitioned but partition spec is not specified"); } return; } int columnsFound = 0; for (FieldSchema fs : partCols) { if (spec.containsKey(fs.getName())) { ++columnsFound; } if (columnsFound == spec.size()) break; } if (columnsFound < spec.size()) { throw new ValidationFailureSemanticException("Partition spec " + spec + " contains non-partition columns"); } if (shouldBeFull && (spec.size() != partCols.size())) { throw new ValidationFailureSemanticException("partition spec " + spec + " doesn't contain all (" + partCols.size() + ") partition columns"); } } public void setProperty(String name, String value) { tTable.getParameters().put(name, value); } public void setParameters(Map<String, String> params) { tTable.setParameters(params); } public String getProperty(String name) { return tTable.getParameters().get(name); } public boolean isImmutable(){ return (tTable.getParameters().containsKey(hive_metastoreConstants.IS_IMMUTABLE) && tTable.getParameters().get(hive_metastoreConstants.IS_IMMUTABLE).equalsIgnoreCase("true")); } public void setTableType(TableType tableType) { tTable.setTableType(tableType.toString()); } public TableType getTableType() { return Enum.valueOf(TableType.class, tTable.getTableType()); } public ArrayList<StructField> getFields() { ArrayList<StructField> fields = new ArrayList<StructField>(); try { Deserializer decoder = getDeserializer(); // Expand out all the columns of the table StructObjectInspector structObjectInspector = (StructObjectInspector) decoder .getObjectInspector(); List<? extends StructField> fld_lst = structObjectInspector .getAllStructFieldRefs(); for (StructField field : fld_lst) { fields.add(field); } } catch (SerDeException e) { throw new RuntimeException(e); } return fields; } public StructField getField(String fld) { try { StructObjectInspector structObjectInspector = (StructObjectInspector) getDeserializer() .getObjectInspector(); return structObjectInspector.getStructFieldRef(fld); } catch (Exception e) { throw new RuntimeException(e); } } @Override public String toString() { return tTable.getTableName(); } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((tTable == null) ? 0 : tTable.hashCode()); return result; } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Table other = (Table) obj; if (tTable == null) { if (other.tTable != null) { return false; } } else if (!tTable.equals(other.tTable)) { return false; } return true; } public List<FieldSchema> getPartCols() { List<FieldSchema> partKeys = tTable.getPartitionKeys(); if (partKeys == null) { partKeys = new ArrayList<FieldSchema>(); tTable.setPartitionKeys(partKeys); } return partKeys; } public FieldSchema getPartColByName(String colName) { for (FieldSchema key : getPartCols()) { if (key.getName().toLowerCase().equals(colName)) { return key; } } return null; } public List<String> getPartColNames() { List<String> partColNames = new ArrayList<String>(); for (FieldSchema key : getPartCols()) { partColNames.add(key.getName()); } return partColNames; } public boolean isPartitionKey(String colName) { return getPartColByName(colName) == null ? false : true; } // TODO merge this with getBucketCols function public String getBucketingDimensionId() { List<String> bcols = tTable.getSd().getBucketCols(); if (bcols == null || bcols.size() == 0) { return null; } if (bcols.size() > 1) { LOG.warn(this + " table has more than one dimensions which aren't supported yet"); } return bcols.get(0); } public void setDataLocation(Path path) { this.path = path; tTable.getSd().setLocation(path.toString()); } public void unsetDataLocation() { this.path = null; tTable.getSd().unsetLocation(); } public void setBucketCols(List<String> bucketCols) throws HiveException { if (bucketCols == null) { return; } for (String col : bucketCols) { if (!isField(col)) { throw new HiveException("Bucket columns " + col + " is not part of the table columns (" + getCols() ); } } tTable.getSd().setBucketCols(bucketCols); } public void setSortCols(List<Order> sortOrder) throws HiveException { tTable.getSd().setSortCols(sortOrder); } public void setSkewedValueLocationMap(List<String> valList, String dirName) throws HiveException { Map<List<String>, String> mappings = tTable.getSd().getSkewedInfo() .getSkewedColValueLocationMaps(); if (null == mappings) { mappings = new HashMap<List<String>, String>(); tTable.getSd().getSkewedInfo().setSkewedColValueLocationMaps(mappings); } // Add or update new mapping mappings.put(valList, dirName); } public Map<List<String>,String> getSkewedColValueLocationMaps() { return (tTable.getSd().getSkewedInfo() != null) ? tTable.getSd().getSkewedInfo() .getSkewedColValueLocationMaps() : new HashMap<List<String>, String>(); } public void setSkewedColValues(List<List<String>> skewedValues) throws HiveException { tTable.getSd().getSkewedInfo().setSkewedColValues(skewedValues); } public List<List<String>> getSkewedColValues(){ return (tTable.getSd().getSkewedInfo() != null) ? tTable.getSd().getSkewedInfo() .getSkewedColValues() : new ArrayList<List<String>>(); } public void setSkewedColNames(List<String> skewedColNames) throws HiveException { tTable.getSd().getSkewedInfo().setSkewedColNames(skewedColNames); } public List<String> getSkewedColNames() { return (tTable.getSd().getSkewedInfo() != null) ? tTable.getSd().getSkewedInfo() .getSkewedColNames() : new ArrayList<String>(); } public SkewedInfo getSkewedInfo() { return tTable.getSd().getSkewedInfo(); } public void setSkewedInfo(SkewedInfo skewedInfo) throws HiveException { tTable.getSd().setSkewedInfo(skewedInfo); } public boolean isStoredAsSubDirectories() { return tTable.getSd().isStoredAsSubDirectories(); } public void setStoredAsSubDirectories(boolean storedAsSubDirectories) throws HiveException { tTable.getSd().setStoredAsSubDirectories(storedAsSubDirectories); } private boolean isField(String col) { for (FieldSchema field : getCols()) { if (field.getName().equals(col)) { return true; } } return false; } public List<FieldSchema> getCols() { return getColsInternal(false); } public List<FieldSchema> getColsForMetastore() { return getColsInternal(true); } private List<FieldSchema> getColsInternal(boolean forMs) { String serializationLib = getSerializationLib(); try { // Do the lightweight check for general case. if (hasMetastoreBasedSchema(SessionState.getSessionConf(), serializationLib)) { return tTable.getSd().getCols(); } else if (forMs && !shouldStoreFieldsInMetastore( SessionState.getSessionConf(), serializationLib, tTable.getParameters())) { return Hive.getFieldsFromDeserializerForMsStorage(this, getDeserializer()); } else { return MetaStoreUtils.getFieldsFromDeserializer(getTableName(), getDeserializer()); } } catch (Exception e) { LOG.error("Unable to get field from serde: " + serializationLib, e); } return new ArrayList<FieldSchema>(); } /** * Returns a list of all the columns of the table (data columns + partition * columns in that order. * * @return List<FieldSchema> */ public List<FieldSchema> getAllCols() { ArrayList<FieldSchema> f_list = new ArrayList<FieldSchema>(); f_list.addAll(getCols()); f_list.addAll(getPartCols()); return f_list; } public void setPartCols(List<FieldSchema> partCols) { tTable.setPartitionKeys(partCols); } public String getDbName() { return tTable.getDbName(); } public int getNumBuckets() { return tTable.getSd().getNumBuckets(); } public void setInputFormatClass(String name) throws HiveException { if (name == null) { inputFormatClass = null; tTable.getSd().setInputFormat(null); return; } try { setInputFormatClass((Class<? extends InputFormat<WritableComparable, Writable>>) Class .forName(name, true, Utilities.getSessionSpecifiedClassLoader())); } catch (ClassNotFoundException e) { throw new HiveException("Class not found: " + name, e); } } public void setOutputFormatClass(String name) throws HiveException { if (name == null) { outputFormatClass = null; tTable.getSd().setOutputFormat(null); return; } try { Class<?> origin = Class.forName(name, true, Utilities.getSessionSpecifiedClassLoader()); setOutputFormatClass(HiveFileFormatUtils.getOutputFormatSubstitute(origin)); } catch (ClassNotFoundException e) { throw new HiveException("Class not found: " + name, e); } } public boolean isPartitioned() { if (getPartCols() == null) { return false; } return (getPartCols().size() != 0); } public void setFields(List<FieldSchema> fields) { tTable.getSd().setCols(fields); } public void setNumBuckets(int nb) { tTable.getSd().setNumBuckets(nb); } /** * @return The owner of the table. * @see org.apache.hadoop.hive.metastore.api.Table#getOwner() */ public String getOwner() { return tTable.getOwner(); } /** * @return The table parameters. * @see org.apache.hadoop.hive.metastore.api.Table#getParameters() */ public Map<String, String> getParameters() { return tTable.getParameters(); } /** * @return The retention on the table. * @see org.apache.hadoop.hive.metastore.api.Table#getRetention() */ public int getRetention() { return tTable.getRetention(); } /** * @param owner * @see org.apache.hadoop.hive.metastore.api.Table#setOwner(java.lang.String) */ public void setOwner(String owner) { tTable.setOwner(owner); } /** * @param retention * @see org.apache.hadoop.hive.metastore.api.Table#setRetention(int) */ public void setRetention(int retention) { tTable.setRetention(retention); } private SerDeInfo getSerdeInfo() { return tTable.getSd().getSerdeInfo(); } public void setSerializationLib(String lib) { getSerdeInfo().setSerializationLib(lib); } public String getSerializationLib() { return getSerdeInfo().getSerializationLib(); } public String getSerdeParam(String param) { return getSerdeInfo().getParameters().get(param); } public String setSerdeParam(String param, String value) { return getSerdeInfo().getParameters().put(param, value); } public List<String> getBucketCols() { return tTable.getSd().getBucketCols(); } public List<Order> getSortCols() { return tTable.getSd().getSortCols(); } public void setTableName(String tableName) { tTable.setTableName(tableName); } public void setDbName(String databaseName) { tTable.setDbName(databaseName); } public List<FieldSchema> getPartitionKeys() { return tTable.getPartitionKeys(); } /** * @return the original view text, or null if this table is not a view */ public String getViewOriginalText() { return tTable.getViewOriginalText(); } /** * @param viewOriginalText * the original view text to set */ public void setViewOriginalText(String viewOriginalText) { tTable.setViewOriginalText(viewOriginalText); } /** * @return the expanded view text, or null if this table is not a view */ public String getViewExpandedText() { return tTable.getViewExpandedText(); } /** * @param viewExpandedText * the expanded view text to set */ public void setViewExpandedText(String viewExpandedText) { tTable.setViewExpandedText(viewExpandedText); } /** * @return whether this view can be used for rewriting queries */ public boolean isRewriteEnabled() { return tTable.isRewriteEnabled(); } /** * @param rewriteEnabled * whether this view can be used for rewriting queries */ public void setRewriteEnabled(boolean rewriteEnabled) { tTable.setRewriteEnabled(rewriteEnabled); } public void clearSerDeInfo() { tTable.getSd().getSerdeInfo().getParameters().clear(); } /** * @return whether this table is actually a view */ public boolean isView() { return TableType.VIRTUAL_VIEW.equals(getTableType()); } public boolean isMaterializedView() { return TableType.MATERIALIZED_VIEW.equals(getTableType()); } /** * @return whether this table is actually an index table */ public boolean isIndexTable() { return TableType.INDEX_TABLE.equals(getTableType()); } /** * Creates a partition name -> value spec map object * * @param tp * Use the information from this partition. * @return Partition name to value mapping. */ public LinkedHashMap<String, String> createSpec( org.apache.hadoop.hive.metastore.api.Partition tp) { List<FieldSchema> fsl = getPartCols(); List<String> tpl = tp.getValues(); LinkedHashMap<String, String> spec = new LinkedHashMap<String, String>(fsl.size()); for (int i = 0; i < fsl.size(); i++) { FieldSchema fs = fsl.get(i); String value = tpl.get(i); spec.put(fs.getName(), value); } return spec; } public Table copy() throws HiveException { return new Table(tTable.deepCopy()); } public int getCreateTime() { return tTable.getCreateTime(); } public void setCreateTime(int createTime) { tTable.setCreateTime(createTime); } public int getLastAccessTime() { return tTable.getLastAccessTime(); } public void setLastAccessTime(int lastAccessTime) { tTable.setLastAccessTime(lastAccessTime); } public boolean isNonNative() { return getProperty( org.apache.hadoop.hive.metastore.api.hive_metastoreConstants.META_TABLE_STORAGE) != null; } /** * @return include the db name */ public String getCompleteName() { return getCompleteName(getDbName(), getTableName()); } public static String getCompleteName(String dbName, String tabName) { return dbName + "@" + tabName; } @SuppressWarnings("nls") public FileStatus[] getSortedPaths() { try { // Previously, this got the filesystem of the Table, which could be // different from the filesystem of the partition. FileSystem fs = FileSystem.get(getPath().toUri(), SessionState.getSessionConf()); String pathPattern = getPath().toString(); if (getNumBuckets() > 0) { pathPattern = pathPattern + "/*"; } LOG.info("Path pattern = " + pathPattern); FileStatus srcs[] = fs.globStatus(new Path(pathPattern), FileUtils.HIDDEN_FILES_PATH_FILTER); Arrays.sort(srcs); for (FileStatus src : srcs) { LOG.info("Got file: " + src.getPath()); } if (srcs.length == 0) { return null; } return srcs; } catch (Exception e) { throw new RuntimeException("Cannot get path ", e); } } public boolean isEmpty() throws HiveException { Preconditions.checkNotNull(getPath()); try { FileSystem fs = FileSystem.get(getPath().toUri(), SessionState.getSessionConf()); return !fs.exists(getPath()) || fs.listStatus(getPath(), FileUtils.HIDDEN_FILES_PATH_FILTER).length == 0; } catch (IOException e) { throw new HiveException(e); } } public boolean isTemporary() { return tTable.isTemporary(); } public static boolean hasMetastoreBasedSchema(HiveConf conf, String serdeLib) { return StringUtils.isEmpty(serdeLib) || conf.getStringCollection(ConfVars.SERDESUSINGMETASTOREFORSCHEMA.varname).contains(serdeLib); } public static boolean shouldStoreFieldsInMetastore( HiveConf conf, String serdeLib, Map<String, String> tableParams) { if (hasMetastoreBasedSchema(conf, serdeLib)) return true; // Table may or may not be using metastore. Only the SerDe can tell us. AbstractSerDe deserializer = null; try { Class<?> clazz = conf.getClassByName(serdeLib); if (!AbstractSerDe.class.isAssignableFrom(clazz)) return true; // The default. deserializer = ReflectionUtil.newInstance( conf.getClassByName(serdeLib).asSubclass(AbstractSerDe.class), conf); } catch (Exception ex) { LOG.warn("Cannot initialize SerDe: " + serdeLib + ", ignoring", ex); return true; } return deserializer.shouldStoreFieldsInMetastore(tableParams); } public static void validateColumns(List<FieldSchema> columns, List<FieldSchema> partCols) throws HiveException { Set<String> colNames = new HashSet<>(); for (FieldSchema partCol: columns) { String colName = normalize(partCol.getName()); if (colNames.contains(colName)) { throw new HiveException("Duplicate column name " + colName + " in the table definition."); } colNames.add(colName); } if (partCols != null) { // there is no overlap between columns and partitioning columns for (FieldSchema partCol: partCols) { String colName = normalize(partCol.getName()); if (colNames.contains(colName)) { throw new HiveException("Partition column name " + colName + " conflicts with table columns."); } } } } private static String normalize(String colName) throws HiveException { if (!MetaStoreUtils.validateColumnName(colName)) { throw new HiveException("Invalid column name '" + colName + "' in the table definition"); } return colName.toLowerCase(); } public TableSpec getTableSpec() { return tableSpec; } public void setTableSpec(TableSpec tableSpec) { this.tableSpec = tableSpec; } public boolean hasDeserializer() { return deserializer != null; } };