一、概述
ExtendedParser 用于在不增加 CalciteParser 复杂性的前提下(不用修改Calcite,增加新的关键字),让 Flink SQL 支持更多专用的语法。
二、实现
2.1. 策略
https://www.jianshu.com/p/e4956652cfcb
ExtendedParser 包含如下解析策略:
1 2 3 4 5 6 7
| private static final List<ExtendedParseStrategy> PARSE_STRATEGIES = Arrays.asList( ClearOperationParseStrategy.INSTANCE, HelpOperationParseStrategy.INSTANCE, QuitOperationParseStrategy.INSTANCE, ResetOperationParseStrategy.INSTANCE, SetOperationParseStrategy.INSTANCE);
|
这 5 条策略分别对应:
CLEAR
语句,清空输出
HELP
语句,打印帮助信息
EXIT
或 QUIT
语句,退出执行环境
RESET
语句,重设一个变量的值
SET
语句,设置一个变量的值
2.1.1. SetOperationParseStrategy
把 SET
语句解析为 operation
SetOperationParseStrategy 继承了 AbstractRegexParseStrategy,它包含 statement 正则匹配的逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| protected static final int DEFAULT_PATTERN_FLAGS = Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
protected Pattern pattern;
protected AbstractRegexParseStrategy(Pattern pattern) { this.pattern = pattern; }
@Override public boolean match(String statement) { return pattern.matcher(statement.trim()).matches(); }
|
紧接着我们分析SetOperationParseStrategy
。SET语句的pattern如下:
1 2 3 4 5 6
| protected SetOperationParseStrategy() { super( Pattern.compile( "SET(\\s+(?<key>[^'\\s]+)\\s*=\\s*('(?<quotedVal>[^']*)'|(?<val>\\S+)))?", DEFAULT_PATTERN_FLAGS)); }
|
从正则表达式可知,SET语句的格式为:SET key=’quotedVal’或者SET key=val。
转换SET语句为Operation的过程位于convert
方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| @Override public Operation convert(String statement) { Matcher matcher = pattern.matcher(statement.trim()); final List<String> operands = new ArrayList<>(); if (matcher.find()) { if (matcher.group("key") != null) { operands.add(matcher.group("key")); operands.add( matcher.group("quotedVal") != null ? matcher.group("quotedVal") : matcher.group("val")); } }
if (operands.isEmpty()) { return new SetOperation(); } else if (operands.size() == 2) { return new SetOperation(operands.get(0), operands.get(1)); } else { throw new TableException( String.format( "Failed to convert the statement to SET operation: %s.", statement)); } }
|