这是本节的多页打印视图。
点击此处打印.
返回本页常规视图.
UDx 参数
形参可让您为 UDx 定义具有以下特性的实参:在由调用 UDx 的 SQL 语句处理的所有行之间保持恒定。通常,您的 UDxs 允许在 SQL 语句中使用来自列的参数。例如,在以下 SQL 语句中,add2ints
UDSF 的参数 a 和 b 会在 SELECT 语句处理每行时更改值:
=> SELECT a, b, add2ints(a,b) AS 'sum' FROM example;
a | b | sum
---+----+-----
1 | 2 | 3
3 | 4 | 7
5 | 6 | 11
7 | 8 | 15
9 | 10 | 19
(5 rows)
UDx 处理的所有行的参数都保持恒定。您还可以将参数变为可选,从而当用户没有提供参数时,UDx 可以使用默认值。例如,以下示例说明了调用名为 add2intsWithConstant
的 UDSF 的过程,其中具有一个名为 constant 的参数值,该参数值会添加到每个输入行提供的每个参数:
=> SELECT a, b, add2intsWithConstant(a, b USING PARAMETERS constant=42)
AS 'a+b+42' from example;
a | b | a+b+42
---+----+--------
1 | 2 | 45
3 | 4 | 49
5 | 6 | 53
7 | 8 | 57
9 | 10 | 61
(5 rows)
注意
调用具有实参的 UDx 时,最后一个参数和 USING PARAMETERS 子句之间没有逗号。
此部分的主题说明了如何开发接收参数的 UDX。
1 - 定义 UDx 接受的参数
可以通过实施 getParameterType()
在 UDx 的工厂类(ScalarFunctionFactory
和 AggregateFunctionFactory
等)中定义其接受的参数。此方法与 getReturnType()
相似:对作为参数传入的 SizedColumnTypes
对象调用特定于数据类型的方法。每个函数调用都会设置参数的名称、数据类型和宽度或精度(如果数据类型需要此设置)。
设置参数属性(仅限 C++)
使用 C++ API 将参数添加到 getParameterType()
函数时,您还可以设置每个参数的属性。例如,您可以在 UDx 需要时定义一个参数。这样做可告知 Vertica 服务器每次调用 UDx 必须提供指定的参数,否则查询将失败。
通过将对象传递至 SizedColumnTypes::Properties
类,可以定义下列四个参数属性:
设置参数属性(仅限 R)
在 R UDx 中使用参数时,您必须在名为 parametertypecallback
的工厂函数中指定一个字段。此字段指向回调函数,而该回调函数定义函数所需的参数。回调函数定义了具有以下属性的四列数据帧:
如果任何列保留为空(或忽略 parametertypecallback
函数),则 Vertica 将使用默认值。
有关详细信息,请参阅Parametertypecallback 函数。
2 - 获取 UDx 中的参数值
在函数类的处理方法(例如 processBlock()
或 processPartition()
)中,UDx 会使用在其工厂类中声明的参数值(请参阅定义 UDx 接受的参数)。它从 ParamReader
对象(可通过传递到处理方法的 ServerInterface
对象访问此对象)获取参数值。从此对象读取参数类似于从 BlockReader
或 PartitionReader
对象读取参数值:使用该参数名称调用特定于数据类型的函数以检索其值。例如,在 C++ 中:
注意
在字符串数据值传递到函数之前,其任何转义字符均未经过处理。因此,如果函数需要对未转义的字符值执行操作,它可能需要自己处理转义序列。
使用工厂类中的参数
除了在 UDx 函数类中使用参数之外,您还可以在工厂类中访问参数。您可能希望访问参数,以让用户通过某种方法控制函数的输入值或输出值。例如,UDx 可以具有一个参数,该参数允许用户选择让 UDx 返回单精度值或双精度值。在工厂类中访问参数的过程与在函数类中访问参数的过程相同:从 ServerInterface
's getParamReader()
方法获取 ParamReader
对象,然后读取参数值。
测试用户是否提供了参数值
与实参处理不同,当用户的函数调用不包含由 UDx 工厂类定义的参数值时,Vertica 不会立即返回错误。这意味着函数可以尝试读取用户未提供的参数值。如果函数进行此尝试,则在默认情况下,Vertica 将向用户返回参数不存在警告,并且包含该函数调用的查询将继续运行。
如果希望参数是可选的,您可以在尝试访问参数的值之前测试用户是否提供了该参数的值。函数通过使用该参数名称调用 ParamReader
的 containsParameter()
方法来确定特定参数的值是否存在。如果此调用返回 true,则函数可以安全地检索值。如果此调用返回 false,则 UDx 可以使用默认值或将其处理更改为某种其他方法以弥补参数值不存在的问题。只要 UDx 不尝试访问不存在的参数值,Vertica 就不会生成有关缺失参数的错误或警告。
有关示例,请参阅 C++ 示例:定义参数。
3 - 使用参数调用 UDx
可以通过在函数调用中的最后一个参数之后添加 USING PARAMETERS 子句来将参数传递到 UDx。
-
请勿在最后一个参数和 USING PARAMETERS 子句之间插入逗号。
-
在 USING PARAMETERS 子句之后,使用以下格式添加一个或多个参数定义:
<parameter name> = <parameter value>
-
用逗号分隔各个参数定义。
参数值可以是常量表达式(例如 1234 + SQRT(5678)
)。不能在表达式中使用易变函数(例如 RANDOM),因为易变函数不会返回常量值。如果确实提供了易变表达式作为参数值,则在默认情况下,Vertica 将返回参数类型不正确警告。然后,Vertica 会尝试运行不带有参数值的 UDx。如果 UDx 需要参数,则它会返回自己的错误,该错误会导致取消查询。
调用带有单个参数的 UDx
以下示例演示了如何调用 C++ 示例:定义参数 中所示的 Add2intsWithConstant UDSF 示例:
=> SELECT a, b, Add2intsWithConstant(a, b USING PARAMETERS constant=42) AS 'a+b+42' from example;
a | b | a+b+42
---+----+--------
1 | 2 | 45
3 | 4 | 49
5 | 6 | 53
7 | 8 | 57
9 | 10 | 61
(5 rows)
要移除数字 3 的第一个实例,您可以调用 RemoveSymbol UDSF 示例:
=> SELECT '3re3mo3ve3sy3mb3ol' original_string, RemoveSymbol('3re3mo3ve3sy3mb3ol' USING PARAMETERS symbol='3');
original_string | RemoveSymbol
--------------------+-------------------
3re3mo3ve3sy3mb3ol | re3mo3ve3sy3mb3ol
(1 row)
调用带有多个参数的 UDx
以下示例显示了如何调用某个版本的 tokenize UDTF。此 UDTF 包含用于限制允许的最短单词的参数和用于强制以大写输出单词的参数。用逗号分隔多个参数。
=> SELECT url, tokenize(description USING PARAMETERS minLength=4, uppercase=true) OVER (partition by url) FROM T;
url | words
-----------------+-----------
www.amazon.com | ONLINE
www.amazon.com | RETAIL
www.amazon.com | MERCHANT
www.amazon.com | PROVIDER
www.amazon.com | CLOUD
www.amazon.com | SERVICES
www.dell.com | LEADING
www.dell.com | PROVIDER
www.dell.com | COMPUTER
www.dell.com | HARDWARE
www.vertica.com | WORLD'S
www.vertica.com | FASTEST
www.vertica.com | ANALYTIC
www.vertica.com | DATABASE
(16 rows)
以下示例将调用 RemoveSymbol UDSF。通过更改可选参数 n
的值,您可以移除数字 3 的所有实例:
=> SELECT '3re3mo3ve3sy3mb3ol' original_string, RemoveSymbol('3re3mo3ve3sy3mb3ol' USING PARAMETERS symbol='3', n=6);
original_string | RemoveSymbol
--------------------+--------------
3re3mo3ve3sy3mb3ol | removesymbol
(1 row)
调用带有可选参数或不正确参数的 UDx
您可以选择添加 Add2intsWithConstant UDSF 的常量参数。在未使用参数的情况下调用此约束不会返回错误或警告:
=> SELECT a,b,Add2intsWithConstant(a, b) AS 'sum' FROM example;
a | b | sum
---+----+-----
1 | 2 | 3
3 | 4 | 7
5 | 6 | 11
7 | 8 | 15
9 | 10 | 19
(5 rows)
虽然调用带有不正确参数的 UDx 将生成警告,但在默认情况下,查询仍会运行。有关设置 UDx 在您提供不正确参数时的行为的详细信息,请参阅指定传递未注册参数的行为。
=> SELECT a, b, add2intsWithConstant(a, b USING PARAMETERS wrongparam=42) AS 'result' from example;
WARNING 4332: Parameter wrongparam was not registered by the function and cannot
be coerced to a definite data type
a | b | result
---+----+--------
1 | 2 | 3
3 | 4 | 7
5 | 6 | 11
7 | 8 | 15
9 | 10 | 19
(5 rows)
4 - 指定传递未注册参数的行为
默认情况下,Vertica 会在您向 UDx 传递未注册参数时发出警告消息。未注册参数是指未在 getParameterType()
方法中声明的参数。
可以通过更改 StrictUDxParameterChecking
配置参数来控制 UDx 在您向其传递未注册参数时的行为。
未注册参数行为设置
可以指定 UDx 为响应一个或多个未注册参数而做出的行为。要执行此操作,请将 StrictUDxParameterChecking
配置参数设置为以下值之一:
示例
以下示例演示了可以通过对 StrictUDxParameterChecking
参数使用不同的值来指定的行为。
查看 StrictUDxParameterChecking 的当前值
要查看 StrictUDxParameterChecking
配置参数的当前值,请运行以下查询:
=> \x
Expanded display is on.
=> SELECT * FROM configuration_parameters WHERE parameter_name = 'StrictUDxParameterChecking';
-[ RECORD 1 ]-----------------+------------------------------------------------------------------
node_name | ALL
parameter_name | StrictUDxParameterChecking
current_value | 1
restart_value | 1
database_value | 1
default_value | 1
current_level | DATABASE
restart_level | DATABASE
is_mismatch | f
groups |
allowed_levels | DATABASE
superuser_only | f
change_under_support_guidance | f
change_requires_restart | f
description | Sets the behavior to deal with undeclared UDx function parameters
更改 StrictUDxParameterChecking 的值
可以在数据库级别、节点级别或会话级别更改 StrictUDxParameterChecking
配置参数的值。例如,可以将值更改为“0”,以指定可以向 UDx 传递未注册参数而不显示警告或错误消息:
=> ALTER DATABASE DEFAULT SET StrictUDxParameterChecking = 0;
ALTER DATABASE
RemoveSymbol 的无效参数行为
以下示例演示了如何调用 RemoveSymbol UDSF 示例。RemoveSymbol UDSF 具有一个必需参数 (symbol
) 和一个可选参数 (n
)。在此示例中,未使用可选参数。
如果同时传递 symbol
和一个名为 wrongParam
的附加参数(未在 UDx 中声明此参数),UDx 的行为会根据 StrictUDxParameterChecking
的值相应地更改。
如果将 StrictUDxParameterChecking
设置为“0”,UDx 将正常运行而不显示警告。此外,wrongParam
将变为可供 UDx 访问(通过 ServerInterface
对象的 ParamReader
对象):
=> ALTER DATABASE DEFAULT SET StrictUDxParameterChecking = 0;
ALTER DATABASE
=> SELECT '3re3mo3ve3sy3mb3ol' original_string, RemoveSymbol('3re3mo3ve3sy3mb3ol' USING PARAMETERS symbol='3', wrongParam='x');
original_string | RemoveSymbol
--------------------+-------------------
3re3mo3ve3sy3mb3ol | re3mo3ve3sy3mb3ol
(1 row)
如果将 StrictUDxParameterChecking
设置为“1”,UDx 将忽略 wrongParam
并正常运行。但是,它还会发出警告消息:
=> ALTER DATABASE DEFAULT SET StrictUDxParameterChecking = 1;
ALTER DATABASE
=> SELECT '3re3mo3ve3sy3mb3ol' original_string, RemoveSymbol('3re3mo3ve3sy3mb3ol' USING PARAMETERS symbol='3', wrongParam='x');
WARNING 4320: Parameter wrongParam was not registered by the function and cannot be coerced to a definite data type
original_string | RemoveSymbol
--------------------+-------------------
3re3mo3ve3sy3mb3ol | re3mo3ve3sy3mb3ol
(1 row)
如果将 StrictUDxParameterChecking
设置为 '2',UDx 将在尝试调用 wrongParam
时遇到错误并且无法运行。相反,它会生成错误消息:
=> ALTER DATABASE DEFAULT SET StrictUDxParameterChecking = 2;
ALTER DATABASE
=> SELECT '3re3mo3ve3sy3mb3ol' original_string, RemoveSymbol('3re3mo3ve3sy3mb3ol' USING PARAMETERS symbol='3', wrongParam='x');
ERROR 0: Parameter wrongParam was not registered by the function
5 - 用户定义的会话参数
使用用户定义的会话参数,可以编写比 Vertica 提供的参数更通用的参数。您可以使用以下方法配置用户定义的会话参数:
用户定义的会话参数可以传递到受 Vertica 支持的任何类型的 UDx。您还可以在会话级别为您的 UDx 设置参数。通过指定用户定义的会话参数,您可以持续保存参数状态。甚至当 UDx 在单个会话期间被多次调用时,Vertica 也可以保存参数状态。
RowCount 示例使用用户定义的会话参数。此参数会计算出每次运行时 UDx 处理的行的总数。然后,RowCount 会显示所有执行操作处理的行的总数。有关如何实施,请参阅 C++ 示例:使用会话参数和 Java 示例:使用会话参数。
查看用户定义的会话参数
输入以下命令以查看所有会话参数的值:
=> SHOW SESSION UDPARAMETER all;
schema | library | key | value
--------+---------+-----+-------
(0 rows)
尚未设置任何值,因此该表为空。现在执行 UDx:
=> SELECT RowCount(5,5);
RowCount
----------
10
(1 row)
再次输入命令,查看会话参数的值:
=> SHOW SESSION UDPARAMETER all;
schema | library | key | value
--------+-----------+----------+-------
public | UDSession | rowcount | 1
(1 row)
库列显示包含 UDx 的库的名称。这是使用 CREATE LIBRARY 设置的名称。因为 UDx 已经处理了一行,所以 rowcount 会话参数的值当前为 1。再运行两次 Udx 应将该值增加 2。
=> SELECT RowCount(10,10);
RowCount
----------
20
(1 row)
=> SELECT RowCount(15,15);
RowCount
----------
30
(1 row)
现在您已经执行了三次 UDx,获取了 5 + 5、10 + 10 和 15 + 15 的总和。现在,检查 rowcount 的值。
=> SHOW SESSION UDPARAMETER all;
schema | library | key | value
--------+-----------+----------+-------
public | UDSession | rowcount | 3
(1 row)
更改用户定义的会话参数
您还可以手动更改 rowcount 的值。为此,请输入以下命令:
=> ALTER SESSION SET UDPARAMETER FOR UDSession rowcount = 25;
ALTER SESSION
检查 RowCount 的值:
=> SHOW SESSION UDPARAMETER all;
schema | library | key | value
--------+-----------+----------+-------
public | UDSession | rowcount | 25
(1 row)
清除用户定义的会话参数
从客户端:
要清除 rowcount 的当前值,请输入以下命令:
=> ALTER SESSION CLEAR UDPARAMETER FOR UDSession rowcount;
ALTER SESSION
确认 rowcount 已被清除:
=> SHOW SESSION UDPARAMETER all;
schema | library | key | value
--------+---------+-----+-------
(0 rows)
通过 C++ UDx:
可以将会话参数通过 UDx 自身进行清除。例如,要在其值达到 10 或更大值时清除 rowcount,请执行下列操作:
-
从 RowCount 类的 destroy()
方法中移除以下行:
udParams.getUDSessionParamWriter("library").getStringRef("rowCount").copy(i_as_string);
-
将已从 destroy()
方法中移除的行替换为以下代码:
if (rowCount < 10)
{
udParams.getUDSessionParamWriter("library").getStringRef("rowCount").copy(i_as_string);
}
else
{
udParams.getUDSessionParamWriter("library").clearParameter("rowCount");
}
-
要查看 Udx 是否已清除会话参数,请将 rowcount 的值设置为 9:
=> ALTER SESSION SET UDPARAMETER FOR UDSession rowcount = 9;
ALTER SESSION
-
检查 rowcount 的值:
=> SHOW SESSION UDPARAMETER all;
schema | library | key | value
--------+-----------+----------+-------
public | UDSession | rowcount | 9
(1 row)
-
调用 RowCount,使它的值变成 10:
=> SELECT RowCount(15,15);
RowCount
----------
30
(1 row)
-
再次检查 rowcount 的值。由于值已达到 10(即 UDx 中指定的阈值),因此可认为 rowcount 已被清除:
=> SHOW SESSION UDPARAMETER all;
schema | library | key | value
--------+---------+-----+-------
(0 rows)
正如预计的那样,RowCount 已被清除。
通过 Java UDx:
-
从 RowCount 类的 destroy()
方法中移除以下行:
udParams.getUDSessionParamWriter("library").setString("rowCount", Integer.toString(rowCount));
srvInterface.log("RowNumber processed %d records", count);
-
将已从 destroy()
方法中移除的行替换为以下代码:
if (rowCount < 10)
{
udParams.getUDSessionParamWriter("library").setString("rowCount", Integer.toString(rowCount));
srvInterface.log("RowNumber processed %d records", count);
}
else
{
udParams.getUDSessionParamWriter("library").clearParameter("rowCount");
}
-
要查看 Udx 是否已清除会话参数,请将 rowcount 的值设置为 9:
=> ALTER SESSION SET UDPARAMETER FOR UDSession rowcount = 9;
ALTER SESSION
-
检查 rowcount 的值:
=> SHOW SESSION UDPARAMETER all;
schema | library | key | value
--------+-----------+----------+-------
public | UDSession | rowcount | 9
(1 row)
-
调用 RowCount,使它的值变成 10:
=> SELECT RowCount(15,15);
RowCount
----------
30
(1 row)
-
检查 rowcount 的值。由于值已达到 10(即 UDx 中指定的阈值),因此可认为 rowcount 已被清除:
=> SHOW SESSION UDPARAMETER all;
schema | library | key | value
--------+---------+-----+-------
(0 rows)
正如预计的那样,rowcount 已被清除。
只读会话参数和隐藏的会话参数
如果不想在 UDx 之外的其他地方设置参数,您可以将其设为只读。此外,如果不想让参数在客户端内可见,您可以将其设为隐藏。
将参数变为只读,就意味着它不能在客户端中设置,但是可以进行查看。要将参数变为只读,请在参数名称前面添加单下划线。例如,要将 rowCount 变为只读,请将 UDx 中的所有“rowCount”实例更改为“_rowCount”。
将参数设为隐藏,就意味着它不能在客户端中查看,也不能设置。要将参数设为隐藏,请在参数名称前面添加两个下划线。例如,要将 rowCount 变为隐藏,请将 UDx 中的所有“rowCount”实例更改为“__rowCount”。
另请参阅
Kafka 用户定义的会话参数
6 - C++ 示例:定义参数
以下代码片段演示了如何将单个参数添加到 C++ add2ints UDSF 示例。getParameterType()
函数定义了名为 constant
的单个整数参数。
有关定义参数时可调用的特定于数据类型的函数的完整列表,请参阅 SizedColumnTypes
的 Vertica SDK 条目。
以下代码片段演示了使用参数值。Add2intsWithConstant
类定义了一个可将两个整数值相加的函数。如果用户提供了名为 constant 的可选整数参数,则函数还会加上该参数的值。
7 - C++ 示例:使用会话参数
RowCount 示例使用用户定义会话参数,也称为 RowCount。此参数会计算出每次运行时 UDx 处理的行的总数。然后,RowCount 会显示所有执行操作处理的行的总数。
8 - Java 示例:定义参数
以下代码片段演示了将单个参数添加到 Java add2ints UDSF 示例。getParameterType()
函数定义了名为 constant 的单个整数参数。
有关定义参数时可调用的特定于数据类型的方法的完整列表,请参阅 SizedColumnTypes
的 Vertica Java SDK 条目。
9 - Java 示例:使用会话参数
RowCount 示例使用用户定义会话参数,也称为 RowCount。此参数会计算出每次运行时 UDx 处理的行的总数。然后,RowCount 会显示所有执行操作处理的行的总数。