diff --git a/ql/src/java/org/apache/hadoop/hive/ql/Driver.java b/ql/src/java/org/apache/hadoop/hive/ql/Driver.java index 94999fed93..4384551e88 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/Driver.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/Driver.java @@ -191,6 +191,10 @@ // either initTxnMgr or from the SessionState, in that order. private HiveTxnManager queryTxnMgr; + // Boolean to store information about whether valid txn list was generated + // for current query. + private boolean validTxnListsGenerated; + private CacheUsage cacheUsage; private CacheEntry usedCacheEntry; @@ -595,6 +599,23 @@ public void run() { long txnid = queryTxnMgr.openTxn(ctx, userFromUGI); } } + + // Record current valid txn list that will be used throughout the query + // compilation and processing. We only do this if 1) a transaction + // was already opened and 2) the list has not been recorded yet, + // e.g., by an explicit open transaction command. + validTxnListsGenerated = false; + String currentTxnString = conf.get(ValidTxnList.VALID_TXNS_KEY); + if (queryTxnMgr.isTxnOpen() && (currentTxnString == null || currentTxnString.isEmpty())) { + try { + recordValidTxns(queryTxnMgr); + validTxnListsGenerated = true; + } catch (Exception e) { + LOG.error("Exception while acquiring valid txn list", e); + throw e; + } + } + // Do semantic analysis and plan generation if (hookRunner.hasPreAnalyzeHooks()) { HiveSemanticAnalyzerHookContext hookCtx = new HiveSemanticAnalyzerHookContextImpl(); @@ -1335,8 +1356,10 @@ private void acquireLocks() throws CommandProcessorResponse { /*It's imperative that {@code acquireLocks()} is called for all commands so that HiveTxnManager can transition its state machine correctly*/ queryTxnMgr.acquireLocks(plan, ctx, userFromUGI, lDrvState); - if (queryTxnMgr.recordSnapshot(plan)) { - recordValidTxns(queryTxnMgr); + // This check is for controlling the correctness of the current state + if (queryTxnMgr.recordSnapshot(plan) && !validTxnListsGenerated) { + throw new IllegalStateException("calling recordValidTxn() more than once in the same " + + JavaUtils.txnIdToString(queryTxnMgr.getCurrentTxnId())); } if (plan.hasAcidResourcesInQuery()) { recordValidWriteIds(queryTxnMgr); @@ -1499,6 +1522,10 @@ public CommandProcessorResponse compileAndRespond(String command) { return createProcessorResponse(0); } catch (CommandProcessorResponse e) { return e; + } finally { + // Valid txn list might be generated for a query compiled using this + // command, thus we need to reset it + conf.unset(ValidTxnList.VALID_TXNS_KEY); } }