public abstract class SqlNode implements Cloneable {
public static final SqlNode[] EMPTY_ARRAY = new SqlNode[0];
protected final SqlParserPos pos;
SqlNode(SqlParserPos pos) {
this.pos = (SqlParserPos)Objects.requireNonNull(pos, "pos");
}
/** @deprecated */
@Deprecated
public Object clone() {
return this.clone(this.getParserPosition());
}
public static <E extends SqlNode> E clone(E e) {
return e.clone(e.pos);
}
public abstract SqlNode clone(SqlParserPos var1);
public SqlKind getKind() {
return SqlKind.OTHER;
}
public final boolean isA(Set<SqlKind> category) {
return this.getKind().belongsTo(category);
}
/** @deprecated */
@Deprecated
public static SqlNode[] cloneArray(SqlNode[] nodes) {
SqlNode[] clones = (SqlNode[])nodes.clone();
for(int i = 0; i < clones.length; ++i) {
SqlNode node = clones[i];
if (node != null) {
clones[i] = clone(node);
}
}
return clones;
}
public String toString() {
return this.toSqlString((c) -> {
return c.withDialect(AnsiSqlDialect.DEFAULT).withAlwaysUseParentheses(false).withSelectListItemsOnSeparateLines(false).withUpdateSetListNewline(false).withIndentation(0);
}).getSql();
}
public SqlString toSqlString(UnaryOperator<SqlWriterConfig> transform) {
SqlWriterConfig config = (SqlWriterConfig)transform.apply(SqlPrettyWriter.config());
SqlPrettyWriter writer = new SqlPrettyWriter(config);
this.unparse(writer, 0, 0);
return writer.toSqlString();
}
public SqlString toSqlString(@Nullable SqlDialect dialect, boolean forceParens) {
return this.toSqlString((c) -> {
return c.withDialect((SqlDialect)Util.first(dialect, AnsiSqlDialect.DEFAULT)).withAlwaysUseParentheses(forceParens).withSelectListItemsOnSeparateLines(false).withUpdateSetListNewline(false).withIndentation(0);
});
}
public SqlString toSqlString(@Nullable SqlDialect dialect) {
return this.toSqlString(dialect, false);
}
public abstract void unparse(SqlWriter var1, int var2, int var3);
public void unparseWithParentheses(SqlWriter writer, int leftPrec, int rightPrec, boolean parentheses) {
if (parentheses) {
Frame frame = writer.startList("(", ")");
this.unparse(writer, 0, 0);
writer.endList(frame);
} else {
this.unparse(writer, leftPrec, rightPrec);
}
}
public SqlParserPos getParserPosition() {
return this.pos;
}
public abstract void validate(SqlValidator var1, SqlValidatorScope var2);
public void findValidOptions(SqlValidator validator, SqlValidatorScope scope, SqlParserPos pos, Collection<SqlMoniker> hintList) {
}
public void validateExpr(SqlValidator validator, SqlValidatorScope scope) {
this.validate(validator, scope);
Util.discard(validator.deriveType(scope, this));
}
public abstract <R> R accept(SqlVisitor<R> var1);
public abstract boolean equalsDeep(@Nullable SqlNode var1, Litmus var2);
/** @deprecated */
@Deprecated
public final boolean equalsDeep(@Nullable SqlNode node, boolean fail) {
return this.equalsDeep(node, fail ? Litmus.THROW : Litmus.IGNORE);
}
public static boolean equalDeep(@Nullable SqlNode node1, @Nullable SqlNode node2, Litmus litmus) {
if (node1 == null) {
return node2 == null;
} else {
return node2 == null ? false : node1.equalsDeep(node2, litmus);
}
}
public SqlMonotonicity getMonotonicity(@Nullable SqlValidatorScope scope) {
return SqlMonotonicity.NOT_MONOTONIC;
}
public static boolean equalDeep(List<SqlNode> operands0, List<SqlNode> operands1, Litmus litmus) {
if (operands0.size() != operands1.size()) {
return litmus.fail((String)null, new Object[0]);
} else {
for(int i = 0; i < operands0.size(); ++i) {
if (!equalDeep((SqlNode)operands0.get(i), (SqlNode)operands1.get(i), litmus)) {
return litmus.fail((String)null, new Object[0]);
}
}
return litmus.succeed();
}
}
public static <T extends SqlNode> Collector<T, ArrayList<SqlNode>, SqlNodeList> toList() {
return toList(SqlParserPos.ZERO);
}
public static <T extends SqlNode> Collector<T, ArrayList<SqlNode>, SqlNodeList> toList(SqlParserPos pos) {
return Collector.of(ArrayList::new, ArrayList::add, Util::combine, (list) -> {
return SqlNodeList.of(pos, list);
});
}
}
这是Apache Calcite库中的 一个抽象类 `SqlNode`,用于表示SQL语句的语法树中的一个节点。
让我们逐行解释代码的功能和参数的意义:
1. `package org.apache.calcite.sql;`:这是代码所属的包名,指明了代码文件的位置。
2. `import` 语句:引入了一些需要使用的类和接口。
3. `public abstract class SqlNode implements Cloneable`:定义了一个抽象类 `SqlNode`,它实现了 `Cloneable` 接口。这意味着 `SqlNode` 可以被继承,并且支持克隆操作。
4. `public static final SqlNode[] EMPTY_ARRAY = new SqlNode[0];`:定义了一个空数组常量 `EMPTY_ARRAY`,它的类型是 `SqlNode[]`,表示一个空的 `SqlNode` 数组。
5. `protected final SqlParserPos pos;`:定义了一个受保护的成员变量 `pos`,它表示该节点在SQL语句中的位置信息。
6. `SqlNode(SqlParserPos pos)`:构造函数,接收一个 `SqlParserPos` 类型的参数,用于初始化 `pos` 成员变量。
7. `public Object clone()`:克隆方法,用于创建当前对象的副本。这个方法已经被标记为 `@Deprecated`,表示不推荐使用,因为它直接调用了 `clone(SqlParserPos)` 方法。
8. `public static <E extends SqlNode> E clone(E e)`:静态泛型方法,用于克隆一个 `SqlNode` 对象。它接收一个泛型参数 `E`,表示要克隆的对象的类型,并返回克隆后的对象。
9. `public abstract SqlNode clone(SqlParserPos var1)`:抽象方法,用于克隆当前对象并返回克隆后的对象。它接收一个 `SqlParserPos` 参数,表示新对象的位置信息。
10. `public SqlKind getKind()`:获取当前节点的类型。返回一个 `SqlKind` 枚举值,表示该节点的类型。
11. `public final boolean isA(Set<SqlKind> category)`:判断当前节点是否属于指定的节点类型集合。它接收一个 `Set<SqlKind>` 类型的参数 `category`,表示节点类型的集合。如果当前节点的类型属于集合中的任何一种类型,返回 `true`,否则返回 `false`。
12. `public static SqlNode[] cloneArray(SqlNode[] nodes)`:静态方法,用于克隆一个 `SqlNode` 数组。它接收一个 `SqlNode[]` 类型的参数 `nodes`,表示要克隆的数组。返回克隆后的数组,其中每个元素都是原数组对应位置元素的克隆。
13. `public String toString()`:将当前节点转换为字符串表示。它使用默认的 `SqlWriterConfig` 配置,并调用 `toSqlString(UnaryOperator<SqlWriterConfig> transform)` 方法进行转换。
14. `public SqlString toSqlString(UnaryOperator<SqlWriterConfig> transform)`:将当前节点转换为 `SqlString` 对象,该对象包含节点的SQL字符串表示。
它接收一个 `UnaryOperator<SqlWriterConfig>` 参数 `transform`,用于修改默认的 `SqlWriterConfig` 配置。返回一个 `SqlString` 对象。
15. `public SqlString toSqlString(@Nullable SqlDialect dialect, boolean forceParens)`:将当前节点转换为 `SqlString` 对象,该对象包含节点的SQL字符串表示。它接收一个可为空的 `SqlDialect` 参数 `dialect`,表示要使用的SQL方言;以及一个 `boolean` 参数 `forceParens`,表示是否强制使用括号。返回一个 `SqlString` 对象。
16. `public abstract void unparse(SqlWriter var1, int var2, int var3)`:抽象方法,用于将当前节点解析为SQL字符串,并输出到指定的 `SqlWriter` 对象中。它接收一个 `SqlWriter` 参数 `var1`,表示输出的目标;以及两个 `int` 参数 `var2` 和 `var3`,表示解析过程中的上下文信息。
17. `public void unparseWithParentheses(SqlWriter writer, int leftPrec, int rightPrec, boolean parentheses)`:将当前节点解析为SQL字符串,并输出到指定的 `SqlWriter` 对象中。如果 `parentheses` 为 `true`,则将节点用括号括起来;否则直接输出。它接收一个 `SqlWriter` 参数 `writer`,表示输出的目标;两个 `int` 参数 `leftPrec` 和 `rightPrec`,表示解析过程中的上下文信息;以及一个 `boolean` 参数 `parentheses`,表示是否使用括号。
18. `public SqlParserPos getParserPosition()`:获取当前节点在SQL语句中的位置信息。
19. `public abstract void validate(SqlValidator var1, SqlValidatorScope var2)`:抽象方法,用于验证当前节点是否符合SQL语法规则。它接收一个 `SqlValidator` 参数 `var1`,表示用于验证的验证器;以及一个 `SqlValidatorScope` 参数 `var2`,表示验证的作用域。
20. `public void findValidOptions(SqlValidator validator, SqlValidatorScope scope, SqlParserPos pos, Collection<SqlMoniker> hintList)`:在给定的验证器和作用域中,查找当前节点的有效选项。它接收一个 `SqlValidator` 参数 `validator`,表示用于验证的验证器;一个 `SqlValidatorScope` 参数 `scope`,表示验证的作用域;一个 `SqlParserPos` 参数 `pos`,表示位置信息;以及一个 `Collection<SqlMoniker>` 参数 `hintList`,表示找到的有效选项的列表。
21. `public void validateExpr(SqlValidator validator, SqlValidatorScope scope)`:验证表达式节点。它先调用 `validate()` 方法进行语法验证,然后调用 `validator.deriveType()` 方法获取表达式的类型。
22. `public abstract <R> R accept(SqlVisitor<R> var1)`:抽象方法,接
受一个 `SqlVisitor<R>` 参数,表示访问器。它用于实现访问者模式,允许对当前节点进行自定义操作。
23. `public abstract boolean equalsDeep(@Nullable SqlNode var1, Litmus var2)`:抽象方法,用于深度比较两个节点是否相等。它接收一个可为空的 `SqlNode` 参数 `var1`,表示要比较的节点;以及一个 `Litmus` 参数 `var2`,表示比较的结果。返回比较结果。
24. `public final boolean equalsDeep(@Nullable SqlNode node, boolean fail)`:比较两个节点是否相等。如果 `fail` 为 `true`,则在比较失败时抛出异常;否则只返回比较结果。这个方法已经被标记为 `@Deprecated`,表示不推荐使用,因为它直接调用了 `equalsDeep(SqlNode, Litmus)` 方法。
25. `public static boolean equalDeep(@Nullable SqlNode node1, @Nullable SqlNode node2, Litmus litmus)`:比较两个节点是否相等。如果两个节点都为 `null`,返回 `true`;如果其中一个节点为 `null`,返回 `false`;否则调用节点的 `equalsDeep()` 方法进行比较。它接收两个可为空的 `SqlNode` 参数 `node1` 和 `node2`,表示要比较的两个节点;以及一个 `Litmus` 参数 `litmus`,表示比较的结果。
26. `public SqlMonotonicity getMonotonicity(@Nullable SqlValidatorScope scope)`:获取当前节点的单调性。它接收一个可为空的 `SqlValidatorScope` 参数 `scope`,表示验证的作用域。返回一个 `SqlMonotonicity` 枚举值,表示节点的单调性。
27. `public static boolean equalDeep(List<SqlNode> operands0, List<SqlNode> operands1, Litmus litmus)`:比较两个节点列表是否相等。首先比较两个列表的长度,如果不相等则返回比较失败;然后逐个比较列表中对应位置的节点,如果任何一个节点不相等,则返回比较失败。如果所有节点都相等,则返回比较成功。它接收两个 `List<SqlNode>` 类型的参数 `operands0` 和 `operands1`,表示要比较的两个节点列表;以及一个 `Litmus` 参数 `litmus`,表示比较的结果。
28. `public static <T extends SqlNode> Collector<T, ArrayList<SqlNode>, SqlNodeList> toList()`:返回一个 `Collector` 对象,用于将 `SqlNode` 对象流收集为 `SqlNodeList` 对象。这个方法没有参数,使用默认的 `SqlParserPos.ZERO` 作为位置信息。
29. `public static <T extends SqlNode> Collector<T, ArrayList<SqlNode>, SqlNodeList> toList(SqlParserPos pos)`:返回一个 `Collector` 对象,用于将 `SqlNode` 对象流收集为 `SqlNodeList` 对象。它接收一个 `SqlParserPos` 参数 `pos`,表示收
集后的 `SqlNodeList` 的位置信息。
总结:这段代码提供了 `SqlNode` 类的基本功能,包括克隆、转换为字符串、解析、验证等操作。它还支持访问者模式,允许对节点进行自定义操作。这些功能在解析和处理SQL语句时非常有用。