PostgreSQL函数参数是按引用还是按值传递的?

5
当我调用一个函数并传递参数时,这个参数的值是否实际上被复制到内存中,以便被调用的函数接收到该值的副本,还是它被传递一个引用/指针?
我猜在某些情况下很明显 - 例如,我期望整数被复制,但如果我有一个大字符串或数组或表行呢?
从我的观察来看,似乎始终会复制该值,因为我可以在调用的函数中编辑该值而不更改调用函数中的值。实际上,我无法想象任何情况下我能够修改传递的参数,并使调用函数在没有从被调用函数返回更改后的数据的情况下捕获更改。
因此,对于这个原因,我总是对从一个函数传递大量数据感到不安。我没有找到关于postgres如何处理参数的任何文档,因此提出了这个问题。我使用的函数类型是SQL和plpgsql。
1个回答

6

这取决于过程语言和类型。

C函数:

  • 如果pg_type中的typbyval列为TRUE,则传递固定长度数据类型的值。

  • 除非你使用--disable-float4-byval配置PostgreSQL,否则会传递real值。

  • 在64位体系结构上,传递bigintdouble precisiontimestamp类型的值,除非你使用--disable-float8-byval配置PostgreSQL。

所有其他数据类型都通过引用传递,你有责任不修改数据(参见文档以及configure.insrc/include/postgres.h中的源代码)。

PL/pgSQL函数:

所有参数都通过值传递,因为src/pl/plpgsql/src/pl_exec.c中的函数plpgsql_exec_function创建了一份副本。

/*
 * Make local execution copies of all the datums
 */
estate.err_text = gettext_noop("during initialization of execution state");
copy_plpgsql_datums(&estate, func);

我没有明确检查其他过程式语言,但我相当确定所有内容也将按值传递,因为这些数据必须转换为相应编程语言的内部表示。


谢谢。我可以问一下你是怎么知道的吗?这是有文档记录的吗,还是通过阅读源代码得出的结论,或者其他什么方式? - 404
1
好的,我检查了一下,结果发现答案更加复杂。 - Laurenz Albe
@LaurenzAlbe 在C中,函数是公开的(https://www.postgresql.org/docs/current/xfunc-c.html#XFUNC-C-BASETYPE),在pgsql中调用时仍然使用传值方式吗? - mleko
此外,如果我们在 pgsql 中返回记录,那么记录是否也会被复制返回? - mleko
@mleko 这是一个不同的问题。 - Laurenz Albe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接