此类的public方法只有下面这些:
static类:
org.h2.command.Parser.isKeyword(String, boolean)
org.h2.command.Parser.quoteIdentifier(String)
非static类:
org.h2.command.Parser.Parser(Session)
org.h2.command.Parser.getSession()
org.h2.command.Parser.parseExpression(String)
org.h2.command.Parser.prepare(String)
org.h2.command.Parser.prepareCommand(String)
org.h2.command.Parser.setRightsChecked(boolean)
包级别的方法只有一个:
org.h2.command.Parser.parse(String) //除此类外,只看到在org.h2.command.CommandContainer.recompileIfRequired()中使用
org.h2.command.Parser.parse(String) 是起点
由下面两者触发
org.h2.command.Parser.parse(String)
<= org.h2.command.Parser.prepare(String) (得到一个Prepared)
<= org.h2.engine.Session.prepare(String, boolean) 在起动时调用,用于非远程客户端发起的调用,org.h2.engine.MetaRecord.execute(Database, Session, DatabaseEventListener)
(得到一个CommandContainer,CommandContainer有Prepared,Prepared也有对CommandContainer的引用)
<= org.h2.command.Parser.prepareCommand(String)
<= org.h2.engine.Session.prepareLocal(String) 远程客户端发起的调用,见org.h2.server.TcpServerThread.process()
上面两者都会调用Prepared.prepare()
流程分析:
org.h2.command.Parser.parse(String)
=> org.h2.command.Parser.parse(String, boolean) 只在parse(String)中调用
=> org.h2.command.Parser.initialize(String)
=> org.h2.command.Parser.read()
=> org.h2.command.Parser.parsePrepared() 核心在这里
/**
* Parse the statement, but don't prepare it for execution.
*
* @param sql the SQL statement to parse
* @return the prepared object
*/
Prepared parse(String sql) {
Prepared p;
try {
// first, try the fast variant
//大多数情况下SQL都是正确的,所以这里做了些优化: 默认不使用expectedList,当出现错误时捕获DbException,
//如果是语法错误那么再解析一次,并用expectedList记录SQL在语法层面缺了哪些东西,
//如果是非语法错误,则把SQL关联到异常,直接抛出异常。
//如果不起用这个优化,那么因为频繁调用readIf->addExpected会导致expectedList变得很大
p = parse(sql, false);
} catch (DbException e) {
if (e.getErrorCode() == ErrorCode.SYNTAX_ERROR_1) {
// now, get the detailed exception
p = parse(sql, true);
} else {
throw e.addSQL(sql);
}
}
p.setPrepareAlways(recompileAlways);
p.setParameterList(parameters);
return p;
}
private Prepared parse(String sql, boolean withExpectedList) {
initialize(sql);
if (withExpectedList) {
expectedList = New.arrayList();
} else {
expectedList = null;
}
parameters = New.arrayList();
currentSelect = null;
currentPrepared = null;
createView = null;
recompileAlways = false;
indexedParameterList = null;
read();
return parsePrepared();
}
org.h2.command.Parser.initialize(String)
提前分析sql语句中的每个字符,比如把注释替换成空格