前提條件:已經寫好自定義函數的java類了,這裏是AddAnyIntsInfo.java
具體如何寫UDX見:https://github.com/vertica/UDx-Examples.git
vertica官方文檔:https://www.vertica.com/documentation/vertica/9-3-x-documentation/
在寫udx的時候注意:
當SDK將Vertica時間戳轉換爲Java時間戳時,它使用JVM的時區。如果JVM運行的時區與Vertica使用的時區不同,那麼結果可能會令人困惑。
Vertica在數據庫中以UTC格式存儲時間戳。(如果設置了數據庫時區,則在查詢時進行轉換。)要防止來自JVM時區的錯誤,請將以下代碼添加到UDx的處理方法中:
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
/* Copyright (c) 2005 - 2016 Hewlett Packard Enterprise Development LP -*- Java -*-*/
/*
*
* Description: Example User Defined Scalar Function: Add any number of ints
*
* Create Date: June 01, 2013
*/
package com.unisinsight.CustomUDXs;
import com.vertica.sdk.*;
import java.util.ArrayList;
import java.util.TimeZone;
/*
* This is a simple function that adds any numebr of integers and returns the result
*/
public class AddAnyIntsInfo extends ScalarFunctionFactory {
@Override
public void getPrototype(ServerInterface srvInterface,
ColumnTypes argTypes,
ColumnTypes returnType) {
argTypes.addAny();
returnType.addInt();
}
public class AddAnyInts extends ScalarFunction {
/*
* This method processes a block of rows in a single invocation.
*
* The inputs are retrieved via argReader
* The outputs are returned via resWriter
*/
@Override
public void processBlock(ServerInterface srvInterface,
BlockReader arg_reader,
BlockWriter res_writer)
throws UdfException, DestroyInvocation {
// 防止jvm時區影響
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
SizedColumnTypes inTypes = arg_reader.getTypeMetaData();
ArrayList<Integer> argCols = new ArrayList<Integer>(); // Argument column indexes.
inTypes.getArgumentColumns(argCols);
// While we have inputs to process
do {
long sum = 0;
for (int i = 0; i < argCols.size(); ++i) {
long a = arg_reader.getLong(i);
sum += a;
}
res_writer.setLong(sum);
res_writer.next();
} while (arg_reader.next());
}
}
@Override
public ScalarFunction createScalarFunction(ServerInterface srvInterface) {
return new AddAnyInts();
}
}
idea中必須要 import VerticaSDK.jar
在vertica所在節點正式部署:
1. 安裝Java 環境
yum localinstall jdk-8u202-linux-x64.rpm
2. 創建臨時目錄,並編譯VerticaSDK.jar和BuildInfo.java,生成相關的.class文件A
[dbadmin@V001 ~]$ mkdir -p /home/soft/customUDXs/fisrtFunc/
[dbadmin@V001 ~]$ cd /home/soft/customUDXs/fisrtFunc/
javac -g -cp /opt/vertica/bin/VerticaSDK.jar /opt/vertica/sdk/BuildInfo.java -d .
3.編譯自定義java udx類 生成相關的.class文件B
-- 上傳AddAnyIntsInfo.java類到該目錄,然後編譯
javac -g -cp /opt/vertica/bin/VerticaSDK.jar AddAnyIntsInfo.java -d .
4.將所有A和B打包爲AddAnyIntLib.jar
jar cf AddAnyIntLib.jar com/unisinsight/CustomUDXs/*.class com/vertica/sdk/*.class
5.切換到vertica的dbadmin賬戶
[root@V001 fisrtFunc]# su - dbadmin
[dbadmin@V001 ~]$ cd /home/soft/customUDXs/fisrtFunc/
6.登錄需要安裝自定義函數的數據庫(viid)
[dbadmin@V001 fisrtFunc]$ vsql -w dbadmin -U dbadmin -d viid -h 192.168.xxx.xx
Welcome to vsql, the Vertica Analytic Database interactive terminal.
Type: \h or \? for help with vsql commands
\g or terminate with semicolon to execute query
\q to quit
viid=> CREATE LIBRARY AddAnyIntLib AS '/home/soft/customUDXs/fisrtFunc/AddAnyIntLib.jar' LANGUAGE 'JAVA';
ROLLBACK 5699: Cannot find java binary: neither the Linux environment variable JAVA_HOME nor Vertica config parameter JavaBinaryForUDx is set
HINT: Please set JAVA_HOME environment variable or JavaBinaryForUDx config parameter to help vertica find java binary
7.聲明JAVA_HOME路徑
viid=> SELECT SET_CONFIG_PARAMETER('JavaBinaryForUDx','/usr/bin/java');
SET_CONFIG_PARAMETER
----------------------------
Parameter set successfully
(1 row)
8.創建LIBRARY
viid=> CREATE LIBRARY AddAnyIntLib AS '/home/soft/customUDXs/fisrtFunc/AddAnyIntLib.jar' LANGUAGE 'JAVA';
CREATE LIBRARY
9.創建FUNCTION
viid=> CREATE FUNCTION AddAnyInt AS language 'java' NAME 'com.unisinsight.CustomUDXs.AddAnyIntsInfo' LIBRARY AddAnyIntLib;
CREATE FUNCTION
10.測試函數功能
viid=> select AddAnyInt(1,2,3);
AddAnyInt
-----------
6
(1 row)
11.退出
viid=>\q;