@Override
  public int add_partitions_pspec(final List<PartitionSpec> partSpecs)
      throws TException {
    if (partSpecs.isEmpty()) {
      return 0;
    }

    String catName = partSpecs.get(0).isSetCatName() ? partSpecs.get(0).getCatName() : getDefaultCatalog(conf);
    String dbName = partSpecs.get(0).getDbName();
    String tableName = partSpecs.get(0).getTableName();
    startTableFunction("add_partitions_pspec", catName, dbName, tableName);

    Integer ret = null;
    Exception ex = null;
    try {
      // If the catalog name isn't set, we need to go through and set it.
      if (!partSpecs.get(0).isSetCatName()) {
        partSpecs.forEach(ps -> ps.setCatName(catName));
      }
      dbName = normalizeIdentifier(dbName);
      tableName = normalizeIdentifier(tableName);

      PartitionSpecProxy partitionSpecProxy = PartitionSpecProxy.Factory.get(partSpecs);
      final PartitionSpecProxy.PartitionIterator partitionIterator = partitionSpecProxy
              .getPartitionIterator();
      List<Partition> partitionsToAdd = new ArrayList<>(partitionSpecProxy.size());
      while (partitionIterator.hasNext()) {
        final Partition part = partitionIterator.getCurrent();
        // Normalize dbName and tblName of each part
        // to follow the case-insensitive behavior of replaced add_partitions_pspec_core
        part.setDbName(normalizeIdentifier(part.getDbName()));
        part.setTableName(normalizeIdentifier(part.getTableName()));

        partitionsToAdd.add(part);
        partitionIterator.next();
      }
      ret = add_partitions_core(getMS(), catName, dbName, tableName, partitionsToAdd,
          false, false, null).size();
    } catch (Exception e) {
      ex = e;
      throw handleException(e)
          .throwIfInstance(MetaException.class, InvalidObjectException.class, AlreadyExistsException.class)
          .defaultMetaException();
    } finally {
      endFunction("add_partitions_pspec", ret != null, ex, tableName);
    }
    return ret;
  }
Create the location folders for the partitions. For each partition a separate thread will be
started to create the folder. The method will wait until all threads are finished and returns
the partitions whose folders were created successfully. If an error occurs during the
execution of a thread, a MetaException will be thrown.
@param partitionsToAdd
@param table
@param addedPartitions
@return
@throws MetaException
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HMSHandler.java