Vertica实现mysql函数substring_index:
package com.yy.vertica; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import com.vertica.sdk.BlockReader; import com.vertica.sdk.BlockWriter; import com.vertica.sdk.ColumnTypes; import com.vertica.sdk.DestroyInvocation; import com.vertica.sdk.ScalarFunction; import com.vertica.sdk.ScalarFunctionFactory; import com.vertica.sdk.ServerInterface; import com.vertica.sdk.SizedColumnTypes; import com.vertica.sdk.UdfException; import com.vertica.sdk.VerticaType; /** * vertica udf : substring_index * */ public class UDFSubStringIndexFactory extends ScalarFunctionFactory { @Override public ScalarFunction createScalarFunction(ServerInterface arg0) { return new SubStringIndex(); } public class SubStringIndex extends ScalarFunction{ @Override public void processBlock(ServerInterface serverInterface, BlockReader argReader, BlockWriter argWriter) throws UdfException, DestroyInvocation { //see how many arguments were passed in int numCols = argReader.getNumCols(); //check argument nums if (numCols != 3) { throw new UdfException(0, "Must supply 3 arguments:String input, String stripChars, int index"); } //make sure input columns : String input, String stripChars, int index SizedColumnTypes inTypes = argReader.getTypeMetaData(); VerticaType firstParamType = inTypes.getColumnType(0); VerticaType secondParamType = inTypes.getColumnType(1); VerticaType thirdParamType = inTypes.getColumnType(2); if (!firstParamType.isStringType() && !secondParamType.isStringType() && !thirdParamType.isInt()) { throw new UdfException(0, "make sure input columns is : String input, String stripChars, int index"); } String paramString = argReader.getString(0); String stripChars = argReader.getString(1); int index = NumberUtils.toInt(Long.toString(argReader.getLong(2))); argWriter.setString(evaluate(paramString, stripChars, index)); } public String evaluate(String input, String stripChars, int index) { String[] al = StringUtils.split(input, stripChars); if (al == null || stripChars == null || index == 0) { return null; } int indexAbs = Math.abs(index)>=al.length ? al.length: Math.abs(index); String[] result = new String[indexAbs]; List<String> tmp = Arrays.asList(al); if (index > 0) { System.arraycopy(tmp.toArray(), 0, result, 0, indexAbs); return StringUtils.join(result, stripChars); } // 反向取值 Collections.reverse(tmp); System.arraycopy(tmp.toArray(), 0, result, 0, indexAbs); List<String> res = Arrays.asList(result); Collections.reverse(res); return StringUtils.join(res, stripChars); } } @Override public void getPrototype(ServerInterface serverInterface, ColumnTypes argTypes, ColumnTypes returnType) { // Accepts any number and type or arguments. The ScalarFunction // class handles parsing the arguments. argTypes.addVarchar(); argTypes.addVarchar(); argTypes.addInt(); returnType.addVarchar(); } @Override public void getReturnType(ServerInterface srvInterface, final SizedColumnTypes argTypes, SizedColumnTypes returnType){ VerticaType type = argTypes.getColumnType(0); returnType.addVarchar(type.getStringLength()); } }
结果输出
Vmart=> select substring_index('a/b/c','/',2); -[ RECORD 1 ]---+---- substring_index | a/b Vmart=> select substring_index('a/b/c','/',3); -[ RECORD 1 ]---+------ substring_index | a/b/c Vmart=> select substring_index('a/b/c','/',1); -[ RECORD 1 ]---+-- substring_index | a
注意点:
abstract void com.vertica.sdk.UDXFactory.getReturnType ( ServerInterface srvInterface, SizedColumnTypes argTypes,
SizedColumnTypes returnType ) throws UdfException [pure virtual]
Function to tell Vertica what the return types (and length/precision if necessary) of this UDX are.
For CHAR/VARCHAR types, specify the max length,
For NUMERIC types, specify the precision and scale.
For Time types (with or without time zone), specify the precision, -1 means unspecified/don’t care
For IntervalYM/IntervalDS types, specify the precision and range
For all other types, no length/precision specification needed
字符串返回值需要指定返回长度。
创建自定义函数分两个步骤:
1、创建lib
2、创建function
Vmart=> SELECT SET_CONFIG_PARAMETER('JavaBinaryForUDx','/usr/bin/java'); Vmart=> create LIBRARY verticaextlib as '/home/dbadmin/verticaext.jar' language 'Java'; CREATE LIBRARY Vmart=> create function substring_index as language 'Java' name 'com.yy.vertica.UDFSubStringIndexFactory' librARY verticaextlib; CREATE FUNCTION
相关推荐
“Extending Vertica”章节讨论了如何通过开发自定义函数、加载器和其他扩展来定制Vertica的功能,以满足特定业务需求。 “Connecting to Vertica”提供了连接到Vertica的各种方法,包括使用JDBC、ODBC驱动程序,...
对于开发人员,文档中的API参考章节尤为重要,它提供了关于SQL扩展、存储过程、UDX(用户自定义函数)的详细说明,帮助开发者利用Vertica的强大功能构建定制化的数据处理逻辑。同时,文档还可能涵盖与各种编程语言...
- 如何在Vertica上进行高级自定义和扩展,可能包括编写自定义函数、存储过程等。 11. **使用云平台上的Vertica**: - Vertica也支持云环境部署,该部分将介绍如何在云服务如AWS、Azure等平台上部署和使用Vertica...
- **内容概览**:介绍了如何通过自定义函数、UDFs(用户定义函数)等方式增强HP Vertica的功能性和灵活性。 #### 十四、连接至HP Vertica - **章节位置**:文档第3711页。 - **内容概览**:涵盖各种编程语言和工具...
- **自定义函数**:支持用户自定义 SQL 函数,提高查询灵活性。 - **存储过程**:支持编写复杂的业务逻辑,增强数据处理能力。 - **触发器**:能够在特定事件发生时自动执行 SQL 语句。 #### 六、案例与实践 - **...
- **扩展Vertica**(第4173页):介绍如何通过自定义函数等手段扩展Vertica的功能。 - **连接到Vertica**(第4439页):涵盖不同编程语言如何连接到Vertica的方法。 - **在云环境中使用Vertica**(第4943页):讨论...
10. **Extending Vertica**: 这一部分介绍如何利用Vertica的扩展能力,例如开发自定义函数、加载用户定义的聚合函数(UDAF)和操作符,以及实现数据处理的高级功能。 11. **Using Vertica on the Cloud**: 云使用...
- **扩展 HP Vertica(第 3410 页)**:介绍了如何通过编写自定义函数或使用第三方插件来扩展 HP Vertica 的功能。 - **连接到 HP Vertica(第 3636 页)**:提供了多种连接方式的详细介绍,如 JDBC、ODBC 等,方便...
ClickHouse 中的投影是通过自定义的 SELECT 查询来定义的,可以支持任意函数和组合。投影可以在物理层面上实现,也可以作为逻辑视图,或者两者结合。ClickHouse 投影的特点是可以存储派生数据,以优化查询执行。 三...