Index: conf/hive-default.xml =================================================================== --- conf/hive-default.xml (revision 1155569) +++ conf/hive-default.xml (working copy) @@ -533,6 +533,12 @@ + hive.exec.failure.hooks + + Comma-separated list of on-failure hooks to be invoked for each statement. An on-failure hook is specified as the name of Java class which implements the org.apache.hadoop.hive.ql.hooks.ExecuteWithHookContext interface. + + + hive.merge.mapfiles true Merge small files at the end of a map-only job Index: common/src/java/org/apache/hadoop/hive/conf/HiveConf.java =================================================================== --- common/src/java/org/apache/hadoop/hive/conf/HiveConf.java (revision 1155569) +++ common/src/java/org/apache/hadoop/hive/conf/HiveConf.java (working copy) @@ -122,6 +122,7 @@ MAXREDUCERS("hive.exec.reducers.max", 999), PREEXECHOOKS("hive.exec.pre.hooks", ""), POSTEXECHOOKS("hive.exec.post.hooks", ""), + ONFAILUREHOOKS("hive.exec.failure.hooks", ""), EXECPARALLEL("hive.exec.parallel", false), // parallel query launching EXECPARALLETHREADNUMBER("hive.exec.parallel.thread.number", 8), HIVESPECULATIVEEXECREDUCERS("hive.mapred.reduce.tasks.speculative.execution", true), Index: ql/src/java/org/apache/hadoop/hive/ql/hooks/HookContext.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/hooks/HookContext.java (revision 1155569) +++ ql/src/java/org/apache/hadoop/hive/ql/hooks/HookContext.java (working copy) @@ -39,7 +39,7 @@ public class HookContext { static public enum HookType { - PRE_EXEC_HOOK, POST_EXEC_HOOK + PRE_EXEC_HOOK, POST_EXEC_HOOK, ON_FAILURE_HOOK } private QueryPlan queryPlan; Index: ql/src/java/org/apache/hadoop/hive/ql/Driver.java =================================================================== --- ql/src/java/org/apache/hadoop/hive/ql/Driver.java (revision 1155569) +++ ql/src/java/org/apache/hadoop/hive/ql/Driver.java (working copy) @@ -24,7 +24,6 @@ import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; -import java.util.Stack; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -357,7 +356,7 @@ public boolean isInitialized() { return this.init; } - + public HiveOperation getOp() { return this.op; } @@ -976,7 +975,7 @@ private List getPreExecHooks() throws Exception { - ArrayList pehooks = new ArrayList(); + List pehooks = new ArrayList(); String pestr = conf.getVar(HiveConf.ConfVars.PREEXECHOOKS); pestr = pestr.trim(); if (pestr.equals("")) { @@ -999,7 +998,7 @@ } private List getPostExecHooks() throws Exception { - ArrayList pehooks = new ArrayList(); + List pehooks = new ArrayList(); String pestr = conf.getVar(HiveConf.ConfVars.POSTEXECHOOKS); pestr = pestr.trim(); if (pestr.equals("")) { @@ -1021,6 +1020,29 @@ return pehooks; } + private List getOnFailureHooks() throws Exception { + List ofhooks = new ArrayList(); + String ofstr = conf.getVar(HiveConf.ConfVars.ONFAILUREHOOKS); + ofstr = ofstr.trim(); + if (ofstr.equals("")) { + return ofhooks; + } + + String[] ofClasses = ofstr.split(","); + + for (String ofClass : ofClasses) { + try { + ofhooks.add((Hook) Class.forName(ofClass.trim(), true, JavaUtils.getClassLoader()) + .newInstance()); + } catch (ClassNotFoundException e) { + console.printError("On Failure Hook Class not found:" + e.getMessage()); + throw e; + } + } + + return ofhooks; + } + public int execute() throws CommandNeedRetryException { Utilities.PerfLogBegin(LOG, "Driver.execute"); @@ -1139,6 +1161,16 @@ continue; } else { + hookContext.setHookType(HookContext.HookType.ON_FAILURE_HOOK); + // Get all the failure execution hooks and execute them. + for (Hook ofh : getOnFailureHooks()) { + Utilities.PerfLogBegin(LOG, "FailureHook." + ofh.getClass().getSimpleName()); + + ((ExecuteWithHookContext) ofh).run(hookContext); + + Utilities.PerfLogEnd(LOG, "FailureHook." + ofh.getClass().getSimpleName()); + } + // TODO: This error messaging is not very informative. Fix that. errorMessage = "FAILED: Execution Error, return code " + exitVal + " from " + tsk.getClass().getName();