diff --git ql/src/java/org/apache/hadoop/hive/ql/hooks/ReadEntity.java ql/src/java/org/apache/hadoop/hive/ql/hooks/ReadEntity.java index 6d7c4f6..7ed50b4 100644 --- ql/src/java/org/apache/hadoop/hive/ql/hooks/ReadEntity.java +++ ql/src/java/org/apache/hadoop/hive/ql/hooks/ReadEntity.java @@ -41,6 +41,11 @@ // For example in the case of "select * from V join T ..." T would be direct dependency private boolean isDirect = true; + // Note that we do not need a lock for this entity. This is used by operations like alter + // table ... partition where its actually the partition that needs locked even though the table + // is marked as being read. Defaults to true as that is the most common case. + private boolean needsLock = true; + // For views, the entities can be nested - by default, entities are at the top level private final Set parents = new HashSet(); @@ -147,6 +152,11 @@ public void setDirect(boolean isDirect) { this.isDirect = isDirect; } + public boolean needsLock() { + return needsLock; + } - + public void noLockNeeded() { + needsLock = false; + } } diff --git ql/src/java/org/apache/hadoop/hive/ql/hooks/WriteEntity.java ql/src/java/org/apache/hadoop/hive/ql/hooks/WriteEntity.java index 3f92d94..26836b6 100644 --- ql/src/java/org/apache/hadoop/hive/ql/hooks/WriteEntity.java +++ ql/src/java/org/apache/hadoop/hive/ql/hooks/WriteEntity.java @@ -20,6 +20,8 @@ import java.io.Serializable; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hive.metastore.api.Database; import org.apache.hadoop.hive.ql.metadata.DummyPartition; @@ -33,6 +35,8 @@ */ public class WriteEntity extends Entity implements Serializable { + private static final Log LOG = LogFactory.getLog(WriteEntity.class); + private boolean isTempURI = false; public static enum WriteType { diff --git ql/src/java/org/apache/hadoop/hive/ql/lockmgr/DbTxnManager.java ql/src/java/org/apache/hadoop/hive/ql/lockmgr/DbTxnManager.java index 33c12e7..f2f416e 100644 --- ql/src/java/org/apache/hadoop/hive/ql/lockmgr/DbTxnManager.java +++ ql/src/java/org/apache/hadoop/hive/ql/lockmgr/DbTxnManager.java @@ -88,6 +88,7 @@ public void acquireLocks(QueryPlan plan, Context ctx, String username) throws Lo // For each source to read, get a shared lock for (ReadEntity input : plan.getInputs()) { + if (!input.needsLock()) continue; LockComponentBuilder compBuilder = new LockComponentBuilder(); compBuilder.setShared(); diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/DDLSemanticAnalyzer.java ql/src/java/org/apache/hadoop/hive/ql/parse/DDLSemanticAnalyzer.java index 1208bce..6cd1f39 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/DDLSemanticAnalyzer.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/DDLSemanticAnalyzer.java @@ -1402,7 +1402,12 @@ private void addInputsOutputsAlterTable(String tableName, Map pa outputs.add(new WriteEntity(tab, writeType)); } else { - inputs.add(new ReadEntity(tab)); + ReadEntity re = new ReadEntity(tab); + // In the case of altering a table for its partitions we don't need to lock the table + // itself, just the partitions. But the table will have a ReadEntity. So mark that + // ReadEntity as no lock. + re.noLockNeeded(); + inputs.add(re); if (desc == null || desc.getOp() != AlterTableDesc.AlterTableTypes.ALTERPROTECTMODE) { Partition part = getPartition(tab, partSpec, true); outputs.add(new WriteEntity(part, writeType)); diff --git ql/src/test/queries/clientpositive/dbtxnmgr_ddl1.q ql/src/test/queries/clientpositive/dbtxnmgr_ddl1.q index 3126bd6..23076a9 100644 --- ql/src/test/queries/clientpositive/dbtxnmgr_ddl1.q +++ ql/src/test/queries/clientpositive/dbtxnmgr_ddl1.q @@ -41,9 +41,11 @@ alter table T4 add partition (ds='tomorrow'); create table T5 (a string, b int); alter table T5 set fileformat orc; +alter table T4 partition (ds='tomorrow') set fileformat RCFILE; create table T7 (a string, b int); alter table T7 set location 'file:///tmp'; +alter table T4 partition (ds='tomorrow') set location 'file:///tmp'; alter table T2 touch; alter table T4 touch partition (ds='tomorrow'); diff --git ql/src/test/results/clientpositive/dbtxnmgr_ddl1.q.out ql/src/test/results/clientpositive/dbtxnmgr_ddl1.q.out index 2dc3bdc..fe7d582 100644 --- ql/src/test/results/clientpositive/dbtxnmgr_ddl1.q.out +++ ql/src/test/results/clientpositive/dbtxnmgr_ddl1.q.out @@ -160,6 +160,15 @@ POSTHOOK: query: alter table T5 set fileformat orc POSTHOOK: type: ALTERTABLE_FILEFORMAT POSTHOOK: Input: default@t5 POSTHOOK: Output: default@t5 +PREHOOK: query: alter table T4 partition (ds='tomorrow') set fileformat RCFILE +PREHOOK: type: ALTERPARTITION_FILEFORMAT +PREHOOK: Input: default@t4 +PREHOOK: Output: default@t4@ds=tomorrow +POSTHOOK: query: alter table T4 partition (ds='tomorrow') set fileformat RCFILE +POSTHOOK: type: ALTERPARTITION_FILEFORMAT +POSTHOOK: Input: default@t4 +POSTHOOK: Input: default@t4@ds=tomorrow +POSTHOOK: Output: default@t4@ds=tomorrow PREHOOK: query: create table T7 (a string, b int) PREHOOK: type: CREATETABLE PREHOOK: Output: database:default @@ -176,6 +185,15 @@ POSTHOOK: type: ALTERTABLE_LOCATION POSTHOOK: Input: default@t7 POSTHOOK: Output: default@t7 #### A masked pattern was here #### +PREHOOK: type: ALTERPARTITION_LOCATION +PREHOOK: Input: default@t4 +PREHOOK: Output: default@t4@ds=tomorrow +#### A masked pattern was here #### +POSTHOOK: type: ALTERPARTITION_LOCATION +POSTHOOK: Input: default@t4 +POSTHOOK: Input: default@t4@ds=tomorrow +POSTHOOK: Output: default@t4@ds=tomorrow +#### A masked pattern was here #### PREHOOK: query: alter table T2 touch PREHOOK: type: ALTERTABLE_TOUCH PREHOOK: Input: default@t2