io.trino.operator.scalar.annotations.ScalarFromAnnotationsParser
这里是提取注解元素的方法
String baseName = scalarFunction.value().isEmpty() ? camelToSnake(annotatedName(annotated)) : scalarFunction.value();
这里如果 scalarFunction 的注解没有没有值,直接对函数名进行snake命名法
一般程序设计中,有两种变量命名规范:Snake方式和Camel方式。
例如,你想定义一个变量表示一个数组数字之和,并且用英文“sum of array”。我们使用Snake方式的变量名为:sum_of_array;用Camel命名方式的变量名为:sumOfArray。
public static List fromAnnotatedElement(AnnotatedElement annotated)
{
ScalarFunction scalarFunction = annotated.getAnnotation(ScalarFunction.class);
ScalarOperator scalarOperator = annotated.getAnnotation(ScalarOperator.class);
Optional description = parseDescription(annotated);
ImmutableList.Builder builder = ImmutableList.builder();
if (scalarFunction != null) {
String baseName = scalarFunction.value().isEmpty() ? camelToSnake(annotatedName(annotated)) : scalarFunction.value();
builder.add(new ScalarImplementationHeader(baseName, new ScalarHeader(description, scalarFunction.hidden(), scalarFunction.deterministic())));
for (String alias : scalarFunction.alias()) {
builder.add(new ScalarImplementationHeader(alias, new ScalarHeader(description, scalarFunction.hidden(), scalarFunction.deterministic())));
}
}
if (scalarOperator != null) {
builder.add(new ScalarImplementationHeader(scalarOperator.value(), new ScalarHeader(description, true, true)));
}
List result = builder.build();
checkArgument(!result.isEmpty());
return result;
}
io.trino.operator.scalar.annotations.ScalarImplementationHeader
private static String annotatedName(AnnotatedElement annotatedElement)
{
if (annotatedElement instanceof Class>) {
return ((Class>) annotatedElement).getSimpleName();
}
if (annotatedElement instanceof Method) {
return ((Method) annotatedElement).getName();
}
checkArgument(false, "Only Classes and Methods are supported as annotated elements.");
return null;
}
由上可得 method 也是一种 AnnotatedElement
io.trino.operator.scalar.annotations.ScalarImplementationHeader
private static String camelToSnake(String name)
{
return LOWER_CAMEL.to(LOWER_UNDERSCORE, name);
}
com.google.common.base.CaseFormat
/**
* Converts the specified {@code String str} from this format to the specified {@code format}. A
* "best effort" approach is taken; if {@code str} does not conform to the assumed format, then
* the behavior of this method is undefined but we make a reasonable effort at converting anyway.
*/
public final String to(CaseFormat format, String str) {
checkNotNull(format);
checkNotNull(str);
return (format == this) ? str : convert(format, str);
}
/** Enum values can override for performance reasons. */
String convert(CaseFormat format, String s) {
// deal with camel conversion
StringBuilder out = null;
int i = 0;
int j = -1;
while ((j = wordBoundary.indexIn(s, ++j)) != -1) {
if (i == 0) {
// include some extra space for separators
out = new StringBuilder(s.length() + 4 * format.wordSeparator.length());
out.append(format.normalizeFirstWord(s.substring(i, j)));
} else {
requireNonNull(out).append(format.normalizeWord(s.substring(i, j)));
}
out.append(format.wordSeparator);
i = j + wordSeparator.length();
}
return (i == 0)
? format.normalizeFirstWord(s)
: requireNonNull(out).append(format.normalizeWord(s.substring(i))).toString();
}
When you implement a new Trino plugin, you implement interfaces and override methods defined by the Service Provider Interface (SPI).
Every Trino plugin should be in a separate directory. Do not put JAR files directly into the plugin directory. Plugins should only contain JAR files, so any subdirectories will not be traversed and will be ignored.