如何访问传入pl / tcl函数的数组?参数不应该变成列表吗?在下面的代码中,无论输入是什么,它都会打印“1”,例如“select foobar(array [1,2,3]);”
我感兴趣的是构建自定义聚合,它使用数组来保持调用之间的状态。
编辑:
这是一个新功能:
create function foobar(int[]) returns int[] as $$
elog INFO "$1, [llength $1]"
return $1
$$ language pltcl;
这是调用和输出,它显示了进出函数的数组:
postgis20=# select (array[1,2,3])[1];
array
-------
1
(1 row)
postgis20=# select foobar(array[1,2,3]);
INFO: {1,2,3}, 1
foobar
---------
{1,2,3}
(1 row)
postgis20=# select (foobar(array[1,2,3]))[1];
INFO: {1,2,3}, 1
foobar
--------
1
(1 row)
谢谢!
答案 0 :(得分:1)
documentation有点不可知,但它包括:
提供给PL / Tcl函数代码的参数值只是转换为文本形式的输入参数(就像它们已由
SELECT
语句显示一样)。相反,return
命令将接受函数声明的返回类型的可接受输入格式的任何字符串。因此,在PL / Tcl函数中,所有值都只是文本字符串。
因此来自Tcl的PoV的数组值将是{1,2,3}
或类似的东西。其他一切都是在序列化和Tcl列表之间进行转换。 (所有这些对于其他类型的数值数组也可以正常工作,但如果你做了字符或字符串数组会很危险,因为分隔符字符可以出现在其中。当然,在这种情况下,我也认为你在做首先有点不对劲......)
int[]
数组要从这样的事物中提取整数,我们会这样做:
set tclListOfValues [split [string trim $1 "{}"] ","]
之后,您可以使用llength
和lindex
以及foreach
等。反向操作,将Tcl列表(假设为整数)转换为int[]
以便返回:
return \{[join $tclListOfValues ","]\}
如果您需要访问嵌套数组,事情会变得更加尴尬。问题在于它是一个两级分割,最好通过在外部string map
之前使用split
应用一些聪明的魔法来实现:
set listOfLists {}
foreach innerArray [split [string map {"\},\{" "\u0000"} [string trim $1 "{}"]] "\u0000"] {
lappend listOfLists [split $innerArray ","]
}
在Tcl 8.6中,你可以用这样的lmap
稍微整齐地做这个(概念上是单行,但是为了清晰起见):
set listOfLists [lmap innerArray \
[split [string map {"\},\{" "\u0000"} [string trim $1 "{}"]] "\u0000"] {
split $innerArray ","
}]
反方向:
set resultAccumulator {}
foreach innerList $listOfLists {
lappend resultAccumulator [join $innerList ","]
}
return \{[join $resultAccumulator "\},\{"]\}
或者再次使用lmap
的Tcl 8.6样式:
return \{[join [lmap innerList $listOfLists {join $innerList ","}] "\},\{"]\}