AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 144839
Accepted
andilabs
andilabs
Asked: 2016-07-26 07:44:16 +0800 CST2016-07-26 07:44:16 +0800 CST 2016-07-26 07:44:16 +0800 CST

CONCAT usado em INDEX causa ERRO: as funções na expressão de índice devem ser marcadas como IMUTÁVEIS

  • 772

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).

postgresql index
  • 3 3 respostas
  • 6913 Views

3 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2016-07-27T04:28:16+08:002016-07-27T04:28:16+08:00

    O fator decisivo para Postgres é que a função concat()é definida como estável e não imutável no catálogo do sistema pg_proc:

    SELECT proname, provolatile, proargtypes, proargtypes[0]::regtype AS argtype, prosrc
    FROM pg_proc
    WHERE proname = 'concat';
    
    proname | provolatile | proargtypes| argtype | prosrc
    --------+-------------+------------+---------+-----------
    concat  | s           | 2276       | "any"   | text_concat
    

    O manual sobre pg_proc.provolatile:

    provolatileinforma se o resultado da função depende apenas de seus argumentos de entrada ou é afetado por fatores externos. É ipara funções "imutáveis", que sempre fornecem o mesmo resultado para as mesmas entradas. É spara funções "estáveis", cujos resultados (para entradas fixas) não mudam dentro de uma varredura.

    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:

    • Corrompendo intencionalmente um índice no PostgreSQL

    Quanto ao uso do operador ||:

        SELECT o.oprname, o.oprleft::regtype, o.oprright::regtype, o.oprcode, p.provolatile
        FROM   pg_operator o
        JOIN   pg_proc     p ON p.oid = o.oprcode
        WHERE  oprname = '||';
    
    
     oprname |   oprleft   |  oprright   |     oprcode     | provolatile
    ---------+-------------+-------------+-----------------+-------------
     ||      | anyarray    | anyelement  | array_append    | i
     ||      | anyelement  | anyarray    | array_prepend   | i
     ||      | anyarray    | anyarray    | array_cat       | i
     ||      | text        | text        | textcat         | i
     ||      | bit varying | bit varying | bitcat          | i
     ||      | bytea       | bytea       | byteacat        | i
     ||      | text        | anynonarray | textanycat      | s
     ||      | anynonarray | text        | anytextcat      | s
     ||      | tsvector    | tsvector    | tsvector_concat | i
     ||      | tsquery     | tsquery     | tsquery_or      | i
     ||      | jsonb       | jsonb       | jsonb_concat    | i
    

    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_concatanteriores. ||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 qualquer varcharvariante) é binário-coercível para textque o padrão de resolução do tipo de funçãotext seja .

    • 9
  2. jjanes
    2016-07-26T08:18:22+08:002016-07-26T08:18:22+08:00

    Para preencher a resposta de dezso, aqui está um exemplo da mesma entrada gerando saídas diferentes, dependendo do estado do banco de dados:

    select concat(1.0000000000003::float8,56);
    
    1.000000000000356
    
    set extra_float_digits TO 3;
    
    select concat(1.0000000000003::float8,56);
    
    1.0000000000002999856
    
    • 4
  3. dezso
    2016-07-26T08:00:00+08:002016-07-26T08:00:00+08:00

    Acredito concat, definido na documentação da seguinte forma:

    FUNCTION                                  RETURN TYPE  DESCRIPTION
    -----------------------------------------------------------------------------------
    concat(str "any" [, str "any" [, ...] ])  text         Concatenate the text repre-
                                                           sentations of all the arguments. 
                                                           NULL arguments are ignored.
    

    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 .

    • 3

relate perguntas

  • Quanto "Padding" coloco em meus índices?

  • Sequências Biológicas do UniProt no PostgreSQL

  • O que significa "índice" em RDBMSs? [fechado]

  • Como criar um índice condicional no MySQL?

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve