hive Cli 启动
[toc]
CliDriver
作用: 执行命令:hive时 实际上运行的类是org.apache.hadoop.hive.cli.CliDriver.java 。
入口
public static void main(String[] args) throws Exception {
int ret = new CliDriver().run(args);
System.exit(ret);
}
public int run(String[] args) throws Exception {
//解析命令行参数, 把hiveconf 的参数设置到环境变量,吧define,和hivevar等参数添加到一个map中
OptionsProcessor oproc = new OptionsProcessor();
if (!oproc.process_stage1(args)) {
return 1;
}
//初始化Log4j日志组件
// NOTE: It is critical to do this here so that log4j is reinitialized
// before any of the other core hive classes are loaded
boolean logInitFailed = false;
String logInitDetailMessage;
try {
logInitDetailMessage = LogUtils.initHiveLog4j();
} catch (LogInitializationException e) {
logInitFailed = true;
logInitDetailMessage = e.getMessage();
}
//初始化HiveConf,并根据HiveConf实例化CliSessionState,设置输入输出流为标准控制台。
//CliSessionState 继承了SessionState类,
//创建了一些记录用户输入的字符串,在实例化的过程中,主要是用来记录HiveConf,并生成一个会话ID,参见SessionState构造函数.
CliSessionState ss = new CliSessionState(new HiveConf(SessionState.class));
//设置ss的输入,输出,把对ss的和hive cli的关联起来
ss.in = System.in;
try {
ss.out = new PrintStream(System.out, true, "UTF-8");
ss.info = new PrintStream(System.err, true, "UTF-8");
ss.err = new CachingPrintStream(System.err, true, "UTF-8");
} catch (UnsupportedEncodingException e) {
return 3;
}
//根据stage1解析的参数内容,填充CliSessionState的字符串,比如用户输入了-e 则这个stage就把-e 对应的字符串赋值给CliSessionState的 execString成员。
// -S 表示 沉默状态
// -e 获取执行sql
// -f 获取要执行的sql文件
// -v 是否详细显示
// 其他, 处理hiveconf 和 i 等参数
if (!oproc.process_stage2(ss)) {
return 2;
}
//在允许打印输出的模式下,如果日志初始化失败,打印失败信息
if (!ss.getIsSilent()) {
if (logInitFailed) {
System.err.println(logInitDetailMessage);
} else {
SessionState.getConsole().printInfo(logInitDetailMessage);
}
}
//将用户命令行输入的配置信息和变量等,覆盖HiveConf的默认值
// set all properties specified via command line
HiveConf conf = ss.getConf();
for (Map.Entry<Object, Object> item : ss.cmdProperties.entrySet()) {
conf.set((String) item.getKey(), (String) item.getValue());
ss.getOverriddenConfigurations().put((String) item.getKey(), (String) item.getValue());
}
// read prompt configuration and substitute variables.
prompt = conf.getVar(HiveConf.ConfVars.CLIPROMPT);
prompt = new VariableSubstitution(new HiveVariableSource() {
@Override
public Map<String, String> getHiveVariable() {
return SessionState.get().getHiveVariables();
}
}).substitute(conf, prompt);
prompt2 = spacesForString(prompt);
//设置当前回话状态,执行CLI驱动
SessionState.start(ss);
//在这之前都是准备hive 参数
try {
return executeDriver(ss, conf, oproc);
} finally {
ss.close();
}
}
初始化cli命令
private int executeDriver(CliSessionState ss, HiveConf conf, OptionsProcessor oproc)
throws Exception {
CliDriver cli = new CliDriver();
cli.setHiveVariables(oproc.getHiveVariables());
//设置使用的数据库
// use the specified database if specified
cli.processSelectDatabase(ss);
// Execute -i init files (always in silent mode)
cli.processInitFiles(ss);
//如果传递了要执行的sql 执行后退出
if (ss.execString != null) {
int cmdProcessStatus = cli.processLine(ss.execString);
return cmdProcessStatus;
}
//执行sql文件
try {
if (ss.fileName != null) {
return cli.processFile(ss.fileName);
}
} catch (FileNotFoundException e) {
System.err.println("Could not open input file for reading. (" + e.getMessage() + ")");
return 3;
}
//获取命令行的reader
ConsoleReader reader = getConsoleReader();
reader.setExpandEvents(false);
reader.setBellEnabled(false);
// reader.setDebug(new PrintWriter(new FileWriter("writer.debug", true)));
for (Completer completer : getCommandCompleter()) {
reader.addCompleter(completer);
}
//略去一部分不重要代码
int ret = 0;
String prefix = "";
String curDB = getFormattedDb(conf, ss);
String curPrompt = prompt + curDB;
String dbSpaces = spacesForString(curDB);
//开始从命令行获取sql 语句,如果是以 ; 结尾,则开始执行sql
while ((line = reader.readLine(curPrompt + "> ")) != null) {
if (!prefix.equals("")) {
prefix += '\n';
}
if (line.trim().endsWith(";") && !line.trim().endsWith("\\;")) {
line = prefix + line;
//开始执行hive 命令
ret = cli.processLine(line, true);
prefix = "";
curDB = getFormattedDb(conf, ss);
curPrompt = prompt + curDB;
dbSpaces = dbSpaces.length() == curDB.length() ? dbSpaces : spacesForString(curDB);
} else {
prefix = prefix + line;
curPrompt = prompt2 + dbSpaces;
continue;
}
}
if (history != null) {
history.flush();
}
return ret;
}