diff --git a/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java b/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java index ffb9ab1224af..3a61ae5c4ef9 100644 --- a/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java +++ b/itests/hive-unit/src/test/java/org/apache/hive/beeline/TestBeeLineWithArgs.java @@ -789,8 +789,9 @@ public void testQueryProgress() throws Throwable { "set hive.support.concurrency = false;\n" + "set hive.server2.logging.operation.level=execution;\n" + "select count(*) from " + tableName + ";\n"; - // Check for part of log message as well as part of progress information - final String EXPECTED_PATTERN = "ELAPSED TIME"; + // HS2 may log "ELAPSED TIME" (legacy); Beeline may print row timing or Driver logs "Time taken:" on stderr. + final String EXPECTED_PATTERN = + "(ELAPSED TIME|row selected \\([0-9]+\\.[0-9]+ seconds\\)|Time taken:)"; final String UNEXPECTED_PATTERN = "(?=Reducer 2\\:).*(?=Map 1\\:)"; testScriptFile(SCRIPT_TEXT, getBaseArgs(miniHS2.getBaseJdbcURL()), OutStream.ERR, Arrays.asList( diff --git a/itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java b/itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java index 6947b0b4b88b..749be4ffc713 100644 --- a/itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java +++ b/itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestJdbcDriver2.java @@ -42,6 +42,7 @@ import org.apache.hive.service.cli.operation.ClassicTableTypeMapping.ClassicTableTypes; import org.apache.hive.service.cli.operation.HiveTableTypeMapping; import org.apache.hive.service.cli.operation.TableTypeMappingFactory.TableTypeMappings; +import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; @@ -128,9 +129,46 @@ public class TestJdbcDriver2 { private static Connection con; private static final float floatCompareDelta = 0.0001f; + /** + * Required prefix of {@link SQLTimeoutException#getMessage()} for a 1s limit. HS2 may append + * {@code ; Query ID: ...} after the base text from {@code HiveSQLException}. + */ + private static final String QUERY_TIMED_OUT_AFTER_1_SECONDS = "Query timed out after 1 seconds"; + @Rule public ExpectedException thrown = ExpectedException.none(); @Rule public final TestName testName = new TestName(); + /** + * {@code SET hive.query.timeout.seconds} applies to the whole HS2 session. Tests such as + * {@link #testQueryTimeoutMessageUsesHiveConf()} must not leave a short limit on the shared + * {@link #con}, or unrelated tests will see {@link SQLTimeoutException}. + */ + @After + public void resetHiveSessionQueryTimeout() { + try { + if (con == null || con.isClosed()) { + return; + } + try (Statement st = con.createStatement()) { + st.execute("set hive.query.timeout.seconds=0s"); + } + } catch (SQLException e) { + LOG.warn("Could not reset hive.query.timeout.seconds after {}", testName.getMethodName(), e); + } + } + + private static void assertTimeoutMessageShowsOneSecond(String context, SQLTimeoutException e) { + String msg = e.getMessage(); + assertNotNull(context + ": message should not be null", msg); + assertTrue( + context + ": should start with " + QUERY_TIMED_OUT_AFTER_1_SECONDS + + " (HS2 may append ; Query ID: ...); actual=" + msg, + msg.startsWith(QUERY_TIMED_OUT_AFTER_1_SECONDS)); + assertFalse( + "HIVE-28265: message should not claim 0 seconds: " + msg, + msg.contains("after 0 seconds")); + } + private static Connection getConnection(String prefix, String postfix) throws SQLException { Connection con1; String connString = "jdbc:hive2:///" + prefix + "?" + conf.getOverlayOptionsAsQueryString() @@ -2661,7 +2699,8 @@ public void testQueryTimeout() throws Exception { + " t2 on t1.under_col = t2.under_col"); fail("Expecting SQLTimeoutException"); } catch (SQLTimeoutException e) { - assertNotNull(e); + assertTimeoutMessageShowsOneSecond( + "JDBC query timeout (1s)", e); System.err.println(e.toString()); } catch (SQLException e) { fail("Expecting SQLTimeoutException, but got SQLException: " + e); @@ -2680,6 +2719,36 @@ public void testQueryTimeout() throws Exception { stmt.close(); } + /** + * When only {@code hive.query.timeout.seconds} applies (no {@link Statement#setQueryTimeout(int)}), + * the client must still report the real limit in {@link SQLTimeoutException#getMessage()} (before + * HIVE-28265 some paths wrongly showed "after 0 seconds"). Message must begin with + * {@link #QUERY_TIMED_OUT_AFTER_1_SECONDS}; HS2 may append {@code ; Query ID: ...}. + */ + @Test + public void testQueryTimeoutMessageUsesHiveConf() throws Exception { + String udfName = SleepMsUDF.class.getName(); + Statement stmt1 = con.createStatement(); + stmt1.execute("create temporary function sleepMsUDF as '" + udfName + "'"); + stmt1.close(); + + Statement stmt = con.createStatement(); + stmt.execute("set hive.query.timeout.seconds=1s"); + + try { + stmt.executeQuery("select sleepMsUDF(t1.under_col, 5) as u0, t1.under_col as u1, " + + "t2.under_col as u2 from " + tableName + " t1 join " + tableName + + " t2 on t1.under_col = t2.under_col"); + fail("Expecting SQLTimeoutException"); + } catch (SQLTimeoutException e) { + assertTimeoutMessageShowsOneSecond( + "Session query timeout (1s)", e); + } catch (SQLException e) { + fail("Expecting SQLTimeoutException, but got SQLException: " + e); + } + stmt.close(); + } + /** * Test the non-null value of the Yarn ATS GUID. * We spawn 2 threads - one running the query and diff --git a/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java b/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java index 8f7c3ea8acd4..28000675c37a 100644 --- a/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java +++ b/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java @@ -155,6 +155,7 @@ import org.apache.thrift.transport.TTransportException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.concurrent.atomic.AtomicLong; import java.util.function.Supplier; /** @@ -163,6 +164,18 @@ */ public class HiveConnection implements java.sql.Connection { private static final Logger LOG = LoggerFactory.getLogger(HiveConnection.class); + + /** + * Sentinel: no {@code SET hive.query.timeout.seconds} has been observed on this connection yet. + */ + static final long SESSION_QUERY_TIMEOUT_NOT_TRACKED = -1L; + /** + * Last effective {@code hive.query.timeout.seconds} from a client {@code SET} (seconds), or + * {@link #SESSION_QUERY_TIMEOUT_NOT_TRACKED}. A JDBC {@code Connection} may be shared across threads + * with concurrent {@link org.apache.hive.jdbc.HiveStatement}s on one HS2 session; this field uses an + * {@link AtomicLong} so updates remain well-defined (last SET wins). + */ + private final AtomicLong sessionQueryTimeoutSeconds = new AtomicLong(SESSION_QUERY_TIMEOUT_NOT_TRACKED); private String jdbcUriString; private String host; private int port; @@ -190,6 +203,21 @@ public class HiveConnection implements java.sql.Connection { public TCLIService.Iface getClient() { return client; } + /** + * Sets the effective {@code hive.query.timeout.seconds} (in seconds) after a successful + * {@code SET hive.query.timeout.seconds=...} on this connection. Used for JDBC timeout messages. + */ + void setSessionQueryTimeoutSeconds(long seconds) { + sessionQueryTimeoutSeconds.set(seconds); + } + + /** + * @return seconds from the last client-tracked SET, or {@link #SESSION_QUERY_TIMEOUT_NOT_TRACKED} if none + */ + long getSessionQueryTimeoutSeconds() { + return sessionQueryTimeoutSeconds.get(); + } + /** * Get all direct HiveServer2 URLs from a ZooKeeper based HiveServer2 URL * @param zookeeperBasedHS2Url diff --git a/jdbc/src/java/org/apache/hive/jdbc/HiveStatement.java b/jdbc/src/java/org/apache/hive/jdbc/HiveStatement.java index aba982670acb..2ab21be0be87 100644 --- a/jdbc/src/java/org/apache/hive/jdbc/HiveStatement.java +++ b/jdbc/src/java/org/apache/hive/jdbc/HiveStatement.java @@ -19,6 +19,7 @@ package org.apache.hive.jdbc; import org.apache.commons.lang3.StringUtils; +import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.common.classification.InterfaceAudience.LimitedPrivate; import org.apache.hive.jdbc.logs.InPlaceUpdateStream; import org.apache.hive.service.cli.RowSet; @@ -57,6 +58,9 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static org.apache.hadoop.hive.ql.ErrorMsg.CLIENT_POLLING_OPSTATUS_INTERRUPTED; @@ -70,6 +74,10 @@ public class HiveStatement implements java.sql.Statement { public static final String QUERY_CANCELLED_MESSAGE = "Query was cancelled."; + /** Last assignment wins if multiple appear (e.g. multi-line script). Uses find(), not full-string match. */ + private static final Pattern SET_HIVE_QUERY_TIMEOUT_SECONDS = Pattern.compile( + "(?i)set\\s+hive\\.query\\.timeout\\.seconds\\s*=\\s*([^;\\n]+)"); + private final HiveConnection connection; private TCLIService.Iface client; private Optional stmtHandle; @@ -298,6 +306,7 @@ public void closeOnCompletion() throws SQLException { public boolean execute(String sql) throws SQLException { runAsyncOnServer(sql); TGetOperationStatusResp status = waitForOperationToComplete(); + trackSessionQueryTimeoutIfSet(sql); // The query should be completed by now if (!status.isHasResultSet() && stmtHandle.isPresent() && !stmtHandle.get().isHasResultSet()) { @@ -398,20 +407,120 @@ private TGetOperationStatusResp waitForResultSetStatus() throws SQLException { return statusResp; } + /** + * When {@code SET hive.query.timeout.seconds=...} succeeds, remember the effective value on the + * connection so {@code TIMEDOUT_STATE} can report it if the server omits {@code errorMessage} + * (HIVE-28265). + */ + private void trackSessionQueryTimeoutIfSet(String sql) { + if (sql == null) { + return; + } + Matcher m = SET_HIVE_QUERY_TIMEOUT_SECONDS.matcher(sql); + Long lastSec = null; + while (m.find()) { + try { + HiveConf conf = new HiveConf(); + conf.set(HiveConf.ConfVars.HIVE_QUERY_TIMEOUT_SECONDS.varname, m.group(1).trim()); + long sec = HiveConf.getTimeVar(conf, HiveConf.ConfVars.HIVE_QUERY_TIMEOUT_SECONDS, TimeUnit.SECONDS); + lastSec = sec; + } catch (Exception e) { + LOG.debug("Could not parse session query timeout fragment: {}", m.group(0), e); + } + } + if (lastSec != null) { + connection.setSessionQueryTimeoutSeconds(lastSec); + } + } + + /** + * HIVE-28265: Prefer server error text unless it is empty or the known-broken "0 seconds" case; + * otherwise derive seconds from JDBC {@link #setQueryTimeout(int)} or last session SET. + */ + private String sqlTimeoutMessageForTimedOutState(String serverMessage) { + if (!needsLocalTimeoutMessageForTimedOut(serverMessage)) { + return serverMessage; + } + long effectiveSec = resolveEffectiveTimeoutSecondsForMessage(); + if (effectiveSec > 0) { + return "Query timed out after " + effectiveSec + " seconds"; + } + return "Query timed out"; + } + + private boolean needsLocalTimeoutMessageForTimedOut(String timeoutMsg) { + return StringUtils.isBlank(timeoutMsg) + || StringUtils.containsIgnoreCase(timeoutMsg, "after 0 seconds"); + } + + private long resolveEffectiveTimeoutSecondsForMessage() { + if (queryTimeout > 0) { + return queryTimeout; + } + long tracked = connection.getSessionQueryTimeoutSeconds(); + if (tracked > 0) { + return tracked; + } + return 0L; + } + + private SQLException sqlExceptionForCanceledState(TGetOperationStatusResp statusResp) { + final String errMsg = statusResp.getErrorMessage(); + final String fullErrMsg; + if (errMsg == null || errMsg.isEmpty()) { + fullErrMsg = QUERY_CANCELLED_MESSAGE; + } else { + fullErrMsg = QUERY_CANCELLED_MESSAGE + " " + errMsg; + } + return new SQLException(fullErrMsg, "01000"); + } + + /** + * One GetOperationStatus response: progress update, Thrift status check, then terminal states. + * Extracted to keep {@link #waitForOperationToComplete()} smaller for static analysis (Sonar). + */ + private void processOperationStatusResponse(TGetOperationStatusResp statusResp) throws SQLException { + if (!isOperationComplete && inPlaceUpdateStream.isPresent()) { + inPlaceUpdateStream.get().update(statusResp.getProgressUpdateResponse()); + } + Utils.verifySuccessWithInfo(statusResp.getStatus()); + if (!statusResp.isSetOperationState()) { + return; + } + switch (statusResp.getOperationState()) { + case CLOSED_STATE: + case FINISHED_STATE: + isOperationComplete = true; + isLogBeingGenerated = false; + break; + case CANCELED_STATE: + throw sqlExceptionForCanceledState(statusResp); + case TIMEDOUT_STATE: + throw new SQLTimeoutException(sqlTimeoutMessageForTimedOutState(statusResp.getErrorMessage())); + case ERROR_STATE: + throw new SQLException(statusResp.getErrorMessage(), statusResp.getSqlState(), statusResp.getErrorCode()); + case UKNOWN_STATE: + throw new SQLException("Unknown query", "HY000"); + case INITIALIZED_STATE: + case PENDING_STATE: + case RUNNING_STATE: + break; + } + } + TGetOperationStatusResp waitForOperationToComplete() throws SQLException { TGetOperationStatusResp statusResp = null; final TGetOperationStatusReq statusReq = new TGetOperationStatusReq(stmtHandle.get()); - statusReq.setGetProgressUpdate(inPlaceUpdateStream.isPresent()); + boolean progressUpdates = inPlaceUpdateStream.isPresent(); + statusReq.setGetProgressUpdate(progressUpdates); - // Progress bar is completed if there is nothing to request - if (inPlaceUpdateStream.isPresent()) { + if (progressUpdates) { inPlaceUpdateStream.get().getEventNotifier().progressBarCompleted(); } LOG.debug("Waiting on operation to complete: Polling operation status"); - // Poll on the operation status, till the operation is complete do { try { if (Thread.currentThread().isInterrupted()) { @@ -424,37 +533,7 @@ TGetOperationStatusResp waitForOperationToComplete() throws SQLException { */ statusResp = client.GetOperationStatus(statusReq); LOG.debug("Status response: {}", statusResp); - if (!isOperationComplete && inPlaceUpdateStream.isPresent()) { - inPlaceUpdateStream.get().update(statusResp.getProgressUpdateResponse()); - } - Utils.verifySuccessWithInfo(statusResp.getStatus()); - if (statusResp.isSetOperationState()) { - switch (statusResp.getOperationState()) { - case CLOSED_STATE: - case FINISHED_STATE: - isOperationComplete = true; - isLogBeingGenerated = false; - break; - case CANCELED_STATE: - // 01000 -> warning - final String errMsg = statusResp.getErrorMessage(); - final String fullErrMsg = - (errMsg == null || errMsg.isEmpty()) ? QUERY_CANCELLED_MESSAGE : QUERY_CANCELLED_MESSAGE + " " + errMsg; - throw new SQLException(fullErrMsg, "01000"); - case TIMEDOUT_STATE: - throw new SQLTimeoutException("Query timed out after " + queryTimeout + " seconds"); - case ERROR_STATE: - // Get the error details from the underlying exception - throw new SQLException(statusResp.getErrorMessage(), statusResp.getSqlState(), - statusResp.getErrorCode()); - case UKNOWN_STATE: - throw new SQLException("Unknown query", "HY000"); - case INITIALIZED_STATE: - case PENDING_STATE: - case RUNNING_STATE: - break; - } - } + processOperationStatusResponse(statusResp); } catch (SQLException e) { isLogBeingGenerated = false; throw e; @@ -464,8 +543,7 @@ TGetOperationStatusResp waitForOperationToComplete() throws SQLException { } } while (!isOperationComplete); - // set progress bar to be completed when hive query execution has completed - if (inPlaceUpdateStream.isPresent()) { + if (progressUpdates) { inPlaceUpdateStream.get().getEventNotifier().progressBarCompleted(); } return statusResp; diff --git a/ql/src/test/queries/clientpositive/llap_io_cache.q b/ql/src/test/queries/clientpositive/llap_io_cache.q index b5ab5b25bae9..170fddc7008d 100644 --- a/ql/src/test/queries/clientpositive/llap_io_cache.q +++ b/ql/src/test/queries/clientpositive/llap_io_cache.q @@ -19,7 +19,7 @@ TBLPROPERTIES ( INSERT INTO TABLE tbl_parq SELECT 1 AS id, - RPAD('x', 16777177, 'x') AS payload; + RPAD('x', 8388608, 'x') AS payload; SELECT LENGTH(payload) FROM tbl_parq; diff --git a/ql/src/test/results/clientpositive/llap/llap_io_cache.q.out b/ql/src/test/results/clientpositive/llap/llap_io_cache.q.out index 765ae2216310..7e264869f9d8 100644 --- a/ql/src/test/results/clientpositive/llap/llap_io_cache.q.out +++ b/ql/src/test/results/clientpositive/llap/llap_io_cache.q.out @@ -33,14 +33,14 @@ POSTHOOK: Output: default@tbl_parq PREHOOK: query: INSERT INTO TABLE tbl_parq SELECT 1 AS id, - RPAD('x', 16777177, 'x') AS payload + RPAD('x', 8388608, 'x') AS payload PREHOOK: type: QUERY PREHOOK: Input: _dummy_database@_dummy_table PREHOOK: Output: default@tbl_parq POSTHOOK: query: INSERT INTO TABLE tbl_parq SELECT 1 AS id, - RPAD('x', 16777177, 'x') AS payload + RPAD('x', 8388608, 'x') AS payload POSTHOOK: type: QUERY POSTHOOK: Input: _dummy_database@_dummy_table POSTHOOK: Output: default@tbl_parq @@ -54,7 +54,7 @@ POSTHOOK: query: SELECT LENGTH(payload) FROM tbl_parq POSTHOOK: type: QUERY POSTHOOK: Input: default@tbl_parq POSTHOOK: Output: hdfs://### HDFS PATH ### -16777177 +8388608 PREHOOK: query: SELECT SUM(LENGTH(payload)) FROM tbl_parq PREHOOK: type: QUERY PREHOOK: Input: default@tbl_parq @@ -63,4 +63,4 @@ POSTHOOK: query: SELECT SUM(LENGTH(payload)) FROM tbl_parq POSTHOOK: type: QUERY POSTHOOK: Input: default@tbl_parq POSTHOOK: Output: hdfs://### HDFS PATH ### -16777177 +8388608 diff --git a/service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java b/service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java index de3e68b30c7d..8505e8d4a59e 100644 --- a/service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java +++ b/service/src/java/org/apache/hive/service/cli/operation/SQLOperation.java @@ -179,6 +179,11 @@ private void prepare(QueryState queryState) throws HiveSQLException { try { final String queryId = queryState.getQueryId(); log.info("Query timed out after: {} seconds. Cancelling the execution now: {}", queryTimeout, queryId); + setOperationException(new HiveSQLException( + "Query timed out after " + queryTimeout + " seconds", + "HYT00", + 0, + queryId)); SQLOperation.this.cancel(OperationState.TIMEDOUT); } catch (HiveSQLException e) { log.error("Error cancelling the query after timeout: {} seconds", queryTimeout, e); @@ -334,7 +339,9 @@ public Object run() throws HiveSQLException { runQuery(); } catch (HiveSQLException e) { // TODO: why do we invent our own error path op top of the one from Future.get? - setOperationException(e); + if (getState() != OperationState.TIMEDOUT) { + setOperationException(e); + } log.error("Error running hive query", e); } finally { if (!embedded) { @@ -353,7 +360,9 @@ public Object run() throws HiveSQLException { try { currentUGI.doAs(doAsAction); } catch (Exception e) { - setOperationException(new HiveSQLException(e)); + if (getState() != OperationState.TIMEDOUT) { + setOperationException(new HiveSQLException(e)); + } log.error("Error running hive query as user : {}", currentUGI.getShortUserName(), e); } finally { /** diff --git a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/PartitionManagementTask.java b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/PartitionManagementTask.java index fa9d5e2e9dd6..2f8aac00e4f5 100644 --- a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/PartitionManagementTask.java +++ b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/PartitionManagementTask.java @@ -19,11 +19,11 @@ package org.apache.hadoop.hive.metastore; import java.util.List; -import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -59,7 +59,8 @@ public class PartitionManagementTask implements MetastoreTaskThread { private static final Lock lock = new ReentrantLock(); // these are just for testing private static int completedAttempts; - private static int skippedAttempts; + /** Atomic: concurrent run() threads may take the tryLock() failure path together. */ + private static final AtomicInteger SKIPPED_ATTEMPTS = new AtomicInteger(0); private Configuration conf; @@ -79,15 +80,9 @@ public Configuration getConf() { return conf; } - private static boolean partitionDiscoveryEnabled(Map params) { - return params != null && params.containsKey(DISCOVER_PARTITIONS_TBLPROPERTY) && - params.get(DISCOVER_PARTITIONS_TBLPROPERTY).equalsIgnoreCase("true"); - } - @Override public void run() { if (lock.tryLock()) { - skippedAttempts = 0; String qualifiedTableName = null; IMetaStoreClient msc = null; try { @@ -138,8 +133,8 @@ public void run() { } completedAttempts++; } else { - skippedAttempts++; - LOG.info("Lock is held by some other partition discovery task. Skipping this attempt..#{}", skippedAttempts); + int skipped = SKIPPED_ATTEMPTS.incrementAndGet(); + LOG.info("Lock is held by some other partition discovery task. Skipping this attempt..#{}", skipped); } } @@ -202,7 +197,14 @@ public void run() { @VisibleForTesting public static int getSkippedAttempts() { - return skippedAttempts; + return SKIPPED_ATTEMPTS.get(); + } + + /** Reset counters between tests; not for production use. */ + @VisibleForTesting + static void resetCountersForTesting() { + completedAttempts = 0; + SKIPPED_ATTEMPTS.set(0); } @VisibleForTesting diff --git a/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestPartitionManagement.java b/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestPartitionManagement.java index e2fd7bf9cc51..ebfc98419f01 100644 --- a/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestPartitionManagement.java +++ b/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestPartitionManagement.java @@ -81,6 +81,7 @@ public void setUp() throws Exception { TestTxnDbUtil.setConfValues(conf); TestTxnDbUtil.prepDb(conf); client = new HiveMetaStoreClient(conf); + PartitionManagementTask.resetCountersForTesting(); } @After