Author: thejas
Date: Thu Jul 31 16:19:23 2014
New Revision: 1614931

URL: http://svn.apache.org/r1614931
Log:
HIVE-7488 : pass column names being used for inputs to authorization api 
(Thejas Nair reviewed by Jason Dere, Navis)

Added:
    
hive/trunk/itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/authorization/
    
hive/trunk/itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/authorization/plugin/
    
hive/trunk/itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/authorization/plugin/TestHiveAuthorizerCheckInvocation.java
Modified:
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/Driver.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/Table.java
    hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
    
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationUtils.java
    
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrivilegeObject.java
    
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveV1Authorizer.java

Added: 
hive/trunk/itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/authorization/plugin/TestHiveAuthorizerCheckInvocation.java
URL: 
http://svn.apache.org/viewvc/hive/trunk/itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/authorization/plugin/TestHiveAuthorizerCheckInvocation.java?rev=1614931&view=auto
==============================================================================
--- 
hive/trunk/itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/authorization/plugin/TestHiveAuthorizerCheckInvocation.java
 (added)
+++ 
hive/trunk/itests/hive-unit/src/test/java/org/apache/hadoop/hive/ql/security/authorization/plugin/TestHiveAuthorizerCheckInvocation.java
 Thu Jul 31 16:19:23 2014
@@ -0,0 +1,177 @@
+/**
+ * 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.security.authorization.plugin;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.hadoop.hive.conf.HiveConf;
+import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
+import org.apache.hadoop.hive.ql.CommandNeedRetryException;
+import org.apache.hadoop.hive.ql.Driver;
+import org.apache.hadoop.hive.ql.processors.CommandProcessorResponse;
+import org.apache.hadoop.hive.ql.security.HiveAuthenticationProvider;
+import org.apache.hadoop.hive.ql.security.SessionStateUserAuthenticator;
+import 
org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject.HivePrivilegeObjectType;
+import org.apache.hadoop.hive.ql.session.SessionState;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+
+/**
+ * Test HiveAuthorizer api invocation
+ */
+public class TestHiveAuthorizerCheckInvocation {
+  protected static HiveConf conf;
+  protected static Driver driver;
+  private static final String tableName = 
TestHiveAuthorizerCheckInvocation.class.getSimpleName();
+  static HiveAuthorizer mockedAuthorizer;
+
+  /**
+   * This factory creates a mocked HiveAuthorizer class. Use the mocked class 
to
+   * capture the argument passed to it in the test case.
+   */
+  static class MockedHiveAuthorizerFactory implements HiveAuthorizerFactory {
+    @Override
+    public HiveAuthorizer createHiveAuthorizer(HiveMetastoreClientFactory 
metastoreClientFactory,
+        HiveConf conf, HiveAuthenticationProvider authenticator) {
+      TestHiveAuthorizerCheckInvocation.mockedAuthorizer = 
Mockito.mock(HiveAuthorizer.class);
+      return TestHiveAuthorizerCheckInvocation.mockedAuthorizer;
+    }
+
+  }
+
+  @BeforeClass
+  public static void beforeTest() throws Exception {
+    conf = new HiveConf();
+
+    // Turn on mocked authorization
+    conf.setVar(ConfVars.HIVE_AUTHORIZATION_MANAGER, 
MockedHiveAuthorizerFactory.class.getName());
+    conf.setVar(ConfVars.HIVE_AUTHENTICATOR_MANAGER, 
SessionStateUserAuthenticator.class.getName());
+    conf.setBoolVar(ConfVars.HIVE_AUTHORIZATION_ENABLED, true);
+    conf.setBoolVar(ConfVars.HIVE_SUPPORT_CONCURRENCY, false);
+    conf.setBoolVar(ConfVars.HIVE_SERVER2_ENABLE_DOAS, false);
+
+    SessionState.start(conf);
+    driver = new Driver(conf);
+    CommandProcessorResponse resp = driver.run("create table " + tableName
+        + " (i int, j int, k string) partitioned by (city string, date string) 
");
+    assertEquals(0, resp.getResponseCode());
+  }
+
+  @AfterClass
+  public static void afterTests() throws Exception {
+    driver.close();
+  }
+
+  @Test
+  public void testInputSomeColumnsUsed() throws HiveAuthzPluginException, 
HiveAccessControlException,
+      CommandNeedRetryException {
+
+    reset(mockedAuthorizer);
+    int status = driver.compile("select i from " + tableName
+        + " where k = 'X' and city = 'Scottsdale-AZ' ");
+    assertEquals(0, status);
+
+    List<HivePrivilegeObject> inputs = getHivePrivilegeObjectInputs();
+    checkSingleTableInput(inputs);
+    HivePrivilegeObject tableObj = inputs.get(0);
+    assertEquals("no of columns used", 3, tableObj.getColumns().size());
+    assertEquals("Columns used", Arrays.asList("city", "i", "k"),
+        getSortedList(tableObj.getColumns()));
+  }
+
+  private List<String> getSortedList(Set<String> columns) {
+    List<String> sortedCols = new ArrayList<String>(columns);
+    Collections.sort(sortedCols);
+    return sortedCols;
+  }
+
+  @Test
+  public void testInputAllColumnsUsed() throws HiveAuthzPluginException, 
HiveAccessControlException,
+      CommandNeedRetryException {
+
+    reset(mockedAuthorizer);
+    int status = driver.compile("select * from " + tableName + " order by i");
+    assertEquals(0, status);
+
+    List<HivePrivilegeObject> inputs = getHivePrivilegeObjectInputs();
+    checkSingleTableInput(inputs);
+    HivePrivilegeObject tableObj = inputs.get(0);
+    assertEquals("no of columns used", 5, tableObj.getColumns().size());
+    assertEquals("Columns used", Arrays.asList("city", "date", "i", "j", "k"),
+        getSortedList(tableObj.getColumns()));
+  }
+
+  @Test
+  public void testInputNoColumnsUsed() throws HiveAuthzPluginException, 
HiveAccessControlException,
+      CommandNeedRetryException {
+
+    reset(mockedAuthorizer);
+    int status = driver.compile("describe " + tableName);
+    assertEquals(0, status);
+
+    List<HivePrivilegeObject> inputs = getHivePrivilegeObjectInputs();
+    checkSingleTableInput(inputs);
+    HivePrivilegeObject tableObj = inputs.get(0);
+    assertNull("columns used", tableObj.getColumns());
+  }
+
+  private void checkSingleTableInput(List<HivePrivilegeObject> inputs) {
+    assertEquals("number of inputs", 1, inputs.size());
+
+    HivePrivilegeObject tableObj = inputs.get(0);
+    assertEquals("input type", HivePrivilegeObjectType.TABLE_OR_VIEW, 
tableObj.getType());
+    assertTrue("table name", 
tableName.equalsIgnoreCase(tableObj.getObjectName()));
+  }
+
+  /**
+   * @return the inputs passed in current call to authorizer.checkPrivileges
+   * @throws HiveAuthzPluginException
+   * @throws HiveAccessControlException
+   */
+  private List<HivePrivilegeObject> getHivePrivilegeObjectInputs() throws 
HiveAuthzPluginException,
+      HiveAccessControlException {
+    // Create argument capturer
+    // a class variable cast to this generic of generic class
+    Class<List<HivePrivilegeObject>> class_listPrivObjects = (Class) 
List.class;
+    ArgumentCaptor<List<HivePrivilegeObject>> inputsCapturer = ArgumentCaptor
+        .forClass(class_listPrivObjects);
+
+    verify(mockedAuthorizer).checkPrivileges(any(HiveOperationType.class),
+        inputsCapturer.capture(), 
Matchers.anyListOf(HivePrivilegeObject.class),
+        any(HiveAuthzContext.class));
+
+    return inputsCapturer.getValue();
+  }
+
+}

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/Driver.java
URL: 
http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/Driver.java?rev=1614931&r1=1614930&r2=1614931&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/Driver.java (original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/Driver.java Thu Jul 31 
16:19:23 2014
@@ -82,6 +82,7 @@ import org.apache.hadoop.hive.ql.metadat
 import org.apache.hadoop.hive.ql.optimizer.ppr.PartitionPruner;
 import org.apache.hadoop.hive.ql.parse.ASTNode;
 import org.apache.hadoop.hive.ql.parse.BaseSemanticAnalyzer;
+import org.apache.hadoop.hive.ql.parse.ColumnAccessInfo;
 import org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHook;
 import org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHookContext;
 import org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHookContextImpl;
@@ -503,8 +504,13 @@ public class Driver implements CommandPr
     Hive db = sem.getDb();
 
     if (ss.isAuthorizationModeV2()) {
-      doAuthorizationV2(ss, op, inputs, outputs, command);
-      return;
+      // get mapping of tables to columns used
+      ColumnAccessInfo colAccessInfo = sem.getColumnAccessInfo();
+      // colAccessInfo is set only in case of SemanticAnalyzer
+      Map<String, Set<String>> tab2Cols = colAccessInfo != null ? colAccessInfo
+          .getTableToColumnAccessMap() : null;
+      doAuthorizationV2(ss, op, inputs, outputs, command, tab2Cols);
+     return;
     }
     if (op == null) {
       throw new HiveException("Operation should not be null");
@@ -583,56 +589,9 @@ public class Driver implements CommandPr
         }
       }
 
-      //for a select or create-as-select query, populate the partition to 
column (par2Cols) or
-      // table to columns mapping (tab2Cols)
-      if (op.equals(HiveOperation.CREATETABLE_AS_SELECT)
-          || op.equals(HiveOperation.QUERY)) {
-        SemanticAnalyzer querySem = (SemanticAnalyzer) sem;
-        ParseContext parseCtx = querySem.getParseContext();
-        Map<TableScanOperator, Table> tsoTopMap = parseCtx.getTopToTable();
-
-        for (Map.Entry<String, Operator<? extends OperatorDesc>> topOpMap : 
querySem
-            .getParseContext().getTopOps().entrySet()) {
-          Operator<? extends OperatorDesc> topOp = topOpMap.getValue();
-          if (topOp instanceof TableScanOperator
-              && tsoTopMap.containsKey(topOp)) {
-            TableScanOperator tableScanOp = (TableScanOperator) topOp;
-            Table tbl = tsoTopMap.get(tableScanOp);
-            List<Integer> neededColumnIds = tableScanOp.getNeededColumnIDs();
-            List<FieldSchema> columns = tbl.getCols();
-            List<String> cols = new ArrayList<String>();
-            for (int i = 0; i < neededColumnIds.size(); i++) {
-              cols.add(columns.get(neededColumnIds.get(i)).getName());
-            }
-            //map may not contain all sources, since input list may have been 
optimized out
-            //or non-existent tho such sources may still be referenced by the 
TableScanOperator
-            //if it's null then the partition probably doesn't exist so let's 
use table permission
-            if (tbl.isPartitioned() &&
-                tableUsePartLevelAuth.get(tbl.getTableName()) == Boolean.TRUE) 
{
-              String alias_id = topOpMap.getKey();
-
-              PrunedPartitionList partsList = 
PartitionPruner.prune(tableScanOp,
-                  parseCtx, alias_id);
-              Set<Partition> parts = partsList.getPartitions();
-              for (Partition part : parts) {
-                List<String> existingCols = part2Cols.get(part);
-                if (existingCols == null) {
-                  existingCols = new ArrayList<String>();
-                }
-                existingCols.addAll(cols);
-                part2Cols.put(part, existingCols);
-              }
-            } else {
-              List<String> existingCols = tab2Cols.get(tbl);
-              if (existingCols == null) {
-                existingCols = new ArrayList<String>();
-              }
-              existingCols.addAll(cols);
-              tab2Cols.put(tbl, existingCols);
-            }
-          }
-        }
-      }
+      getTablePartitionUsedColumns(op, sem, tab2Cols, part2Cols, 
tableUsePartLevelAuth);
+
+
 
       // cache the results for table authorization
       Set<String> tableAuthChecked = new HashSet<String>();
@@ -683,8 +642,65 @@ public class Driver implements CommandPr
     }
   }
 
+  private static void getTablePartitionUsedColumns(HiveOperation op, 
BaseSemanticAnalyzer sem,
+      Map<Table, List<String>> tab2Cols, Map<Partition, List<String>> 
part2Cols,
+      Map<String, Boolean> tableUsePartLevelAuth) throws HiveException {
+    // for a select or create-as-select query, populate the partition to column
+    // (par2Cols) or
+    // table to columns mapping (tab2Cols)
+    if (op.equals(HiveOperation.CREATETABLE_AS_SELECT)
+        || op.equals(HiveOperation.QUERY)) {
+      SemanticAnalyzer querySem = (SemanticAnalyzer) sem;
+      ParseContext parseCtx = querySem.getParseContext();
+      Map<TableScanOperator, Table> tsoTopMap = parseCtx.getTopToTable();
+
+      for (Map.Entry<String, Operator<? extends OperatorDesc>> topOpMap : 
querySem
+          .getParseContext().getTopOps().entrySet()) {
+        Operator<? extends OperatorDesc> topOp = topOpMap.getValue();
+        if (topOp instanceof TableScanOperator
+            && tsoTopMap.containsKey(topOp)) {
+          TableScanOperator tableScanOp = (TableScanOperator) topOp;
+          Table tbl = tsoTopMap.get(tableScanOp);
+          List<Integer> neededColumnIds = tableScanOp.getNeededColumnIDs();
+          List<FieldSchema> columns = tbl.getCols();
+          List<String> cols = new ArrayList<String>();
+          for (int i = 0; i < neededColumnIds.size(); i++) {
+            cols.add(columns.get(neededColumnIds.get(i)).getName());
+          }
+          //map may not contain all sources, since input list may have been 
optimized out
+          //or non-existent tho such sources may still be referenced by the 
TableScanOperator
+          //if it's null then the partition probably doesn't exist so let's 
use table permission
+          if (tbl.isPartitioned() &&
+              tableUsePartLevelAuth.get(tbl.getTableName()) == Boolean.TRUE) {
+            String alias_id = topOpMap.getKey();
+
+            PrunedPartitionList partsList = PartitionPruner.prune(tableScanOp,
+                parseCtx, alias_id);
+            Set<Partition> parts = partsList.getPartitions();
+            for (Partition part : parts) {
+              List<String> existingCols = part2Cols.get(part);
+              if (existingCols == null) {
+                existingCols = new ArrayList<String>();
+              }
+              existingCols.addAll(cols);
+              part2Cols.put(part, existingCols);
+            }
+          } else {
+            List<String> existingCols = tab2Cols.get(tbl);
+            if (existingCols == null) {
+              existingCols = new ArrayList<String>();
+            }
+            existingCols.addAll(cols);
+            tab2Cols.put(tbl, existingCols);
+          }
+        }
+      }
+    }
+
+  }
+
   private static void doAuthorizationV2(SessionState ss, HiveOperation op, 
HashSet<ReadEntity> inputs,
-      HashSet<WriteEntity> outputs, String command) throws HiveException {
+      HashSet<WriteEntity> outputs, String command, Map<String, Set<String>> 
tab2cols) throws HiveException {
 
     HiveAuthzContext.Builder authzContextBuilder = new 
HiveAuthzContext.Builder();
 
@@ -696,11 +712,34 @@ public class Driver implements CommandPr
 
     HiveOperationType hiveOpType = getHiveOperationType(op);
     List<HivePrivilegeObject> inputsHObjs = getHivePrivObjects(inputs);
+    updateInputColumnInfo(inputsHObjs, tab2cols);
+
     List<HivePrivilegeObject> outputHObjs = getHivePrivObjects(outputs);
     ss.getAuthorizerV2().checkPrivileges(hiveOpType, inputsHObjs, outputHObjs, 
authzContextBuilder.build());
     return;
   }
 
+  /**
+   * Add column information for input table objects
+   * @param inputsHObjs input HivePrivilegeObject
+   * @param map table to used input columns mapping
+   */
+  private static void updateInputColumnInfo(List<HivePrivilegeObject> 
inputsHObjs,
+      Map<String, Set<String>> tableName2Cols) {
+    if(tableName2Cols == null) {
+      return;
+    }
+    for(HivePrivilegeObject inputObj : inputsHObjs){
+      if(inputObj.getType() != HivePrivilegeObjectType.TABLE_OR_VIEW){
+        // input columns are relevant only for tables or views
+        continue;
+      }
+      Set<String> cols = 
tableName2Cols.get(Table.getCompleteName(inputObj.getDbname(),
+          inputObj.getObjectName()));
+      inputObj.setColumns(cols);
+    }
+  }
+
   private static List<HivePrivilegeObject> getHivePrivObjects(HashSet<? 
extends Entity> privObjects) {
     List<HivePrivilegeObject> hivePrivobjs = new 
ArrayList<HivePrivilegeObject>();
     if(privObjects == null){

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java
URL: 
http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java?rev=1614931&r1=1614930&r2=1614931&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java 
(original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java Thu Jul 
31 16:19:23 2014
@@ -35,6 +35,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -599,10 +600,13 @@ public class DDLTask extends Task<DDLWor
 
     HiveAuthorizer authorizer = getSessionAuthorizer();
     try {
+      Set<String> colSet = showGrantDesc.getColumns() != null ? new 
HashSet<String>(
+          showGrantDesc.getColumns()) : null;
       List<HivePrivilegeInfo> privInfos = authorizer.showPrivileges(
           
AuthorizationUtils.getHivePrincipal(showGrantDesc.getPrincipalDesc()),
           AuthorizationUtils.getHivePrivilegeObject(showGrantDesc.getHiveObj(),
-              showGrantDesc.getColumns()));
+              colSet
+              ));
       boolean testMode = conf.getBoolVar(HiveConf.ConfVars.HIVE_IN_TEST);
       writeToFile(writeGrantInfo(privInfos, testMode), 
showGrantDesc.getResFile());
     } catch (IOException e) {

Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/Table.java
URL: 
http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/Table.java?rev=1614931&r1=1614930&r2=1614931&view=diff
==============================================================================
--- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/Table.java 
(original)
+++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/metadata/Table.java Thu 
Jul 31 16:19:23 2014
@@ -933,7 +933,11 @@ public class Table implements Serializab
    * @return include the db name
    */
   public String getCompleteName() {
-    return getDbName() + "@" + getTableName();
+    return getCompleteName(getDbName(), getTableName());
+  }
+
+  public static String getCompleteName(String dbName, String tabName) {
+    return dbName + "@" + tabName;
   }
 
   /**

Modified: 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java
URL: 
http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java?rev=1614931&r1=1614930&r2=1614931&view=diff
==============================================================================
--- 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java 
(original)
+++ 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java 
Thu Jul 31 16:19:23 2014
@@ -19,7 +19,6 @@
 package org.apache.hadoop.hive.ql.parse;
 
 import static org.apache.hadoop.hive.conf.HiveConf.ConfVars.HIVESTATSDBCLASS;
-import static 
org.apache.hadoop.hive.metastore.MetaStoreUtils.DATABASE_WAREHOUSE_SUFFIX;
 
 import java.io.IOException;
 import java.io.Serializable;
@@ -31,10 +30,10 @@ import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.UUID;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.UUID;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
@@ -2328,13 +2327,13 @@ public class SemanticAnalyzer extends Ba
    * for inner joins push a 'is not null predicate' to the join sources for
    * every non nullSafe predicate.
    */
-  private Operator genNotNullFilterForJoinSourcePlan(QB qb, Operator input, 
+  private Operator genNotNullFilterForJoinSourcePlan(QB qb, Operator input,
       QBJoinTree joinTree, ExprNodeDesc[] joinKeys) throws SemanticException {
 
     if (qb == null || joinTree == null) {
       return input;
     }
-    
+
     if (!joinTree.getNoOuterJoin()) {
       return input;
     }
@@ -9491,7 +9490,11 @@ public class SemanticAnalyzer extends Ba
 
     // Generate column access stats if required - wait until column pruning 
takes place
     // during optimization
-    if (HiveConf.getBoolVar(this.conf, 
HiveConf.ConfVars.HIVE_STATS_COLLECT_SCANCOLS) == true) {
+    boolean isColumnInfoNeedForAuth = 
SessionState.get().isAuthorizationModeV2()
+        && HiveConf.getBoolVar(conf, 
HiveConf.ConfVars.HIVE_AUTHORIZATION_ENABLED);
+
+    if (isColumnInfoNeedForAuth
+        || HiveConf.getBoolVar(this.conf, 
HiveConf.ConfVars.HIVE_STATS_COLLECT_SCANCOLS) == true) {
       ColumnAccessAnalyzer columnAccessAnalyzer = new 
ColumnAccessAnalyzer(pCtx);
       setColumnAccessInfo(columnAccessAnalyzer.analyzeColumnAccess());
     }
@@ -9538,7 +9541,7 @@ public class SemanticAnalyzer extends Ba
             if (((TableScanDesc)topOp.getConf()).getIsMetadataOnly()) {
               continue;
             }
-            PrunedPartitionList parts = 
pCtx.getOpToPartList().get((TableScanOperator) topOp);
+            PrunedPartitionList parts = pCtx.getOpToPartList().get(topOp);
             if (parts.getPartitions().size() > scanLimit) {
               throw new 
SemanticException(ErrorMsg.PARTITION_SCAN_LIMIT_EXCEEDED, ""
                   + parts.getPartitions().size(), "" + 
parts.getSourceTable().getTableName(), ""
@@ -10159,7 +10162,7 @@ public class SemanticAnalyzer extends Ba
     String dbName = qualified.length == 1 ? 
SessionState.get().getCurrentDatabase() : qualified[0];
     Database database  = getDatabase(dbName);
     outputs.add(new WriteEntity(database, WriteEntity.WriteType.DDL_SHARED));
- 
+
     if (isTemporary) {
       if (partCols.size() > 0) {
         throw new SemanticException("Partition columns are not supported on 
temporary tables");

Modified: 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationUtils.java
URL: 
http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationUtils.java?rev=1614931&r1=1614930&r2=1614931&view=diff
==============================================================================
--- 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationUtils.java
 (original)
+++ 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/AuthorizationUtils.java
 Thu Jul 31 16:19:23 2014
@@ -17,6 +17,10 @@
  */
 package org.apache.hadoop.hive.ql.security.authorization;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
 import org.apache.hadoop.classification.InterfaceAudience.LimitedPrivate;
 import org.apache.hadoop.hive.metastore.api.HiveObjectPrivilege;
 import org.apache.hadoop.hive.metastore.api.HiveObjectRef;
@@ -24,8 +28,8 @@ import org.apache.hadoop.hive.metastore.
 import org.apache.hadoop.hive.metastore.api.PrincipalType;
 import org.apache.hadoop.hive.metastore.api.PrivilegeGrantInfo;
 import org.apache.hadoop.hive.ql.ErrorMsg;
-import org.apache.hadoop.hive.ql.hooks.Entity;
 import org.apache.hadoop.hive.ql.exec.Utilities;
+import org.apache.hadoop.hive.ql.hooks.Entity;
 import org.apache.hadoop.hive.ql.hooks.Entity.Type;
 import org.apache.hadoop.hive.ql.hooks.WriteEntity;
 import org.apache.hadoop.hive.ql.hooks.WriteEntity.WriteType;
@@ -42,9 +46,6 @@ import org.apache.hadoop.hive.ql.securit
 import 
org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject.HivePrivilegeObjectType;
 import org.apache.hadoop.hive.ql.session.SessionState;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * Utility code shared by hive internal code and sql standard authorization 
plugin implementation
  */
@@ -173,7 +174,7 @@ public class AuthorizationUtils {
   }
 
   public static HivePrivilegeObject getHivePrivilegeObject(
-      PrivilegeObjectDesc privSubjectDesc, List<String> columns) throws 
HiveException {
+      PrivilegeObjectDesc privSubjectDesc, Set<String> columns) throws 
HiveException {
 
     // null means ALL for show grants, GLOBAL for grant/revoke
     HivePrivilegeObjectType objectType = null;

Modified: 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrivilegeObject.java
URL: 
http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrivilegeObject.java?rev=1614931&r1=1614930&r2=1614931&view=diff
==============================================================================
--- 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrivilegeObject.java
 (original)
+++ 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HivePrivilegeObject.java
 Thu Jul 31 16:19:23 2014
@@ -17,9 +17,12 @@
  */
 package org.apache.hadoop.hive.ql.security.authorization.plugin;
 
-import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 import 
org.apache.hadoop.hive.common.classification.InterfaceAudience.LimitedPrivate;
 import 
org.apache.hadoop.hive.common.classification.InterfaceStability.Unstable;
@@ -57,9 +60,18 @@ public class HivePrivilegeObject impleme
     return compare;
   }
 
-  private int compare(List<String> o1, List<String> o2) {
-    for (int i = 0; i < Math.min(o1.size(), o2.size()); i++) {
-      int compare = o1.get(i).compareTo(o2.get(i));
+  private int compare(Collection<String> o1, Collection<String> o2) {
+    Iterator<String> it1 = o1.iterator();
+    Iterator<String> it2 = o2.iterator();
+    while (it1.hasNext()) {
+      if (!it2.hasNext()) {
+        break;
+      }
+      String s1 = it1.next();
+      String s2 = it2.next();
+      int compare = s1 != null ?
+          (s2 != null ? s1.compareTo(s2) : 1) :
+            (s2 != null ? -1 : 0);
       if (compare != 0) {
         return compare;
       }
@@ -79,7 +91,7 @@ public class HivePrivilegeObject impleme
   private final String objectName;
   private final List<String> commandParams;
   private final List<String> partKeys;
-  private final List<String> columns;
+  private Set<String> columns;
   private final HivePrivObjectActionType actionType;
 
   public HivePrivilegeObject(HivePrivilegeObjectType type, String dbname, 
String objectName) {
@@ -94,9 +106,8 @@ public class HivePrivilegeObject impleme
   public HivePrivilegeObject(HivePrivilegeObjectType type, String dbname, 
String objectName,
       List<String> partKeys, String column) {
     this(type, dbname, objectName, partKeys,
-        column == null ? null : new ArrayList<String>(Arrays.asList(column)),
+        column == null ? null : new HashSet<String>(Arrays.asList(column)),
         HivePrivObjectActionType.OTHER, null);
-
   }
 
   /**
@@ -110,12 +121,12 @@ public class HivePrivilegeObject impleme
   }
 
   public HivePrivilegeObject(HivePrivilegeObjectType type, String dbname, 
String objectName,
-    List<String> partKeys, List<String> columns, List<String> commandParams) {
+    List<String> partKeys, Set<String> columns, List<String> commandParams) {
     this(type, dbname, objectName, partKeys, columns, 
HivePrivObjectActionType.OTHER, commandParams);
   }
 
   public HivePrivilegeObject(HivePrivilegeObjectType type, String dbname, 
String objectName,
-      List<String> partKeys, List<String> columns, HivePrivObjectActionType 
actionType,
+      List<String> partKeys, Set<String> columns, HivePrivObjectActionType 
actionType,
       List<String> commandParams) {
     this.type = type;
     this.dbname = dbname;
@@ -153,7 +164,13 @@ public class HivePrivilegeObject impleme
     return partKeys;
   }
 
-  public List<String> getColumns() {
+  /**
+   * Applicable columns in this object
+   * In case of DML read operations, this is the set of columns being used.
+   * Column information is not set for DDL operations and for tables being 
written into
+   * @return list of applicable columns
+   */
+  public Set<String> getColumns() {
     return columns;
   }
 
@@ -202,4 +219,8 @@ public class HivePrivilegeObject impleme
     return (dbname == null ? "" : dbname + ".") + objectName;
   }
 
+  public void setColumns(Set<String> columnms) {
+    this.columns = columnms;
+  }
+
 }

Modified: 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveV1Authorizer.java
URL: 
http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveV1Authorizer.java?rev=1614931&r1=1614930&r2=1614931&view=diff
==============================================================================
--- 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveV1Authorizer.java
 (original)
+++ 
hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/security/authorization/plugin/HiveV1Authorizer.java
 Thu Jul 31 16:19:23 2014
@@ -21,6 +21,7 @@ package org.apache.hadoop.hive.ql.securi
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.metastore.Warehouse;
@@ -318,7 +319,7 @@ public class HiveV1Authorizer implements
           privs.addAll(hive.showPrivilegeGrant(HiveObjectType.DATABASE,
               name, type, dbObj.getName(), null, null, null));
         } else {
-          List<String> columns = privObj.getColumns();
+          Set<String> columns = privObj.getColumns();
           if (columns != null && !columns.isEmpty()) {
             // show column level privileges
             for (String columnName : columns) {


Reply via email to