Postgresql

不可變的動態 sql 函式

  • January 22, 2022

情景#1

基本上,假設我們有一個使用動態 SQL 的函式,但也知道它總是為相同的輸入返回相同的輸出並聲明它是不可變的,它真的是不可變的嗎?aka 編譯器/查詢處理器會知道這種特定情況嗎?

根據官方文件

IMMUTABLE 函式不能修改數據庫,並且保證在給定相同參數的情況下永遠返回相同的結果。此類別允許優化器在查詢使用常量參數呼叫該函式時預先評估該函式。

按照這個邏輯,它應該可以正常工作,因為它只關心輸入是否相同。

情景#2

同上,但輸入類型為anyelementor anyarray。考慮到 SQL 是一種強類型語言(來自官方文件)

SQL 是一種強類型語言。也就是說,每個數據項都有一個關聯的數據類型,它決定了它的行為和允許的使用。

並且知道這anyelement只是一個偽類型,因為實際上在處理函式期間它知道它(例如)是一個整數或字元串。因此,從這個角度來看,一個函式anyelement在不可變時是否接受並不重要。


我想知道上面寫的是否確實是 PostgreSQL 在這些條件下的真實行為。如果與使用正常 SQL 的正常不可變函式相比有什麼不同的話。

如果聲明了一個函式IMMUTABLE,但函式體包含波動較小的函式 ( STABLE, VOLATILE),則禁用 SQL 函式的函式內聯。所以,是的,Postgres 確實關心“裡面有什麼”。

SQL 函式與其他過程語言(如 PL/pgSQL)的函式之間存在差異。動態 SQL 在 SQL 函式中是不可能的。有關的:

但出於許多目的,Postgres 對聲明的函式易變性感到滿意。例如,如果您建構一個涉及自定義函式的索引,則必須聲明它IMMUTABLE。信守承諾是您的責任,否則索引將無聲無息地崩潰。

例子:

多態性(使用anyelement等)是一個正交概念。多態函式可以有任何易失性聲明。

引用自:https://dba.stackexchange.com/questions/306309