解析sql的库。
主要类
名称 | 说明 |
CodeGenerate | 代码生成器,主要对Expression生成对应的java代码,输出ExprCode。里面包含了一系列的ExprCode子类。 |
ExprCode | 生成java代码,和Expression对应。Expression还有eval方法在InternalRow上判断条件表达式是否满足。 |
Expression | 条件表达式,主要的方法是eval和genCode,后者生成对应的ExprCode |
predicates | 条件表达式。 LessThanOrEqual:小于等于; MoreThan:。。 LessThan等 |
|
|
|
|
-
- predicates
定义了一系列条件表达式,如大于小于,等于,in ()操作等等。每种操作符定义一个单独的类处理,通过统一的eval()方法返回匹配的结果,是null还是false还是true。
例如:
-
-
- Or
-
或操作
override def eval(input: InternalRow): Any = {
val input1 = left.eval(input)
if (input1 == true) {
true
} else {
val input2 = right.eval(input)
if (input2 == true) {
true
} else {
if (input1 != null && input2 != null) {
false
} else {
null
}
}
}
}
left和right只要满足一个就返回true,只要有一个是null则返回null,否则返回false。
再看一个And
-
-
- And
-
override def eval(input: InternalRow): Any = {
val input1 = left.eval(input)
if (input1 == false) {
false
} else {
val input2 = right.eval(input)
if (input2 == false) {
false
} else {
if (input1 != null && input2 != null) {
true
} else {
null
}
}
}
}
left和right只要一个为false则返回false,如果有null则返回null,否则返回true。
其他的就不列举了。
-
- Expression
Expression:函数表达式,如name(string)这样的定义格式。
LeafExpression:没有子节点。child为nil
UnaryExpression:一个子节点。children只有一个元素[child]
BinaryExpression:两个子节点
TernaryExpression:三个子节点
TernaryExpression:特殊的BinaryExpression,两个子节点有相同的输出数据类型。
每个列的值先是Expression,然后Seq[Expression]解析成InternalRow
Expression是TreeNode的子类。
大部分的Expression子类应该都是继承UnaryExpression或者BinaryExpression。
-
-
- NamedExpressions
-
命名表达式,判断select后多个列表达式是否指向同一个,或者对sql语句进行预处理,转换列表达式。
其中一个重载方式sql,返回处理后的sql语句。
-
-
- UnaryExpression
-
只有一个child,children也是只有一个child的列表。
override def eval(input: InternalRow): Any = {
val value = child.eval(input)
if (value == null) {
null
} else {
nullSafeEval(value)
}
}
protected def nullSafeEval(input: Any): Any =
sys.error(s"UnaryExpressions must override either eval or nullSafeEval")
当子类继承UnaryExpression时,可能需要重写eval和nullSafeEval两个方法。
defineCodeGen方法:返回java source代码。可以重写。
-
-
- BinaryExpression
-
继承Expression,两个输入,一个输出。也是一个基类,不直接使用。
-
-
- BinaryOperator
-
继承BinaryExpression。是一个抽象类,表达式格式:
是类似"x symbol y", 而不是"funcName(x, y)".
主要是一个方法的重写:
override def sql: String = s"(${left.sql} $sqlOperator ${right.sql})"
输出sql语句。