You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by se...@apache.org on 2017/12/21 02:32:17 UTC

[1/2] hive git commit: HIVE-18230 : create plan like plan, and replace plan commands for easy modification (Sergey Shelukhin, reviewed by Harish Jaiprakash and Prasanth Jayachandran)

Repository: hive
Updated Branches:
  refs/heads/master 025ced9bc -> 3407e723a


http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
index e8762ff..eb811f0 100644
--- a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
@@ -20,7 +20,7 @@ package org.apache.hadoop.hive.metastore;
 
 import static org.apache.commons.lang.StringUtils.join;
 import static org.apache.hadoop.hive.metastore.utils.StringUtils.normalizeIdentifier;
-
+import java.util.Random;
 import com.google.common.collect.Sets;
 import org.apache.hadoop.hive.metastore.api.WMPoolTrigger;
 import org.apache.hadoop.hive.metastore.api.WMMapping;
@@ -29,7 +29,6 @@ import org.apache.hadoop.hive.metastore.model.MWMMapping.EntityType;
 import org.apache.hadoop.hive.metastore.api.WMPool;
 import org.apache.hadoop.hive.metastore.model.MWMPool;
 import org.apache.hadoop.hive.metastore.api.WMFullResourcePlan;
-
 import java.io.IOException;
 import java.lang.reflect.Field;
 import java.net.InetAddress;
@@ -60,7 +59,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.regex.Pattern;
-
 import javax.jdo.JDOCanRetryException;
 import javax.jdo.JDODataStoreException;
 import javax.jdo.JDOException;
@@ -74,8 +72,6 @@ import javax.jdo.datastore.DataStoreCache;
 import javax.jdo.datastore.JDOConnection;
 import javax.jdo.identity.IntIdentity;
 import javax.sql.DataSource;
-
-
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.exception.ExceptionUtils;
@@ -201,7 +197,6 @@ import org.datanucleus.store.scostore.Store;
 import org.datanucleus.util.WeakValueMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import com.codahale.metrics.Counter;
 import com.codahale.metrics.MetricRegistry;
 import com.google.common.annotations.VisibleForTesting;
@@ -221,6 +216,9 @@ public class ObjectStore implements RawStore, Configurable {
   private static PersistenceManagerFactory pmf = null;
   private static boolean forTwoMetastoreTesting = false;
 
+  private static final DateTimeFormatter YMDHMS_FORMAT = DateTimeFormatter.ofPattern(
+      "yyyy_MM_dd_HH_mm_ss");
+
   private static Lock pmfPropLock = new ReentrantLock();
   /**
   * Verify the schema only once per JVM since the db connection info is static
@@ -9536,32 +9534,49 @@ public class ObjectStore implements RawStore, Configurable {
   }
 
   @Override
-  public void createResourcePlan(WMResourcePlan resourcePlan, int defaultPoolSize)
-      throws AlreadyExistsException, InvalidObjectException, MetaException {
+  public void createResourcePlan(
+      WMResourcePlan resourcePlan, String copyFromName, int defaultPoolSize)
+      throws AlreadyExistsException, InvalidObjectException, MetaException, NoSuchObjectException {
     boolean commited = false;
     String rpName = normalizeIdentifier(resourcePlan.getName());
-    Integer queryParallelism = resourcePlan.isSetQueryParallelism() ?
-        resourcePlan.getQueryParallelism() : null;
-    MWMResourcePlan rp = new MWMResourcePlan(
-        rpName, queryParallelism, MWMResourcePlan.Status.DISABLED);
     if (rpName.isEmpty()) {
       throw new InvalidObjectException("Resource name cannot be empty.");
     }
-    if (queryParallelism != null && queryParallelism <= 0) {
-      throw new InvalidObjectException("Query parallelism should be positive.");
+    MWMResourcePlan rp = null;
+    if (copyFromName == null) {
+      Integer queryParallelism = null;
+      if (resourcePlan.isSetQueryParallelism()) {
+        queryParallelism = resourcePlan.getQueryParallelism();
+        if (queryParallelism <= 0) {
+          throw new InvalidObjectException("Query parallelism should be positive.");
+        }
+      }
+      rp = new MWMResourcePlan(rpName, queryParallelism, Status.DISABLED);
+    } else {
+      rp = new MWMResourcePlan(rpName, null, Status.DISABLED);
     }
     try {
       openTransaction();
       pm.makePersistent(rp);
-      // TODO: ideally, this should be moved outside to HiveMetaStore to be shared between
-      //       all the RawStore-s. Right now there's no method to create a pool.
-      if (defaultPoolSize > 0) {
-        MWMPool defaultPool = new MWMPool(rp, "default", 1.0, defaultPoolSize, null);
-        pm.makePersistent(defaultPool);
-        rp.setPools(Sets.newHashSet(defaultPool));
-        rp.setDefaultPool(defaultPool);
+      if (copyFromName != null) {
+        MWMResourcePlan copyFrom = getMWMResourcePlan(copyFromName, false);
+        if (copyFrom == null) {
+          throw new NoSuchObjectException(copyFromName);
+        }
+        copyRpContents(rp, copyFrom);
+      } else {
+        // TODO: ideally, this should be moved outside to HiveMetaStore to be shared between
+        //       all the RawStore-s. Right now there's no method to create a pool.
+        if (defaultPoolSize > 0) {
+          MWMPool defaultPool = new MWMPool(rp, "default", 1.0, defaultPoolSize, null);
+          pm.makePersistent(defaultPool);
+          rp.setPools(Sets.newHashSet(defaultPool));
+          rp.setDefaultPool(defaultPool);
+        }
       }
       commited = commitTransaction();
+    } catch (InvalidOperationException e) {
+      throw new RuntimeException(e);
     } catch (Exception e) {
       checkForConstraintException(e, "Resource plan already exists: ");
       throw e;
@@ -9572,6 +9587,60 @@ public class ObjectStore implements RawStore, Configurable {
     }
   }
 
+  private void copyRpContents(MWMResourcePlan dest, MWMResourcePlan src) {
+    dest.setQueryParallelism(src.getQueryParallelism());
+    Map<String, MWMPool> pools = new HashMap<>();
+    Map<String, Set<MWMPool>> triggersToPools = new HashMap<>();
+    for (MWMPool copyPool : src.getPools()) {
+      MWMPool pool = new MWMPool(dest, copyPool.getPath(), copyPool.getAllocFraction(),
+          copyPool.getQueryParallelism(), copyPool.getSchedulingPolicy());
+      pm.makePersistent(pool);
+      pools.put(copyPool.getPath(), pool);
+      if (copyPool.getTriggers() != null) {
+        for (MWMTrigger trigger : copyPool.getTriggers()) {
+          Set<MWMPool> p2t = triggersToPools.get(trigger.getName());
+          if (p2t == null) {
+            p2t = new HashSet<>();
+            triggersToPools.put(trigger.getName(), p2t);
+          }
+          p2t.add(pool);
+          pool.setTriggers(new HashSet<>());
+        }
+      }
+    }
+    dest.setPools(new HashSet<>(pools.values()));
+    if (src.getDefaultPool() != null) {
+      dest.setDefaultPool(pools.get(src.getDefaultPool().getPath()));
+    }
+    Set<MWMMapping> mappings = new HashSet<>();
+    for (MWMMapping copyMapping : src.getMappings()) {
+      MWMPool pool = null;
+      if (copyMapping.getPool() != null) {
+        pool = pools.get(copyMapping.getPool().getPath());
+      }
+      MWMMapping mapping = new MWMMapping(dest, copyMapping.getEntityType(),
+          copyMapping.getEntityName(), pool, copyMapping.getOrdering());
+      pm.makePersistent(mapping);
+      mappings.add(mapping);
+    }
+    dest.setMappings(mappings);
+    Set<MWMTrigger> triggers = new HashSet<>();
+    for (MWMTrigger copyTrigger : src.getTriggers()) {
+      Set<MWMPool> p2t = triggersToPools.get(copyTrigger.getName());
+      if (p2t == null) {
+        p2t = new HashSet<>();
+      }
+      MWMTrigger trigger = new MWMTrigger(dest, copyTrigger.getName(),
+          copyTrigger.getTriggerExpression(), copyTrigger.getActionExpression(), p2t);
+      pm.makePersistent(trigger);
+      for (MWMPool pool : p2t) {
+        pool.getTriggers().add(trigger);
+      }
+      triggers.add(trigger);
+    }
+    dest.setTriggers(triggers);
+  }
+
   private WMResourcePlan fromMResourcePlan(MWMResourcePlan mplan) {
     if (mplan == null) {
       return null;
@@ -9644,6 +9713,11 @@ public class ObjectStore implements RawStore, Configurable {
 
   private MWMResourcePlan getMWMResourcePlan(String name, boolean editCheck)
       throws NoSuchObjectException, InvalidOperationException {
+    return getMWMResourcePlan(name, editCheck, true);
+  }
+
+  private MWMResourcePlan getMWMResourcePlan(String name, boolean editCheck, boolean mustExist)
+      throws NoSuchObjectException, InvalidOperationException {
     MWMResourcePlan resourcePlan;
     boolean commited = false;
     Query query = null;
@@ -9660,10 +9734,11 @@ public class ObjectStore implements RawStore, Configurable {
     } finally {
       rollbackAndCleanup(commited, query);
     }
-    if (resourcePlan == null) {
+    if (mustExist && resourcePlan == null) {
       throw new NoSuchObjectException("There is no resource plan named: " + name);
     }
-    if (editCheck && resourcePlan.getStatus() != MWMResourcePlan.Status.DISABLED) {
+    if (editCheck && resourcePlan != null
+        && resourcePlan.getStatus() != MWMResourcePlan.Status.DISABLED) {
       throw new InvalidOperationException("Resource plan must be disabled to edit it.");
     }
     return resourcePlan;
@@ -9692,10 +9767,13 @@ public class ObjectStore implements RawStore, Configurable {
   }
 
   @Override
-  public WMFullResourcePlan alterResourcePlan(String name, WMResourcePlan resourcePlan,
-      boolean canActivateDisabled, boolean canDeactivate) throws AlreadyExistsException,
-      NoSuchObjectException, InvalidOperationException, MetaException {
+  public WMFullResourcePlan alterResourcePlan(String name, WMResourcePlan changes,
+      boolean canActivateDisabled, boolean canDeactivate, boolean isReplace)
+    throws AlreadyExistsException, NoSuchObjectException, InvalidOperationException, MetaException {
     name = name == null ? null : normalizeIdentifier(name);
+    if (isReplace && name == null) {
+      throw new InvalidOperationException("Cannot replace without specifying the source plan");
+    }
     boolean commited = false;
     Query query = null;
     // This method only returns the result when activating a resource plan.
@@ -9704,38 +9782,12 @@ public class ObjectStore implements RawStore, Configurable {
     WMFullResourcePlan result = null;
     try {
       openTransaction();
-      MWMResourcePlan mResourcePlan = name == null ? getActiveMWMResourcePlan()
-          : getMWMResourcePlan(name, !resourcePlan.isSetStatus());
-      boolean hasNameChange = resourcePlan.isSetName() && !resourcePlan.getName().equals(name);
-      if (resourcePlan.isSetQueryParallelism() || resourcePlan.isSetDefaultPoolPath()
-        || hasNameChange) {
-        if (resourcePlan.isSetStatus()) {
-          throw new InvalidOperationException("Cannot change values during status switch.");
-        } else if (resourcePlan.getStatus() == WMResourcePlanStatus.DISABLED) {
-          throw new InvalidOperationException("Resource plan must be disabled to edit it.");
-        }
-      }
-      if (hasNameChange) {
-        String newName = normalizeIdentifier(resourcePlan.getName());
-        if (newName.isEmpty()) {
-          throw new InvalidOperationException("Cannot rename to empty value.");
-        }
-        mResourcePlan.setName(resourcePlan.getName());
-      }
-      if (resourcePlan.isSetQueryParallelism()) {
-        if (resourcePlan.getQueryParallelism() <= 0) {
-          throw new InvalidOperationException("queryParallelism should be positive.");
-        }
-        mResourcePlan.setQueryParallelism(resourcePlan.getQueryParallelism());
-      }
-      if (resourcePlan.isSetDefaultPoolPath()) {
-        MWMPool pool = getPool(mResourcePlan, resourcePlan.getDefaultPoolPath());
-        mResourcePlan.setDefaultPool(pool);
-      }
-      if (resourcePlan.isSetStatus()) {
-        result = switchStatus(name, mResourcePlan,
-            resourcePlan.getStatus().name(), canActivateDisabled, canDeactivate);
+      if (isReplace) {
+        result = handleAlterReplace(name, changes);
+      } else {
+        result = handleSimpleAlter(name, changes, canActivateDisabled, canDeactivate);
       }
+ 
       commited = commitTransaction();
       return result;
     } catch (Exception e) {
@@ -9746,6 +9798,102 @@ public class ObjectStore implements RawStore, Configurable {
     }
   }
 
+  private WMFullResourcePlan handleSimpleAlter(String name, WMResourcePlan changes,
+      boolean canActivateDisabled, boolean canDeactivate)
+          throws InvalidOperationException, NoSuchObjectException, MetaException {
+    MWMResourcePlan plan = name == null ? getActiveMWMResourcePlan()
+        : getMWMResourcePlan(name, !changes.isSetStatus());
+    boolean hasNameChange = changes.isSetName() && !changes.getName().equals(name);
+    // Verify that field changes are consistent with what Hive does. Note: we could handle this.
+    if (changes.isSetQueryParallelism() || changes.isSetDefaultPoolPath() || hasNameChange) {
+      if (changes.isSetStatus()) {
+        throw new InvalidOperationException("Cannot change values during status switch.");
+      } else if (plan.getStatus() != MWMResourcePlan.Status.DISABLED) {
+        throw new InvalidOperationException("Resource plan must be disabled to edit it.");
+      }
+    }
+
+    // Handle rename and other changes.
+    if (changes.isSetName()) {
+      String newName = normalizeIdentifier(changes.getName());
+      if (newName.isEmpty()) {
+        throw new InvalidOperationException("Cannot rename to empty value.");
+      }
+      if (!newName.equals(plan.getName())) {
+        plan.setName(newName);
+      }
+    }
+    if (changes.isSetQueryParallelism()) {
+      if (changes.getQueryParallelism() <= 0) {
+        throw new InvalidOperationException("queryParallelism should be positive.");
+      }
+      plan.setQueryParallelism(changes.getQueryParallelism());
+    }
+    if (changes.isSetDefaultPoolPath()) {
+      MWMPool pool = getPool(plan, changes.getDefaultPoolPath());
+      plan.setDefaultPool(pool);
+    }
+
+    // Handle the status change.
+    if (changes.isSetStatus()) {
+      return switchStatus(name, plan,
+          changes.getStatus().name(), canActivateDisabled, canDeactivate);
+    }
+    return null;
+  }
+
+  private WMFullResourcePlan handleAlterReplace(String name, WMResourcePlan changes)
+          throws InvalidOperationException, NoSuchObjectException, MetaException {
+    // Verify that field changes are consistent with what Hive does. Note: we could handle this.
+    if (changes.isSetQueryParallelism() || changes.isSetDefaultPoolPath()) {
+      throw new InvalidOperationException("Cannot change values during replace.");
+    }
+    boolean isReplacingSpecific = changes.isSetName();
+    boolean isReplacingActive = (changes.isSetStatus()
+        && changes.getStatus() == WMResourcePlanStatus.ACTIVE);
+    if (isReplacingActive == isReplacingSpecific) {
+      throw new InvalidOperationException("Must specify a name, or the active plan; received "
+          + changes.getName() + ", " + (changes.isSetStatus() ? changes.getStatus() : null));
+    }
+    if (name == null) {
+      throw new InvalidOperationException("Invalid replace - no name specified");
+    }
+    MWMResourcePlan replacedPlan = isReplacingSpecific
+        ? getMWMResourcePlan(changes.getName(), false) : getActiveMWMResourcePlan();
+    MWMResourcePlan plan = getMWMResourcePlan(name, false);
+
+    if (replacedPlan.getName().equals(plan.getName())) {
+      throw new InvalidOperationException("A plan cannot replace itself");
+    }
+    // We will inherit the name and status from the plan we are replacing.
+    String newName = replacedPlan.getName();
+    int i = 0;
+    String copyName = generateOldPlanName(newName, i);
+    while (true) {
+      MWMResourcePlan dup = getMWMResourcePlan(copyName, false, false);
+      if (dup == null) break;
+      // Note: this can still conflict with parallel transactions. We do not currently handle
+      //       parallel changes from two admins (by design :().
+      copyName = generateOldPlanName(newName, ++i);
+    }
+    replacedPlan.setName(copyName);
+    plan.setName(newName);
+    plan.setStatus(replacedPlan.getStatus());
+    replacedPlan.setStatus(MWMResourcePlan.Status.DISABLED);
+    // TODO: add a configurable option to skip the history and just drop it?
+    return plan.getStatus() == Status.ACTIVE ? fullFromMResourcePlan(plan) : null;
+  }
+
+  private String generateOldPlanName(String newName, int i) {
+    if (MetastoreConf.getBoolVar(conf, ConfVars.HIVE_IN_TEST)) {
+      // Do not use datetime in tests to avoid result changes.
+      return newName + "-old-" + i;
+    } else {
+      return newName + "-old-"
+          + LocalDateTime.now().format(YMDHMS_FORMAT) + (i == 0 ? "" : ("-" + i));
+    }
+  }
+
   @Override
   public WMFullResourcePlan getActiveResourcePlan() throws MetaException {
     // Note: fullFromMResroucePlan needs to be called inside the txn, otherwise we could have
@@ -9779,6 +9927,7 @@ public class ObjectStore implements RawStore, Configurable {
       query.declareParameters("java.lang.String activeStatus");
       query.setUnique(true);
       result = (MWMResourcePlan) query.execute(Status.ACTIVE.toString());
+      pm.retrieve(result);
       commited = commitTransaction();
     } finally {
       rollbackAndCleanup(commited, query);

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/RawStore.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/RawStore.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/RawStore.java
index a7abb4e..8af96db 100644
--- a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/RawStore.java
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/RawStore.java
@@ -753,15 +753,15 @@ public interface RawStore extends Configurable {
    */
   String getMetastoreDbUuid() throws MetaException;
 
-  void createResourcePlan(WMResourcePlan resourcePlan, int defaultPoolSize)
-      throws AlreadyExistsException, MetaException, InvalidObjectException;
+  void createResourcePlan(WMResourcePlan resourcePlan, String copyFrom, int defaultPoolSize)
+      throws AlreadyExistsException, MetaException, InvalidObjectException, NoSuchObjectException;
 
   WMResourcePlan getResourcePlan(String name) throws NoSuchObjectException, MetaException;
 
   List<WMResourcePlan> getAllResourcePlans() throws MetaException;
 
   WMFullResourcePlan alterResourcePlan(String name, WMResourcePlan resourcePlan,
-      boolean canActivateDisabled, boolean canDeactivate)
+      boolean canActivateDisabled, boolean canDeactivate, boolean isReplace)
       throws AlreadyExistsException, NoSuchObjectException, InvalidOperationException,
           MetaException;
 

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/cache/CachedStore.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/cache/CachedStore.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/cache/CachedStore.java
index ec2d5dd..9856f8a 100644
--- a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/cache/CachedStore.java
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/cache/CachedStore.java
@@ -18,7 +18,6 @@
 package org.apache.hadoop.hive.metastore.cache;
 
 import org.apache.hadoop.hive.metastore.api.WMFullResourcePlan;
-
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -35,7 +34,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-
 import org.apache.hadoop.conf.Configurable;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hive.common.StatsSetupConst;
@@ -103,7 +101,6 @@ import org.apache.hadoop.hive.metastore.utils.StringUtils;
 import org.apache.thrift.TException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
 import com.google.common.annotations.VisibleForTesting;
 
 // TODO filter->expr
@@ -2383,9 +2380,9 @@ public class CachedStore implements RawStore, Configurable {
   }
 
   @Override
-  public void createResourcePlan(WMResourcePlan resourcePlan, int defaultPoolSize)
-      throws AlreadyExistsException, InvalidObjectException, MetaException {
-    rawStore.createResourcePlan(resourcePlan, defaultPoolSize);
+  public void createResourcePlan(WMResourcePlan resourcePlan, String copyFrom, int defaultPoolSize)
+      throws AlreadyExistsException, InvalidObjectException, MetaException, NoSuchObjectException {
+    rawStore.createResourcePlan(resourcePlan, copyFrom, defaultPoolSize);
   }
 
   @Override
@@ -2399,11 +2396,12 @@ public class CachedStore implements RawStore, Configurable {
   }
 
   @Override
-  public WMFullResourcePlan alterResourcePlan(
-      String name, WMResourcePlan resourcePlan, boolean canActivateDisabled, boolean canDeactivate)
+  public WMFullResourcePlan alterResourcePlan(String name, WMResourcePlan resourcePlan,
+    boolean canActivateDisabled, boolean canDeactivate, boolean isReplace)
       throws AlreadyExistsException, NoSuchObjectException, InvalidOperationException,
           MetaException {
-    return rawStore.alterResourcePlan(name, resourcePlan, canActivateDisabled, canDeactivate);
+    return rawStore.alterResourcePlan(
+      name, resourcePlan, canActivateDisabled, canDeactivate, isReplace);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/main/thrift/hive_metastore.thrift
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/thrift/hive_metastore.thrift b/standalone-metastore/src/main/thrift/hive_metastore.thrift
index 36ece3f..de07179 100644
--- a/standalone-metastore/src/main/thrift/hive_metastore.thrift
+++ b/standalone-metastore/src/main/thrift/hive_metastore.thrift
@@ -1086,6 +1086,7 @@ struct WMFullResourcePlan {
 
 struct WMCreateResourcePlanRequest {
   1: optional WMResourcePlan resourcePlan;
+  2: optional string copyFrom;
 }
 
 struct WMCreateResourcePlanResponse {
@@ -1118,6 +1119,7 @@ struct WMAlterResourcePlanRequest {
   2: optional WMResourcePlan resourcePlan;
   3: optional bool isEnableAndActivate;
   4: optional bool isForceDeactivate;
+  5: optional bool isReplace;
 }
 
 struct WMAlterResourcePlanResponse {

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/DummyRawStoreControlledCommit.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/DummyRawStoreControlledCommit.java b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/DummyRawStoreControlledCommit.java
index 6de4a2c..e59e349 100644
--- a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/DummyRawStoreControlledCommit.java
+++ b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/DummyRawStoreControlledCommit.java
@@ -943,9 +943,9 @@ public class DummyRawStoreControlledCommit implements RawStore, Configurable {
   }
 
   @Override
-  public void createResourcePlan(WMResourcePlan resourcePlan, int defaultPoolSize)
-      throws AlreadyExistsException, InvalidObjectException, MetaException {
-    objectStore.createResourcePlan(resourcePlan, defaultPoolSize);
+  public void createResourcePlan(WMResourcePlan resourcePlan, String copyFrom, int defaultPoolSize)
+      throws AlreadyExistsException, InvalidObjectException, MetaException, NoSuchObjectException {
+    objectStore.createResourcePlan(resourcePlan, copyFrom, defaultPoolSize);
   }
 
   @Override
@@ -960,10 +960,11 @@ public class DummyRawStoreControlledCommit implements RawStore, Configurable {
 
   @Override
   public WMFullResourcePlan alterResourcePlan(String name, WMResourcePlan resourcePlan,
-      boolean canActivateDisabled, boolean canDeactivate)
+      boolean canActivateDisabled, boolean canDeactivate, boolean isReplace)
       throws AlreadyExistsException, NoSuchObjectException, InvalidOperationException,
           MetaException {
-    return objectStore.alterResourcePlan(name, resourcePlan, canActivateDisabled, canDeactivate);
+    return objectStore.alterResourcePlan(
+      name, resourcePlan, canActivateDisabled, canDeactivate, isReplace);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/DummyRawStoreForJdoConnection.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/DummyRawStoreForJdoConnection.java b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/DummyRawStoreForJdoConnection.java
index 610a08e..8be099c 100644
--- a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/DummyRawStoreForJdoConnection.java
+++ b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/DummyRawStoreForJdoConnection.java
@@ -956,7 +956,7 @@ public class DummyRawStoreForJdoConnection implements RawStore {
 
   @Override
   public void createResourcePlan(
-      WMResourcePlan resourcePlan, int defaultPoolSize) throws MetaException {
+      WMResourcePlan resourcePlan, String copyFrom, int defaultPoolSize) throws MetaException {
   }
 
   @Override
@@ -971,7 +971,8 @@ public class DummyRawStoreForJdoConnection implements RawStore {
 
   @Override
   public WMFullResourcePlan alterResourcePlan(
-      String name, WMResourcePlan resourcePlan, boolean canActivateDisabled, boolean canDeactivate)
+      String name, WMResourcePlan resourcePlan, boolean canActivateDisabled, boolean canDeactivate,
+      boolean isReplace)
       throws NoSuchObjectException, InvalidOperationException, MetaException {
     return null;
   }


[2/2] hive git commit: HIVE-18230 : create plan like plan, and replace plan commands for easy modification (Sergey Shelukhin, reviewed by Harish Jaiprakash and Prasanth Jayachandran)

Posted by se...@apache.org.
HIVE-18230 : create plan like plan, and replace plan commands for easy modification (Sergey Shelukhin, reviewed by Harish Jaiprakash and Prasanth Jayachandran)


Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/3407e723
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/3407e723
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/3407e723

Branch: refs/heads/master
Commit: 3407e723af7855bf075022be076a5ba48b9ee088
Parents: 025ced9
Author: sergey <se...@apache.org>
Authored: Wed Dec 20 18:26:35 2017 -0800
Committer: sergey <se...@apache.org>
Committed: Wed Dec 20 18:26:35 2017 -0800

----------------------------------------------------------------------
 .../listener/DummyRawStoreFailEvent.java        |  17 +-
 .../org/apache/hadoop/hive/ql/exec/DDLTask.java |  16 +-
 .../apache/hadoop/hive/ql/metadata/Hive.java    |  10 +-
 .../hive/ql/parse/DDLSemanticAnalyzer.java      |  63 +++--
 .../org/apache/hadoop/hive/ql/parse/HiveLexer.g |   1 +
 .../apache/hadoop/hive/ql/parse/HiveParser.g    |   2 +
 .../hadoop/hive/ql/parse/IdentifiersParser.g    |   3 +-
 .../hadoop/hive/ql/parse/ResourcePlanParser.g   |  22 +-
 .../hive/ql/plan/AlterResourcePlanDesc.java     |  13 +-
 .../hive/ql/plan/CreateResourcePlanDesc.java    |  10 +-
 .../test/queries/clientpositive/resourceplan.q  |  29 ++
 .../clientpositive/llap/resourceplan.q.out      | 207 ++++++++++++++-
 .../gen/thrift/gen-cpp/hive_metastore_types.cpp |  44 ++++
 .../gen/thrift/gen-cpp/hive_metastore_types.h   |  24 +-
 .../api/WMAlterResourcePlanRequest.java         | 107 +++++++-
 .../api/WMCreateResourcePlanRequest.java        | 114 +++++++-
 .../src/gen/thrift/gen-php/metastore/Types.php  |  46 ++++
 .../gen/thrift/gen-py/hive_metastore/ttypes.py  |  30 ++-
 .../gen/thrift/gen-rb/hive_metastore_types.rb   |   8 +-
 .../hadoop/hive/metastore/HiveMetaStore.java    |  10 +-
 .../hive/metastore/HiveMetaStoreClient.java     |   6 +-
 .../hadoop/hive/metastore/IMetaStoreClient.java |   4 +-
 .../hadoop/hive/metastore/ObjectStore.java      | 263 +++++++++++++++----
 .../apache/hadoop/hive/metastore/RawStore.java  |   6 +-
 .../hive/metastore/cache/CachedStore.java       |  16 +-
 .../src/main/thrift/hive_metastore.thrift       |   2 +
 .../DummyRawStoreControlledCommit.java          |  11 +-
 .../DummyRawStoreForJdoConnection.java          |   5 +-
 28 files changed, 945 insertions(+), 144 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/itests/hcatalog-unit/src/test/java/org/apache/hive/hcatalog/listener/DummyRawStoreFailEvent.java
----------------------------------------------------------------------
diff --git a/itests/hcatalog-unit/src/test/java/org/apache/hive/hcatalog/listener/DummyRawStoreFailEvent.java b/itests/hcatalog-unit/src/test/java/org/apache/hive/hcatalog/listener/DummyRawStoreFailEvent.java
index 1b3baab..6dc052d 100644
--- a/itests/hcatalog-unit/src/test/java/org/apache/hive/hcatalog/listener/DummyRawStoreFailEvent.java
+++ b/itests/hcatalog-unit/src/test/java/org/apache/hive/hcatalog/listener/DummyRawStoreFailEvent.java
@@ -19,13 +19,11 @@
 package org.apache.hive.hcatalog.listener;
 
 import org.apache.hadoop.hive.metastore.api.WMFullResourcePlan;
-
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-
 import org.apache.hadoop.conf.Configurable;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hive.metastore.FileMetadataHandler;
@@ -983,9 +981,9 @@ public class DummyRawStoreFailEvent implements RawStore, Configurable {
   }
 
   @Override
-  public void createResourcePlan(WMResourcePlan resourcePlan, int defaultPoolSize)
-      throws AlreadyExistsException, InvalidObjectException, MetaException {
-    objectStore.createResourcePlan(resourcePlan, defaultPoolSize);
+  public void createResourcePlan(WMResourcePlan resourcePlan, String copyFrom, int defaultPoolSize)
+      throws AlreadyExistsException, MetaException, InvalidObjectException, NoSuchObjectException {
+    objectStore.createResourcePlan(resourcePlan, copyFrom, defaultPoolSize);
   }
 
   @Override
@@ -997,12 +995,11 @@ public class DummyRawStoreFailEvent implements RawStore, Configurable {
   public List<WMResourcePlan> getAllResourcePlans() throws MetaException {
     return objectStore.getAllResourcePlans();
   }
-
+ 
   @Override
-  public WMFullResourcePlan alterResourcePlan(String name, WMResourcePlan resourcePlan, boolean canActivateDisabled, boolean canDeactivate)
-      throws AlreadyExistsException, NoSuchObjectException, InvalidOperationException,
-          MetaException {
-    return objectStore.alterResourcePlan(name, resourcePlan, canActivateDisabled, canDeactivate);
+  public WMFullResourcePlan alterResourcePlan(String name, WMResourcePlan resourcePlan, boolean canActivateDisabled, boolean canDeactivate, boolean isReplace)
+      throws AlreadyExistsException, NoSuchObjectException, InvalidOperationException, MetaException {
+    return objectStore.alterResourcePlan(name, resourcePlan, canActivateDisabled, canDeactivate, isReplace);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java
index b4e0852..f10c31e 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/DDLTask.java
@@ -687,7 +687,8 @@ public class DDLTask extends Task<DDLWork> implements Serializable {
 
   private int createResourcePlan(Hive db, CreateResourcePlanDesc createResourcePlanDesc)
       throws HiveException {
-    db.createResourcePlan(createResourcePlanDesc.getResourcePlan());
+    db.createResourcePlan(createResourcePlanDesc.getResourcePlan(),
+        createResourcePlanDesc.getCopyFromName());
     return 0;
   }
 
@@ -731,17 +732,20 @@ public class DDLTask extends Task<DDLWork> implements Serializable {
       isActivate = resourcePlan.getStatus() == WMResourcePlanStatus.ACTIVE;
     }
 
-    WMFullResourcePlan appliedRp = db.alterResourcePlan(
-      desc.getResourcePlanName(), resourcePlan, desc.isEnableActivate(), desc.isForceDeactivate());
-    if (!isActivate && !desc.isForceDeactivate()) return 0; // DB-only modification.
-    if (wm == null && isInTest) {
-      return 0;
+    WMFullResourcePlan appliedRp = db.alterResourcePlan(desc.getResourcePlanName(), resourcePlan,
+        desc.isEnableActivate(), desc.isForceDeactivate(), desc.isReplace());
+    boolean mustHaveAppliedChange = isActivate || desc.isForceDeactivate();
+    if (!mustHaveAppliedChange && !desc.isReplace()) {
+      return 0; // The modification cannot affect an active plan.
     }
+    if (appliedRp == null && !mustHaveAppliedChange) return 0; // Replacing an inactive plan.
+    if (wm == null && isInTest) return 0; // Skip for tests if WM is not present.
 
     if ((appliedRp == null) != desc.isForceDeactivate()) {
       throw new HiveException("Cannot get a resource plan to apply; or non-null plan on disable");
       // TODO: shut down HS2?
     }
+    assert appliedRp == null || appliedRp.getPlan().getStatus() == WMResourcePlanStatus.ACTIVE;
 
     handleWorkloadManagementServiceChange(wm, pm, isActivate, appliedRp);
     return 0;

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java b/ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java
index b068ec8..022ba04 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/metadata/Hive.java
@@ -4749,9 +4749,10 @@ private void constructOneLBLocationMap(FileStatus fSta,
     }
   }
 
-  public void createResourcePlan(WMResourcePlan resourcePlan) throws HiveException {
+  public void createResourcePlan(WMResourcePlan resourcePlan, String copyFromName)
+      throws HiveException {
     try {
-      getMSC().createResourcePlan(resourcePlan);
+      getMSC().createResourcePlan(resourcePlan, copyFromName);
     } catch (Exception e) {
       throw new HiveException(e);
     }
@@ -4784,10 +4785,11 @@ private void constructOneLBLocationMap(FileStatus fSta,
   }
 
   public WMFullResourcePlan alterResourcePlan(String rpName, WMResourcePlan resourcePlan,
-      boolean canActivateDisabled, boolean isForceDeactivate) throws HiveException {
+      boolean canActivateDisabled, boolean isForceDeactivate, boolean isReplace)
+          throws HiveException {
     try {
       return getMSC().alterResourcePlan(
-          rpName, resourcePlan, canActivateDisabled, isForceDeactivate);
+          rpName, resourcePlan, canActivateDisabled, isForceDeactivate, isReplace);
     } catch (Exception e) {
       throw new HiveException(e);
     }

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/ql/src/java/org/apache/hadoop/hive/ql/parse/DDLSemanticAnalyzer.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/DDLSemanticAnalyzer.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/DDLSemanticAnalyzer.java
index c30f8a4..c8c1665 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/parse/DDLSemanticAnalyzer.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/DDLSemanticAnalyzer.java
@@ -900,19 +900,30 @@ public class DDLSemanticAnalyzer extends BaseSemanticAnalyzer {
     }
     String resourcePlanName = unescapeIdentifier(ast.getChild(0).getText());
     Integer queryParallelism = null;
+    String likeName = null;
     for (int i = 1; i < ast.getChildCount(); ++i) {
       Tree child = ast.getChild(i);
-      if (child.getType() == HiveParser.TOK_QUERY_PARALLELISM) {
-        if (queryParallelism == null) {
+      switch (child.getType()) {
+      case HiveParser.TOK_QUERY_PARALLELISM:
+        // Note: later we may be able to set multiple things together (except LIKE).
+        if (queryParallelism == null && likeName == null) {
           queryParallelism = Integer.parseInt(child.getChild(0).getText());
         } else {
-          throw new SemanticException("QUERY_PARALLELISM should be set only once.");
+          throw new SemanticException("Conflicting create arguments " + ast.toStringTree());
         }
-      } else {
-        throw new SemanticException("Invalid set in create resource plan: " + child.getText());
+        break;
+      case HiveParser.TOK_LIKERP:
+        if (queryParallelism == null && likeName == null) {
+          likeName = unescapeIdentifier(child.getChild(0).getText());
+        } else {
+          throw new SemanticException("Conflicting create arguments " + ast.toStringTree());
+        }
+        break;
+      default: throw new SemanticException("Invalid create arguments " + ast.toStringTree());
       }
     }
-    CreateResourcePlanDesc desc = new CreateResourcePlanDesc(resourcePlanName, queryParallelism);
+    CreateResourcePlanDesc desc = new CreateResourcePlanDesc(
+        resourcePlanName, queryParallelism, likeName);
     rootTasks.add(TaskFactory.get(new DDLWork(getInputs(), getOutputs(), desc), conf));
   }
 
@@ -942,7 +953,8 @@ public class DDLSemanticAnalyzer extends BaseSemanticAnalyzer {
     case HiveParser.TOK_DISABLE:
       WMResourcePlan anyRp = new WMResourcePlan();
       anyRp.setStatus(WMResourcePlanStatus.ENABLED);
-      AlterResourcePlanDesc desc = new AlterResourcePlanDesc(anyRp, null, false, false, true);
+      AlterResourcePlanDesc desc = new AlterResourcePlanDesc(
+          anyRp, null, false, false, true, false);
       rootTasks.add(TaskFactory.get(new DDLWork(getInputs(), getOutputs(), desc), conf));
       return;
     default: // Continue to handle changes to a specific plan.
@@ -952,7 +964,7 @@ public class DDLSemanticAnalyzer extends BaseSemanticAnalyzer {
     }
     String rpName = unescapeIdentifier(ast.getChild(0).getText());
     WMResourcePlan resourcePlan = new WMResourcePlan();
-    boolean isEnableActive = false;
+    boolean isEnableActivate = false, isReplace = false;
     boolean validate = false;
     for (int i = 1; i < ast.getChildCount(); ++i) {
       Tree child = ast.getChild(i);
@@ -962,13 +974,22 @@ public class DDLSemanticAnalyzer extends BaseSemanticAnalyzer {
         break;
       case HiveParser.TOK_ACTIVATE:
         if (resourcePlan.getStatus() == WMResourcePlanStatus.ENABLED) {
-          isEnableActive = true;
+          isEnableActivate = true;
+        }
+        if (child.getChildCount() > 1) {
+          throw new SemanticException("Expected 0 or 1 arguments " + ast.toStringTree());
+        } else if (child.getChildCount() == 1) {
+          if (child.getChild(0).getType() != HiveParser.TOK_REPLACE) {
+            throw new SemanticException("Incorrect syntax " + ast.toStringTree());
+          }
+          isReplace = true;
+          isEnableActivate = false; // Implied.
         }
         resourcePlan.setStatus(WMResourcePlanStatus.ACTIVE);
         break;
       case HiveParser.TOK_ENABLE:
         if (resourcePlan.getStatus() == WMResourcePlanStatus.ACTIVE) {
-          isEnableActive = true;
+          isEnableActivate = !isReplace;
         } else {
           resourcePlan.setStatus(WMResourcePlanStatus.ENABLED);
         }
@@ -976,6 +997,17 @@ public class DDLSemanticAnalyzer extends BaseSemanticAnalyzer {
       case HiveParser.TOK_DISABLE:
         resourcePlan.setStatus(WMResourcePlanStatus.DISABLED);
         break;
+      case HiveParser.TOK_REPLACE:
+        isReplace = true;
+        if (child.getChildCount() > 1) {
+          throw new SemanticException("Expected 0 or 1 arguments " + ast.toStringTree());
+        } else if (child.getChildCount() == 1) {
+          // Replace is essentially renaming a plan to the name of an existing plan, with backup.
+          resourcePlan.setName(unescapeIdentifier(child.getChild(0).getText()));
+        } else {
+          resourcePlan.setStatus(WMResourcePlanStatus.ACTIVE);
+        }
+        break;
       case HiveParser.TOK_QUERY_PARALLELISM:
         if (child.getChildCount() != 1) {
           throw new SemanticException("Expected one argument");
@@ -989,18 +1021,18 @@ public class DDLSemanticAnalyzer extends BaseSemanticAnalyzer {
         resourcePlan.setDefaultPoolPath(poolPath(child.getChild(0)));
         break;
       case HiveParser.TOK_RENAME:
-        if (ast.getChildCount() == (i + 1)) {
-          throw new SemanticException("Expected an argument");
+        if (child.getChildCount() != 1) {
+          throw new SemanticException("Expected one argument");
         }
-        resourcePlan.setName(unescapeIdentifier(ast.getChild(++i).getText()));
+        resourcePlan.setName(unescapeIdentifier(child.getChild(0).getText()));
         break;
       default:
         throw new SemanticException(
           "Unexpected token in alter resource plan statement: " + child.getType());
       }
     }
-    AlterResourcePlanDesc desc =
-        new AlterResourcePlanDesc(resourcePlan, rpName, validate, isEnableActive, false);
+    AlterResourcePlanDesc desc = new AlterResourcePlanDesc(
+        resourcePlan, rpName, validate, isEnableActivate, false, isReplace);
     if (validate) {
       ctx.setResFile(ctx.getLocalTmpPath());
       desc.setResFile(ctx.getResFile().toString());
@@ -1106,6 +1138,7 @@ public class DDLSemanticAnalyzer extends BaseSemanticAnalyzer {
   }
 
   private void analyzeCreatePool(ASTNode ast) throws SemanticException {
+    // TODO: allow defaults for e.g. scheduling policy.
     if (ast.getChildCount() != 5) {
       throw new SemanticException("Invalid syntax for create pool.");
     }

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveLexer.g
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveLexer.g b/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveLexer.g
index 53f7c4f..070f06a 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveLexer.g
+++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveLexer.g
@@ -368,6 +368,7 @@ KW_PATH: 'PATH';
 KW_MAPPING: 'MAPPING';
 KW_WORKLOAD: 'WORKLOAD';
 KW_MANAGEMENT: 'MANAGEMENT';
+KW_ACTIVE: 'ACTIVE';
 
 // Operators
 // NOTE: if you add a new function/operator, add it to sysFuncNames so that describe function _FUNC_ will work.

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g b/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g
index 1378950..3a460ff 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g
+++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/HiveParser.g
@@ -432,6 +432,8 @@ TOK_CREATE_MAPPING;
 TOK_ALTER_MAPPING;
 TOK_DROP_MAPPING;
 TOK_ADD_TRIGGER;
+TOK_REPLACE;
+TOK_LIKERP;
 }
 
 

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/ql/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g b/ql/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g
index f1ca301..8bf4d70 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g
+++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/IdentifiersParser.g
@@ -831,7 +831,8 @@ nonReserved
     | KW_TIMESTAMPTZ
     | KW_DEFAULT
     | KW_RESOURCE | KW_PLAN | KW_PLANS | KW_QUERY_PARALLELISM | KW_ACTIVATE | KW_MOVE | KW_DO
-    | KW_POOL | KW_ALLOC_FRACTION | KW_SCHEDULING_POLICY | KW_PATH | KW_MAPPING
+    | KW_POOL | KW_ALLOC_FRACTION | KW_SCHEDULING_POLICY | KW_PATH | KW_MAPPING | KW_WORKLOAD | KW_MANAGEMENT | KW_ACTIVE
+
 ;
 
 //The following SQL2011 reserved keywords are used as function name only, but not as identifiers.

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/ql/src/java/org/apache/hadoop/hive/ql/parse/ResourcePlanParser.g
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/ResourcePlanParser.g b/ql/src/java/org/apache/hadoop/hive/ql/parse/ResourcePlanParser.g
index 78b288f..3829089 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/parse/ResourcePlanParser.g
+++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/ResourcePlanParser.g
@@ -29,6 +29,7 @@ resourcePlanDdlStatements
     | alterResourcePlanStatement
     | dropResourcePlanStatement
     | globalWmStatement
+    | replaceResourcePlanStatement
     | createTriggerStatement
     | alterTriggerStatement
     | dropTriggerStatement
@@ -58,11 +59,15 @@ rpAssignList
 createResourcePlanStatement
 @init { gParent.pushMsg("create resource plan statement", state); }
 @after { gParent.popMsg(state); }
-    : KW_CREATE KW_RESOURCE KW_PLAN name=identifier (KW_WITH rpAssignList)?
-    -> ^(TOK_CREATE_RP $name rpAssignList?)
+    : KW_CREATE KW_RESOURCE KW_PLAN (
+          (name=identifier KW_LIKE likeName=identifier -> ^(TOK_CREATE_RP $name ^(TOK_LIKERP $likeName)))
+        | (name=identifier (KW_WITH rpAssignList)? -> ^(TOK_CREATE_RP $name rpAssignList?))
+      )
     ;
 
-activate : KW_ACTIVATE -> ^(TOK_ACTIVATE);
+
+withReplace : KW_WITH KW_REPLACE -> ^(TOK_REPLACE);
+activate : KW_ACTIVATE withReplace? -> ^(TOK_ACTIVATE withReplace?);
 enable : KW_ENABLE -> ^(TOK_ENABLE);
 disable : KW_DISABLE -> ^(TOK_DISABLE);
 
@@ -73,7 +78,7 @@ alterResourcePlanStatement
           (KW_VALIDATE -> ^(TOK_ALTER_RP $name TOK_VALIDATE))
         | (KW_DISABLE -> ^(TOK_ALTER_RP $name TOK_DISABLE))
         | (KW_SET rpAssignList -> ^(TOK_ALTER_RP $name rpAssignList))
-        | (KW_RENAME KW_TO newName=identifier -> ^(TOK_ALTER_RP $name TOK_RENAME $newName))
+        | (KW_RENAME KW_TO newName=identifier -> ^(TOK_ALTER_RP $name ^(TOK_RENAME $newName)))
         | ((activate enable? | enable activate?) -> ^(TOK_ALTER_RP $name activate? enable?))
       )
     ;
@@ -86,6 +91,15 @@ globalWmStatement
     : (enable | disable) KW_WORKLOAD KW_MANAGEMENT -> ^(TOK_ALTER_RP enable? disable?)
     ;
 
+replaceResourcePlanStatement
+@init { gParent.pushMsg("replace resource plan statement", state); }
+@after { gParent.popMsg(state); }
+    : KW_REPLACE (
+          (KW_ACTIVE KW_RESOURCE KW_PLAN KW_WITH src=identifier -> ^(TOK_ALTER_RP $src TOK_REPLACE))
+        | (KW_RESOURCE KW_PLAN dest=identifier KW_WITH src=identifier -> ^(TOK_ALTER_RP $src ^(TOK_REPLACE $dest)))
+      )
+    ;
+
 dropResourcePlanStatement
 @init { gParent.pushMsg("drop resource plan statement", state); }
 @after { gParent.popMsg(state); }

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/ql/src/java/org/apache/hadoop/hive/ql/plan/AlterResourcePlanDesc.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/plan/AlterResourcePlanDesc.java b/ql/src/java/org/apache/hadoop/hive/ql/plan/AlterResourcePlanDesc.java
index 2b8f7e7..7339520 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/plan/AlterResourcePlanDesc.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/plan/AlterResourcePlanDesc.java
@@ -31,18 +31,19 @@ public class AlterResourcePlanDesc extends DDLDesc implements Serializable {
   private WMResourcePlan resourcePlan;
   private String rpName;
   private boolean validate;
-  private boolean isEnableActivate, isForceDeactivate;
+  private boolean isEnableActivate, isForceDeactivate, isReplace;
   private String resFile;
 
   public AlterResourcePlanDesc() {}
 
   public AlterResourcePlanDesc(WMResourcePlan resourcePlan, String rpName, boolean validate,
-      boolean isEnableActivate, boolean isForceDeactivate) {
+      boolean isEnableActivate, boolean isForceDeactivate, boolean isReplace) {
     this.resourcePlan = resourcePlan;
     this.rpName = rpName;
     this.validate = validate;
     this.isEnableActivate = isEnableActivate;
     this.isForceDeactivate = isForceDeactivate;
+    this.isReplace = isReplace;
   }
 
   @Explain(displayName="Resource plan changed fields",
@@ -91,6 +92,14 @@ public class AlterResourcePlanDesc extends DDLDesc implements Serializable {
     this.isForceDeactivate = b;
   }
 
+  public boolean isReplace() {
+    return isReplace;
+  }
+
+  public void setIsReplace(boolean b) {
+    this.isReplace = b;
+  }
+
   @Explain(displayName = "result file", explainLevels = { Level.EXTENDED })
   public String getResFile() {
     return resFile;

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/ql/src/java/org/apache/hadoop/hive/ql/plan/CreateResourcePlanDesc.java
----------------------------------------------------------------------
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/plan/CreateResourcePlanDesc.java b/ql/src/java/org/apache/hadoop/hive/ql/plan/CreateResourcePlanDesc.java
index efdd05c..f9190c8 100644
--- a/ql/src/java/org/apache/hadoop/hive/ql/plan/CreateResourcePlanDesc.java
+++ b/ql/src/java/org/apache/hadoop/hive/ql/plan/CreateResourcePlanDesc.java
@@ -19,7 +19,6 @@
 package org.apache.hadoop.hive.ql.plan;
 
 import java.io.Serializable;
-
 import org.apache.hadoop.hive.metastore.api.WMResourcePlan;
 import org.apache.hadoop.hive.ql.plan.Explain.Level;
 
@@ -28,20 +27,27 @@ public class CreateResourcePlanDesc extends DDLDesc implements Serializable {
   private static final long serialVersionUID = -3492803425541479414L;
 
   private WMResourcePlan resourcePlan;
+  private String copyFromName;
 
   // For serialization only.
   public CreateResourcePlanDesc() {
   }
 
-  public CreateResourcePlanDesc(String planName, Integer queryParallelism) {
+  public CreateResourcePlanDesc(String planName, Integer queryParallelism, String copyFromName) {
     resourcePlan = new WMResourcePlan(planName);
     if (queryParallelism != null) {
       resourcePlan.setQueryParallelism(queryParallelism);
     }
+    this.copyFromName = copyFromName;
   }
 
   @Explain(displayName="resourcePlan", explainLevels = { Level.USER, Level.DEFAULT, Level.EXTENDED })
   public WMResourcePlan getResourcePlan() {
     return resourcePlan;
   }
+
+  @Explain(displayName="Copy from", explainLevels = { Level.USER, Level.DEFAULT, Level.EXTENDED })
+  public String getCopyFromName() {
+    return copyFromName;
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/ql/src/test/queries/clientpositive/resourceplan.q
----------------------------------------------------------------------
diff --git a/ql/src/test/queries/clientpositive/resourceplan.q b/ql/src/test/queries/clientpositive/resourceplan.q
index 1b0de8b..997292a 100644
--- a/ql/src/test/queries/clientpositive/resourceplan.q
+++ b/ql/src/test/queries/clientpositive/resourceplan.q
@@ -333,3 +333,32 @@ SELECT * FROM SYS.WM_POOLS;
 SELECT * FROM SYS.WM_TRIGGERS;
 SELECT * FROM SYS.WM_POOLS_TO_TRIGGERS;
 SELECT * FROM SYS.WM_MAPPINGS;
+
+-- Create like another plan; modify, replace. Create all manner of things to make sure LIKE works.
+CREATE RESOURCE PLAN plan_4a LIKE plan_4;
+CREATE POOL plan_4a.pool1 WITH SCHEDULING_POLICY='fair', QUERY_PARALLELISM=2, ALLOC_FRACTION=0.0;
+CREATE USER MAPPING "user1" IN plan_4a TO pool1;
+CREATE TRIGGER plan_4a.trigger_1 WHEN BYTES_READ = 10G DO KILL;
+CREATE TRIGGER plan_4a.trigger_2 WHEN BYTES_READ = 11G DO KILL;
+ALTER POOL plan_4a.pool1 ADD TRIGGER trigger_2;
+
+CREATE RESOURCE PLAN plan_4b LIKE plan_4a;
+CREATE POOL plan_4b.pool2 WITH SCHEDULING_POLICY='fair', QUERY_PARALLELISM=3, ALLOC_FRACTION=0.0;
+SELECT * FROM SYS.WM_RESOURCEPLANS;
+SELECT * FROM SYS.WM_POOLS;
+SELECT * FROM SYS.WM_TRIGGERS;
+SELECT * FROM SYS.WM_POOLS_TO_TRIGGERS;
+SELECT * FROM SYS.WM_MAPPINGS;
+
+REPLACE RESOURCE PLAN plan_4a WITH plan_4b;
+SELECT * FROM SYS.WM_RESOURCEPLANS;
+SELECT * FROM SYS.WM_POOLS;
+REPLACE ACTIVE RESOURCE PLAN WITH plan_4a;
+SELECT * FROM SYS.WM_RESOURCEPLANS;
+CREATE RESOURCE PLAN plan_4a LIKE plan_4;
+CREATE POOL plan_4a.pool3 WITH SCHEDULING_POLICY='fair', QUERY_PARALLELISM=3, ALLOC_FRACTION=0.0;
+ALTER RESOURCE PLAN plan_4a ENABLE ACTIVATE WITH REPLACE;
+SELECT * FROM SYS.WM_RESOURCEPLANS;
+SELECT * FROM SYS.WM_POOLS;
+
+

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/ql/src/test/results/clientpositive/llap/resourceplan.q.out
----------------------------------------------------------------------
diff --git a/ql/src/test/results/clientpositive/llap/resourceplan.q.out b/ql/src/test/results/clientpositive/llap/resourceplan.q.out
index 820edb2..d9f22b8 100644
--- a/ql/src/test/results/clientpositive/llap/resourceplan.q.out
+++ b/ql/src/test/results/clientpositive/llap/resourceplan.q.out
@@ -3177,7 +3177,7 @@ POSTHOOK: Input: sys@wm_resourceplans
 #### A masked pattern was here ####
 plan_1	DISABLED	NULL	default
 plan_2	DISABLED	4	default
-FAILED: SemanticException Invalid set in create resource plan: TOK_DEFAULT_POOL
+FAILED: SemanticException Invalid create arguments (tok_create_rp plan_3 (tok_query_parallelism 5) (tok_default_pool all))
 PREHOOK: query: ALTER RESOURCE PLAN plan_1 RENAME TO plan_2
 PREHOOK: type: ALTER RESOURCEPLAN
 FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. AlreadyExistsException(message:Resource plan name should be unique: )
@@ -4099,3 +4099,208 @@ POSTHOOK: query: SELECT * FROM SYS.WM_MAPPINGS
 POSTHOOK: type: QUERY
 POSTHOOK: Input: sys@wm_mappings
 #### A masked pattern was here ####
+PREHOOK: query: CREATE RESOURCE PLAN plan_4a LIKE plan_4
+PREHOOK: type: CREATE RESOURCEPLAN
+POSTHOOK: query: CREATE RESOURCE PLAN plan_4a LIKE plan_4
+POSTHOOK: type: CREATE RESOURCEPLAN
+PREHOOK: query: CREATE POOL plan_4a.pool1 WITH SCHEDULING_POLICY='fair', QUERY_PARALLELISM=2, ALLOC_FRACTION=0.0
+PREHOOK: type: CREATE POOL
+POSTHOOK: query: CREATE POOL plan_4a.pool1 WITH SCHEDULING_POLICY='fair', QUERY_PARALLELISM=2, ALLOC_FRACTION=0.0
+POSTHOOK: type: CREATE POOL
+PREHOOK: query: CREATE USER MAPPING "user1" IN plan_4a TO pool1
+PREHOOK: type: CREATE MAPPING
+POSTHOOK: query: CREATE USER MAPPING "user1" IN plan_4a TO pool1
+POSTHOOK: type: CREATE MAPPING
+PREHOOK: query: CREATE TRIGGER plan_4a.trigger_1 WHEN BYTES_READ = 10G DO KILL
+PREHOOK: type: CREATE TRIGGER
+POSTHOOK: query: CREATE TRIGGER plan_4a.trigger_1 WHEN BYTES_READ = 10G DO KILL
+POSTHOOK: type: CREATE TRIGGER
+PREHOOK: query: CREATE TRIGGER plan_4a.trigger_2 WHEN BYTES_READ = 11G DO KILL
+PREHOOK: type: CREATE TRIGGER
+POSTHOOK: query: CREATE TRIGGER plan_4a.trigger_2 WHEN BYTES_READ = 11G DO KILL
+POSTHOOK: type: CREATE TRIGGER
+PREHOOK: query: ALTER POOL plan_4a.pool1 ADD TRIGGER trigger_2
+PREHOOK: type: ALTER POOL
+POSTHOOK: query: ALTER POOL plan_4a.pool1 ADD TRIGGER trigger_2
+POSTHOOK: type: ALTER POOL
+PREHOOK: query: CREATE RESOURCE PLAN plan_4b LIKE plan_4a
+PREHOOK: type: CREATE RESOURCEPLAN
+POSTHOOK: query: CREATE RESOURCE PLAN plan_4b LIKE plan_4a
+POSTHOOK: type: CREATE RESOURCEPLAN
+PREHOOK: query: CREATE POOL plan_4b.pool2 WITH SCHEDULING_POLICY='fair', QUERY_PARALLELISM=3, ALLOC_FRACTION=0.0
+PREHOOK: type: CREATE POOL
+POSTHOOK: query: CREATE POOL plan_4b.pool2 WITH SCHEDULING_POLICY='fair', QUERY_PARALLELISM=3, ALLOC_FRACTION=0.0
+POSTHOOK: type: CREATE POOL
+PREHOOK: query: SELECT * FROM SYS.WM_RESOURCEPLANS
+PREHOOK: type: QUERY
+PREHOOK: Input: sys@wm_resourceplans
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM SYS.WM_RESOURCEPLANS
+POSTHOOK: type: QUERY
+POSTHOOK: Input: sys@wm_resourceplans
+#### A masked pattern was here ####
+plan_1	ENABLED	NULL	default
+plan_2	DISABLED	NULL	default
+plan_4	ACTIVE	NULL	default
+plan_4a	DISABLED	NULL	default
+plan_4b	DISABLED	NULL	default
+table	DISABLED	1	table.pool
+PREHOOK: query: SELECT * FROM SYS.WM_POOLS
+PREHOOK: type: QUERY
+PREHOOK: Input: sys@wm_pools
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM SYS.WM_POOLS
+POSTHOOK: type: QUERY
+POSTHOOK: Input: sys@wm_pools
+#### A masked pattern was here ####
+plan_1	default	1.0	4	NULL
+plan_2	default	1.0	4	NULL
+plan_4	default	1.0	4	NULL
+plan_4a	default	1.0	4	NULL
+plan_4a	pool1	0.0	2	fair
+plan_4b	default	1.0	4	NULL
+plan_4b	pool1	0.0	2	fair
+plan_4b	pool2	0.0	3	fair
+table	table	0.0	1	random
+table	table.pool	0.9	3	priority
+PREHOOK: query: SELECT * FROM SYS.WM_TRIGGERS
+PREHOOK: type: QUERY
+PREHOOK: Input: sys@wm_triggers
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM SYS.WM_TRIGGERS
+POSTHOOK: type: QUERY
+POSTHOOK: Input: sys@wm_triggers
+#### A masked pattern was here ####
+plan_1	trigger_2	BYTES_READ > 100	MOVE TO slow_pool
+plan_4a	trigger_1	BYTES_READ = 10G	KILL
+plan_4a	trigger_2	BYTES_READ = 11G	KILL
+plan_4b	trigger_1	BYTES_READ = 10G	KILL
+plan_4b	trigger_2	BYTES_READ = 11G	KILL
+table	table	BYTES_WRITTEN > 100K	MOVE TO table
+table	trigger	BYTES_WRITTEN > 100K	MOVE TO default
+table	trigger1	ELAPSED_TIME > 10	KILL
+table	trigger2	BYTES_READ > 100	KILL
+PREHOOK: query: SELECT * FROM SYS.WM_POOLS_TO_TRIGGERS
+PREHOOK: type: QUERY
+PREHOOK: Input: sys@wm_pools_to_triggers
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM SYS.WM_POOLS_TO_TRIGGERS
+POSTHOOK: type: QUERY
+POSTHOOK: Input: sys@wm_pools_to_triggers
+#### A masked pattern was here ####
+plan_4a	pool1	trigger_2
+plan_4b	pool1	trigger_2
+table	table	table
+PREHOOK: query: SELECT * FROM SYS.WM_MAPPINGS
+PREHOOK: type: QUERY
+PREHOOK: Input: sys@wm_mappings
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM SYS.WM_MAPPINGS
+POSTHOOK: type: QUERY
+POSTHOOK: Input: sys@wm_mappings
+#### A masked pattern was here ####
+plan_4a	USER	user1	pool1	0
+plan_4b	USER	user1	pool1	0
+PREHOOK: query: REPLACE RESOURCE PLAN plan_4a WITH plan_4b
+PREHOOK: type: ALTER RESOURCEPLAN
+POSTHOOK: query: REPLACE RESOURCE PLAN plan_4a WITH plan_4b
+POSTHOOK: type: ALTER RESOURCEPLAN
+PREHOOK: query: SELECT * FROM SYS.WM_RESOURCEPLANS
+PREHOOK: type: QUERY
+PREHOOK: Input: sys@wm_resourceplans
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM SYS.WM_RESOURCEPLANS
+POSTHOOK: type: QUERY
+POSTHOOK: Input: sys@wm_resourceplans
+#### A masked pattern was here ####
+plan_1	ENABLED	NULL	default
+plan_2	DISABLED	NULL	default
+plan_4	ACTIVE	NULL	default
+plan_4a	DISABLED	NULL	default
+plan_4a-old-0	DISABLED	NULL	default
+table	DISABLED	1	table.pool
+PREHOOK: query: SELECT * FROM SYS.WM_POOLS
+PREHOOK: type: QUERY
+PREHOOK: Input: sys@wm_pools
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM SYS.WM_POOLS
+POSTHOOK: type: QUERY
+POSTHOOK: Input: sys@wm_pools
+#### A masked pattern was here ####
+plan_1	default	1.0	4	NULL
+plan_2	default	1.0	4	NULL
+plan_4	default	1.0	4	NULL
+plan_4a	default	1.0	4	NULL
+plan_4a	pool1	0.0	2	fair
+plan_4a	pool2	0.0	3	fair
+plan_4a-old-0	default	1.0	4	NULL
+plan_4a-old-0	pool1	0.0	2	fair
+table	table	0.0	1	random
+table	table.pool	0.9	3	priority
+PREHOOK: query: REPLACE ACTIVE RESOURCE PLAN WITH plan_4a
+PREHOOK: type: ALTER RESOURCEPLAN
+POSTHOOK: query: REPLACE ACTIVE RESOURCE PLAN WITH plan_4a
+POSTHOOK: type: ALTER RESOURCEPLAN
+PREHOOK: query: SELECT * FROM SYS.WM_RESOURCEPLANS
+PREHOOK: type: QUERY
+PREHOOK: Input: sys@wm_resourceplans
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM SYS.WM_RESOURCEPLANS
+POSTHOOK: type: QUERY
+POSTHOOK: Input: sys@wm_resourceplans
+#### A masked pattern was here ####
+plan_1	ENABLED	NULL	default
+plan_2	DISABLED	NULL	default
+plan_4	ACTIVE	NULL	default
+plan_4-old-0	DISABLED	NULL	default
+plan_4a-old-0	DISABLED	NULL	default
+table	DISABLED	1	table.pool
+PREHOOK: query: CREATE RESOURCE PLAN plan_4a LIKE plan_4
+PREHOOK: type: CREATE RESOURCEPLAN
+POSTHOOK: query: CREATE RESOURCE PLAN plan_4a LIKE plan_4
+POSTHOOK: type: CREATE RESOURCEPLAN
+PREHOOK: query: CREATE POOL plan_4a.pool3 WITH SCHEDULING_POLICY='fair', QUERY_PARALLELISM=3, ALLOC_FRACTION=0.0
+PREHOOK: type: CREATE POOL
+POSTHOOK: query: CREATE POOL plan_4a.pool3 WITH SCHEDULING_POLICY='fair', QUERY_PARALLELISM=3, ALLOC_FRACTION=0.0
+POSTHOOK: type: CREATE POOL
+PREHOOK: query: ALTER RESOURCE PLAN plan_4a ENABLE ACTIVATE WITH REPLACE
+PREHOOK: type: ALTER RESOURCEPLAN
+POSTHOOK: query: ALTER RESOURCE PLAN plan_4a ENABLE ACTIVATE WITH REPLACE
+POSTHOOK: type: ALTER RESOURCEPLAN
+PREHOOK: query: SELECT * FROM SYS.WM_RESOURCEPLANS
+PREHOOK: type: QUERY
+PREHOOK: Input: sys@wm_resourceplans
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM SYS.WM_RESOURCEPLANS
+POSTHOOK: type: QUERY
+POSTHOOK: Input: sys@wm_resourceplans
+#### A masked pattern was here ####
+plan_1	ENABLED	NULL	default
+plan_2	DISABLED	NULL	default
+plan_4	ACTIVE	NULL	default
+plan_4-old-0	DISABLED	NULL	default
+plan_4-old-1	DISABLED	NULL	default
+plan_4a-old-0	DISABLED	NULL	default
+table	DISABLED	1	table.pool
+PREHOOK: query: SELECT * FROM SYS.WM_POOLS
+PREHOOK: type: QUERY
+PREHOOK: Input: sys@wm_pools
+#### A masked pattern was here ####
+POSTHOOK: query: SELECT * FROM SYS.WM_POOLS
+POSTHOOK: type: QUERY
+POSTHOOK: Input: sys@wm_pools
+#### A masked pattern was here ####
+plan_1	default	1.0	4	NULL
+plan_2	default	1.0	4	NULL
+plan_4	default	1.0	4	NULL
+plan_4	pool1	0.0	2	fair
+plan_4	pool2	0.0	3	fair
+plan_4	pool3	0.0	3	fair
+plan_4-old-0	default	1.0	4	NULL
+plan_4-old-1	default	1.0	4	NULL
+plan_4-old-1	pool1	0.0	2	fair
+plan_4-old-1	pool2	0.0	3	fair
+plan_4a-old-0	default	1.0	4	NULL
+plan_4a-old-0	pool1	0.0	2	fair
+table	table	0.0	1	random
+table	table.pool	0.9	3	priority

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/gen/thrift/gen-cpp/hive_metastore_types.cpp
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/gen/thrift/gen-cpp/hive_metastore_types.cpp b/standalone-metastore/src/gen/thrift/gen-cpp/hive_metastore_types.cpp
index 5ed4784..9f78146 100644
--- a/standalone-metastore/src/gen/thrift/gen-cpp/hive_metastore_types.cpp
+++ b/standalone-metastore/src/gen/thrift/gen-cpp/hive_metastore_types.cpp
@@ -21820,6 +21820,11 @@ void WMCreateResourcePlanRequest::__set_resourcePlan(const WMResourcePlan& val)
 __isset.resourcePlan = true;
 }
 
+void WMCreateResourcePlanRequest::__set_copyFrom(const std::string& val) {
+  this->copyFrom = val;
+__isset.copyFrom = true;
+}
+
 uint32_t WMCreateResourcePlanRequest::read(::apache::thrift::protocol::TProtocol* iprot) {
 
   apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
@@ -21849,6 +21854,14 @@ uint32_t WMCreateResourcePlanRequest::read(::apache::thrift::protocol::TProtocol
           xfer += iprot->skip(ftype);
         }
         break;
+      case 2:
+        if (ftype == ::apache::thrift::protocol::T_STRING) {
+          xfer += iprot->readString(this->copyFrom);
+          this->__isset.copyFrom = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
       default:
         xfer += iprot->skip(ftype);
         break;
@@ -21871,6 +21884,11 @@ uint32_t WMCreateResourcePlanRequest::write(::apache::thrift::protocol::TProtoco
     xfer += this->resourcePlan.write(oprot);
     xfer += oprot->writeFieldEnd();
   }
+  if (this->__isset.copyFrom) {
+    xfer += oprot->writeFieldBegin("copyFrom", ::apache::thrift::protocol::T_STRING, 2);
+    xfer += oprot->writeString(this->copyFrom);
+    xfer += oprot->writeFieldEnd();
+  }
   xfer += oprot->writeFieldStop();
   xfer += oprot->writeStructEnd();
   return xfer;
@@ -21879,15 +21897,18 @@ uint32_t WMCreateResourcePlanRequest::write(::apache::thrift::protocol::TProtoco
 void swap(WMCreateResourcePlanRequest &a, WMCreateResourcePlanRequest &b) {
   using ::std::swap;
   swap(a.resourcePlan, b.resourcePlan);
+  swap(a.copyFrom, b.copyFrom);
   swap(a.__isset, b.__isset);
 }
 
 WMCreateResourcePlanRequest::WMCreateResourcePlanRequest(const WMCreateResourcePlanRequest& other900) {
   resourcePlan = other900.resourcePlan;
+  copyFrom = other900.copyFrom;
   __isset = other900.__isset;
 }
 WMCreateResourcePlanRequest& WMCreateResourcePlanRequest::operator=(const WMCreateResourcePlanRequest& other901) {
   resourcePlan = other901.resourcePlan;
+  copyFrom = other901.copyFrom;
   __isset = other901.__isset;
   return *this;
 }
@@ -21895,6 +21916,7 @@ void WMCreateResourcePlanRequest::printTo(std::ostream& out) const {
   using ::apache::thrift::to_string;
   out << "WMCreateResourcePlanRequest(";
   out << "resourcePlan="; (__isset.resourcePlan ? (out << to_string(resourcePlan)) : (out << "<null>"));
+  out << ", " << "copyFrom="; (__isset.copyFrom ? (out << to_string(copyFrom)) : (out << "<null>"));
   out << ")";
 }
 
@@ -22481,6 +22503,11 @@ void WMAlterResourcePlanRequest::__set_isForceDeactivate(const bool val) {
 __isset.isForceDeactivate = true;
 }
 
+void WMAlterResourcePlanRequest::__set_isReplace(const bool val) {
+  this->isReplace = val;
+__isset.isReplace = true;
+}
+
 uint32_t WMAlterResourcePlanRequest::read(::apache::thrift::protocol::TProtocol* iprot) {
 
   apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
@@ -22534,6 +22561,14 @@ uint32_t WMAlterResourcePlanRequest::read(::apache::thrift::protocol::TProtocol*
           xfer += iprot->skip(ftype);
         }
         break;
+      case 5:
+        if (ftype == ::apache::thrift::protocol::T_BOOL) {
+          xfer += iprot->readBool(this->isReplace);
+          this->__isset.isReplace = true;
+        } else {
+          xfer += iprot->skip(ftype);
+        }
+        break;
       default:
         xfer += iprot->skip(ftype);
         break;
@@ -22571,6 +22606,11 @@ uint32_t WMAlterResourcePlanRequest::write(::apache::thrift::protocol::TProtocol
     xfer += oprot->writeBool(this->isForceDeactivate);
     xfer += oprot->writeFieldEnd();
   }
+  if (this->__isset.isReplace) {
+    xfer += oprot->writeFieldBegin("isReplace", ::apache::thrift::protocol::T_BOOL, 5);
+    xfer += oprot->writeBool(this->isReplace);
+    xfer += oprot->writeFieldEnd();
+  }
   xfer += oprot->writeFieldStop();
   xfer += oprot->writeStructEnd();
   return xfer;
@@ -22582,6 +22622,7 @@ void swap(WMAlterResourcePlanRequest &a, WMAlterResourcePlanRequest &b) {
   swap(a.resourcePlan, b.resourcePlan);
   swap(a.isEnableAndActivate, b.isEnableAndActivate);
   swap(a.isForceDeactivate, b.isForceDeactivate);
+  swap(a.isReplace, b.isReplace);
   swap(a.__isset, b.__isset);
 }
 
@@ -22590,6 +22631,7 @@ WMAlterResourcePlanRequest::WMAlterResourcePlanRequest(const WMAlterResourcePlan
   resourcePlan = other922.resourcePlan;
   isEnableAndActivate = other922.isEnableAndActivate;
   isForceDeactivate = other922.isForceDeactivate;
+  isReplace = other922.isReplace;
   __isset = other922.__isset;
 }
 WMAlterResourcePlanRequest& WMAlterResourcePlanRequest::operator=(const WMAlterResourcePlanRequest& other923) {
@@ -22597,6 +22639,7 @@ WMAlterResourcePlanRequest& WMAlterResourcePlanRequest::operator=(const WMAlterR
   resourcePlan = other923.resourcePlan;
   isEnableAndActivate = other923.isEnableAndActivate;
   isForceDeactivate = other923.isForceDeactivate;
+  isReplace = other923.isReplace;
   __isset = other923.__isset;
   return *this;
 }
@@ -22607,6 +22650,7 @@ void WMAlterResourcePlanRequest::printTo(std::ostream& out) const {
   out << ", " << "resourcePlan="; (__isset.resourcePlan ? (out << to_string(resourcePlan)) : (out << "<null>"));
   out << ", " << "isEnableAndActivate="; (__isset.isEnableAndActivate ? (out << to_string(isEnableAndActivate)) : (out << "<null>"));
   out << ", " << "isForceDeactivate="; (__isset.isForceDeactivate ? (out << to_string(isForceDeactivate)) : (out << "<null>"));
+  out << ", " << "isReplace="; (__isset.isReplace ? (out << to_string(isReplace)) : (out << "<null>"));
   out << ")";
 }
 

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/gen/thrift/gen-cpp/hive_metastore_types.h
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/gen/thrift/gen-cpp/hive_metastore_types.h b/standalone-metastore/src/gen/thrift/gen-cpp/hive_metastore_types.h
index 0d0bc19..96e5234 100644
--- a/standalone-metastore/src/gen/thrift/gen-cpp/hive_metastore_types.h
+++ b/standalone-metastore/src/gen/thrift/gen-cpp/hive_metastore_types.h
@@ -8932,8 +8932,9 @@ inline std::ostream& operator<<(std::ostream& out, const WMFullResourcePlan& obj
 }
 
 typedef struct _WMCreateResourcePlanRequest__isset {
-  _WMCreateResourcePlanRequest__isset() : resourcePlan(false) {}
+  _WMCreateResourcePlanRequest__isset() : resourcePlan(false), copyFrom(false) {}
   bool resourcePlan :1;
+  bool copyFrom :1;
 } _WMCreateResourcePlanRequest__isset;
 
 class WMCreateResourcePlanRequest {
@@ -8941,22 +8942,29 @@ class WMCreateResourcePlanRequest {
 
   WMCreateResourcePlanRequest(const WMCreateResourcePlanRequest&);
   WMCreateResourcePlanRequest& operator=(const WMCreateResourcePlanRequest&);
-  WMCreateResourcePlanRequest() {
+  WMCreateResourcePlanRequest() : copyFrom() {
   }
 
   virtual ~WMCreateResourcePlanRequest() throw();
   WMResourcePlan resourcePlan;
+  std::string copyFrom;
 
   _WMCreateResourcePlanRequest__isset __isset;
 
   void __set_resourcePlan(const WMResourcePlan& val);
 
+  void __set_copyFrom(const std::string& val);
+
   bool operator == (const WMCreateResourcePlanRequest & rhs) const
   {
     if (__isset.resourcePlan != rhs.__isset.resourcePlan)
       return false;
     else if (__isset.resourcePlan && !(resourcePlan == rhs.resourcePlan))
       return false;
+    if (__isset.copyFrom != rhs.__isset.copyFrom)
+      return false;
+    else if (__isset.copyFrom && !(copyFrom == rhs.copyFrom))
+      return false;
     return true;
   }
   bool operator != (const WMCreateResourcePlanRequest &rhs) const {
@@ -9277,11 +9285,12 @@ inline std::ostream& operator<<(std::ostream& out, const WMGetAllResourcePlanRes
 }
 
 typedef struct _WMAlterResourcePlanRequest__isset {
-  _WMAlterResourcePlanRequest__isset() : resourcePlanName(false), resourcePlan(false), isEnableAndActivate(false), isForceDeactivate(false) {}
+  _WMAlterResourcePlanRequest__isset() : resourcePlanName(false), resourcePlan(false), isEnableAndActivate(false), isForceDeactivate(false), isReplace(false) {}
   bool resourcePlanName :1;
   bool resourcePlan :1;
   bool isEnableAndActivate :1;
   bool isForceDeactivate :1;
+  bool isReplace :1;
 } _WMAlterResourcePlanRequest__isset;
 
 class WMAlterResourcePlanRequest {
@@ -9289,7 +9298,7 @@ class WMAlterResourcePlanRequest {
 
   WMAlterResourcePlanRequest(const WMAlterResourcePlanRequest&);
   WMAlterResourcePlanRequest& operator=(const WMAlterResourcePlanRequest&);
-  WMAlterResourcePlanRequest() : resourcePlanName(), isEnableAndActivate(0), isForceDeactivate(0) {
+  WMAlterResourcePlanRequest() : resourcePlanName(), isEnableAndActivate(0), isForceDeactivate(0), isReplace(0) {
   }
 
   virtual ~WMAlterResourcePlanRequest() throw();
@@ -9297,6 +9306,7 @@ class WMAlterResourcePlanRequest {
   WMResourcePlan resourcePlan;
   bool isEnableAndActivate;
   bool isForceDeactivate;
+  bool isReplace;
 
   _WMAlterResourcePlanRequest__isset __isset;
 
@@ -9308,6 +9318,8 @@ class WMAlterResourcePlanRequest {
 
   void __set_isForceDeactivate(const bool val);
 
+  void __set_isReplace(const bool val);
+
   bool operator == (const WMAlterResourcePlanRequest & rhs) const
   {
     if (__isset.resourcePlanName != rhs.__isset.resourcePlanName)
@@ -9326,6 +9338,10 @@ class WMAlterResourcePlanRequest {
       return false;
     else if (__isset.isForceDeactivate && !(isForceDeactivate == rhs.isForceDeactivate))
       return false;
+    if (__isset.isReplace != rhs.__isset.isReplace)
+      return false;
+    else if (__isset.isReplace && !(isReplace == rhs.isReplace))
+      return false;
     return true;
   }
   bool operator != (const WMAlterResourcePlanRequest &rhs) const {

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/gen/thrift/gen-javabean/org/apache/hadoop/hive/metastore/api/WMAlterResourcePlanRequest.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/gen/thrift/gen-javabean/org/apache/hadoop/hive/metastore/api/WMAlterResourcePlanRequest.java b/standalone-metastore/src/gen/thrift/gen-javabean/org/apache/hadoop/hive/metastore/api/WMAlterResourcePlanRequest.java
index bf67e2f..cc85d0a 100644
--- a/standalone-metastore/src/gen/thrift/gen-javabean/org/apache/hadoop/hive/metastore/api/WMAlterResourcePlanRequest.java
+++ b/standalone-metastore/src/gen/thrift/gen-javabean/org/apache/hadoop/hive/metastore/api/WMAlterResourcePlanRequest.java
@@ -42,6 +42,7 @@ import org.slf4j.LoggerFactory;
   private static final org.apache.thrift.protocol.TField RESOURCE_PLAN_FIELD_DESC = new org.apache.thrift.protocol.TField("resourcePlan", org.apache.thrift.protocol.TType.STRUCT, (short)2);
   private static final org.apache.thrift.protocol.TField IS_ENABLE_AND_ACTIVATE_FIELD_DESC = new org.apache.thrift.protocol.TField("isEnableAndActivate", org.apache.thrift.protocol.TType.BOOL, (short)3);
   private static final org.apache.thrift.protocol.TField IS_FORCE_DEACTIVATE_FIELD_DESC = new org.apache.thrift.protocol.TField("isForceDeactivate", org.apache.thrift.protocol.TType.BOOL, (short)4);
+  private static final org.apache.thrift.protocol.TField IS_REPLACE_FIELD_DESC = new org.apache.thrift.protocol.TField("isReplace", org.apache.thrift.protocol.TType.BOOL, (short)5);
 
   private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
   static {
@@ -53,13 +54,15 @@ import org.slf4j.LoggerFactory;
   private WMResourcePlan resourcePlan; // optional
   private boolean isEnableAndActivate; // optional
   private boolean isForceDeactivate; // optional
+  private boolean isReplace; // optional
 
   /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
   public enum _Fields implements org.apache.thrift.TFieldIdEnum {
     RESOURCE_PLAN_NAME((short)1, "resourcePlanName"),
     RESOURCE_PLAN((short)2, "resourcePlan"),
     IS_ENABLE_AND_ACTIVATE((short)3, "isEnableAndActivate"),
-    IS_FORCE_DEACTIVATE((short)4, "isForceDeactivate");
+    IS_FORCE_DEACTIVATE((short)4, "isForceDeactivate"),
+    IS_REPLACE((short)5, "isReplace");
 
     private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
 
@@ -82,6 +85,8 @@ import org.slf4j.LoggerFactory;
           return IS_ENABLE_AND_ACTIVATE;
         case 4: // IS_FORCE_DEACTIVATE
           return IS_FORCE_DEACTIVATE;
+        case 5: // IS_REPLACE
+          return IS_REPLACE;
         default:
           return null;
       }
@@ -124,8 +129,9 @@ import org.slf4j.LoggerFactory;
   // isset id assignments
   private static final int __ISENABLEANDACTIVATE_ISSET_ID = 0;
   private static final int __ISFORCEDEACTIVATE_ISSET_ID = 1;
+  private static final int __ISREPLACE_ISSET_ID = 2;
   private byte __isset_bitfield = 0;
-  private static final _Fields optionals[] = {_Fields.RESOURCE_PLAN_NAME,_Fields.RESOURCE_PLAN,_Fields.IS_ENABLE_AND_ACTIVATE,_Fields.IS_FORCE_DEACTIVATE};
+  private static final _Fields optionals[] = {_Fields.RESOURCE_PLAN_NAME,_Fields.RESOURCE_PLAN,_Fields.IS_ENABLE_AND_ACTIVATE,_Fields.IS_FORCE_DEACTIVATE,_Fields.IS_REPLACE};
   public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
   static {
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
@@ -137,6 +143,8 @@ import org.slf4j.LoggerFactory;
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
     tmpMap.put(_Fields.IS_FORCE_DEACTIVATE, new org.apache.thrift.meta_data.FieldMetaData("isForceDeactivate", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
+    tmpMap.put(_Fields.IS_REPLACE, new org.apache.thrift.meta_data.FieldMetaData("isReplace", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
     metaDataMap = Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(WMAlterResourcePlanRequest.class, metaDataMap);
   }
@@ -157,6 +165,7 @@ import org.slf4j.LoggerFactory;
     }
     this.isEnableAndActivate = other.isEnableAndActivate;
     this.isForceDeactivate = other.isForceDeactivate;
+    this.isReplace = other.isReplace;
   }
 
   public WMAlterResourcePlanRequest deepCopy() {
@@ -171,6 +180,8 @@ import org.slf4j.LoggerFactory;
     this.isEnableAndActivate = false;
     setIsForceDeactivateIsSet(false);
     this.isForceDeactivate = false;
+    setIsReplaceIsSet(false);
+    this.isReplace = false;
   }
 
   public String getResourcePlanName() {
@@ -263,6 +274,28 @@ import org.slf4j.LoggerFactory;
     __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ISFORCEDEACTIVATE_ISSET_ID, value);
   }
 
+  public boolean isIsReplace() {
+    return this.isReplace;
+  }
+
+  public void setIsReplace(boolean isReplace) {
+    this.isReplace = isReplace;
+    setIsReplaceIsSet(true);
+  }
+
+  public void unsetIsReplace() {
+    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __ISREPLACE_ISSET_ID);
+  }
+
+  /** Returns true if field isReplace is set (has been assigned a value) and false otherwise */
+  public boolean isSetIsReplace() {
+    return EncodingUtils.testBit(__isset_bitfield, __ISREPLACE_ISSET_ID);
+  }
+
+  public void setIsReplaceIsSet(boolean value) {
+    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __ISREPLACE_ISSET_ID, value);
+  }
+
   public void setFieldValue(_Fields field, Object value) {
     switch (field) {
     case RESOURCE_PLAN_NAME:
@@ -297,6 +330,14 @@ import org.slf4j.LoggerFactory;
       }
       break;
 
+    case IS_REPLACE:
+      if (value == null) {
+        unsetIsReplace();
+      } else {
+        setIsReplace((Boolean)value);
+      }
+      break;
+
     }
   }
 
@@ -314,6 +355,9 @@ import org.slf4j.LoggerFactory;
     case IS_FORCE_DEACTIVATE:
       return isIsForceDeactivate();
 
+    case IS_REPLACE:
+      return isIsReplace();
+
     }
     throw new IllegalStateException();
   }
@@ -333,6 +377,8 @@ import org.slf4j.LoggerFactory;
       return isSetIsEnableAndActivate();
     case IS_FORCE_DEACTIVATE:
       return isSetIsForceDeactivate();
+    case IS_REPLACE:
+      return isSetIsReplace();
     }
     throw new IllegalStateException();
   }
@@ -386,6 +432,15 @@ import org.slf4j.LoggerFactory;
         return false;
     }
 
+    boolean this_present_isReplace = true && this.isSetIsReplace();
+    boolean that_present_isReplace = true && that.isSetIsReplace();
+    if (this_present_isReplace || that_present_isReplace) {
+      if (!(this_present_isReplace && that_present_isReplace))
+        return false;
+      if (this.isReplace != that.isReplace)
+        return false;
+    }
+
     return true;
   }
 
@@ -413,6 +468,11 @@ import org.slf4j.LoggerFactory;
     if (present_isForceDeactivate)
       list.add(isForceDeactivate);
 
+    boolean present_isReplace = true && (isSetIsReplace());
+    list.add(present_isReplace);
+    if (present_isReplace)
+      list.add(isReplace);
+
     return list.hashCode();
   }
 
@@ -464,6 +524,16 @@ import org.slf4j.LoggerFactory;
         return lastComparison;
       }
     }
+    lastComparison = Boolean.valueOf(isSetIsReplace()).compareTo(other.isSetIsReplace());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetIsReplace()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.isReplace, other.isReplace);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
     return 0;
   }
 
@@ -515,6 +585,12 @@ import org.slf4j.LoggerFactory;
       sb.append(this.isForceDeactivate);
       first = false;
     }
+    if (isSetIsReplace()) {
+      if (!first) sb.append(", ");
+      sb.append("isReplace:");
+      sb.append(this.isReplace);
+      first = false;
+    }
     sb.append(")");
     return sb.toString();
   }
@@ -596,6 +672,14 @@ import org.slf4j.LoggerFactory;
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
             }
             break;
+          case 5: // IS_REPLACE
+            if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
+              struct.isReplace = iprot.readBool();
+              struct.setIsReplaceIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
           default:
             org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
         }
@@ -633,6 +717,11 @@ import org.slf4j.LoggerFactory;
         oprot.writeBool(struct.isForceDeactivate);
         oprot.writeFieldEnd();
       }
+      if (struct.isSetIsReplace()) {
+        oprot.writeFieldBegin(IS_REPLACE_FIELD_DESC);
+        oprot.writeBool(struct.isReplace);
+        oprot.writeFieldEnd();
+      }
       oprot.writeFieldStop();
       oprot.writeStructEnd();
     }
@@ -663,7 +752,10 @@ import org.slf4j.LoggerFactory;
       if (struct.isSetIsForceDeactivate()) {
         optionals.set(3);
       }
-      oprot.writeBitSet(optionals, 4);
+      if (struct.isSetIsReplace()) {
+        optionals.set(4);
+      }
+      oprot.writeBitSet(optionals, 5);
       if (struct.isSetResourcePlanName()) {
         oprot.writeString(struct.resourcePlanName);
       }
@@ -676,12 +768,15 @@ import org.slf4j.LoggerFactory;
       if (struct.isSetIsForceDeactivate()) {
         oprot.writeBool(struct.isForceDeactivate);
       }
+      if (struct.isSetIsReplace()) {
+        oprot.writeBool(struct.isReplace);
+      }
     }
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, WMAlterResourcePlanRequest struct) throws org.apache.thrift.TException {
       TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(4);
+      BitSet incoming = iprot.readBitSet(5);
       if (incoming.get(0)) {
         struct.resourcePlanName = iprot.readString();
         struct.setResourcePlanNameIsSet(true);
@@ -699,6 +794,10 @@ import org.slf4j.LoggerFactory;
         struct.isForceDeactivate = iprot.readBool();
         struct.setIsForceDeactivateIsSet(true);
       }
+      if (incoming.get(4)) {
+        struct.isReplace = iprot.readBool();
+        struct.setIsReplaceIsSet(true);
+      }
     }
   }
 

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/gen/thrift/gen-javabean/org/apache/hadoop/hive/metastore/api/WMCreateResourcePlanRequest.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/gen/thrift/gen-javabean/org/apache/hadoop/hive/metastore/api/WMCreateResourcePlanRequest.java b/standalone-metastore/src/gen/thrift/gen-javabean/org/apache/hadoop/hive/metastore/api/WMCreateResourcePlanRequest.java
index 1af2159..902dcfc 100644
--- a/standalone-metastore/src/gen/thrift/gen-javabean/org/apache/hadoop/hive/metastore/api/WMCreateResourcePlanRequest.java
+++ b/standalone-metastore/src/gen/thrift/gen-javabean/org/apache/hadoop/hive/metastore/api/WMCreateResourcePlanRequest.java
@@ -39,6 +39,7 @@ import org.slf4j.LoggerFactory;
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("WMCreateResourcePlanRequest");
 
   private static final org.apache.thrift.protocol.TField RESOURCE_PLAN_FIELD_DESC = new org.apache.thrift.protocol.TField("resourcePlan", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+  private static final org.apache.thrift.protocol.TField COPY_FROM_FIELD_DESC = new org.apache.thrift.protocol.TField("copyFrom", org.apache.thrift.protocol.TType.STRING, (short)2);
 
   private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
   static {
@@ -47,10 +48,12 @@ import org.slf4j.LoggerFactory;
   }
 
   private WMResourcePlan resourcePlan; // optional
+  private String copyFrom; // optional
 
   /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
   public enum _Fields implements org.apache.thrift.TFieldIdEnum {
-    RESOURCE_PLAN((short)1, "resourcePlan");
+    RESOURCE_PLAN((short)1, "resourcePlan"),
+    COPY_FROM((short)2, "copyFrom");
 
     private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
 
@@ -67,6 +70,8 @@ import org.slf4j.LoggerFactory;
       switch(fieldId) {
         case 1: // RESOURCE_PLAN
           return RESOURCE_PLAN;
+        case 2: // COPY_FROM
+          return COPY_FROM;
         default:
           return null;
       }
@@ -107,12 +112,14 @@ import org.slf4j.LoggerFactory;
   }
 
   // isset id assignments
-  private static final _Fields optionals[] = {_Fields.RESOURCE_PLAN};
+  private static final _Fields optionals[] = {_Fields.RESOURCE_PLAN,_Fields.COPY_FROM};
   public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
   static {
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.RESOURCE_PLAN, new org.apache.thrift.meta_data.FieldMetaData("resourcePlan", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
         new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, WMResourcePlan.class)));
+    tmpMap.put(_Fields.COPY_FROM, new org.apache.thrift.meta_data.FieldMetaData("copyFrom", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
     metaDataMap = Collections.unmodifiableMap(tmpMap);
     org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(WMCreateResourcePlanRequest.class, metaDataMap);
   }
@@ -127,6 +134,9 @@ import org.slf4j.LoggerFactory;
     if (other.isSetResourcePlan()) {
       this.resourcePlan = new WMResourcePlan(other.resourcePlan);
     }
+    if (other.isSetCopyFrom()) {
+      this.copyFrom = other.copyFrom;
+    }
   }
 
   public WMCreateResourcePlanRequest deepCopy() {
@@ -136,6 +146,7 @@ import org.slf4j.LoggerFactory;
   @Override
   public void clear() {
     this.resourcePlan = null;
+    this.copyFrom = null;
   }
 
   public WMResourcePlan getResourcePlan() {
@@ -161,6 +172,29 @@ import org.slf4j.LoggerFactory;
     }
   }
 
+  public String getCopyFrom() {
+    return this.copyFrom;
+  }
+
+  public void setCopyFrom(String copyFrom) {
+    this.copyFrom = copyFrom;
+  }
+
+  public void unsetCopyFrom() {
+    this.copyFrom = null;
+  }
+
+  /** Returns true if field copyFrom is set (has been assigned a value) and false otherwise */
+  public boolean isSetCopyFrom() {
+    return this.copyFrom != null;
+  }
+
+  public void setCopyFromIsSet(boolean value) {
+    if (!value) {
+      this.copyFrom = null;
+    }
+  }
+
   public void setFieldValue(_Fields field, Object value) {
     switch (field) {
     case RESOURCE_PLAN:
@@ -171,6 +205,14 @@ import org.slf4j.LoggerFactory;
       }
       break;
 
+    case COPY_FROM:
+      if (value == null) {
+        unsetCopyFrom();
+      } else {
+        setCopyFrom((String)value);
+      }
+      break;
+
     }
   }
 
@@ -179,6 +221,9 @@ import org.slf4j.LoggerFactory;
     case RESOURCE_PLAN:
       return getResourcePlan();
 
+    case COPY_FROM:
+      return getCopyFrom();
+
     }
     throw new IllegalStateException();
   }
@@ -192,6 +237,8 @@ import org.slf4j.LoggerFactory;
     switch (field) {
     case RESOURCE_PLAN:
       return isSetResourcePlan();
+    case COPY_FROM:
+      return isSetCopyFrom();
     }
     throw new IllegalStateException();
   }
@@ -218,6 +265,15 @@ import org.slf4j.LoggerFactory;
         return false;
     }
 
+    boolean this_present_copyFrom = true && this.isSetCopyFrom();
+    boolean that_present_copyFrom = true && that.isSetCopyFrom();
+    if (this_present_copyFrom || that_present_copyFrom) {
+      if (!(this_present_copyFrom && that_present_copyFrom))
+        return false;
+      if (!this.copyFrom.equals(that.copyFrom))
+        return false;
+    }
+
     return true;
   }
 
@@ -230,6 +286,11 @@ import org.slf4j.LoggerFactory;
     if (present_resourcePlan)
       list.add(resourcePlan);
 
+    boolean present_copyFrom = true && (isSetCopyFrom());
+    list.add(present_copyFrom);
+    if (present_copyFrom)
+      list.add(copyFrom);
+
     return list.hashCode();
   }
 
@@ -251,6 +312,16 @@ import org.slf4j.LoggerFactory;
         return lastComparison;
       }
     }
+    lastComparison = Boolean.valueOf(isSetCopyFrom()).compareTo(other.isSetCopyFrom());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetCopyFrom()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.copyFrom, other.copyFrom);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
     return 0;
   }
 
@@ -280,6 +351,16 @@ import org.slf4j.LoggerFactory;
       }
       first = false;
     }
+    if (isSetCopyFrom()) {
+      if (!first) sb.append(", ");
+      sb.append("copyFrom:");
+      if (this.copyFrom == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.copyFrom);
+      }
+      first = false;
+    }
     sb.append(")");
     return sb.toString();
   }
@@ -335,6 +416,14 @@ import org.slf4j.LoggerFactory;
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
             }
             break;
+          case 2: // COPY_FROM
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.copyFrom = iprot.readString();
+              struct.setCopyFromIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
           default:
             org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
         }
@@ -355,6 +444,13 @@ import org.slf4j.LoggerFactory;
           oprot.writeFieldEnd();
         }
       }
+      if (struct.copyFrom != null) {
+        if (struct.isSetCopyFrom()) {
+          oprot.writeFieldBegin(COPY_FROM_FIELD_DESC);
+          oprot.writeString(struct.copyFrom);
+          oprot.writeFieldEnd();
+        }
+      }
       oprot.writeFieldStop();
       oprot.writeStructEnd();
     }
@@ -376,21 +472,31 @@ import org.slf4j.LoggerFactory;
       if (struct.isSetResourcePlan()) {
         optionals.set(0);
       }
-      oprot.writeBitSet(optionals, 1);
+      if (struct.isSetCopyFrom()) {
+        optionals.set(1);
+      }
+      oprot.writeBitSet(optionals, 2);
       if (struct.isSetResourcePlan()) {
         struct.resourcePlan.write(oprot);
       }
+      if (struct.isSetCopyFrom()) {
+        oprot.writeString(struct.copyFrom);
+      }
     }
 
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, WMCreateResourcePlanRequest struct) throws org.apache.thrift.TException {
       TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(1);
+      BitSet incoming = iprot.readBitSet(2);
       if (incoming.get(0)) {
         struct.resourcePlan = new WMResourcePlan();
         struct.resourcePlan.read(iprot);
         struct.setResourcePlanIsSet(true);
       }
+      if (incoming.get(1)) {
+        struct.copyFrom = iprot.readString();
+        struct.setCopyFromIsSet(true);
+      }
     }
   }
 

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/gen/thrift/gen-php/metastore/Types.php
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/gen/thrift/gen-php/metastore/Types.php b/standalone-metastore/src/gen/thrift/gen-php/metastore/Types.php
index 39167f5..3e15816 100644
--- a/standalone-metastore/src/gen/thrift/gen-php/metastore/Types.php
+++ b/standalone-metastore/src/gen/thrift/gen-php/metastore/Types.php
@@ -21454,6 +21454,10 @@ class WMCreateResourcePlanRequest {
    * @var \metastore\WMResourcePlan
    */
   public $resourcePlan = null;
+  /**
+   * @var string
+   */
+  public $copyFrom = null;
 
   public function __construct($vals=null) {
     if (!isset(self::$_TSPEC)) {
@@ -21463,12 +21467,19 @@ class WMCreateResourcePlanRequest {
           'type' => TType::STRUCT,
           'class' => '\metastore\WMResourcePlan',
           ),
+        2 => array(
+          'var' => 'copyFrom',
+          'type' => TType::STRING,
+          ),
         );
     }
     if (is_array($vals)) {
       if (isset($vals['resourcePlan'])) {
         $this->resourcePlan = $vals['resourcePlan'];
       }
+      if (isset($vals['copyFrom'])) {
+        $this->copyFrom = $vals['copyFrom'];
+      }
     }
   }
 
@@ -21499,6 +21510,13 @@ class WMCreateResourcePlanRequest {
             $xfer += $input->skip($ftype);
           }
           break;
+        case 2:
+          if ($ftype == TType::STRING) {
+            $xfer += $input->readString($this->copyFrom);
+          } else {
+            $xfer += $input->skip($ftype);
+          }
+          break;
         default:
           $xfer += $input->skip($ftype);
           break;
@@ -21520,6 +21538,11 @@ class WMCreateResourcePlanRequest {
       $xfer += $this->resourcePlan->write($output);
       $xfer += $output->writeFieldEnd();
     }
+    if ($this->copyFrom !== null) {
+      $xfer += $output->writeFieldBegin('copyFrom', TType::STRING, 2);
+      $xfer += $output->writeString($this->copyFrom);
+      $xfer += $output->writeFieldEnd();
+    }
     $xfer += $output->writeFieldStop();
     $xfer += $output->writeStructEnd();
     return $xfer;
@@ -22034,6 +22057,10 @@ class WMAlterResourcePlanRequest {
    * @var bool
    */
   public $isForceDeactivate = null;
+  /**
+   * @var bool
+   */
+  public $isReplace = null;
 
   public function __construct($vals=null) {
     if (!isset(self::$_TSPEC)) {
@@ -22055,6 +22082,10 @@ class WMAlterResourcePlanRequest {
           'var' => 'isForceDeactivate',
           'type' => TType::BOOL,
           ),
+        5 => array(
+          'var' => 'isReplace',
+          'type' => TType::BOOL,
+          ),
         );
     }
     if (is_array($vals)) {
@@ -22070,6 +22101,9 @@ class WMAlterResourcePlanRequest {
       if (isset($vals['isForceDeactivate'])) {
         $this->isForceDeactivate = $vals['isForceDeactivate'];
       }
+      if (isset($vals['isReplace'])) {
+        $this->isReplace = $vals['isReplace'];
+      }
     }
   }
 
@@ -22121,6 +22155,13 @@ class WMAlterResourcePlanRequest {
             $xfer += $input->skip($ftype);
           }
           break;
+        case 5:
+          if ($ftype == TType::BOOL) {
+            $xfer += $input->readBool($this->isReplace);
+          } else {
+            $xfer += $input->skip($ftype);
+          }
+          break;
         default:
           $xfer += $input->skip($ftype);
           break;
@@ -22157,6 +22198,11 @@ class WMAlterResourcePlanRequest {
       $xfer += $output->writeBool($this->isForceDeactivate);
       $xfer += $output->writeFieldEnd();
     }
+    if ($this->isReplace !== null) {
+      $xfer += $output->writeFieldBegin('isReplace', TType::BOOL, 5);
+      $xfer += $output->writeBool($this->isReplace);
+      $xfer += $output->writeFieldEnd();
+    }
     $xfer += $output->writeFieldStop();
     $xfer += $output->writeStructEnd();
     return $xfer;

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/gen/thrift/gen-py/hive_metastore/ttypes.py
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/gen/thrift/gen-py/hive_metastore/ttypes.py b/standalone-metastore/src/gen/thrift/gen-py/hive_metastore/ttypes.py
index 6175e6a..b5671f4 100644
--- a/standalone-metastore/src/gen/thrift/gen-py/hive_metastore/ttypes.py
+++ b/standalone-metastore/src/gen/thrift/gen-py/hive_metastore/ttypes.py
@@ -15124,15 +15124,18 @@ class WMCreateResourcePlanRequest:
   """
   Attributes:
    - resourcePlan
+   - copyFrom
   """
 
   thrift_spec = (
     None, # 0
     (1, TType.STRUCT, 'resourcePlan', (WMResourcePlan, WMResourcePlan.thrift_spec), None, ), # 1
+    (2, TType.STRING, 'copyFrom', None, None, ), # 2
   )
 
-  def __init__(self, resourcePlan=None,):
+  def __init__(self, resourcePlan=None, copyFrom=None,):
     self.resourcePlan = resourcePlan
+    self.copyFrom = copyFrom
 
   def read(self, iprot):
     if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
@@ -15149,6 +15152,11 @@ class WMCreateResourcePlanRequest:
           self.resourcePlan.read(iprot)
         else:
           iprot.skip(ftype)
+      elif fid == 2:
+        if ftype == TType.STRING:
+          self.copyFrom = iprot.readString()
+        else:
+          iprot.skip(ftype)
       else:
         iprot.skip(ftype)
       iprot.readFieldEnd()
@@ -15163,6 +15171,10 @@ class WMCreateResourcePlanRequest:
       oprot.writeFieldBegin('resourcePlan', TType.STRUCT, 1)
       self.resourcePlan.write(oprot)
       oprot.writeFieldEnd()
+    if self.copyFrom is not None:
+      oprot.writeFieldBegin('copyFrom', TType.STRING, 2)
+      oprot.writeString(self.copyFrom)
+      oprot.writeFieldEnd()
     oprot.writeFieldStop()
     oprot.writeStructEnd()
 
@@ -15173,6 +15185,7 @@ class WMCreateResourcePlanRequest:
   def __hash__(self):
     value = 17
     value = (value * 31) ^ hash(self.resourcePlan)
+    value = (value * 31) ^ hash(self.copyFrom)
     return value
 
   def __repr__(self):
@@ -15602,6 +15615,7 @@ class WMAlterResourcePlanRequest:
    - resourcePlan
    - isEnableAndActivate
    - isForceDeactivate
+   - isReplace
   """
 
   thrift_spec = (
@@ -15610,13 +15624,15 @@ class WMAlterResourcePlanRequest:
     (2, TType.STRUCT, 'resourcePlan', (WMResourcePlan, WMResourcePlan.thrift_spec), None, ), # 2
     (3, TType.BOOL, 'isEnableAndActivate', None, None, ), # 3
     (4, TType.BOOL, 'isForceDeactivate', None, None, ), # 4
+    (5, TType.BOOL, 'isReplace', None, None, ), # 5
   )
 
-  def __init__(self, resourcePlanName=None, resourcePlan=None, isEnableAndActivate=None, isForceDeactivate=None,):
+  def __init__(self, resourcePlanName=None, resourcePlan=None, isEnableAndActivate=None, isForceDeactivate=None, isReplace=None,):
     self.resourcePlanName = resourcePlanName
     self.resourcePlan = resourcePlan
     self.isEnableAndActivate = isEnableAndActivate
     self.isForceDeactivate = isForceDeactivate
+    self.isReplace = isReplace
 
   def read(self, iprot):
     if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None:
@@ -15648,6 +15664,11 @@ class WMAlterResourcePlanRequest:
           self.isForceDeactivate = iprot.readBool()
         else:
           iprot.skip(ftype)
+      elif fid == 5:
+        if ftype == TType.BOOL:
+          self.isReplace = iprot.readBool()
+        else:
+          iprot.skip(ftype)
       else:
         iprot.skip(ftype)
       iprot.readFieldEnd()
@@ -15674,6 +15695,10 @@ class WMAlterResourcePlanRequest:
       oprot.writeFieldBegin('isForceDeactivate', TType.BOOL, 4)
       oprot.writeBool(self.isForceDeactivate)
       oprot.writeFieldEnd()
+    if self.isReplace is not None:
+      oprot.writeFieldBegin('isReplace', TType.BOOL, 5)
+      oprot.writeBool(self.isReplace)
+      oprot.writeFieldEnd()
     oprot.writeFieldStop()
     oprot.writeStructEnd()
 
@@ -15687,6 +15712,7 @@ class WMAlterResourcePlanRequest:
     value = (value * 31) ^ hash(self.resourcePlan)
     value = (value * 31) ^ hash(self.isEnableAndActivate)
     value = (value * 31) ^ hash(self.isForceDeactivate)
+    value = (value * 31) ^ hash(self.isReplace)
     return value
 
   def __repr__(self):

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/gen/thrift/gen-rb/hive_metastore_types.rb
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/gen/thrift/gen-rb/hive_metastore_types.rb b/standalone-metastore/src/gen/thrift/gen-rb/hive_metastore_types.rb
index 606716c..3d8346d 100644
--- a/standalone-metastore/src/gen/thrift/gen-rb/hive_metastore_types.rb
+++ b/standalone-metastore/src/gen/thrift/gen-rb/hive_metastore_types.rb
@@ -3405,9 +3405,11 @@ end
 class WMCreateResourcePlanRequest
   include ::Thrift::Struct, ::Thrift::Struct_Union
   RESOURCEPLAN = 1
+  COPYFROM = 2
 
   FIELDS = {
-    RESOURCEPLAN => {:type => ::Thrift::Types::STRUCT, :name => 'resourcePlan', :class => ::WMResourcePlan, :optional => true}
+    RESOURCEPLAN => {:type => ::Thrift::Types::STRUCT, :name => 'resourcePlan', :class => ::WMResourcePlan, :optional => true},
+    COPYFROM => {:type => ::Thrift::Types::STRING, :name => 'copyFrom', :optional => true}
   }
 
   def struct_fields; FIELDS; end
@@ -3533,12 +3535,14 @@ class WMAlterResourcePlanRequest
   RESOURCEPLAN = 2
   ISENABLEANDACTIVATE = 3
   ISFORCEDEACTIVATE = 4
+  ISREPLACE = 5
 
   FIELDS = {
     RESOURCEPLANNAME => {:type => ::Thrift::Types::STRING, :name => 'resourcePlanName', :optional => true},
     RESOURCEPLAN => {:type => ::Thrift::Types::STRUCT, :name => 'resourcePlan', :class => ::WMResourcePlan, :optional => true},
     ISENABLEANDACTIVATE => {:type => ::Thrift::Types::BOOL, :name => 'isEnableAndActivate', :optional => true},
-    ISFORCEDEACTIVATE => {:type => ::Thrift::Types::BOOL, :name => 'isForceDeactivate', :optional => true}
+    ISFORCEDEACTIVATE => {:type => ::Thrift::Types::BOOL, :name => 'isForceDeactivate', :optional => true},
+    ISREPLACE => {:type => ::Thrift::Types::BOOL, :name => 'isReplace', :optional => true}
   }
 
   def struct_fields; FIELDS; end

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
index 5b7d75e..7c0b7f1 100644
--- a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java
@@ -7268,9 +7268,9 @@ public class HiveMetaStore extends ThriftHiveMetastore {
         throws AlreadyExistsException, InvalidObjectException, MetaException, TException {
       int defaultPoolSize = MetastoreConf.getIntVar(
           conf, MetastoreConf.ConfVars.WM_DEFAULT_POOL_SIZE);
-
       try {
-        getMS().createResourcePlan(request.getResourcePlan(), defaultPoolSize);
+        getMS().createResourcePlan(
+            request.getResourcePlan(), request.getCopyFrom(), defaultPoolSize);
         return new WMCreateResourcePlanResponse();
       } catch (MetaException e) {
         LOG.error("Exception while trying to persist resource plan", e);
@@ -7309,12 +7309,16 @@ public class HiveMetaStore extends ThriftHiveMetastore {
     public WMAlterResourcePlanResponse alter_resource_plan(WMAlterResourcePlanRequest request)
         throws NoSuchObjectException, InvalidOperationException, MetaException, TException {
       try {
+        if (((request.isIsEnableAndActivate() ? 1 : 0) + (request.isIsReplace() ? 1 : 0)
+           + (request.isIsForceDeactivate() ? 1 : 0)) > 1) {
+          throw new MetaException("Invalid request; multiple flags are set");
+        }
         WMAlterResourcePlanResponse response = new WMAlterResourcePlanResponse();
         // This method will only return full resource plan when activating one,
         // to give the caller the result atomically with the activation.
         WMFullResourcePlan fullPlanAfterAlter = getMS().alterResourcePlan(
             request.getResourcePlanName(), request.getResourcePlan(),
-            request.isIsEnableAndActivate(), request.isIsForceDeactivate());
+            request.isIsEnableAndActivate(), request.isIsForceDeactivate(), request.isIsReplace());
         if (fullPlanAfterAlter != null) {
           response.setFullResourcePlan(fullPlanAfterAlter);
         }

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java
index c0b4cfe..2b6b0b6 100644
--- a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java
@@ -2604,10 +2604,11 @@ public class HiveMetaStoreClient implements IMetaStoreClient, AutoCloseable {
   }
 
   @Override
-  public void createResourcePlan(WMResourcePlan resourcePlan)
+  public void createResourcePlan(WMResourcePlan resourcePlan, String copyFromName)
       throws InvalidObjectException, MetaException, TException {
     WMCreateResourcePlanRequest request = new WMCreateResourcePlanRequest();
     request.setResourcePlan(resourcePlan);
+    request.setCopyFrom(copyFromName);
     client.create_resource_plan(request);
   }
 
@@ -2636,13 +2637,14 @@ public class HiveMetaStoreClient implements IMetaStoreClient, AutoCloseable {
 
   @Override
   public WMFullResourcePlan alterResourcePlan(String resourcePlanName, WMResourcePlan resourcePlan,
-      boolean canActivateDisabled, boolean isForceDeactivate)
+      boolean canActivateDisabled, boolean isForceDeactivate, boolean isReplace)
       throws NoSuchObjectException, InvalidObjectException, MetaException, TException {
     WMAlterResourcePlanRequest request = new WMAlterResourcePlanRequest();
     request.setResourcePlanName(resourcePlanName);
     request.setResourcePlan(resourcePlan);
     request.setIsEnableAndActivate(canActivateDisabled);
     request.setIsForceDeactivate(isForceDeactivate);
+    request.setIsReplace(isReplace);
     WMAlterResourcePlanResponse resp = client.alter_resource_plan(request);
     return resp.isSetFullResourcePlan() ? resp.getFullResourcePlan() : null;
   }

http://git-wip-us.apache.org/repos/asf/hive/blob/3407e723/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java
index 91d0020..6905bd4 100644
--- a/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java
+++ b/standalone-metastore/src/main/java/org/apache/hadoop/hive/metastore/IMetaStoreClient.java
@@ -1771,7 +1771,7 @@ public interface IMetaStoreClient {
    */
   String getMetastoreDbUuid() throws MetaException, TException;
 
-  void createResourcePlan(WMResourcePlan resourcePlan)
+  void createResourcePlan(WMResourcePlan resourcePlan, String copyFromName)
       throws InvalidObjectException, MetaException, TException;
 
   WMResourcePlan getResourcePlan(String resourcePlanName)
@@ -1784,7 +1784,7 @@ public interface IMetaStoreClient {
       throws NoSuchObjectException, MetaException, TException;
 
   WMFullResourcePlan alterResourcePlan(String resourcePlanName, WMResourcePlan resourcePlan,
-      boolean canActivateDisabled, boolean isForceDeactivate)
+      boolean canActivateDisabled, boolean isForceDeactivate, boolean isReplace)
       throws NoSuchObjectException, InvalidObjectException, MetaException, TException;
 
   WMFullResourcePlan getActiveResourcePlan() throws MetaException, TException;