Back to home page

OSCL-LXR

 
 

    


0001 /**
0002  * Licensed to the Apache Software Foundation (ASF) under one
0003  * or more contributor license agreements.  See the NOTICE file
0004  * distributed with this work for additional information
0005  * regarding copyright ownership.  The ASF licenses this file
0006  * to you under the Apache License, Version 2.0 (the
0007  * "License"); you may not use this file except in compliance
0008  * with the License.  You may obtain a copy of the License at
0009  *
0010  *     http://www.apache.org/licenses/LICENSE-2.0
0011  *
0012  * Unless required by applicable law or agreed to in writing, software
0013  * distributed under the License is distributed on an "AS IS" BASIS,
0014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0015  * See the License for the specific language governing permissions and
0016  * limitations under the License.
0017  */
0018 
0019 package org.apache.hive.service.cli.operation;
0020 
0021 import java.sql.DatabaseMetaData;
0022 import java.util.ArrayList;
0023 import java.util.Collections;
0024 import java.util.HashMap;
0025 import java.util.List;
0026 import java.util.Map;
0027 import java.util.Map.Entry;
0028 import java.util.regex.Pattern;
0029 
0030 import org.apache.hadoop.hive.metastore.IMetaStoreClient;
0031 import org.apache.hadoop.hive.metastore.api.Table;
0032 import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveOperationType;
0033 import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject;
0034 import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject.HivePrivilegeObjectType;
0035 import org.apache.hive.service.cli.ColumnDescriptor;
0036 import org.apache.hive.service.cli.FetchOrientation;
0037 import org.apache.hive.service.cli.HiveSQLException;
0038 import org.apache.hive.service.cli.OperationState;
0039 import org.apache.hive.service.cli.OperationType;
0040 import org.apache.hive.service.cli.RowSet;
0041 import org.apache.hive.service.cli.RowSetFactory;
0042 import org.apache.hive.service.cli.TableSchema;
0043 import org.apache.hive.service.cli.Type;
0044 import org.apache.hive.service.cli.session.HiveSession;
0045 
0046 /**
0047  * GetColumnsOperation.
0048  *
0049  */
0050 public class GetColumnsOperation extends MetadataOperation {
0051 
0052   protected static final TableSchema RESULT_SET_SCHEMA = new TableSchema()
0053   .addPrimitiveColumn("TABLE_CAT", Type.STRING_TYPE,
0054       "Catalog name. NULL if not applicable")
0055   .addPrimitiveColumn("TABLE_SCHEM", Type.STRING_TYPE,
0056       "Schema name")
0057   .addPrimitiveColumn("TABLE_NAME", Type.STRING_TYPE,
0058       "Table name")
0059   .addPrimitiveColumn("COLUMN_NAME", Type.STRING_TYPE,
0060       "Column name")
0061   .addPrimitiveColumn("DATA_TYPE", Type.INT_TYPE,
0062       "SQL type from java.sql.Types")
0063   .addPrimitiveColumn("TYPE_NAME", Type.STRING_TYPE,
0064       "Data source dependent type name, for a UDT the type name is fully qualified")
0065   .addPrimitiveColumn("COLUMN_SIZE", Type.INT_TYPE,
0066       "Column size. For char or date types this is the maximum number of characters,"
0067       + " for numeric or decimal types this is precision.")
0068   .addPrimitiveColumn("BUFFER_LENGTH", Type.TINYINT_TYPE,
0069       "Unused")
0070   .addPrimitiveColumn("DECIMAL_DIGITS", Type.INT_TYPE,
0071       "The number of fractional digits")
0072   .addPrimitiveColumn("NUM_PREC_RADIX", Type.INT_TYPE,
0073       "Radix (typically either 10 or 2)")
0074   .addPrimitiveColumn("NULLABLE", Type.INT_TYPE,
0075       "Is NULL allowed")
0076   .addPrimitiveColumn("REMARKS", Type.STRING_TYPE,
0077       "Comment describing column (may be null)")
0078   .addPrimitiveColumn("COLUMN_DEF", Type.STRING_TYPE,
0079       "Default value (may be null)")
0080   .addPrimitiveColumn("SQL_DATA_TYPE", Type.INT_TYPE,
0081       "Unused")
0082   .addPrimitiveColumn("SQL_DATETIME_SUB", Type.INT_TYPE,
0083       "Unused")
0084   .addPrimitiveColumn("CHAR_OCTET_LENGTH", Type.INT_TYPE,
0085       "For char types the maximum number of bytes in the column")
0086   .addPrimitiveColumn("ORDINAL_POSITION", Type.INT_TYPE,
0087       "Index of column in table (starting at 1)")
0088   .addPrimitiveColumn("IS_NULLABLE", Type.STRING_TYPE,
0089       "\"NO\" means column definitely does not allow NULL values; "
0090       + "\"YES\" means the column might allow NULL values. An empty "
0091       + "string means nobody knows.")
0092   .addPrimitiveColumn("SCOPE_CATALOG", Type.STRING_TYPE,
0093       "Catalog of table that is the scope of a reference attribute "
0094       + "(null if DATA_TYPE isn't REF)")
0095   .addPrimitiveColumn("SCOPE_SCHEMA", Type.STRING_TYPE,
0096       "Schema of table that is the scope of a reference attribute "
0097       + "(null if the DATA_TYPE isn't REF)")
0098   .addPrimitiveColumn("SCOPE_TABLE", Type.STRING_TYPE,
0099       "Table name that this the scope of a reference attribure "
0100       + "(null if the DATA_TYPE isn't REF)")
0101   .addPrimitiveColumn("SOURCE_DATA_TYPE", Type.SMALLINT_TYPE,
0102       "Source type of a distinct type or user-generated Ref type, "
0103       + "SQL type from java.sql.Types (null if DATA_TYPE isn't DISTINCT or user-generated REF)")
0104   .addPrimitiveColumn("IS_AUTO_INCREMENT", Type.STRING_TYPE,
0105       "Indicates whether this column is auto incremented.");
0106 
0107   private final String catalogName;
0108   private final String schemaName;
0109   private final String tableName;
0110   private final String columnName;
0111 
0112   protected final RowSet rowSet;
0113 
0114   protected GetColumnsOperation(HiveSession parentSession, String catalogName, String schemaName,
0115       String tableName, String columnName) {
0116     super(parentSession, OperationType.GET_COLUMNS);
0117     this.catalogName = catalogName;
0118     this.schemaName = schemaName;
0119     this.tableName = tableName;
0120     this.columnName = columnName;
0121     this.rowSet = RowSetFactory.create(RESULT_SET_SCHEMA, getProtocolVersion());
0122   }
0123 
0124   @Override
0125   public void runInternal() throws HiveSQLException {
0126     setState(OperationState.RUNNING);
0127     try {
0128       IMetaStoreClient metastoreClient = getParentSession().getMetaStoreClient();
0129       String schemaPattern = convertSchemaPattern(schemaName);
0130       String tablePattern = convertIdentifierPattern(tableName, true);
0131 
0132       Pattern columnPattern = null;
0133       if (columnName != null) {
0134         columnPattern = Pattern.compile(convertIdentifierPattern(columnName, false));
0135       }
0136 
0137       List<String> dbNames = metastoreClient.getDatabases(schemaPattern);
0138       Collections.sort(dbNames);
0139       Map<String, List<String>> db2Tabs = new HashMap<>();
0140 
0141       for (String dbName : dbNames) {
0142         List<String> tableNames = metastoreClient.getTables(dbName, tablePattern);
0143         Collections.sort(tableNames);
0144         db2Tabs.put(dbName, tableNames);
0145       }
0146 
0147       if (isAuthV2Enabled()) {
0148         List<HivePrivilegeObject> privObjs = getPrivObjs(db2Tabs);
0149         String cmdStr = "catalog : " + catalogName + ", schemaPattern : " + schemaName
0150             + ", tablePattern : " + tableName;
0151         authorizeMetaGets(HiveOperationType.GET_COLUMNS, privObjs, cmdStr);
0152       }
0153 
0154       for (Entry<String, List<String>> dbTabs : db2Tabs.entrySet()) {
0155         String dbName = dbTabs.getKey();
0156         List<String> tableNames = dbTabs.getValue();
0157         for (Table table : metastoreClient.getTableObjectsByName(dbName, tableNames)) {
0158           TableSchema schema = new TableSchema(metastoreClient.getSchema(dbName, table.getTableName()));
0159           for (ColumnDescriptor column : schema.getColumnDescriptors()) {
0160             if (columnPattern != null && !columnPattern.matcher(column.getName()).matches()) {
0161               continue;
0162             }
0163             Object[] rowData = new Object[] {
0164                 null,  // TABLE_CAT
0165                 table.getDbName(), // TABLE_SCHEM
0166                 table.getTableName(), // TABLE_NAME
0167                 column.getName(), // COLUMN_NAME
0168                 column.getType().toJavaSQLType(), // DATA_TYPE
0169                 column.getTypeName(), // TYPE_NAME
0170                 column.getTypeDescriptor().getColumnSize(), // COLUMN_SIZE
0171                 null, // BUFFER_LENGTH, unused
0172                 column.getTypeDescriptor().getDecimalDigits(), // DECIMAL_DIGITS
0173                 column.getType().getNumPrecRadix(), // NUM_PREC_RADIX
0174                 DatabaseMetaData.columnNullable, // NULLABLE
0175                 column.getComment(), // REMARKS
0176                 null, // COLUMN_DEF
0177                 null, // SQL_DATA_TYPE
0178                 null, // SQL_DATETIME_SUB
0179                 null, // CHAR_OCTET_LENGTH
0180                 column.getOrdinalPosition(), // ORDINAL_POSITION
0181                 "YES", // IS_NULLABLE
0182                 null, // SCOPE_CATALOG
0183                 null, // SCOPE_SCHEMA
0184                 null, // SCOPE_TABLE
0185                 null, // SOURCE_DATA_TYPE
0186                 "NO", // IS_AUTO_INCREMENT
0187             };
0188             rowSet.addRow(rowData);
0189           }
0190         }
0191       }
0192       setState(OperationState.FINISHED);
0193     } catch (Exception e) {
0194       setState(OperationState.ERROR);
0195       throw new HiveSQLException(e);
0196     }
0197 
0198   }
0199 
0200 
0201   private List<HivePrivilegeObject> getPrivObjs(Map<String, List<String>> db2Tabs) {
0202     List<HivePrivilegeObject> privObjs = new ArrayList<>();
0203     for (Entry<String, List<String>> dbTabs : db2Tabs.entrySet()) {
0204       for (String tabName : dbTabs.getValue()) {
0205         privObjs.add(new HivePrivilegeObject(HivePrivilegeObjectType.TABLE_OR_VIEW, dbTabs.getKey(),
0206             tabName));
0207       }
0208     }
0209     return privObjs;
0210   }
0211 
0212   /* (non-Javadoc)
0213    * @see org.apache.hive.service.cli.Operation#getResultSetSchema()
0214    */
0215   @Override
0216   public TableSchema getResultSetSchema() throws HiveSQLException {
0217     assertState(OperationState.FINISHED);
0218     return RESULT_SET_SCHEMA;
0219   }
0220 
0221   /* (non-Javadoc)
0222    * @see org.apache.hive.service.cli.Operation#getNextRowSet(org.apache.hive.service.cli.FetchOrientation, long)
0223    */
0224   @Override
0225   public RowSet getNextRowSet(FetchOrientation orientation, long maxRows) throws HiveSQLException {
0226     assertState(OperationState.FINISHED);
0227     validateDefaultFetchOrientation(orientation);
0228     if (orientation.equals(FetchOrientation.FETCH_FIRST)) {
0229       rowSet.setStartOffset(0);
0230     }
0231     return rowSet.extractSubset((int)maxRows);
0232   }
0233 
0234 }