1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shardingsphere.sqlfederation.optimizer.converter.segment.expression.impl;
19
20 import lombok.AccessLevel;
21 import lombok.NoArgsConstructor;
22 import org.apache.calcite.sql.SqlBasicCall;
23 import org.apache.calcite.sql.SqlFunctionCategory;
24 import org.apache.calcite.sql.SqlIdentifier;
25 import org.apache.calcite.sql.SqlNode;
26 import org.apache.calcite.sql.SqlNodeList;
27 import org.apache.calcite.sql.SqlOperator;
28 import org.apache.calcite.sql.SqlSyntax;
29 import org.apache.calcite.sql.SqlUnresolvedFunction;
30 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
31 import org.apache.calcite.sql.parser.SqlParserPos;
32 import org.apache.calcite.sql.validate.SqlNameMatchers;
33 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
34 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment;
35 import org.apache.shardingsphere.sqlfederation.optimizer.converter.segment.expression.ExpressionConverter;
36
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.LinkedList;
40 import java.util.List;
41 import java.util.Optional;
42
43
44
45
46 @NoArgsConstructor(access = AccessLevel.PRIVATE)
47 public final class FunctionConverter {
48
49
50
51
52
53
54
55 public static Optional<SqlNode> convert(final FunctionSegment segment) {
56 SqlIdentifier functionName = new SqlIdentifier(segment.getFunctionName(), SqlParserPos.ZERO);
57
58 if ("CURRENT_USER".equalsIgnoreCase(functionName.getSimple())) {
59 return Optional.of(functionName);
60 }
61 if ("TRIM".equalsIgnoreCase(functionName.getSimple())) {
62 return TrimFunctionConverter.convert(segment);
63 }
64 if ("OVER".equalsIgnoreCase(functionName.getSimple())) {
65 return WindowFunctionConverter.convert(segment);
66 }
67 List<SqlOperator> functions = new LinkedList<>();
68 SqlStdOperatorTable.instance().lookupOperatorOverloads(functionName, null, SqlSyntax.FUNCTION, functions, SqlNameMatchers.withCaseSensitive(false));
69 return Optional.of(functions.isEmpty()
70 ? new SqlBasicCall(
71 new SqlUnresolvedFunction(functionName, null, null, null, null, SqlFunctionCategory.USER_DEFINED_FUNCTION), getFunctionParameters(segment.getParameters()), SqlParserPos.ZERO)
72 : new SqlBasicCall(functions.iterator().next(), getFunctionParameters(segment.getParameters()), SqlParserPos.ZERO));
73 }
74
75 private static List<SqlNode> getFunctionParameters(final Collection<ExpressionSegment> sqlSegments) {
76 List<SqlNode> result = new LinkedList<>();
77 for (ExpressionSegment each : sqlSegments) {
78 ExpressionConverter.convert(each).ifPresent(optional -> result.addAll(optional instanceof SqlNodeList ? ((SqlNodeList) optional).getList() : Collections.singleton(optional)));
79 }
80 return result;
81 }
82 }