Estou enfrentando o seguinte erro:
ERROR: functions in index expression must be marked IMMUTABLE
Ao tentar criar um índice como este:
CREATE INDEX full_phone_number ON orders_clientphone (concat(area_code, phone));
Por outro lado, ao usar sintaxe alternativa para concatenação:
CREATE INDEX full_phone_number ON orders_clientphone ((area_code || phone));
Postgres está muito bem com isso.
Ambas as colunas são definidas como character varying(256)
.
O fator decisivo para Postgres é que a função
concat()
é definida como estável e não imutável no catálogo do sistemapg_proc
:O manual sobre
pg_proc.provolatile
:Também adicionei os tipos de argumento da função (
"any"
) para conectar às respostas de @dezso e @jjanes, que fornecem a lógica por trás da decisão de tornar essa função apenas estável. E o nome da função interna (text_concat
).Aqui está uma questão relacionada para ilustrar por que a imutabilidade das expressões de índice é uma condição sine qua non:
Quanto ao uso do operador
||
:A função a ser usada internamente depende do tipo de dado real dos operandos. A definição de um operador inclui os tipos de dados dos operandos no Postgres. Todas as funções são diferentes e também diferentes das
text_concat
anteriores.||
também é estável, quando um dos operadores éanynonarray
. As coisas não são tão triviais atrás das cortinas.character varying(256)
(como qualquervarchar
variante) é binário-coercível paratext
que o padrão de resolução do tipo de funçãotext
seja .Para preencher a resposta de dezso, aqui está um exemplo da mesma entrada gerando saídas diferentes, dependendo do estado do banco de dados:
Acredito concat, definido na documentação da seguinte forma:
não é imutável porque a representação do texto pode depender das configurações do banco de dados, como data ou carimbo de data/hora .