以mysql为例,update语法如下:官网地址
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
SET assignment_list
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
value:
{expr | DEFAULT}
assignment:
col_name = value
assignment_list:
assignment [, assignment] ...
UPDATE [LOW_PRIORITY] [IGNORE] table_references
SET assignment_list
[WHERE where_condition]
update语句经过语法解析器,最终会交由AbstractUpdateParser的parser方法去处理。前面过程请参考上篇博客。
public abstract class AbstractUpdateParser implements SQLParser {
private final ShardingRule shardingRule;
private final LexerEngine lexerEngine;
private final AbstractUpdateClauseParserFacade updateClauseParserFacade;
@Override
public DMLStatement parse() {
lexerEngine.nextToken();
lexerEngine.skipAll(getSkippedKeywordsBetweenUpdateAndTable());
lexerEngine.unsupportedIfEqual(getUnsupportedKeywordsBetweenUpdateAndTable());
DMLStatement result = new DMLStatement();
//解析表引用关系
updateClauseParserFacade.getTableReferencesClauseParser().parse(result, true);
//解释update语句
updateClauseParserFacade.getUpdateSetItemsClauseParser().parse(result);
lexerEngine.skipUntil(DefaultKeyword.WHERE);
//update语句的where条件处理
updateClauseParserFacade.getWhereClauseParser().parse(shardingRule, result, Collections.<SelectItem>emptyList());
return result;
}
protected Keyword[] getSkippedKeywordsBetweenUpdateAndTable() {
return new Keyword[0];
}
protected Keyword[] getUnsupportedKeywordsBetweenUpdateAndTable() {
return new Keyword[0];
}
}
where条件解析和表引用关系解析在select语句处理的时候解释过,这里不再细看。
public void parse(final DMLStatement updateStatement) {
//接受set关键词
lexerEngine.accept(DefaultKeyword.SET);
do {
parseSetItem(updateStatement);
//如果是,则循环处理
} while (lexerEngine.skipIfEqual(Symbol.COMMA));
}
private void parseSetItem(final DMLStatement updateStatement) {
//列名解析
parseSetColumn(updateStatement);
//判断是否是=,或者是 :=
lexerEngine.skipIfEqual(Symbol.EQ, Symbol.COLON_EQ);
//列名对应value值解析
parseSetValue(updateStatement);
//跳过::
skipsDoubleColon();
}
private void parseSetColumn(final DMLStatement updateStatement) {
if (lexerEngine.equalAny(Symbol.LEFT_PAREN)) {
lexerEngine.skipParentheses(updateStatement);
return;
}
int beginPosition = lexerEngine.getCurrentToken().getEndPosition();
String literals = lexerEngine.getCurrentToken().getLiterals();
lexerEngine.nextToken();
//如果有表的别名
if (lexerEngine.skipIfEqual(Symbol.DOT)) {
if (updateStatement.getTables().getSingleTableName().equalsIgnoreCase(SQLUtil.getExactlyValue(literals))) {
updateStatement.getSqlTokens().add(new TableToken(beginPosition - literals.length(), 0, literals));
}
lexerEngine.nextToken();
}
}
private void parseSetValue(final DMLStatement updateStatement) {
basicExpressionParser.parse(updateStatement);
}