如何访问传递给 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)
谢谢!
最佳答案
documentation有点不可知论,但它包括:
The argument values supplied to a PL/Tcl function's code are simply the input arguments converted to text form (just as if they had been displayed by a
SELECT
statement). Conversely, thereturn
command will accept any string that is acceptable input format for the function's declared return type. So, within the PL/Tcl function, all values are just text strings.
因此来自 Tcl 的 PoV 的数组值将是 {1,2,3}
或类似的东西。其他一切都在该序列化和 Tcl 的列表之间进行转换。 (所有这些也适用于其他类型的数字数组,但如果你做字符或字符串数组会很危险,因为分隔符可以出现在其中。当然,在那种情况下我也认为你在做首先有点不对劲……)
处理 PostgreSQL int[]
数组
要从这样的事情中提取整数,我们会这样做:
set tclListOfValues [split [string trim $1 "{}"] ","]
之后可以使用llength
和lindex
和foreach
等。反向操作,将 Tcl 列表(假定为整数)转换为 int[]
以返回:
return \{[join $tclListOfValues ","]\}
处理嵌套的 PostgreSQL 数组
如果您需要访问嵌套数组,事情会变得更加尴尬。问题在于它是一个两级拆分,最好通过在外部 拆分
之前使用 string map
应用一些巧妙的魔法来完成:
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 "\},\{"]\}
或者在 Tcl 8.6 风格中再次使用 lmap
:
return \{[join [lmap innerList $listOfLists {join $innerList ","}] "\},\{"]\}
关于postgresql - 如何在 PL/TCL 中访问 PostgreSQL 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17902124/