[ 
https://issues.apache.org/jira/browse/HIVE-26076?focusedWorklogId=765463&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-765463
 ]

ASF GitHub Bot logged work on HIVE-26076:
-----------------------------------------

                Author: ASF GitHub Bot
            Created on: 03/May/22 14:10
            Start Date: 03/May/22 14:10
    Worklog Time Spent: 10m 
      Work Description: deniskuzZ commented on code in PR #3122:
URL: https://github.com/apache/hive/pull/3122#discussion_r863821986


##########
ql/src/test/org/apache/hadoop/hive/ql/lockmgr/TestDbTxnManager2.java:
##########
@@ -4028,4 +4005,88 @@ public void testAddDropConstraintNonBlocking() throws 
Exception {
     checkLock(LockType.EXCL_WRITE,
       LockState.ACQUIRED, "default", "tab_acid", null, locks);
   }
+
+  @Test
+  public void testAddPartitionIfNotExistsNonBlocking() throws Exception {
+    testAddPartitionIfNotExists(false);
+  }
+  @Test
+  public void testAddPartitionIfNotExistsBlocking() throws Exception {
+    testAddPartitionIfNotExists(true);
+  }
+
+  private void testAddPartitionIfNotExists(boolean blocking) throws Exception {
+    dropTable(new String[] {"T", "Tstage"});
+    
+    HiveConf.setIntVar(conf, HiveConf.ConfVars.HIVE_LOCKS_PARTITION_THRESHOLD, 
1);
+    driver = Mockito.spy(driver);
+
+    HiveConf.setBoolVar(driver2.getConf(), 
HiveConf.ConfVars.HIVE_ACID_LOCKLESS_READS_ENABLED, !blocking);
+    driver2 = Mockito.spy(driver2);
+
+    driver.run("create table if not exists T (a int, b int) partitioned by (p 
string) " +
+      "stored as orc TBLPROPERTIES ('transactional'='true')");
+    //bucketed just so that we get 2 files
+    driver.run("create table if not exists Tstage (a int, b int) clustered by 
(a) into 2 " +
+      "buckets stored as orc TBLPROPERTIES ('transactional'='false')");
+    driver.run("insert into Tstage values(1,2),(3,4)");
+    String exportLoc = exportFolder.newFolder("1").toString();
+    driver.run("export table Tstage to '" + exportLoc + "'");
+
+    driver.compileAndRespond("select * from T");
+    List<String> res = new ArrayList<>();
+    
+    driver.lockAndRespond();
+    List<ShowLocksResponseElement> locks = getLocks();
+    Assert.assertEquals("Unexpected lock count", 1, locks.size());
+
+    checkLock(LockType.SHARED_READ,
+      LockState.ACQUIRED, "default", "T", null, locks);
+
+    DbTxnManager txnMgr2 = (DbTxnManager) 
TxnManagerFactory.getTxnManagerFactory().getTxnManager(conf);
+    swapTxnManager(txnMgr2);
+    driver2.compileAndRespond("alter table T add if not exists partition 
(p='foo') location '" + exportLoc + "/data'");
+
+    if (blocking) {
+      txnMgr2.acquireLocks(driver2.getPlan(), ctx, null, false);
+      locks = getLocks();
+
+      ShowLocksResponseElement checkLock = checkLock(LockType.EXCLUSIVE,
+        LockState.WAITING, "default", "T", null, locks);
+
+      swapTxnManager(txnMgr);
+      Mockito.doNothing().when(driver).lockAndRespond();
+      driver.run();
+      
+      driver.getFetchTask().fetch(res);
+      swapTxnManager(txnMgr2);
+
+      FieldSetter.setField(txnMgr2, 
txnMgr2.getClass().getDeclaredField("numStatements"), 0);
+      txnMgr2.getMS().unlock(checkLock.getLockid());
+    }
+    driver2.lockAndRespond();
+    locks = getLocks();
+    Assert.assertEquals("Unexpected lock count", blocking ? 1 : 2, 
locks.size());
+
+    checkLock(blocking ? LockType.EXCLUSIVE : LockType.EXCL_WRITE,
+      LockState.ACQUIRED, "default", "T", null, locks);
+
+    Mockito.doNothing().when(driver2).lockAndRespond();
+    driver2.run();
+
+    if (!blocking) {
+      swapTxnManager(txnMgr);
+      Mockito.doNothing().when(driver).lockAndRespond();
+      driver.run();
+    }
+    Mockito.reset(driver, driver2);
+    
+    driver.getFetchTask().fetch(res);
+    Assert.assertEquals("Expecting 2 rows and found " + res.size(), 0, 
res.size());

Review Comment:
   fixed



##########
ql/src/test/org/apache/hadoop/hive/ql/lockmgr/TestDbTxnManager2.java:
##########
@@ -4028,4 +4005,88 @@ public void testAddDropConstraintNonBlocking() throws 
Exception {
     checkLock(LockType.EXCL_WRITE,
       LockState.ACQUIRED, "default", "tab_acid", null, locks);
   }
+
+  @Test
+  public void testAddPartitionIfNotExistsNonBlocking() throws Exception {
+    testAddPartitionIfNotExists(false);
+  }
+  @Test
+  public void testAddPartitionIfNotExistsBlocking() throws Exception {
+    testAddPartitionIfNotExists(true);
+  }
+
+  private void testAddPartitionIfNotExists(boolean blocking) throws Exception {
+    dropTable(new String[] {"T", "Tstage"});
+    
+    HiveConf.setIntVar(conf, HiveConf.ConfVars.HIVE_LOCKS_PARTITION_THRESHOLD, 
1);
+    driver = Mockito.spy(driver);
+
+    HiveConf.setBoolVar(driver2.getConf(), 
HiveConf.ConfVars.HIVE_ACID_LOCKLESS_READS_ENABLED, !blocking);
+    driver2 = Mockito.spy(driver2);
+
+    driver.run("create table if not exists T (a int, b int) partitioned by (p 
string) " +
+      "stored as orc TBLPROPERTIES ('transactional'='true')");
+    //bucketed just so that we get 2 files
+    driver.run("create table if not exists Tstage (a int, b int) clustered by 
(a) into 2 " +
+      "buckets stored as orc TBLPROPERTIES ('transactional'='false')");
+    driver.run("insert into Tstage values(1,2),(3,4)");
+    String exportLoc = exportFolder.newFolder("1").toString();
+    driver.run("export table Tstage to '" + exportLoc + "'");
+
+    driver.compileAndRespond("select * from T");
+    List<String> res = new ArrayList<>();
+    
+    driver.lockAndRespond();
+    List<ShowLocksResponseElement> locks = getLocks();
+    Assert.assertEquals("Unexpected lock count", 1, locks.size());
+
+    checkLock(LockType.SHARED_READ,
+      LockState.ACQUIRED, "default", "T", null, locks);
+
+    DbTxnManager txnMgr2 = (DbTxnManager) 
TxnManagerFactory.getTxnManagerFactory().getTxnManager(conf);
+    swapTxnManager(txnMgr2);
+    driver2.compileAndRespond("alter table T add if not exists partition 
(p='foo') location '" + exportLoc + "/data'");
+
+    if (blocking) {
+      txnMgr2.acquireLocks(driver2.getPlan(), ctx, null, false);
+      locks = getLocks();
+
+      ShowLocksResponseElement checkLock = checkLock(LockType.EXCLUSIVE,
+        LockState.WAITING, "default", "T", null, locks);
+
+      swapTxnManager(txnMgr);
+      Mockito.doNothing().when(driver).lockAndRespond();
+      driver.run();
+      
+      driver.getFetchTask().fetch(res);
+      swapTxnManager(txnMgr2);
+
+      FieldSetter.setField(txnMgr2, 
txnMgr2.getClass().getDeclaredField("numStatements"), 0);
+      txnMgr2.getMS().unlock(checkLock.getLockid());
+    }
+    driver2.lockAndRespond();
+    locks = getLocks();
+    Assert.assertEquals("Unexpected lock count", blocking ? 1 : 2, 
locks.size());
+
+    checkLock(blocking ? LockType.EXCLUSIVE : LockType.EXCL_WRITE,
+      LockState.ACQUIRED, "default", "T", null, locks);
+
+    Mockito.doNothing().when(driver2).lockAndRespond();
+    driver2.run();
+
+    if (!blocking) {
+      swapTxnManager(txnMgr);
+      Mockito.doNothing().when(driver).lockAndRespond();
+      driver.run();
+    }
+    Mockito.reset(driver, driver2);
+    
+    driver.getFetchTask().fetch(res);
+    Assert.assertEquals("Expecting 2 rows and found " + res.size(), 0, 
res.size());
+    
+    driver.run("select * from T where p='foo'");
+    res = new ArrayList<>();
+    driver.getFetchTask().fetch(res);
+    Assert.assertEquals("Expecting 0 rows and found " + res.size(), 2, 
res.size());

Review Comment:
   fixed





Issue Time Tracking
-------------------

    Worklog Id:     (was: 765463)
    Time Spent: 20m  (was: 10m)

> Non blocking ADD PARTITION if not exists
> ----------------------------------------
>
>                 Key: HIVE-26076
>                 URL: https://issues.apache.org/jira/browse/HIVE-26076
>             Project: Hive
>          Issue Type: Task
>            Reporter: Denys Kuzmenko
>            Priority: Major
>              Labels: pull-request-available
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> Originally X (EXCLUSIVE) lock was used to prevent races between concurrent 
> add partition calls with IF NOT EXISTS, however, the same behavior could be 
> achieved with a less restrictive X-write (EXCL_WRITE) lock. 



--
This message was sent by Atlassian Jira
(v8.20.7#820007)

Reply via email to