Skip to main content

Alterações incompatíveis com versões anteriores

Alterações em consultas, funções e sintaxe

  • Para views cujo corpo é um SELECT simples sobre uma única tabela Distributed, toda a consulta externa agora é enviada aos shards (nova configuração optimize_trivial_view_pushdown_to_distributed, habilitada por padrão). Isso altera o comportamento observável dessas views: FINAL e SAMPLE especificados na referência à view agora são propagados para a tabela local do shard em vez de serem ignorados, e extremes não é retornado em clusters com um único shard. Defina optimize_trivial_view_pushdown_to_distributed = 0 para restaurar o comportamento anterior. #101791 (simonmichal).
  • As partes de patch de UPDATE leve agora usam um novo formato em disco v2, ordenado por (sorting_key..., _block_number, _block_offset) e aplicado com um novo algoritmo de mesclagem. O pico de memória passa a ser limitado pela maior sequência com a mesma chave de ordenação, e não mais pelo patch completo, e atualizações que ultrapassam limites de mesclagem deixam de recorrer à aplicação via Join em memória. Partes de patch no formato antigo continuam legíveis. Durante um upgrade gradual a partir de uma versão anterior à 26.8, mantenha patch_parts_version = 'v1' ou use a configuração compatibility até que todas as réplicas tenham sido atualizadas. #103182 (CurtizJ).
  • AggregatingMergeTree agora rejeita, no momento da criação da tabela, esquemas em que uma coluna não faz parte da chave de ordenação nem é uma medida de estado de agregação (AggregateFunction/SimpleAggregateFunction). Essas colunas são silenciosamente reduzidas a um valor arbitrário durante as mesclagens em segundo plano, gerando resultados incorretos em consultas que aplicam GROUP BY ou filtros sobre elas. Defina allow_dimensions_outside_sorting_key = 1 para restaurar o comportamento anterior. #108087 (alexey-milovidov).
  • O ClickHouse agora sempre usa o hash unificado de desduplicação de insert, tanto para inserts síncronos quanto assíncronos; os comportamentos legados de desduplicação por insert foram removidos. A configuração de servidor insert_deduplication_version é mantida como proteção de migração: o servidor se recusa a iniciar se ela estiver definida com um valor legado (old_separate_hashes ou compatible_double_hashes). Para fazer o upgrade a partir de uma versão que usava um valor legado, primeiro execute uma versão que suporte compatible_double_hashes (que grava tanto os hashes legados quanto os unificados). Para tabelas replicadas, mantenha-a em execução por pelo menos replicated_deduplication_window_seconds (uma hora por padrão; as janelas padrão retêm os hashes unificados de todos os inserts desse período, o que é considerado suficiente para um ciclo de novas tentativas de insert). Para tabelas não replicadas com non_replicated_deduplication_window > 0, essa janela é baseada em contagem, e não em tempo; portanto, execute compatible_double_hashes por pelo menos essa quantidade de inserts. Em seguida, remova a configuração (ou defina-a como new_unified_hash) antes de fazer o upgrade para esta versão. #108361 (CheSema).
  • A configuração use_legacy_to_time agora é 0 por padrão, de modo que toTime converte valores para o tipo de dados Time em vez de converter uma data com hora em uma data fixa. O comportamento legado continua disponível por meio da função toTimeWithFixedDate ou definindo use_legacy_to_time = 1. #108729 (alexey-milovidov).
  • Os models Naive Bayes (usados por naiveBayesClassifier) agora são configurados como um dicionário com o layout NAIVE_BAYES, construído no momento do carregamento a partir de uma tabela de contagens de n-gramas pré-agregadas por classe, em vez da configuração anterior no lado do servidor (um arquivo de configuração XML que referenciava arquivos de modelo .bin serializados), que não é mais suportada — os models existentes devem ser recriados como dicionários. Três novas funções foram adicionadas junto com naiveBayesClassifier: naiveBayesClassifierWithProb retorna a classe prevista junto com sua probabilidade, naiveBayesClassifierWithAllProbs retorna todas as classes com suas respectivas probabilidades, e naiveBayesNgrams tokeniza o texto em n-gramas da mesma forma que o dicionário, permitindo construir os dados de treinamento a partir de texto bruto rotulado. Além disso, foram aplicadas várias otimizações de desempenho: em um modelo de linguagem de trigramas de code points de 9.7 MiB, o uso de memória é ~49× menor (de 1.84 GiB para 38 MiB), o carregamento é ~11× mais rápido e a classificação é ~11× mais rápida. #108773 (nihalzp).
  • O valor default da configuração max_insert_threads foi alterado de 1 (sem paralelismo) para auto, que corresponde ao número de núcleos de CPU disponíveis para o servidor (reduzido sob pressão de memória por meio de max_insert_threads_min_free_memory_per_thread). Com isso, INSERT SELECT passa a ser paralelizado por padrão, e o lado de escrita de um INSERT simples elegível também pode ser paralelizado quando o caminho de escrita de destino puder se ramificar com segurança. Isso pode alterar o número de partes criadas e a ordem das linhas inseridas. Para restaurar o comportamento anterior, defina max_insert_threads como 1 ou defina compatibility para uma versão anterior a 26.8. #109000 (alexey-milovidov). #109006 (alexey-milovidov).
  • A leitura de um Tuple simples em CSV agora considera um campo por elemento em todas as posições, de modo que um \N no campo de um elemento de nível superior corresponde a esse elemento, e input_format_null_as_default se aplica a ele. Antes, um \N inicial era interpretado como se a coluna inteira fosse nula, de modo que a linha era substituída pelo default da coluna e a análise das células dos elementos restantes falhava. Essa mudança é incompatível com versões anteriores no caso de uma linha que fornece um único campo para um Tuple simples inteiro: agora faltam os elementos restantes e a linha é rejeitada. Já para um Tuple de um único elemento, em que a contagem de campos é a mesma em ambos os casos, o resultado passa a ser, silenciosamente, o default do elemento em vez do DEFAULT da coluna. Defina input_format_csv_deserialize_separate_columns_into_tuple = 0 para voltar a ler esse campo como a coluna inteira. #109744 (groeneai).
  • Adicionada a cláusula VALID FOR <interval> a CREATE USER e ALTER USER como forma abreviada de VALID UNTIL. O prazo de expiração é calculado como o horário atual mais o intervalo informado, no momento da execução da consulta, e armazenado na forma VALID UNTIL. A coluna valid_until da tabela system.users agora tem o tipo Array(DateTime64(0)) em vez de Array(DateTime), para que prazos posteriores ao ano 2106 sejam representados com exatidão; ferramentas que leem essa coluna devem ser adaptadas ao novo tipo. #110171 (alexey-milovidov).
  • EXPLAIN SYNTAX agora retorna a consulta reformatada como um único registro String (com quebras de linha incorporadas) em vez de um registro por linha, de modo que sua saída é uma única linha recuperável e diretamente utilizável (por exemplo, SELECT count() FROM (EXPLAIN SYNTAX ...) retorna 1). Esse comportamento é controlado pela nova opção single_record, cujo padrão é 1; defina single_record = 0 para restaurar a saída anterior, com um registro por linha. Os outros tipos de EXPLAIN (PLAN/PIPELINE/AST) mantêm a saída em árvore, linha a linha. #110479 (alexey-milovidov).
  • A função hasColumnInTable não aceita mais os argumentos opcionais hostname, username e password para verificar uma coluna em um servidor remoto arbitrário; resta apenas a forma hasColumnInTable(database, table, column). O modo remoto removido representava um risco de segurança: permitia que qualquer usuário disparasse conexões de saída para hosts arbitrários, expunha credenciais nos logs de consultas e não era controlado por nenhum privilégio. #110881 (alexey-milovidov).
  • Os motores de banco de dados PostgreSQL e MaterializedPostgreSQL agora respeitam a configuração remote_url_allow_hosts do servidor, assim como já faziam o motor de tabela PostgreSQL, a função de tabela postgresql e os dicionários criados via DDL. A política é aplicada em CREATE DATABASE e em ATTACH DATABASE executados pelo usuário: se remote_url_allow_hosts estiver configurado no seu servidor, a criação ou anexação de um banco de dados PostgreSQL ou MaterializedPostgreSQL que aponte para um host fora da lista de permissões passa a ser rejeitada com UNACCEPTABLE_URL. Bancos de dados já existentes continuam sendo carregados na inicialização do servidor, de modo que uma atualização não impede o servidor de iniciar. #111135 (alexey-milovidov).
  • Foram removidos o leitor e o gravador baseados na biblioteca Apache Arrow para os formatos Arrow e ArrowStream. A implementação nativa do ClickHouse, padrão desde a versão 26.7, passa a ser a única. As configurações input_format_arrow_use_native_reader e output_format_arrow_use_native_writer estão obsoletas: ainda são aceitas, mas não têm efeito; assim, uma consulta que as definia como 0 para forçar a implementação do Apache Arrow agora usa a nativa. #111996 (alexey-milovidov).
  • As credenciais TLS de uma fonte MySQL (ssl_ca, ssl_cert, ssl_key) não podem mais ser especificadas como caminhos de arquivo via SQL — em uma coleção nomeada criada com CREATE NAMED COLLECTION, como argumento de consulta ou em uma consulta CREATE DICTIONARY —, porque o servidor abre esses arquivos com seus próprios privilégios. Caminhos continuam sendo suportados no arquivo de configuração do servidor. Nos demais casos, passe o conteúdo do certificado ou da chave nos novos parâmetros ssl_ca_pem, ssl_cert_pem e ssl_key_pem, que são mascarados nos logs e em consultas SHOW, assim como as senhas. #112070 (alexey-milovidov).
  • disable_insertion_and_mutation agora impede o consumo em segundo plano de tabelas Kafka, RabbitMQ e NATS, mas continua permitindo gravações diretas no armazenamento externo. Tabelas Kafka2, NATS e RabbitMQ bloqueadas por essa configuração não inicializam consumidores para SELECT direto. A configuração message_queue_disable_insertion, introduzida recentemente, agora exige a reinicialização do servidor. #113660 (cwurm).
  • Um PARTITION BY ou ORDER BY de janela sobre uma coluna AggregateFunction agora é rejeitado com ILLEGAL_COLUMN, como já acontecia com um ORDER BY de nível superior sobre esse tipo de coluna. Antes, essa consulta era aceita por pelo menos um dos analisadores, e o PARTITION BY de janela particionava de forma diferente dependendo de max_threads. A rejeição também abrange um estado aninhado em Array, Tuple, Map, Variant ou SimpleAggregateFunction. SimpleAggregateFunction sobre um tipo comum, QBit, bem como GROUP BY e DISTINCT sobre um estado, não são afetados. #113878 (groeneai).
  • Correção das verificações de acesso dos comandos SYSTEM ... CACHE ON CLUSTER. Eles exigiam o grupo de privilégios SYSTEM DROP CACHE em vez do privilégio específico de cada comando, o que negava acesso a quem tinha apenas um privilégio granular de cache e, ao mesmo tempo, permitia que quem tinha o grupo executasse SYSTEM SYNC FILESYSTEM CACHE ON CLUSTER sem possuir SYSTEM SYNC FILESYSTEM CACHE. #114042 (groeneai).
  • O motor de tabela NATS aceita credenciais em linha na nova configuração nats_credentials (a mesma carga útil de um arquivo .creds) e não aceita mais nats_credential_file via SQL: o caminho é uma referência a um arquivo no sistema de arquivos do servidor, que o servidor abre com seus próprios privilégios; por isso, ele só pode ser especificado em uma coleção nomeada definida no arquivo de configuração do servidor ou como nats.credential_file na própria configuração do servidor. Uma consulta pode substituir esse caminho configurado por nats_credentials em linha, a menos que o operador o tenha fixado com <nats_credential_file overridable="false">. Tabelas criadas antes dessa restrição continuam funcionando após um upgrade. #114644 (alexey-milovidov).

Alterações de tipo de dado e de formato

  • O formato de arquivo de backup zip/zipx passa a ser rejeitado para backups armazenados em armazenamento de objetos — destinos diretos S3(...)/AzureBlobStorage(...) e destinos Disk(...) com S3 ou Azure como backend —, tanto para BACKUP quanto para RESTORE. O formato zip exige operações de busca (seek) para ler seu diretório central, o que é muito lento em armazenamento de objetos. Use um formato baseado em tar, como tar.gz. #101770 (Onyx2406).
  • O intervalo suportado de DateTime64 foi ampliado de [1900-01-01, 2299-12-31] para [0000-01-01, 9999-12-31]. Valores fora do intervalo anterior agora são calculados corretamente (via cctz), em vez de serem limitados ao valor de fronteira. Com precisão 8 ou 9, o intervalo continua mais restrito porque os ticks são armazenados como Int64 (com precisão de nanossegundos, o máximo ainda é 2262-04-11). Compatibilidade retroativa: se você já usava datas e horas fora do intervalo, mas dependia das regras muito específicas de saturação do intervalo antigo, tenha em mente que os resultados agora passam a ser mais corretos. #107907 (alexey-milovidov).
  • Um número JSON sem aspas para uma coluna DateTime64/DateTime em JSONEachRow e formatos semelhantes agora é interpretado como um Unix timestamp (segundos desde a época) com precisão opcional de frações de segundo, de forma consistente com o formato Values, CAST e toDateTime64. Antes, um número com parte fracionária (por exemplo, 1703363853.035) era rejeitado com CANNOT_PARSE_INPUT_ASSERTION_FAILED, e um inteiro simples (por exemplo, 1703363853) era lido como o valor bruto escalado de um DateTime64, produzindo um timestamp 1970-.... Esta é uma alteração incompatível com versões anteriores para inteiros sem aspas fornecidos a colunas DateTime64; strings entre aspas e a própria saída JSON do ClickHouse (sempre entre aspas) não são afetadas. #108091 (alexey-milovidov).
  • O codec experimental ALP agora executa a aritmética de escalonamento de Float32 em Float64, o que elimina exceções em dados decimais e melhora significativamente as taxas de compressão. #111627 (rienath).
  • Valores de configurações de intervalo de tempo (milissegundos/segundos) que causem overflow de Int64 em microssegundos passam a ser rejeitados #112757 (azat).
  • As métricas assíncronas agora podem ter o tipo de dados Map, e as métricas por núcleo de CPU e por dispositivo foram convertidas em métricas únicas de chave-valor: OSUserTimeCPU0, OSUserTimeCPU1, … passaram a ser uma única métrica OSUserTimeCPU com um map do número do núcleo de CPU para o valor (o mesmo vale para as demais métricas OS*TimeCPU*, CPUFrequencyMHz_*, Temperature*, EDAC*, Block*_*, Network(Receive|Send)*_*, Disk*_*, *BlobsQueueEstimate e AsyncLogging*QueueSize). system.asynchronous_metrics tem uma nova coluna key_values Map(LowCardinality(String), Float64) (a coluna value é NaN para essas métricas), system.asynchronous_metric_log as registra como uma linha por chave usando uma nova coluna key, o endpoint Prometheus as exporta com um rótulo (por exemplo, ClickHouseAsyncMetrics_BlockReadBytes{device="sda"}) e o MetricsTransmitter do Graphite as envia como <prefix>.<Metric>.<key>. Se o seu monitoramento lê os nomes antigos das métricas, defina asynchronous_metrics_key_values_mode como legacy_names para mantê-los, ou como both durante a migração; aplique essa configuração de servidor com SYSTEM RELOAD CONFIG, sem precisar reiniciar. #115333 (alexey-milovidov). #116791 (alexey-milovidov).
  • Os discos de armazenamento de objetos agora usam, por padrão, transações nativas de armazenamento de metadados, o que melhora a consistência das atualizações de seus metadados. #89658 (Michicosun).

Alterações de configurações e parâmetros

  • Foram removidas as funções snowflakeToDateTime, snowflakeToDateTime64, dateTimeToSnowflake e dateTime64ToSnowflake, obsoletas há muito tempo. Elas foram declaradas obsoletas já na v24.6 em favor de snowflakeIDToDateTime, snowflakeIDToDateTime64, dateTimeToSnowflakeID e dateTime64ToSnowflakeID, que devem ser usadas em seu lugar. A configuração allow_deprecated_snowflake_conversion_functions (que antes permitia reabilitá-las) agora está obsoleta e não tem mais efeito. #108711 (alexey-milovidov).
  • O intervalo suportado de Date32 foi ampliado de [1900-01-01, 2299-12-31] para [0000-01-01, 9999-12-31], igualando-se ao de DateTime64. O parsing e as conversões agora aceitam o intervalo ampliado, em vez de restringir silenciosamente os valores aos limites antigos. Notas sobre compatibilidade retroativa: na conversão numérica toDate32(N), valores em [120530, 2932896] passam a ser interpretados como números de dias (datas de 2300-01-01 a 9999-12-31), e não mais como Unix timestamps do início de 1970, seguindo a regra de que um número que cabe no intervalo de números de dias é tratado como número de dias; números abaixo do número de dias de 0000-01-01 e timestamps posteriores a 9999-12-31 são saturados nos novos limites. #111534 (alexey-milovidov).

Outras alterações incompatíveis com versões anteriores

  • arrayIntersect e arraySymmetricDifference não tratam mais um valor repetido dentro de um único argumento como se ele aparecesse em vários argumentos. Consultas que dependem do comportamento anterior agora podem retornar resultados diferentes: arrayIntersect([1], [2], [1, 1]) retorna [] em vez de [1], arrayIntersect([1, 2], [2], [1, 1, 2]) retorna [2] em vez de [1, 2] e arraySymmetricDifference([1], [2], [1, 1]) retorna [2, 1] em vez de [2]. No caso de arraySymmetricDifference, dois argumentos já bastam: arraySymmetricDifference([1], [2, 2]) retorna [2, 1] em vez de [1]. Agora, um valor só é contabilizado para um argumento se estiver presente em todos os argumentos anteriores, de modo que o resultado contém exatamente os valores presentes em todos os argumentos. Como parte da mesma alteração, arrayIntersect passa a construir sua tabela hash a partir do menor argumento, e não de todos eles, o que o torna até 1,85x mais rápido e reduz o uso de memória em um terço quando os argumentos têm tamanhos muito diferentes. arrayUnion não é afetado. #113021 (alexey-milovidov).
  • O tipo de estatísticas de coluna minmax foi marcado como obsoleto. #108680 (hanfei1991).
  • Corrigida a verificação de acesso para SYSTEM PREWARM PRIMARY INDEX CACHE ... ON CLUSTER, que exigia incorretamente o privilégio SYSTEM PREWARM MARK CACHE em vez de SYSTEM PREWARM PRIMARY INDEX CACHE. #109198 (Algunenano).
  • Corrigido o problema em que SYSTEM STOP/START CLEANUP e SYSTEM STOP/START VIRTUAL PARTS UPDATE ON CLUSTER exigiam SYSTEM PULLING REPLICATION LOG em vez de SYSTEM CLEANUP / SYSTEM VIRTUAL PARTS UPDATE. #110289 (groeneai).
  • O glob / (qualquer quantidade de diretórios) agora também corresponde ao próprio diretório. Antes, / em padrões glob não era tratado como caso especial, de modo que data/**/file.txt não correspondia a data/file.txt (zero níveis de diretório). #97676 (alexey-milovidov).

Novos recursos

Funções e tipos de dados

  • Adicionadas as funções parseQueryToJSON e formatQueryFromJSON para serializar e desserializar ASTs como JSON, além de um dialect experimental clickhouse_json, habilitado por enable_json_ast_dialect. #100412 (alexey-milovidov). #113480 (fm4v).
  • Adicionada a tabela de sistema system.stemmers, que mostra todos os idiomas de stemmers disponíveis que podem ser especificados na função stem. #100611 (Ergus).
  • Adicionado suporte aos operadores pós-fixos AT TIME ZONE e AT LOCAL do SQL padrão como açúcar sintático para toTimeZone. A expressão expr AT TIME ZONE zone agora equivale a toTimeZone(expr, zone), e expr AT LOCAL equivale a toTimeZone(expr, timeZone()). #106092 (lvzhipin03).
  • O motor de tabela URL e a função de tabela url agora fazem o encaminhamento para o backend apropriado com base no esquema da URL: file:// é atendido pelo motor File, s3:///gs:///gcs:///oss:// pelo S3, az:///azure:///abfss:///abfs:// pelo AzureBlobStorage, hdfs:// pelo HDFS e http(s):// pelo motor URL, como antes. A configuração url_base é aplicada antes do encaminhamento por esquema. Apenas os esquemas S3 resolvidos pelos url_scheme_mappers padrão são encaminhados; outros esquemas de fornecedores compatíveis com S3 (cos, obs, …) não são e exigem o uso direto do motor/função s3. #106093 (alexey-milovidov).
  • Adicionada a função dotProductTransposed (alias scalarProductTransposed), que calcula o produto interno aproximado entre uma coluna QBit e um vetor de referência, complementando as funções já existentes L2DistanceTransposed e cosineDistanceTransposed. #108100 (alexey-milovidov).
  • Adicionado um parâmetro opcional de stride ao tipo de dado QBit (QBit(T, dimension, stride)), que armazena grupos de dimensões em fluxos separados, permitindo que uma busca vetorial leia de forma eficiente apenas as primeiras dimensões (por exemplo, com Matryoshka embeddings). As funções de distância transpostas aceitam um quarto argumento opcional, used_dims, para ler um número reduzido de dimensões. #108103 (alexey-milovidov).
  • Adicionado suporte ao tipo de elemento Int8 no tipo de dado QBit, permitindo o armazenamento e a busca vetorial por distância transposta (L2DistanceTransposed, cosineDistanceTransposed) em vetores quantizados de inteiros de 8 bits. #108105 (alexey-milovidov).
  • Nova função randomHadamardTransform(vector[, seed[, output_dims]]): uma transformada de Hadamard aleatorizada e determinística de um vetor de ponto flutuante — uma rotação ortogonal que preserva a norma, útil no pré-processamento de embeddings antes da quantização e (quando truncada) como projeção aleatória de Johnson–Lindenstrauss / Hadamard aleatorizada subamostrada. #108227 (alexey-milovidov).
  • Implementada a função de agregação mergedJSONPatch para agregação no estilo merge-patch da RFC 7396 sobre valores JSON, com suporte à mesclagem de estados e ao uso com AggregatingMergeTree. Os usuários podem agregar uma coluna JSON usando um timestamp ou outra coluna de ordenação como chave de ordenação para obter o estado mais recente. #108349 (larryluogit).
  • Adicionada a função xxHash64Spark, que calcula valores xxHash64 compatíveis com o Spark para entradas String e NULL usando a semente 42 e retorna Int64. #108436 (lalitium).
  • Adicionada a função digits(n, offset[, length]), que retorna o número contido em n que começa no índice offset(1-indexed) e tem length dígitos. Se length não for informado, a função retorna o número do deslocamento até o final. #109012 (1000ms).
  • Adicionada a função aritmética sqr para calcular o quadrado de um número. #109061 (lalitium).
  • Adicionadas as funções de distância transpostas quantizadas cosineDistanceTransposedQuantized, L2DistanceTransposedQuantized e dotProductTransposedQuantized, que operam sobre um QBit(Int8) de códigos Lloyd-Max de quantizeBFloat16ToInt8, desquantizando os códigos armazenados em tempo real. Um vetor de referência de ponto flutuante é tratado como a consulta em precisão total e comparado com precisão Float32 (uma consulta Float64 tem a precisão reduzida); já uma referência Array(Int8) também é desquantizada, resultando em uma distância simétrica entre valores quantizados. #109405 (alexey-milovidov).
  • Adicionada a nova função dictGetRoot, que retorna o ancestral mais alto (a raiz) de uma chave em um dicionário hierárquico. É um equivalente prático de dictGetHierarchy(dict_name, key)[-1]. #109459 (alexey-milovidov).
  • Adicionada a função de tabela mergeTreeCodecBlockCounts(database, table), que informa, para cada (parte, coluna, subfluxo) de uma tabela MergeTree, quantos blocos comprimidos usam cada codec. #109623 (rienath).
  • Adicionada a função notHas, a negação de has para arrays, maps e JSON. Quando o conjunto pesquisado é um array constante, notHas(constant_array, x) é reescrito como x NOT IN constant_array por optimize_rewrite_has_to_in (habilitado por padrão), de modo que é executado por meio de uma busca em conjunto e pode fazer a poda pelo índice da chave primária, assim como NOT IN. #109926 (nihalzp).
  • Adicionado o tipo de dado geoespacial MultiPoint, armazenado como Array(Point) e incluído no tipo Geometry. #109951 (davidmenggx).
  • As funções arrayElement (o operador vec[n]) e arraySlice agora funcionam com o tipo de dado QBit: qbit[n] retorna o n-ésimo elemento do vetor em precisão total, e arraySlice(qbit, offset, length) retorna uma projeção para um subconjunto de dimensões. Ambas leem apenas os planos de bits dos grupos de stride necessários, e fatias alinhadas aos limites dos grupos de stride reutilizam os streams armazenados sem fazer cópias. #109953 (Utkal059).
  • Adicionado o tokenizador splitByRegexp para índices de texto e para a função tokens. Ele divide a entrada em tokens usando uma expressão regular como separador, por exemplo tokenizer = splitByRegexp('[^\p{L}\p{N}#+]+'), o que permite preservar tokens com caracteres especiais, como C++ ou C#, que outros tokenizadores quebrariam. #110002 (Ergus).
  • Adicionadas as funções geometryIntersectCartesian e geometryIntersectSpherical, que indicam se duas geometrias se intersectam. Ao contrário de polygonsIntersectCartesian/polygonsIntersectSpherical, elas aceitam qualquer tipo de dado geométrico (Point, LineString, MultiLineString, Ring, Polygon, MultiPolygon), incluindo o tipo genérico Geometry, e os dois argumentos podem ser de tipos diferentes. #110062 (alexey-milovidov).
  • O leitor ORC nativo agora oferece suporte ao uniontype do ORC, mapeando-o para o tipo Variant do ClickHouse (antes, essas colunas eram rejeitadas com Unsupported ORC type). #110078 (alexey-milovidov).
  • O formato de saída ORC nativo agora pode gravar o tipo Variant do ClickHouse, mapeando-o para um uniontype do ORC (antes, a operação falhava com ILLEGAL_COLUMN). #110085 (alexey-milovidov).
  • Adicionados formatos de enquadramento, selecionados pela nova configuração framing_output_format: eles multiplexam as diferentes partes da resposta da consulta em um único stream de resposta HTTP — blocos de dados, totais e extremos, pacotes de progresso, eventos de perfil, logs do servidor e exceções. Formatos de enquadramento implementados: None (padrão; tudo funciona como antes), EventStream (HTTP server-sent events), JSONEachPacketBase64 e JSONEachPacketString (um objeto JSON por pacote, com dados codificados em base64 ou como string). #110127 (alexey-milovidov).
  • Adicionados a função de tabela bigquery e o motor de tabela BigQuery para leitura e gravação em tabelas do Google BigQuery, incluindo conjuntos de dados públicos. A estrutura da tabela é inferida a partir do esquema da tabela no BigQuery. A autenticação oferece suporte a token de acesso OAuth, chave de conta de serviço em formato JSON e cliente OAuth com token de atualização. #110166 (alexey-milovidov).
  • Nova função aiRedact, que detecta e oculta informações de identificação pessoal (PII) em textos usando um provedor de LLM. Especifique as categorias a serem ocultadas (por exemplo, ['email', 'name']) ou passe um array vazio para usar um conjunto padrão de categorias de PII. Os valores identificados são substituídos por um token ([REDACTED] por padrão). #110464 (davidmenggx).
  • Adicionada a função aiFilter, que avalia uma condição em linguagem natural sobre um texto usando um LLM e retorna UInt8 para uso em WHERE, PREWHERE e JOIN ... ON. #110594 (ylw510).
  • Suporte a conexões TLS/SSL com o PostgreSQL no motor de tabela PostgreSQL, na função de tabela postgresql, nos motores de banco de dados PostgreSQL e MaterializedPostgreSQL e nos dicionários PostgreSQL: sslmode, além dos certificados e da chave, fornecidos como conteúdo literal (sslrootcert_pem, sslcert_pem, sslkey_pem; mascarados como senhas) ou como caminhos (sslrootcert, sslcert, sslkey; aceitos somente a partir de uma named collection definida no arquivo de configuração do servidor). #110615 (alexey-milovidov).
  • A função de tabela postgresql e o motor de tabela PostgreSQL agora podem ser usados para se conectar a outro servidor ClickHouse pelo protocolo PostgreSQL (quando se usa um nome de tabela; a variante query(...) ainda não é compatível). Adicionadas as funções de compatibilidade com o PostgreSQL format_type e current_setting. #110760 (alexey-milovidov).
  • Nova função aiSimilarity que calcula a similaridade semântica entre dois textos usando um modelo de embedding. Retorna um Nullable(Float32) no intervalo [-1, 1], em que 1 significa que os textos são idênticos, ou NULL se um operando for NULL/vazio ou se a geração do seu embedding falhar. #110777 (davidmenggx).
  • Adicionados os motores de banco de dados Remote e RemoteSecure, que fornecem acesso em tempo real às tabelas de um banco de dados em um servidor ClickHouse remoto, encaminhando para ele as consultas SELECT e INSERT. Eles são os equivalentes, de ClickHouse para ClickHouse, dos motores de banco de dados MySQL e PostgreSQL. #110975 (alexey-milovidov).
  • Suporte a operadores de pipe em consultas SQL: FROM t |> WHERE x > 1 |> AGGREGATE count() AS c GROUP BY y |> ORDER BY c DESC |> LIMIT 10, de forma semelhante à sintaxe de pipe do GoogleSQL. Qualquer consulta SELECT pode ser seguida por uma cadeia de operadores |>, e cada operador encapsula a consulta anterior em uma subconsulta, de modo que a AST resultante é a mesma da consulta equivalente com subconsultas aninhadas. Em uma consulta que começa com a cláusula FROM, a cláusula SELECT agora é opcional e assume SELECT * por padrão. #111151 (alexey-milovidov).
  • Adicionada a função de agregação gini para calcular o coeficiente de Gini de valores numéricos finitos e não negativos, inclusive em agregações agrupadas e distribuídas. #112280 (amirreza1307). #114643 (groeneai).
  • Suporte a PNG animado no formato de saída PNG. Uma coluna t transforma o resultado de uma consulta em uma animação, com a escala de tempo de t definida por output_format_image_time_multiplier_seconds e output_format_image_time_divisor_seconds; já output_format_image_streaming_animation permite gravar os quadros à medida que a consulta os produz, em vez de mantê-los em buffer na memória. #112846 (alexey-milovidov).
  • Adicionada a coluna finish_time a system.mutations, que registra quando uma mutação foi concluída. Para mutações não concluídas e mutações cujo horário de conclusão é desconhecido, o valor informado é zero. #113474 (nikitamikhaylov).
  • Adicionado um novo tipo de esquema bucketed para system.metric_log, que armazena todas as métricas em uma única coluna Map(Enum16(...), Int64) usando a serialização de Map em buckets, com 128 buckets, além de uma coluna ALIAS por métrica para compatibilidade: a tabela passa a ter poucas colunas em vez de milhares, valores zero não são armazenados e a leitura de uma única métrica acessa apenas um dos 128 buckets. Além disso, um Map com chaves Enum agora pode ser indexado pelo nome em string do valor do enum, por exemplo, map['name']. #115380 (alexey-milovidov).
  • Adicionado o tokenizador chinese para a função tokens e para os índices de texto do MergeTree. Ele segmenta textos em chinês em palavras usando um dicionário e um Modelo Oculto de Markov (o algoritmo segue o jieba), com as granularidades coarse_grained (padrão) e fine_grained. #89945 (amosbird).
  • Adicionada a função de agregação groupFormat, que formata as linhas de cada grupo usando um formato de saída especificado e retorna o resultado como uma string. #93201 (wandersofb).
  • Adicionado o combinador de função de agregação -Tuple, que aplica a função de agregação subjacente a cada elemento de uma coluna Tuple de forma independente e retorna uma Tuple com os resultados, preservando os nomes dos elementos: sumTuple(t) para t = (a, b) retorna (sum(a), sum(b)). Funções de agregação com vários argumentos recebem uma tupla por argumento, combinadas por posição: corrTuple((a1, a2), (b1, b2)) retorna (corr(a1, b1), corr(a2, b2)). Diferentemente de -ForEach aplicado a arrays, os elementos podem ter tipos diferentes, e os tipos de resultado e os nomes de cada elemento são preservados. #98190 (RinChanNOWWW).

Recursos de SQL e de consulta

  • Adicionado suporte a cláusulas WHERE em definições de projeções. Projeções com WHERE materializam apenas as linhas que satisfazem o predicado, e o otimizador pode usá-las (com base em custo) quando o WHERE da consulta implica o WHERE da projeção. #102347 (SBALAVIGNESH123).
  • Adicionada uma forma de acessar tabelas e bancos de dados por meio de caminhos de URL na interface HTTP (por exemplo, `/database/table.format.gz?filter=a>0`), além de novas configurações (`http_allow_database_as_path`, `http_allow_table_as_file`, `http_allow_filters_as_path`, `http_allow_filters_as_unrecognized_url_parameters`, `select`, `order`, `sort`, `filter`, `page`, `compression`, `format`, `input_format`, `output_format`, `default_format`, `database`) que podem ser combinadas entre si e com o parâmetro de URL `query` já existente. #105249 (alexey-milovidov).
  • Adicionados os motores de tabela Remote e RemoteSecure, equivalentes persistentes das funções de tabela remote e remoteSecure. Agora, além de CREATE TABLE ... AS remote(...), também é possível usar CREATE TABLE ... ENGINE = Remote('addresses', db, table, ...). #106189 (alexey-milovidov).
  • Adicionado EXPLAIN ANALYZE para analisar o desempenho de consultas: a consulta é executada e as métricas reais de execução são exibidas no já conhecido formato de plano de consulta. #106586 (Fgrtue). #110668 (Fgrtue).
  • Adicionados os comandos SYSTEM STOP, SYSTEM START, SYSTEM PAUSE, SYSTEM CANCEL e SYSTEM REFRESH, independentes de motor, e suas variantes ... ALL BACKGROUND, que valem para todo o servidor, para controlar a atividade em segundo plano de tabelas Kafka, RabbitMQ, NATS, S3Queue/AzureQueue e de views materializadas atualizáveis por meio de uma interface unificada. Para views materializadas atualizáveis, eles funcionam como aliases dos comandos SYSTEM ... VIEW existentes. Como parte do suporte a esses controles no NATS, as tabelas JetStream agora confirmam (acknowledge) as mensagens somente após um insert bem-sucedido (at-least-once; antes, as mensagens eram confirmadas automaticamente na entrega e podiam ser perdidas se o insert falhasse). A nova configuração nats_wait_for_flush_interval (padrão false, que preserva o comportamento anterior de baixa latência) permite manter um ciclo de consumo aberto durante todo o intervalo de flush, em vez de fazer o flush assim que a fila se esvazia. A nova configuração nats_commit_on_select faz com que um SELECT direto em uma tabela JetStream consuma (confirme) as mensagens lidas. #107476 (NIKTONIKTO717).
  • Adicionado suporte para que as funções de tabela e os motores de tabela mysql, postgresql e sqlite aceitem uma consulta do usuário (em vez de um nome de tabela) e a repassem sem alterações ao banco de dados externo, escrita como subconsulta (SELECT ...) ou como query('SELECT ...'). A estrutura da tabela resultante é inferida a partir do resultado da consulta, e essa tabela é somente leitura. #107740 (alexey-milovidov).
  • Introduz o motor de tabela QueryRunner. Os registros inseridos em uma tabela QueryRunner representam consultas que o motor executa. O motor pode ser usado para execução assíncrona de consultas, execução em lote de consultas geradas, direcionamento de consultas para clusters remotos, benchmarks, fuzzing e testes com tráfego espelhado. #107888 (mstetsyuk).
  • Suporte ao modo de frame GROUPS para funções de janela (SQL:2011), por exemplo, any(price) OVER (PARTITION BY symbol ORDER BY ts GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING). Em um frame GROUPS, os limites contam grupos de pares inteiros — conjuntos de linhas com valores iguais na chave ORDER BY —, de modo que N PRECEDING/N FOLLOWING significam N grupos de pares antes/depois do grupo de pares da linha atual, em vez de linhas físicas (ROWS) ou distâncias entre valores do ORDER BY (RANGE). #108653 (nihalzp).
  • O CREATE MATERIALIZED VIEW ... POPULATE simples agora é atômico localmente: a visão passa a receber os novos inserts da tabela de origem e o snapshot dos dados existentes é obtido no mesmo momento, sob um breve bloqueio exclusivo na origem, de modo que as linhas inseridas pelo mesmo servidor durante o preenchimento não são mais perdidas nem duplicadas (nova configuração materialized_views_populate_atomically, habilitada por padrão). A garantia cobre apenas o caminho de insert local — inserts que chegam em outra réplica ou por um caminho de escrita distribuído ficam de fora — e exige uma origem capaz de fornecer um snapshot fixo (a família MergeTree e Memory); outras origens, assim como CREATE OR REPLACE / REPLACE e visões criadas em bancos de dados Replicated, mantêm o preenchimento legado não atômico. POPULATE agora também pode ser usado em conjunto com TO para preencher retroativamente a tabela de destino. #108715 (alexey-milovidov).
  • ALTER USER, ALTER ROLE e ALTER SETTINGS PROFILE agora aceitam SET name = value como alias para MODIFY SETTING name = value. Essa forma altera configurações individuais diretamente, mantendo as demais, ao contrário da cláusula SETTINGS sem modificador, que substitui toda a lista de configurações. Com isso, fica menos provável apagar acidentalmente as outras configurações de um usuário. #108722 (groeneai).
  • Suporte a ALTER TABLE ... MODIFY CONSTRAINT [IF EXISTS] name CHECK expr para alterar diretamente a expressão de uma restrição existente. #108768 (alexey-milovidov).
  • Adicionado o algoritmo IEJoin, baseado em ordenação, para junções cuja seção ON tenha duas comparações de desigualdade (<, <=, >, >=) entre as tabelas da junção, habilitado ao adicionar ie_join à configuração join_algorithm. Os tipos suportados são ALL INNER/LEFT/RIGHT/FULL JOIN e SEMI/ANTILEFT/RIGHT JOIN. Anteriormente, essas consultas eram executadas como um CROSS JOIN com filtro (apenas INNER), o que é muito mais lento em tabelas grandes. #109920 (vdimir).
  • Adicionada uma nova tabela de sistema, system.user_query_log, que mostra a cada usuário seus próprios registros do log de consultas, sem exigir acesso à tabela de log de consultas. A implementação original e a ideia são de Yue Ni (@niyue). #110156 (alexey-milovidov).
  • Nova configuração run_query_in_background. O servidor aceita a consulta, retorna imediatamente um resultado vazio e a executa até o fim, independentemente do que aconteça com a conexão. O resultado é descartado. Acompanhe a consulta pelo seu query_id em system.processes e system.query_log. Destina-se a consultas longas, como INSERT ... SELECT, CREATE TABLE … AS SELECT ou CREATE MATERIALIZED VIEW … POPULATE, que não podem ser interrompidas pela queda da conexão. #112816 (mstetsyuk).
  • Suporte a ALTER TABLE … MODIFY PROJECTION para alterar configurações no nível da projeção (por exemplo, index_granularity) de uma projeção existente sem precisar reconstruí-la. As novas configurações são aplicadas de forma lazy, à medida que ocorrem as mesclagens. #113343 (diegomestre2).
  • O catálogo do motor de tabelas S3 para lagos de dados agora oferece suporte a INSERT, além de consultas a tabelas existentes. #113505 (scanhex12).
  • O catálogo Iceberg agora oferece suporte ao Snowflake Horizon Catalog com catalog_type = 'horizon', permitindo leituras e gravações em tabelas Iceberg gerenciadas pelo Snowflake. #114547 (melvynator).
  • Adicionada a configuração skip_unavailable_shards_mode (também disponível como configuração do motor Distributed) para controlar quais exceções de um shard remoto são ignoradas silenciosamente quando skip_unavailable_shards está habilitado. Isso oferece um controle mais granular sobre o comportamento das consultas em ambientes distribuídos. #79091 (byte-sourcerer).

Armazenamento, lagos de dados e armazenamento de objetos

  • Adicionado suporte ao formato de arquivo Puffin (https://iceberg.apache.org/puffin-spec/). Agora esse formato pode ser usado em funções de tabela como file, url, s3 etc. #103936 (scanhex12).
  • Adicionado o armazenamento de partes de dados “packed” para tabelas MergeTree, que armazena todos os arquivos de uma parte em um único arquivo (data.packed), em vez de um arquivo por stream. Esse armazenamento é controlado pelas configurações min_bytes_for_full_part_storage, min_rows_for_full_part_storage e min_level_for_full_part_storage e vem desabilitado por padrão. Nota de compatibilidade: depois que uma tabela grava partes packed, versões mais antigas do servidor não conseguem lê-las; portanto, habilitar esse formato impede o downgrade do servidor. #108118 (Algunenano).
  • Adicionada a configuração nats_credentials ao motor de tabela NATS, que permite especificar credenciais NATS em linha como uma string (correspondente ao conteúdo de um arquivo .creds). #110733 (addshore).

Formatos de dados e ingestão

  • Adicionado o formato de saída HiveText, que grava dados no formato de texto LazySimpleSerDe do Apache Hive. Os campos são separados por \x01, as linhas pela nova configuração format_hive_text_rows_delimiter (padrão \n), e os valores aninhados de Array, Map e Tuple usam a lista de separadores do Hive. A saída é voltada para o LazySimpleSerDe padrão do Hive e não é simétrica à entrada HiveText do ClickHouse no caso de valores aninhados ou delimitadores de linha personalizados. #107582 (alexey-milovidov).
  • Adicionado o formato de saída GeoJSON para gravar documentos GeoJSON FeatureCollection com uma feature por linha. A nova configuração format_geojson_validate_geometry (habilitada por padrão) valida as geometrias GeoJSON na leitura e na gravação; o formato de entrada GeoJSON agora infere id como Nullable(String), diferenciando IDs ausentes ou null de strings vazias. #108065 (nihalzp).

Configurações, acesso e observabilidade

  • Adicionada uma página integrada de busca na documentação, disponível no caminho /docs da interface HTTP, que oferece busca instantânea na tabela system.documentation e renderiza a documentação de referência (com realce de sintaxe, fórmulas matemáticas e links cruzados). #108345 (alexey-milovidov).
  • Adicionado um tokenizador japonês para índices de texto e para as funções tokens/hasAnyTokens/hasAllTokens, que utiliza o analisador morfológico MeCab. O dicionário é carregado em tempo de execução a partir de um local definido na configuração do servidor e tem sua integridade verificada por um checksum SHA-256 antes do uso. #111420 (Ergus).
  • Adicionada uma nova configuração do cache do sistema de arquivos, system_cache_extensions, que controla quais arquivos são armazenados no cache do sistema quando use_split_cache está habilitado. #111575 (kirillgarbar).
  • Adicionada a configuração always_fetch_mutated_part, que permite que uma réplica baixe de outras réplicas as partes já alteradas por mutações, em vez de executar as mutações localmente. #113020 (rorylshanks).

Outros novos recursos

  • Adicionado suporte a WITH TIES para LIMIT negativo. #100930 (nihalzp).
  • Adicionadas as configurações de restauração restore_table_data, restore_access_entities e restore_functions, que oferecem controle granular sobre o que é restaurado. Elas podem sobrescrever structure_only para categorias específicas — por exemplo, structure_only=true, restore_access_entities=true restaura as definições de tabela e as entidades de acesso, mas não os dados das tabelas. #102402 (fm4v).
  • Agora é possível configurar o carregamento preguiçoso de cada dicionário individualmente com dictionary_lazy_load na definição do dicionário, sobrescrevendo a configuração global de servidor dictionaries_lazy_load. Assim, alguns dicionários podem ser carregados de forma preguiçosa enquanto outros são carregados imediatamente. #108314 (mstetsyuk).
  • O operador de subscrito de array agora aceita um array de inteiros como índice: arr[indexes] retorna os elementos de todas as posições informadas, o que equivale a arrayMap(i -> arr[i], indexes). #108371 (ucasfl).
  • Adicionadas as funções geoToUTM, UTMToGeo, geoToMGRS e MGRSToGeo para conversão entre coordenadas geográficas WGS84 e os sistemas de coordenadas UTM e MGRS. #108939 (alexey-milovidov).
  • Adicionados os comandos SYSTEM UNLOAD DICTIONARY e SYSTEM UNLOAD DICTIONARIES para liberar a memória ocupada por dicionários sem remover suas definições. Os dicionários serão recarregados de forma preguiçosa no próximo acesso. #109639 (Manerone).
  • Adicionado um novo tokenizador icu para índices de texto e para as funções tokens, hasAnyTokens e hasAllTokens, que oferece segmentação de palavras Unicode sensível à localidade (incluindo segmentação baseada em dicionário para idiomas como chinês, japonês e tailandês). #109940 (Ergus).
  • Adicionado o novo codec ZXC — um codec LZ assimétrico com compressão lenta e descompressão muito rápida, cuja taxa de compressão fica entre a do LZ4 e a do ZSTD. #110620 (alexey-milovidov).
  • Adicionada a configuração s3_base, que permite resolver URLs relativas nas funções de tabela s3, s3Cluster, gcs e oss e no motor de tabela S3 em relação a uma URL base do S3. Adicionado também o motor de banco de dados URL, que resolve nomes de tabela como URLs em relação a uma base opcional e os encaminha ao backend apropriado. #111512 (alexey-milovidov).
  • Habilitada a expansão de wildcards em url() e no motor URL, por meio da listagem de páginas de índice HTTP (listagens de diretórios em HTML ou texto simples) e da extração das URLs correspondentes. Os wildcards são comparados com o componente de caminho da URL, com limites para o tamanho da página de índice e para o número de diretórios lidos. #95181 (niyue).
  • Adicionado AWS_MSK_IAM como valor suportado para kafka_sasl_mechanism, permitindo que o ClickHouse se autentique no Amazon MSK usando funções do IAM, sem precisar gerenciar credenciais SASL/SCRAM. #96100 (kalavt).
  • Adicionado ao índice de texto um pós-processador que transforma os tokens após a tokenização. #98939 (Ergus).

Recursos experimentais

Planejamento e execução de consultas

  • Adicionados “drivers” para funções definidas pelo usuário executáveis. Um driver declarado em <user_defined_executable_function_drivers_config> pode ser usado em CREATE FUNCTION name ARGUMENTS (...) RETURNS T ENGINE = DriverName(...) AS '...code...' para compilar ou processar de outra forma um trecho de código do usuário no momento da criação da função, gerando uma UDF executável pronta para uso. A configuração resultante é armazenada em <dynamic_user_defined_executable_functions_path>, e a consulta de origem é persistida como ATTACH FUNCTION, para que a função seja preservada após reinicializações do servidor. Um driver de prova de conceito, c_function_body, compila e executa corpos de funções em C dentro de contêineres Docker isolados (sandbox) no modo executable_pool. #105131 (alexey-milovidov).
  • As requisições da Prometheus Query API para /api/v1/query e /api/v1/query_range agora são registradas em system.query_log com as métricas read_rows e read_bytes. #106611 (JTCunning).
  • Suporte a leituras com plano de consulta distribuído para SELECT ... FINAL em tabelas da família MergeTree quando make_distributed_plan está habilitado. #108148 (davenger).
  • Adicionada a execução experimental de réplicas paralelas baseadas em plano para consultas MergeTree. #108504 (devcrafter).
  • Adicionada a função de tabela experimental eval, que avalia uma expressão constante como uma string de consulta e executa a consulta SELECT única resultante. O recurso vem desabilitado por padrão e pode ser habilitado com a configuração allow_experimental_eval_table_function. Autor: Yue Ni #110132 (alexey-milovidov).
  • Réplicas paralelas baseadas em plano (parallel_replicas_plan_based): a fronteira entre execução local e remota agora é definida por uma otimização em nível de plano sobre um plano de consulta comum, e consultas sobre views com UNION passam a ser paralelizadas sem parallel_replicas_allow_view_over_mergetree. Consultas que usam IN (subquery) agora recorrem a um plano local em vez de falhar. #111063 (devcrafter). #112443 (devcrafter).
  • Reforço da segurança das funções de IA experimentais: endpoints inseguros (http) para hosts remotos passam a ser bloqueados por padrão (nova configuração ai_function_allow_insecure_endpoint), as chamadas de API de saída por consulta são limitadas por padrão (ai_function_max_api_calls_per_query agora tem o valor padrão 1000) e as respostas de erro dos provedores gravadas nos logs são sanitizadas. #111286 (george-larionov).
  • Réplicas paralelas baseadas em plano (parallel_replicas_plan_based) agora distribuem JOINs elegíveis (INNER, LEFT, RIGHT, incluindo SEMI/ANTI): a junção inteira é executada em um fragmento de plano distribuído, com um lado coordenado entre as réplicas e o outro transmitido por broadcast. #112268 (devcrafter).
  • Passa a ser reportado o erro que cancelou uma consulta distribuída (make_distributed_plan = 1), em vez de apenas QUERY_WAS_CANCELLED. Antes, o erro real de uma tarefa de worker com falha só aparecia no log do servidor. #112590 (davenger).
  • Suporte à execução distribuída de planos de consulta com IN (subquery) sem reescrevê-lo como JOIN. O conjunto é construído uma única vez no iniciador, e seus valores são enviados junto com as tarefas dos workers. A substituição forçada por rewrite_in_to_join foi removida; a reescrita continua disponível como configuração explícita. #113826 (davenger).
  • Uma consulta com plano distribuído (make_distributed_plan) agora interrompe suas etapas upstream quando um LIMIT é atingido, em vez de calcular o resultado completo e descartá-lo. #114806 (davenger).
  • Corrige o erro Illegal type Decimal(18, 0) of argument of function toIntervalNanosecond quando uma consulta PromQL usa offset dentro de um seletor de intervalo, por exemplo, rate(m[2m] offset 5m). #114997 (nikitamikhaylov).
  • Adiciona suporte à agregação GROUPING SETS em planos distribuídos gerados pelo otimizador Cascades (make_distributed_plan = 1, enable_cascades_optimizer = 1). #115426 (davenger).
  • Tabelas TimeSeries agora podem manter uma tabela de “amostras recentes”: quando a nova configuração de motor recent_samples_ttl_seconds é diferente de zero, o motor cria uma cópia com TTL da tabela samples (particionada por recent_samples_partition_by, por dia, por padrão), gravada a cada insert, e as consultas PromQL cujo intervalo de tempo se encaixa na janela de TTL passam a ler automaticamente dessa tabela, tornando regras de alerta/gravação e dashboards de curto intervalo várias vezes mais rápidos em tabelas grandes. Essa preferência pode ser desabilitada com a nova configuração em nível de consulta time_series_prefer_recent_samples_table. #115441 (nikitamikhaylov).
  • Planos de consulta distribuídos (make_distributed_plan) agora interrompem imediatamente as etapas upstream idle depois que um LIMIT é atingido: um sink de exchange idle lê NoMoreDataNeeded assim que ele chega, e uma origem de exchange idle detecta que sua saída foi fechada e propaga a interrupção para upstream. Antes, essas etapas continuavam lendo e calculando dados que ninguém consumia. #115690 (davenger).
  • As réplicas paralelas automáticas agora podem coletar estatísticas em tempo de execução e habilitar réplicas paralelas para consultas compatíveis quando parallel_replicas_plan_based está habilitado. #115788 (devcrafter).
  • Adicionado o Cascades, um otimizador experimental baseado em custo para planos de consulta distribuídos, habilitado por enable_cascades_optimizer = 1 em conjunto com make_distributed_plan = 1. Com base no custo estimado, ele escolhe entre estratégias de join shuffle, broadcast, replicada e local; agregação em duas fases, shuffle e local; top-N distribuído em duas etapas; e leituras paralelas e replicadas, inserindo operadores de exchange conforme necessário. #86353 (davenger).

Armazenamento, lagos de dados e índices

  • Adicionado um cache SLRU em memória para arquivos de metadados do Paimon desserializados (listas de manifestos e manifestos). Quando habilitado pela configuração use_paimon_metadata_files_cache, consultas repetidas na mesma tabela Paimon deixam de baixar e refazer o parsing dos metadados a partir do armazenamento de objetos. #104657 (Binnn-MX).
  • O ReaderExecutor experimental (use_reader_executor, desabilitado por padrão) agora pode manter aberta uma conexão com a fonte remota e reutilizá-la em leituras sequenciais, reduzindo o número de requisições ao armazenamento de objetos durante varreduras. #107735 (CheSema).
  • Adicionado um cache do sistema de arquivos do tipo read-through ao caminho de leitura do ReaderExecutor experimental (use_reader_executor, desabilitado por padrão). #110029 (CheSema).
  • Adicionada a configuração experimental de MergeTree allow_experimental_adaptive_codec_selection. Quando habilitada, mesclagens e mutações escolhem, para cada bloco, o codec que gera a menor saída nas colunas que usam o codec padrão. #111834 (rienath).
  • Adicionada uma camada de page cache em espaço de usuário ao caminho de leitura do ReaderExecutor experimental (use_reader_executor, desabilitado por padrão). Em caso de cache miss, o executor agora preenche o page cache em espaço de usuário e atende às leituras subsequentes a partir dele, sem cópia (zero-copy). #114890 (CheSema).
  • A compactação de arquivos de manifesto do Iceberg agora está disponível por meio de OPTIMIZE TABLE ... MANIFEST, reduzindo o número de arquivos de metadados. O recurso é controlado pela configuração allow_experimental_iceberg_compaction. #98178 (SmitaRKulkarni).

Funções, formatos e IA

  • Experimental: responde a SELECT count(*) FROM t WHERE col <op> default(col) com base nas estatísticas de esparsidade por coluna em serialization.json, sem nenhuma varredura de dados, quando o predicado divide exatamente a coluna em valores padrão e valores diferentes do padrão. #105890 (Algunenano).
  • Adicionada a família experimental de codecs vetoriais Quantize(...) e uma reescrita opcional de busca vetorial aproximada em duas etapas sobre fluxos complementares quantizados. #108565 (shankar-iyer).
  • Reativado o codec experimental SZ3, de compressão com perdas e erro limitado, para colunas Float32/Float64 (e arrays desses tipos). Ele requer allow_experimental_codecs. #108788 (alexey-milovidov).
  • Corrigida a leitura de dados comprimidos com o codec experimental SZ3('ALGO_LORENZO_REG', ...), que antes falhava com CORRUPTED_DATA, e evitado comportamento indefinido ao comprimir valores de ponto flutuante não finitos (NaN e infinitos) com o codec experimental SZ3. #110762 (alexey-milovidov).
  • PromQL: as funções de data/hora (hour(), minute(), month(), year(), day_of_week(), day_of_month(), day_of_year(), days_in_month()) agora podem ser chamadas sem argumentos, usando vector(time()) como padrão, assim como no Prometheus. #111869 (valerypetrov).
  • PromQL: corrigidas operações em vetores instantâneos sem tags, como vector(1) + vector(2), topk(1, vector(1)), label_replace(vector(1), ...) e operadores binários com on(), que falhavam com um erro de tipo. #111872 (valerypetrov).
  • PromQL: implementada a função deriv, corrigindo um bug em que a função de agregação subjacente retornava valores 1000x menores com timestamps de resolução em milissegundos. #112360 (valerypetrov).
  • Aplicada a otimização de leitura em ordem a consultas com ORDER BY quando parallel_replicas_plan_based está habilitado: a ordenação agora é enviada às réplicas e mesclada no iniciador, de modo que cada réplica lê na ordem da sorting key. Também corrige o erro Unknown function __topKFilter em ORDER BY sobre uma coluna que não faz parte da chave primária com essa configuração habilitada. #114315 (devcrafter).
  • Corrigidas as leituras de busca vetorial após o recarregamento de uma data part (por exemplo, após ATTACH ou uma reinicialização do servidor): as partes não perdem mais suas subcolunas do codec Quantized, de modo que as buscas leem as subcolunas quantizadas em vez de recorrer à coluna de precisão total. #114763 (shankar-iyer).
  • O motor de tabela experimental TimeSeries não aplica mais o codec Gorilla às colunas value criadas automaticamente na tabela interna de amostras; agora elas usam CODEC(ZSTD(1)) por padrão. Colunas declaradas explicitamente mantêm os codecs definidos pelo usuário. O padrão da coluna timestamp permanece inalterado (CODEC(DoubleDelta, ZSTD(1))). #112110 (nikitamikhaylov). #114790 (nikitamikhaylov).
  • Adiciona suporte a ROLLUP, CUBE, GROUPING SETS e à função grouping em consultas executadas com make_distributed_plan = 1. #114950 (davenger).
  • Adiciona uma variante Real Doubles (RD) e um argumento opcional ALP(AUTO|STD|RD) ao codec experimental ALP. Quando usado sem argumentos, o ALP agora escolhe automaticamente entre o esquema STD existente e o RD, em vez de usar sempre o STD. #99654 (nazarii-piontko).

Outros recursos experimentais

  • Adiciona afinidade estática entre partições e shards ao StorageKafka2 por meio das configurações kafka_partition_shard_num e kafka_shard_count, permitindo que vários shards do ClickHouse consumam, de forma determinística, subconjuntos disjuntos de partições do Kafka. #108886 (JingYanchao).
  • Agora é possível autenticar no OneLake usando um bearer token obtido previamente, por meio da configuração onelake_bearer_token, em vez de onelake_client_id e onelake_client_secret. Isso evita o compartilhamento de um client secret de longa duração. O token não é renovado, portanto o banco de dados precisa ser recriado quando ele expirar. #109104 (asya-ch).
  • Corrige data_uncompressed_bytes para índices de salto empacotados em skp_idx.packed (via packed_skip_index_max_bytes): o tamanho não comprimido informado era, na verdade, o tamanho comprimido, o que também podia impedir a ativação de distributed_index_analysis. #109272 (Algunenano).
  • Adicionado suporte à compressão Zstandard ao HTTP handler experimental de Prometheus remote-write v1. #110907 (JTCunning).
  • PromQL: implementadas as funções clamp, clamp_min, clamp_max e round. #111870 (valerypetrov).
  • PromQL: quantile com um nível de quantil fora de [0, 1] agora retorna -Inf/+Inf/NaN, como no Prometheus, em vez de lançar um erro, e histogram_quantile agora ignora séries de entrada cujo rótulo le esteja ausente ou seja não analisável, também como no Prometheus. #111871 (valerypetrov).
  • PromQL: implementadas as funções changes() e resets(). #112352 (valerypetrov).
  • Passa a coletar corretamente estatísticas de inserção e consultas recebidas pelo endpoint de Prometheus remote-write. #112825 (JTCunning).
  • PromQL: preserva valores finitos ao usar módulo com um divisor infinito. #113746 (fallintoplace).
  • Rejeita quebras de linha literais em strings PromQL comuns entre aspas. #114381 (fallintoplace).
  • Um valor muito grande em distributed_plan_workers_num não faz mais o servidor abortar com std::length_error quando as configurações experimentais make_distributed_plan e enable_cascades_optimizer estão habilitadas. Agora, essa quantidade de nós é rejeitada com INVALID_SETTING_VALUE. #115398 (groeneai).
  • Implementa o endpoint /api/v1/series da Prometheus HTTP API para tabelas TimeSeries: seletores de séries match[] (valores repetidos formam uma união), um intervalo de tempo start/end opcional e um parâmetro limit opcional. #115676 (nikitamikhaylov).

Melhorias de desempenho

Desempenho de JOINs e agregações

  • Habilita o cache de condições de consulta para consultas que passam pela filtragem dinâmica TopK (ORDER BY ... LIMIT n). A entrada do QCC é particionada pelos parâmetros do plano TopK, de modo que a mesma consulta reutiliza os resultados do filtro WHERE armazenados em cache, enquanto um LIMIT, uma coluna de ordenação ou uma direção de ordenação diferente gera uma nova entrada. #104478 (alexey-milovidov).
  • Propaga o LIMIT para a agregação em ordem, permitindo o encerramento antecipado quando a chave do GROUP BY coincide com a chave do ORDER BY e com a sorting key da tabela, o que reduz significativamente o número de linhas lidas. #104859 (thevar1able).
  • Habilita allow_aggregate_partitions_independently por padrão. Quando uma chave de GROUP BY é compatível com a chave de partição, o ClickHouse pode agregar cada partição de forma independente e dispensar a etapa de mesclagem global. Heurísticas em tempo de execução desativam automaticamente a otimização quando o layout das partições a tornaria desvantajosa (poucas partições, partições demais ou tamanhos de partição muito desbalanceados). #105128 (alexey-milovidov).
  • Habilita read_in_order_use_virtual_row por padrão. Ao ler na ordem da chave primária (por exemplo, ORDER BY primary_key LIMIT n) em uma tabela com muitas partes, apenas as partes que podem de fato contribuir para o resultado são lidas (além de uma janela de leitura antecipada de no máximo max_threads partes, que mantém a leitura em paralelo), o que reduz significativamente o pico de consumo de memória. #106215 (alexey-milovidov).
  • Redução do uso de memória e melhoria do desempenho de JOINs. O lado direito de uma junção hash agora usa uma referência de linha compacta de 8 bytes baseada em índice, de modo que as entradas da tabela hash de junções ALL ficam tão pequenas quanto as de junções ANY para todos os tipos de chave. Em benchmarks com grandes consultas de junção parallel_hash — junções INNER e ANY de tabelas com 100 a 300 milhões de linhas em chaves UInt64 e String, com chaves únicas e duplicadas —, a consulta mediana ficou cerca de 12% mais rápida e teve um pico de memória cerca de 15% menor, sem que nenhuma consulta ficasse mais lenta. As junções INNER em chaves UInt64 foram as mais beneficiadas (mediana cerca de 21% mais rápida, com 38% menos memória). #107189 (harikrishnan94).
  • Adicionado o algoritmo de enumeração de ordem de junção dpsub, que gera planos de junção ótimos com menor sobrecarga de otimização do que o dpsize e oferece suporte a junções não internas. #107351 (fkastrati).
  • Evita converter agregações de nível único com baixo uso de memória em agregações de dois níveis, associando um rastreador de memória ao estado de agregação em vez de usar a memória da consulta inteira. #107490 (m-selmi).
  • Evita construir a AST completa da consulta durante a análise de consultas de agregação, calculando a chave do cache de estatísticas de tamanho da tabela hash de agregação a partir do plano de consulta, e não da AST. #107643 (novikd).
  • Permite trocar a junção hash usada na primeira execução da consulta por parallel_hash nas execuções seguintes, com base em estatísticas de tempo de execução coletadas na primeira execução. #108125 (m-selmi).
  • Usa o tamanho da tabela hash obtido das estatísticas de junção em tempo de execução para otimizar o tamanho dos JOIN runtime filters nas execuções seguintes da consulta. Pode ser controlado pela nova configuração join_runtime_filter_size_from_hash_table_stats. #108313 (m-selmi).
  • Acelera e reduz o uso de memória de consultas DISTINCT em tabelas MergeTree particionadas, mantendo as linhas de cada partição em um único stream, de modo que o DISTINCT preliminar de cada stream opere sobre um conjunto disjunto de chaves, em vez de o mesmo conjunto de chaves aparecer em vários DISTINCTs preliminares. Isso se aplica quando a expressão de partição é uma função determinística das colunas do DISTINCT e depende de uma heurística de custo baseada no número de partições e na distribuição desigual entre elas (que pode ser contornada com a configuração force_distinct_partitions_independently, desabilitada por padrão). A mesma disjunção por partição é propagada pelas etapas Expression, Filter e ARRAY JOIN até os consumidores finais DISTINCT, LIMIT BY e GROUP BY, para que eles também possam dispensar a mesclagem. Controlado pelas novas configurações allow_distinct_partitions_independently (habilitada por padrão) e max_number_of_partitions_for_independent_distinct, que permitem ajustar a heurística. #108326 (nihalzp).
  • Os filtros de tempo de execução agora são construídos sobre chaves de igualdade mesmo quando a cláusula ON também contém predicados de não igualdade, reduzindo as linhas que entram na junção hash em junções mistas equi + não equi. LEFT ANTI JOIN não é afetado. #108579 (29antonioac).
  • Reduz o limite de prefetch por software para tabelas hash de agregação e de junção de 4 * L2 cache size para L2 cache size, de modo que o prefetch seja habilitado assim que a tabela hash deixar de caber no L2. Isso corrige uma regressão em GROUP BY e JOIN sobre tabelas hash de tamanho médio (~1-8 MiB) em plataformas cujo L2 informado é grande (por exemplo, aarch64 com L2 de 2 MiB). #108655 (groeneai).
  • Melhora o desempenho das funções de janela. Consultas de janela sobre tabelas largas que incluem SELECT * agora usam significativamente menos memória e são executadas mais rapidamente. Agregações de janela, incluindo quantile*, uniq* e groupArray, ficaram mais rápidas com OVER () e OVER (ORDER BY ... RANGE ...). A função cume_dist também ficou mais rápida, e janelas que usam PARTITION BY ou ORDER BY agora têm melhor desempenho em colunas com muitos valores repetidos. #108688 (nihalzp).
  • Consultas de agregação sem funções de agregação agora usam métodos baseados em HashSet em vez de HashMap (para os tipos de chave suportados). Foram observados ganhos de velocidade de até 1,8x. #108862 (nickitat).
  • Reduz a sobrecarga causada pela contenção de locks no algoritmo de junção parallel_hash. #108938 (m-selmi).
  • Adicionado um novo valor de join_algorithm, parallel_full_sorting_merge: para junções de igualdade compatíveis com hash, ele divide uma full sorting merge join em shards pelo hash das chaves de junção, gerando junções merge independentes por shard executadas em todas as threads. Ele preserva o baixo uso de memória em streaming de uma junção merge e, ao mesmo tempo, a paraleliza (em um benchmark, ~2,4x mais rápido e ~3,3x menos memória que parallel_hash). Junções ASOF recorrem a um único full_sorting_merge; tipos de chave incompatíveis com hash (ponto flutuante, JSON, Object, Dynamic) ignoram apenas a reescrita por dispersão de hash e ainda podem ser divididos em shards na origem por intervalos de chave primária quando query_plan_join_shard_by_pk_ranges está habilitado. O resultado não é ordenado. #109005 (alexey-milovidov).
  • As estatísticas de coluna agora são materializadas no INSERT por padrão quando o tamanho ativo atual da tabela somado ao tamanho do bloco gravado não ultrapassa o valor da nova configuração materialize_statistics_on_insert_max_table_size (padrão de 25 GiB); a verificação é feita por bloco gravado, portanto uma primeira carga em massa em uma tabela vazia ainda pode materializar estatísticas para cada bloco gravado. Isso fornece ao otimizador de junção baseado em custo estimativas precisas para tabelas de dimensão recém-carregadas e evita ordens de junção patológicas (por exemplo, as consultas Q5 e Q8 do TPC-H deixaram de exceder o tempo limite com fator de escala 40), enquanto grandes tabelas de fatos já estabelecidas continuam materializando estatísticas durante as mesclagens. #109454 (alexey-milovidov).
  • Otimizada a função de agregação uniqCombined em agregações sem chave. #109794 (CurtizJ).
  • Otimizadas as funções de agregação uniqHLL12 e uniqCombined. #109831 (CurtizJ).
  • Paralelizado o processamento de linhas sem correspondência no algoritmo de junção parallel_hash em mais dois casos: quando há um filtro residual e quando as chaves de junção são pequenas (mapa hash de nível único). #110008 (m-selmi).
  • Um filtro agora é empurrado para baixo de uma função de janela quando o predicado referencia apenas as colunas PARTITION BY da janela. Um predicado desse tipo escrito após a janela (um WHERE externo envolvendo uma subconsulta com janela, ou uma conjunção em QUALIFY) agora chega ao armazenamento e habilita a poda por chave primária / poda de partições, índices de salto e projeções. Por exemplo, SELECT ... row_number() OVER (PARTITION BY key ORDER BY ts) AS rn ... QUALIFY rn = 1 AND key = 'x' deixa de ler a tabela inteira e de aplicar a janela sobre ela. #110114 (groeneai).
  • Com join_use_nulls = 1, um WHERE que rejeita valores NULL e referencia colunas de ambos os lados de uma junção externa (por exemplo, WHERE l.k = 42 AND r.k = 42) agora converte a junção em INNER (ou LEFT/RIGHT) e aplica a poda pela chave primária, assim como acontece com join_use_nulls = 0. Antes, a conversão não era feita nesse caso e ambas as tabelas eram lidas por completo. #110121 (groeneai).
  • Otimizadas as funções uniq, uniqExact e uniqHLL12 em agregações sem chave. #110150 (CurtizJ).
  • Um JOIN cuja condição ON é constantemente falsa (por exemplo, ON 1 = 2, ON NULL ou uma condição que se reduz a falso, como a.t = 'A' AND a.t = 'B') deixa de ler o lado que não contribui para o resultado. Uma nova otimização do plano de consulta substitui por uma fonte vazia os lados de entrada que não podem contribuir com nenhuma linha. Controlada pela configuração query_plan_short_circuit_constant_false_join (habilitada por padrão). #110234 (groeneai).
  • Paralelizada a mesclagem final de tabelas hash de agregação de nível único: o espaço de chaves é dividido em partições hash disjuntas, que as threads mesclam de forma independente (configuração enable_parallel_single_level_merge, habilitada por padrão). Acelera consultas GROUP BY cujas tabelas hash por thread ficam abaixo do limite de dois níveis, mas cuja mesclagem dominava o tempo de execução. #110395 (nihalzp).
  • Chaves de agregação compostas por um único String agora usam uma representação de tabela hash menor, melhorando cargas de trabalho de GROUP BY com uso intensivo de strings. A nova configuração enable_packed_string_keys_in_aggregation vem habilitada por padrão; desabilitá-la, ou definir compatibility abaixo de 26.8, restaura o caminho legado StringHashTable, que pode ser mais rápido para chaves de cardinalidade muito baixa com mais de 11 bytes. #110573 (harikrishnan94). #112089 (harikrishnan94).
  • Melhora o desempenho do full sorting merge join em 1,5 a 3 vezes em cenários esparsos. #111200 (vdimir).
  • Habilita join_runtime_filter_from_fixed_hash_table quando os tipos das chaves de junção dos lados de probe e de build são diferentes (por exemplo, uma chave de probe Nullable com uma chave de build não Nullable). #111244 (m-selmi).
  • Melhora o desempenho de junções RIGHT e FULL com o algoritmo parallel_hash quando o lado direito contém chaves de junção NULL ou linhas filtradas pela expressão ON, evitando a reconstrução dos mapas de nulos. #111258 (m-selmi).
  • Novo algoritmo adaptativo para GROUP BY paralelo (controlado pela configuração enable_adaptive_aggregator, habilitada por padrão): cada thread agrega em sua própria tabela hash até que ela atinja adaptive_aggregator_freeze_threshold chaves e, então, a congela. Assim, as chaves frequentes continuam atualizando as pequenas tabelas residentes em cache sem nenhuma coordenação, enquanto as chaves raras são encaminhadas de acordo com seu hash para backlogs por bucket e agregadas uma única vez, dentro da mesclagem paralela por bucket. #111459 (nihalzp).
  • Acelera o hashing linha a linha de valores de colunas JSON/Object armazenados em dados compartilhados (usado, por exemplo, por uniq/uniqExact sobre uma coluna JSON e por chaves de GROUP BY/DISTINCT com hash), evitando a reconstrução de um ColumnDynamic para cada valor. Os valores de hash não mudam. #111501 (valerypetrov).
  • Melhora o desempenho de hash JOIN RIGHT e FULL com múltiplas disjunções OR na seção ON, bem como de JOIN RIGHT/FULL com condições residuais (de desigualdade). #111590 (m-selmi).
  • A leitura em ordem através de um JOIN agora também funciona quando um hash join tem um limiar automático de spill para disco configurado (o padrão desde a versão 26.5). Quando essa otimização se aplica, a junção permanece em memória para preservar a ordem do lado esquerdo; defina query_plan_read_in_order_through_spilling_join = 0 para restaurar o comportamento anterior, em que essas junções não são usadas para leitura em ordem e continuam livres para fazer spill. Além disso, um ORDER BY ... LIMIT sobre um LEFT JOIN lido em ordem deixa de informar a tabela inteira como o número de linhas que pretende ler e, portanto, não aciona mais max_rows_to_read com read_overflow_mode = 'throw' em uma leitura que termina antecipadamente. #111973 (alexey-milovidov).
  • Reabilita a otimização de chaves consecutivas para a agregação TTL ... GROUP BY durante mesclagens. O agregador era construído passando min_chunk_bytes_for_parallel_parsing (um limiar em bytes, padrão de 10 MiB) na posição que espera min_hit_rate_to_use_consecutive_keys_optimization (uma taxa de acerto em [0, 1], padrão de 0,5), de modo que a otimização ficava permanentemente desabilitada nesse caminho. Os resultados não são afetados. #112314 (groeneai).
  • A replicação lazy de colunas para ARRAY JOIN não é mais perdida quando um plano de consulta é serializado. Com serialize_query_plan = 1, o nó que executava um fragmento de plano remoto ignorava enable_lazy_columns_replication e sempre materializava todas as cópias replicadas, embora essa configuração seja habilitada por padrão. #112330 (groeneai).
  • Uma igualdade no WHERE agora é mesclada à condição do JOIN quando seus operandos têm tipos diferentes, mas um supertipo comum, como Int32 e Nullable(Int32). Isso permite converter uma junção CROSS em uma junção INNER. #112630 (m-selmi).
  • Corrigida a realocação quadrática ao replicar um Array cujos elementos contêm valores JSON em dados compartilhados, por exemplo, um Array(JSON) constante passado para uma função de agregação. Essas consultas copiavam uma quantidade de bytes que crescia quadraticamente com o número de linhas. #112897 (groeneai).
  • Restaura a poda de partes e grânulos quando os limites de um predicado de intervalo sobre uma chave primária ou de partição do MergeTree são fornecidos por meio de uma cláusula JOIN ON com um lado constante de linha única, por exemplo, SELECT count() FROM t JOIN bounds ON t.d >= bounds.lo AND t.d <= bounds.hi. Desde a versão 25.2, esse tipo de consulta lia todas as partes, e a configuração query_plan_use_logical_join_step, que antes restaurava a poda, tornou-se obsoleta na versão 26.5, sem deixar nenhuma forma de recuperá-la. #112957 (groeneai).
  • Corrigida a complexidade cúbica do planejamento de consultas para um JOIN com uma tabela Merge sobre muitas tabelas com estruturas diferentes. Antes, essas consultas podiam passar minutos no planejamento sem responder a max_execution_time ou KILL QUERY. #113140 (alexey-milovidov).
  • Corrigida uma regressão de desempenho em que uma agregação sem chaves de GROUP BY serializava, a cada execução, toda a subárvore do plano de entrada, incluindo o conteúdo completo de literais resultantes de constant folding, para calcular uma chave de cache de tamanho de tabela hash que jamais seria usada. Uma consulta como SELECT quantileMerge(arrayJoin(arrayMap(x -> state, range(5000000)))) gastava cerca de 63 ms por execução na otimização do plano de consulta e agora gasta 0,15 ms. #113333 (groeneai).
  • Os operadores de agregação do PromQL topk, bottomk e limitk agora são avaliados com um plano de streaming cujo estado de seleção é O(time_steps * k), em vez de coletar todas as séries em uma única linha com memória intermediária O(time_steps * series^2). Consultas sobre métricas de alta cardinalidade que antes falhavam com MEMORY_LIMIT_EXCEEDED agora são executadas com memória limitada, e a avaliação é paralelizada em vez de ser de thread única. #113656 (nikitamikhaylov).
  • Substituído o hash map por bucket dentro das funções de agregação timeSeries*ToGrid por um array plano e ordenado de amostras: a ingestão de amostras passa a ser um append O(1) para entradas em ordem (de longe o caso mais comum), e a cópia e ordenação por bucket na finalização foi eliminada. #113681 (nikitamikhaylov).
  • Subexpressões do PromQL compartilhadas por várias etapas do plano (o operando de topk/bottomk/limitk, o lado esquerdo de or) agora são avaliadas uma única vez, e não duas: o SQL gerado a partir do PromQL passa a materializar subconsultas compartilhadas. Isso elimina uma varredura duplicada da tabela samples; topk sobre rate fica cerca de 2x mais rápido com cache frio, e as consultas de regras do kubernetes-mixin melhoram de 10% a 29%. #113772 (nikitamikhaylov).
  • O cache de condições de consulta agora está habilitado por padrão para consultas que usam a otimização ORDER BY <column> LIMIT n (TopK). Para desativá-lo, defina use_query_condition_cache_for_top_k = 0. #111492 #114539 (alexey-milovidov).
  • Paraleliza a conversão de nível único para dois níveis dos estados de agregação por thread antes da mesclagem. Isso corrige uma regressão de 2-3x em consultas GROUP BY curtas com estados de agregação pesados (por exemplo, COUNT(DISTINCT ...), ClickBench Q10/Q11) em máquinas com uma quantidade muito grande de núcleos, introduzida nas compilações de desenvolvimento da 26.7, quando a contabilização de memória da agregação passou a ser precisa. #114691 (alexey-milovidov).
  • Acelera as funções de janela em tabelas MergeTree particionadas, lendo cada partição por meio de seu próprio stream e avaliando as janelas por partição, o que dispensa a dispersão por hash que normalmente redistribui todas as linhas entre as threads antes da ordenação da janela. Isso se aplica quando a expressão de partição da tabela é uma função determinística das colunas PARTITION BY da janela e está sujeito à mesma heurística de custo usada em GROUP BY / DISTINCT por partição (partições suficientes em relação a max_threads, sem partição dominante). Controlado pelas novas configurações allow_window_partitions_independently (habilitada por padrão), force_window_partitions_independently e max_number_of_partitions_for_independent_window. #114783 (nihalzp).
  • Acelera as funções de agregação timeSeries*ToGrid: o cálculo de bucket por amostra agora evita a divisão em Int128, e amostras consecutivas no mesmo bucket dispensam a busca no hash map. #114889 (nikitamikhaylov).
  • Processa as amostras das funções de agregação timeSeries*ToGrid em sequências de amostras consecutivas que caem no mesmo bucket da grade, acelerando em 1,2-2x a etapa de ingestão de amostras de timeSeriesRateToGrid e funções relacionadas em dados de séries temporais ordenados. #115041 (nikitamikhaylov).
  • Uma agregação sem chaves de GROUP BY não distribui mais sua saída de linha única para max_threads streams; assim, consultas cujo plano continua após essa agregação obtêm um pipeline muito menor (menos processadores para criar, agendar e perfilar) sem perder paralelismo. #115170 (nikitamikhaylov).
  • Avaliação mais rápida de consultas instantâneas PromQL: as funções de agregação timeSeries*ToGrid usam o caminho vetorizado de classificação de amostras para grades de ponto único, e timeSeriesIdToGroup preenche sua coluna de resultado diretamente. #115267 (nikitamikhaylov).
  • Um JOIN cuja seção ON tem várias igualdades combinadas com OR não materializa mais as colunas de chave do lado direito que não são selecionadas pela consulta. #115465 (nickitat).
  • Acelera a construção da tabela hash de uma junção ANY, SEMI ou ANTI quando o lado direito repete as mesmas chaves de junção muitas vezes: a junção não relê mais a configuração join_any_take_last_row da memória a cada linha do lado direito. #115820 (nickitat).
  • Acelera GROUP BY sem funções de agregação sobre chaves String, FixedString e LowCardinality: a consulta não regrava mais um marcador de posição não utilizado na tabela hash a cada linha, apenas nas linhas que adicionam uma nova chave. #115834 (nickitat).
  • Redução do uso de memória e do tempo de otimização do plano de consulta em agregações com chave sobre literais grandes resultantes de constant folding. A chave de cache das estatísticas da tabela hash de agregação agora tem seu hash calculado à medida que é serializada, em vez de ser acumulada primeiro na memória. Assim, um plano que contém um literal grande deixa de manter uma cópia dele durante a otimização. Para um literal de 80 MB, o pico de memória cai cerca de 250 MB, e o tempo de otimização fica cerca de 2,5x menor. A chave calculada permanece inalterada. #115847 (groeneai).
  • Otimização das consultas GROUP BY ... ORDER BY ... LIMIT e GROUP BY ... LIMIT com a manutenção de um heap limitado durante a agregação, que descarta grupos que não podem aparecer no resultado. Isso reduz significativamente o uso de memória e o tempo de execução em agrupamentos de alta cardinalidade. Controlado pela configuração enable_group_by_top_k_optimization. Baseado na implementação inicial de Dmitriy Terenichev #96630 (thevar1able).

Otimização e execução de consultas

  • A leitura em ordem com réplicas paralelas agora usa a mesma lógica da leitura local para dividir a tabela em max_threads partes, melhorando o paralelismo. #101434 (nickitat).
  • Adiciona ao leitor Parquet a poda espacial GeoParquet nos níveis de grupo de linhas e de página. A poda de grupos de linhas ignora grupos de linhas inteiros cuja caixa delimitadora não se sobrepõe à geometria da consulta. A poda em nível de página usa o índice de coluna covering.bbox para ignorar páginas irrelevantes dentro dos grupos de linhas. Também generaliza o pushdown de predicados espaciais por meio de IFunctionBase::isSpatialPredicate() e adiciona um GeoFilter que avalia predicados espaciais durante a leitura de linhas Parquet. #104435 (bacek).
  • Adicionada a configuração use_constant_folding_in_index_analysis (desabilitada por padrão). Quando habilitada, a análise de chave primária, MinMax e índices de salto do MergeTree incorpora as constantes em nível de partição ao predicado do filtro separadamente para cada parte, melhorando a poda para filtros cujos ramos dependem de valores de partição, por exemplo, (a = 1 AND b >= 1) OR (a = 2 AND b > 10) com PARTITION BY a. #104582 (Michicosun).
  • Aplica o posicionamento exato de linhas em consultas de busca vetorial com vector_search_with_rescoring antes da avaliação exata de distância no pipeline da consulta. #105591 (skuznetsov).
  • Adicionada uma otimização do plano de consulta que move funções redutoras de volume (length, lengthUTF8, empty, notEmpty) para baixo das etapas Sorting e Filter, substituindo o argumento largo String / FixedString pelo resultado de tamanho fixo, de modo que ele não precise ser armazenado em buffer por uma ordenação nem copiado por um filtro. Controlada pela nova configuração query_plan_push_down_volume_reducing_functions, habilitada por padrão. #106199 (fastio).
  • Acelera o carregamento do cache do sistema de arquivos na inicialização ao codificar o tamanho de cada arquivo de cache no próprio nome (<offset>_<size>), evitando uma chamada stat por arquivo. O carregamento de arquivos de cache gravados por versões anteriores continua sendo suportado. #107415 (alexey-milovidov).
  • Melhorado o desempenho de consultas de busca textual combinadas com um filtro de chave primária. #108114 (CurtizJ).
  • Melhora o desempenho da função pointInPolygon com um polígono constante. O cache de polígonos pré-processados agora usa como chave os argumentos constantes brutos, de modo que um polígono constante é interpretado apenas uma vez (em caso de cache miss), em vez de ser reinterpretado a cada bloco de entrada. #108184 (groeneai).
  • Deixa de manter os contadores de seletividade de system.predicate_statistics_log no caminho de leitura do MergeTree quando o recurso está desabilitado (predicate_statistics_sample_rate = 0, o padrão). Isso elimina uma atualização atômica por grânulo e um popcount O(rows) do filtro em cada leitura, corrigindo uma regressão de desempenho mais perceptível em aarch64. #108190 (groeneai).
  • Adiciona a configuração merge_use_batch_sorting_queueMergeTree para usar opcionalmente a fila de ordenação em lote nas mesclagens comuns do MergeTree, reduzindo o uso de CPU e o tempo total de execução em cargas de trabalho de mesclagem nas quais a mesclagem ordenada representa um custo significativo. #108468 (rorylshanks).
  • Acelera o planejamento de consultas no analisador para expressões que referenciam o mesmo alias WITH ou repetem a mesma subexpressão muitas vezes (por exemplo, cadeias profundamente aninhadas de if/multiIf), evitando reconstruir subexpressões compartilhadas durante a construção do DAG de ações. #108523 (novikd).
  • Acelerada a análise de consultas com muitas cadeias AND de comparações ou com cadeias muito grandes: a otimização optimize_and_compare_chain agora é limitada por um orçamento de trabalho (nova configuração optimize_and_compare_chain_max_hash_work) em vez de calcular o hash de uma grande fração da árvore da consulta, e a resolução de lambdas não recalcula mais os hashes do corpo da lambda para sua proteção contra recursão. #108757 (alexey-milovidov).
  • Pós-processadores que apenas filtram (if(..., '', token)) agora constroem o grânulo a partir dos tokens brutos e descartam os vazios durante a construção, evitando a materialização por ocorrência e a execução de ActionsDAG do caminho geral. #109049 (ahmadov).
  • Removido um gargalo de thread única em ShuffleSendStep do plano de consulta distribuída: cada stream upstream agora distribui suas linhas por bucket de destino de forma independente, em vez de canalizar o fragmento inteiro por um único ScatterByPartitionTransform. #109206 (davenger).
  • Reduzida a sobrecarga de CPU na avaliação de expressões em consultas com um grande número de colunas (por exemplo, busca vetorial em uma coluna QBit com stride pequeno, em que cada vetor se expande em centenas de subcolunas de planos de bits, todas passadas para uma única chamada *DistanceTransposed). #109380 (alexey-milovidov).
  • Um filtro agora é empurrado para baixo de LIMIT BY quando o predicado referencia apenas as colunas-chave de LIMIT BY e a cláusula mantém pelo menos uma linha por grupo não vazio (LIMIT n BY com n >= 1 e OFFSET 0). Isso permite que esses predicados (escritos como um WHERE externo envolvendo uma subconsulta LIMIT BY) cheguem ao armazenamento para poda pela chave primária, índices de salto e projeções, em vez de ler a tabela inteira e aplicar primeiro o top-N por grupo, sem alterar a semântica de exceções das formas OFFSET, LIMIT 0 BY ou LIMIT BY negativo. #110116 (groeneai).
  • Eliminada uma alocação de heap por verificação de hiper-retângulo na análise do índice de chave primária, acelerando a filtragem de marcas em 5-26%, dependendo do formato da consulta. #110153 (raimannma).
  • O push-down de filtros do Parquet (poda de row groups e índices de coluna) agora oferece suporte a conversões entre variantes de DateTime64, variantes de Decimal e Float32/Float64. #110457 (al13n321).
  • Otimizada a construção de índices de salto de texto e baseados em filtro de Bloom com o tokenizador sparseGrams #110541 (UnamedRus).
  • Combinado o custo de E/S com a seletividade na ordenação das condições do PREWHERE. Isso corrige uma regressão de desempenho na execução do PREWHERE, em alguns casos, introduzida após https://github.com/ClickHouse/ClickHouse/pull/101275. Parte de https://github.com/ClickHouse/ClickHouse/issues/110462 #110695 (Avogar).
  • Reduzido o cálculo de hash de tokens definidos no filtro IN/NOT IN do pós-processador. #111690 (ahmadov).
  • As funções mapContainsKeyLike, mapContainsValueLike, mapExtractKeyLike e mapExtractValueLike com um pattern não constante consomem menos memória e tempo quando enable_lazy_columns_replication está habilitado. O pattern não é mais copiado antecipadamente para cada entrada do map no momento da captura; a cópia é adiada para a execução da lambda interna e liberada mais cedo, de modo que, no pico, há uma cópia expandida a menos do pattern. #111749 (diegomestre2).
  • Habilitados por padrão (e promovidos a beta) dois recursos em disco: 1) packed_skip_index_max_bytes = '1M': subfluxos de índices de salto de até 1 MiB agora são gravados em um único arquivo skp_idx.packed por parte, reduzindo a quantidade de objetos e de solicitações de gravação no armazenamento de objetos. Compatibilidade: apenas as partes recém-gravadas são afetadas, e elas continuam totalmente legíveis em versões mais antigas; versões anteriores à 26.6 simplesmente não usam os índices empacotados para poda (eles são tratados como não materializados). Defina packed_skip_index_max_bytes = 0 para manter o layout independente por arquivo. 2) compute_exact_num_defaults_for_sparse_columns junto com optimize_trivial_count_with_sparsity_filter: contadores exatos de num_defaults por coluna são persistidos e usados para responder a SELECT count() FROM t WHERE <pred> sem varredura de dados quando o predicado separa as linhas entre valores padrão e não padrão. Compatibilidade: o sinalizador exact_num_defaults em serialization.json é ignorado por versões mais antigas, de modo que as partes permanecem totalmente legíveis após um downgrade; a reescrita da contagem só se aplica a partes que contêm contadores exatos, portanto os resultados continuam corretos em tabelas com partes mistas. #111816 (Algunenano).
  • A otimização de condições transitivas agora usa seu filtro adicional apenas para análise de índice quando não consegue aplicar o filtro completo. Consulte a configuração optimize_and_compare_chain. #112076 (yariks5s).
  • A API de consultas do Prometheus (/api/v1/query, /api/v1/query_range) do motor experimental TimeSeries agora executa consultas em paralelo, e não mais em uma única thread. #112108 (nikitamikhaylov).
  • randomHadamardTransform de um vetor constante agora é avaliado uma única vez, e não uma vez por linha. Isso acelera consultas de busca vetorial que rotacionam o vetor de consulta com randomHadamardTransform antes de compará-lo com uma coluna QBit. #112921 (alexey-milovidov).
  • Restaura o compartilhamento de sets entre as tarefas por parte de uma mesma mutação que filtra com IN (subquery) sobre uma coluna da chave primária. enable_sharing_sets_for_mutations vem ativado por padrão, mas o set construído para a análise da chave primária havia deixado de participar do cache compartilhado, de modo que uma tabela com N partes materializava o mesmo set N vezes. #112941 (groeneai).
  • Em planos de consulta distribuída (make_distributed_plan), ORDER BY ... LIMIT k agora usa materialização tardia em cada réplica: colunas largas são lidas apenas para as top-k linhas locais daquela réplica, e não para todas as linhas candidatas. #113111 (shankar-iyer).
  • Acelera o planejamento de consultas quando são usadas estatísticas de coluna uniq_v2. O número estimado de valores distintos agora é armazenado em cache, em vez de ser recalculado a cada requisição — e o planejamento de consultas emite essas requisições muitas vezes por consulta. #113357 (groeneai).
  • O pushdown de filtros agora funciona para subcolunas Tuple em arquivos Parquet e ORC. Um predicado como WHERE tup.1 = 555555 sobre file(), s3() ou url() agora poda grupos de linhas e intervalos de índice de linhas usando as estatísticas do próprio elemento da tupla, em vez de ler o arquivo inteiro. #113383 (groeneai).
  • Melhora o desempenho de consultas PromQL sobre o motor TimeSeries: o SQL interno do seletor agora lê diretamente as colunas da chave primária da tabela de amostras (sem conversões inócuas) e verifica o intervalo de timestamps antes do set de IDs de séries, o que deixa consultas a frio com uso intenso de seletores de 30% a 44% mais rápidas. #113768 (nikitamikhaylov).
  • Seletores PromQL que correspondem a todas as séries de uma métrica agora filtram a tabela de amostras de uma tabela TimeSeries com um intervalo contínuo de chave primária em id durante a análise de índice, em vez de uma grande condição id IN <set>, quando o layout de id é uma tupla de dois componentes com o gerador de id canônico. Isso elimina o custo dominante de análise de índice single-threaded em consultas PromQL com muitos seletores: redução de até 45% na latência a frio em padrões de consulta de dashboards e regras, e de 11% na média geométrica a frio em todo o conjunto de testes, em uma tabela com 62 bilhões de amostras. #114131 (nikitamikhaylov).
  • Os endpoints /api/v1/query e /api/v1/query_range da Prometheus HTTP API agora avaliam uma única vez uma subconsulta PromQL compartilhada por várias etapas do plano, como as funções de tabela prometheusQuery e prometheusQueryRange já faziam. Antes, uma requisição feita com enable_analyzer = 0, ou por um usuário cujo perfil define essa configuração, voltava a varrer a subconsulta compartilhada uma vez para cada etapa que a referenciava. #114261 (groeneai).
  • Corrigida uma regressão na versão 26.7: em uma tabela MergeTree ordenada por toUnixTimestamp (ou outra conversão para inteiro) de uma coluna DateTime64, um filtro de intervalo simples nessa coluna deixava de usar a chave primária e lia todos os grânulos das partes correspondentes. Além disso, um filtro como toInt64(ts) >= c em uma tabela ordenada pela coluna DateTime64 bruta agora usa a chave primária. #114413 (alexey-milovidov).
  • Acelera a execução de IN sobre colunas agrupadas (por exemplo, ordenadas pela chave primária), reaproveitando o resultado da linha anterior quando linhas consecutivas são iguais. #114853 (nikitamikhaylov).
  • Corrigido o tempo quadrático quando as funções h3kRing, h3ToChildren, h3PolygonToCells e h3PolygonToCellsWithContainment constroem seu resultado a partir de muitas linhas. Uma consulta sobre 196 000 linhas passou 838 segundos copiando memória em uma execução de teste de estresse do CI; agora leva cerca de 5 segundos. #115773 (groeneai).
  • Otimiza buscas inversas em dicionários. Um predicado de igualdade constante como WHERE dictGet(dict, attr, key_expr) = value agora é resolvido por constant folding diretamente em um filtro de chave (key_expr = const, key_expr IN [...] ou WHERE 0), em vez de ser reescrito como uma subconsulta IN (SELECT ... FROM dictionary(...)), e o caminho constante de dictGetKeys agora é executado em paralelo. #91164 (nihalzp).
  • Adicionada a nova configuração merge_tree_generic_exclusion_search_max_steps, que limita o número de passos que o algoritmo de busca por exclusão genérica dedica à análise do índice de chave primária de cada parte de dados. O orçamento é aplicado primeiro aos maiores intervalos de chave restantes, de modo que mesmo um orçamento pequeno descarta a maior parte dos dados; intervalos que não foram totalmente analisados são lidos por inteiro, de forma que os resultados das consultas continuam corretos, embora mais grânulos possam ser lidos. O limite é aplicado de forma flexível: pode ser excedido em no máximo merge_tree_coarse_index_granularity passos, mais um passo para cada intervalo em que a parte já está dividida (por exemplo, pelo cache de condições de consulta). O valor padrão 0 significa passos ilimitados. #92779 (EmeraldShift).
  • Consultas com ORDER BY e LIMIT em VIEWs sobre tabelas distribuídas agora usam a otimização de mesclagem de fluxos ordenados. O ORDER BY/LIMIT externo é propagado para a consulta interna de uma view simples, de modo que cada shard ordena seus dados localmente e o coordenador mescla fluxos já ordenados, em vez de realizar uma ordenação completa no coordenador. #94102 (matanper).

Desempenho de armazenamento, E/S e lago de dados

  • Uso dos limites do índice minmax de partição para podar mais granules durante a análise da chave primária em tabelas MergeTree, quando uma coluna da chave primária também é coluna de entrada da chave de partição. Por exemplo, em uma tabela MergeTree com ORDER BY (id, event_time) e PARTITION BY toYYYYMM(event_time), o ClickHouse usará o índice minmax de partição em event_time durante a análise de índice da chave primária para tomar decisões mais precisas de poda de granules. Controlado pela nova configuração use_partition_minmax_for_primary_key_pruning (habilitada por padrão). #103480 (UnamedRus).
  • Aceleração dos operadores que percorrem um stream ordenado em busca de sequências de valores de chave iguais — DISTINCT em ordem, LIMIT BY em ordem, LIMIT BY negativo em ordem e os joins full_sorting_merge e partial_merge. #106502 (nihalzp).
  • O leitor Parquet v3 agora pode ignorar grupos de linhas inteiros usando a página de dicionário (além das estatísticas de mín./máx. e dos bloom filters) em condições de igualdade e IN, quando um bloco de coluna está totalmente codificado por dicionário. Controlado pela nova configuração input_format_parquet_dictionary_filter_push_down. #106952 (alexey-milovidov).
  • Uso da libdeflate para compressão e descompressão gzip/zlib/deflate, tornando-as mais rápidas (compressão ~1,15× com taxa melhor, descompressão ~1,4–1,5×) para dados .gz/HTTP/url/s3 e para o codec GZIP do Parquet. #108074 (alexey-milovidov).
  • Aceleração das funções trimLeft/trimRight/trimBoth com espaço em branco padrão (e seus aliases ltrim/rtrim/trim): linhas consecutivas que não precisam de remoção de espaços são copiadas em um único lote, e a varredura de espaços por linha só é executada nas linhas que de fato têm espaço no início ou no fim. #108177 (groeneai).
  • Aceleração da leitura de tabelas Iceberg por meio da pré-busca do próximo arquivo de manifesto enquanto o manifesto atual é interpretado, sobrepondo E/S ao processamento de CPU. #108543 (asya-ch).
  • Consultas de busca vetorial que usam rescoring agora restringem o cálculo exato de distância às linhas candidatas do índice vetorial, em vez de reavaliar por força bruta as linhas vizinhas do mesmo granule MergeTree. #108846 (skuznetsov).
  • Adicionada a configuração merge_tree_min_bytes_per_read_stream para reduzir o excesso de streams de leitura e a sobrecarga do pipeline em varreduras MergeTree locais comuns, não ordenadas e de colunas estreitas, em servidores com muitos núcleos. #109035 (jiebinn).
  • Aceleração da serialização e das mesclagens de colunas JSON cujos dados compartilhados contêm muitos caminhos esparsos. Ao achatar os dados compartilhados em colunas por caminho, flattenAndBucketSharedDataPaths não percorre mais todas as colunas de caminho acumuladas a cada linha nem insere valores padrão uma célula por vez; a varredura por linha sobre todos os caminhos foi removida e as lacunas são preenchidas em lote. #109341 (groeneai).
  • O protocolo nativo agora envia colunas String como um stream separado de offsets cumulativos de bytes (o mesmo layout que Array usa para seus offsets), seguido pelos dados concatenados, em vez de um prefixo de comprimento varint por valor, quando ambos os pares estão na revisão de protocolo 54489 ou posterior. Com isso, um cliente pode ler colunas String com pré-alocação exata de buffer e uma única cópia em bloco, cerca de 4 vezes mais rápido do que com o layout por valor. Clientes e servidores antigos não são afetados: o layout é negociado por meio da revisão do protocolo. O mesmo layout está disponível nos formatos Native e Buffers por meio das novas configurações output_format_native_write_string_with_size_stream / input_format_native_read_string_with_size_stream (desabilitadas por padrão, para que os formatos permaneçam portáveis). #110320 (vahid-sohrabloo).
  • Consultas com FINAL que leem na ordem da chave primária (ORDER BY sobre um prefixo da sorting key) com um LIMIT pequeno não usam mais split_intersecting_parts_ranges_into_layers_final. #110431 (KochetovNicolai).
  • Materialização lazy (materialização tardia) na leitura de arquivos Parquet a partir de armazenamento de objetos, incluindo tabelas Iceberg: em consultas ORDER BY ... LIMIT n, as colunas que não são necessárias para ordenação e filtragem são lidas apenas para as n linhas que restam após o LIMIT. Em um arquivo Parquet de 200 MB no S3, SELECT k, s ... ORDER BY k DESC LIMIT 10 lê 3,3 MB em vez de 171 MB (51x menos E/S, 8x mais rápido). Controlada pela nova configuração query_plan_optimize_lazy_materialization_for_object_storage (habilitada por padrão; também requer query_plan_optimize_lazy_materialization). #110970 (alexey-milovidov).
  • Consultas em tabelas Iceberg com muitos arquivos de exclusão agora iniciam mais rápido. O ClickHouse lê e decodifica os arquivos de manifesto de exclusão de forma concorrente, em vez de um por vez, para que as leituras de armazenamento ocorram em paralelo. A nova configuração iceberg_delete_manifest_decode_concurrency (padrão 4) controla quantos arquivos são decodificados simultaneamente. #112679 (asya-ch).
  • Adicionada a serialização opcional em Parquet de UInt128/UInt256/Int128/Int256 como DECIMAL, permitindo a poda de row groups e páginas. #113347 (bobrik).
  • Corrigida a multiplicação de requisições de leitura em discos remotos quando uma etapa da cadeia de leitores lê intervalos de marcas fragmentados, por exemplo, intervalos filtrados por índices primários ou de salto. #113584 (CurtizJ).
  • A verificação redundante de ordenação agora é ignorada ao gravar partes MergeTree cujas sorting keys são todas constantes. #113899 (perfloop-agent).
  • A materialização lazy para consultas ORDER BY ... LIMIT n agora também se aplica a arquivos Parquet locais lidos com a função de tabela file e o mecanismo de tabela File: as colunas que não são necessárias para ordenação e filtragem são lidas apenas para as n linhas que restam após o LIMIT. A segunda leitura de um arquivo remanescente falha de forma segura com o novo erro FILE_CHANGED_DURING_READ se o arquivo tiver sido modificado entre as duas passagens. Controlada pela nova configuração query_plan_optimize_lazy_materialization_for_file (habilitada por padrão). Também corrige a falha Not found column or subcolumn ... in block na materialização lazy para armazenamento de objetos quando uma subcoluna solicitada (por exemplo, de uma coluna JSON) era adiada. #114262 (alexey-milovidov).
  • Acelera a construção do set para IN (subquery) em tabelas MergeTree particionadas, mantendo as linhas de cada partição em um único stream e deduplicando cada stream de forma independente, de modo que a única transformação de preenchimento do set — que antes calculava o hash de cada linha serialmente — processe apenas linhas únicas. Isso se aplica quando a expressão de partição é uma função determinística das colunas de saída da subconsulta. A otimização não é aplicada quando a maior partição contém mais que o dobro de linhas da partição média; a nova configuração force_creating_set_partitions_independently (desabilitada por padrão) ignora essa verificação. Controlada pela nova configuração allow_creating_set_partitions_independently (habilitada por padrão). #114645 (nihalzp).
  • Marca como table_readonly as tabelas de log do sistema MergeTree não replicadas, rotacionadas e sem TTL, para evitar operações desnecessárias em segundo plano. A configuração table_readonlyMergeTree agora também suprime todo o trabalho em segundo plano em uma tabela MergeTree simples — mesclagens regulares, de TTL (DELETE/MOVE/recompressão) e de recompressão, mutações em segundo plano e movimentações de partes em segundo plano — e rejeita os comandos de partição que modificam dados (ATTACH/MOVE/DROP/DROP DETACHED/FETCH/REPLACE PARTITION e MOVE PARTITION ... TO TABLE com destino à tabela), além dos inserts, mutações e OPTIMIZE que ela já rejeitava. Com isso, uma tabela table_readonly com TTL deixa de recuperar seus dados expirados enquanto a configuração estiver habilitada. #95079 (matt-metivier).

Eficiência de memória e de recursos

  • Redução do uso de memória de UNLOCK SNAPSHOT ao deixar de carregar metadados de cada parte de dados que o caminho de desbloqueio não utiliza, evitando falta de memória em snapshots com um número muito grande de partes. #111849 (jkartseva).
  • Redução das alocações de memória na leitura de metadados de backup: cada entrada de arquivo agora é movida para os maps em memória, em vez de ser copiada. #111718 (jkartseva).

Desempenho de funções, tipos e formatos

  • A formatação de valores Decimal como texto está muito mais rápida — até 190 vezes para um Decimal256 com escala grande e cerca de 1,6 vez para um Decimal64. Em processadores com AVX-512 IFMA, a conversão de inteiros de 64 bits em texto está cerca de 1,4 vez mais rápida. Também foi corrigido o arredondamento de toDecimalString, que descartava o “vai um” da parte fracionária: toDecimalString(toDecimal64('9.995', 3), 2) retornava 9.00 e agora retorna 10.00. #112457 (thevar1able).
  • Melhorado o desempenho do algoritmo de junção partial_merge em chaves FixedString, que agora compara sequências de valores de uma só vez em vez de fazer uma chamada de comparação por valor. #105737 (4ertus2).
  • Chaves LowCardinality de string não anuláveis de coluna única agora têm suporte nativo no HashJoin. #107264 (nickitat).
  • Melhorado o desempenho de replaceAll e replaceRegexpAll quando tanto o padrão quanto a substituição são um único caractere (por exemplo, replaceRegexpAll(s, ' ', '_')). Essas substituições não alteram mais o layout da string; assim, a coluna agora é copiada uma única vez e os bytes correspondentes são reescritos no local, em vez de se executar um laço de busca para cada correspondência. #108178 (groeneai).
  • Acelerado o parsing da representação canônica de data e hora YYYY-MM-DD hh:mm:ss no modo best-effort (date_time_input_format = 'best_effort', cast_string_to_date_time_mode = 'best_effort'), que é o padrão. Isso elimina uma regressão de desempenho de parsing introduzida quando esses padrões foram alterados de basic para best_effort. #108187 (groeneai).
  • O parsing de literais de array e tupla profundamente aninhados agora ocorre em tempo linear em vez de quadrático. #108892 (alexey-milovidov).
  • A função toStartOfInterval (aliases time_bucket, date_bin) ficou até 5x mais rápida para intervalos SECOND, MINUTE e HOUR. #109729 (raimannma).
  • As funções arraySort e arrayReverseSort estão várias vezes mais rápidas com arrays numéricos (incluindo Decimal e DateTime64) quando chamadas sem lambda. #109832 (raimannma).
  • addDays, addWeeks, subtractDays e subtractWeeks ficaram mais rápidas com valores DateTime e DateTime64 em fusos horários de deslocamento fixo (como UTC), graças a um caminho rápido aritmético. #109836 (raimannma).
  • Vetorizada a descompressão do codec Delta. A decodificação agora é de 1,5 a 5 vezes mais rápida para tipos de dados de 8/16/32 bits, o que torna as varreduras de colunas comprimidas com Delta até 20% mais rápidas. #110189 (raimannma).
  • Aceleradas as funções de busca em strings (like, position, match, countSubstrings, hasToken etc.) em colunas Enum com agulha constante: a busca agora é feita apenas nos nomes distintos do enum, e os resultados são mapeados de volta para cada linha, em vez de se buscar em todas as linhas. #110325 (alexey-milovidov).
  • Melhorado em até 1,5x o desempenho das funções de busca de substring (position, countSubstrings, multiSearch*, replaceAll/replaceOne e suas variantes sem diferenciar maiúsculas de minúsculas e UTF-8) com um needle não constante, utilizando os buscadores de string baseados em SIMD no caminho por linha em vez de um fallback ingênuo. #110580 (Algunenano).
  • Melhorado o desempenho de squashing e merge de colunas Dynamic e Object com muitas variantes dinâmicas ou caminhos JSON. #110583 (cv4g).
  • estimateCompressionRatio mais rápido com o codec NONE #111107 (rienath).
  • Aceleradas a ordenação e outras operações baseadas em comparação em colunas JSON cujos caminhos são armazenados em shared data. Antes, cada comparação de valores materializava uma coluna Dynamic temporária e executava uma desserialização binária completa dos dois lados, deixando o ORDER BY nessas colunas extremamente lento. #111894 (groeneai).
  • A divisão de inteiros de 256 bits (Int256, UInt256 e Decimal256) agora calcula o quociente um limb de 64 bits por vez, usando um laço de divisões 128 / 64 quando o divisor cabe em 64 bits e o Algoritmo D de Knuth nos demais casos, em vez de um bit por vez com divisão longa por deslocamento e subtração. Isso afeta intDiv, modulo, a aritmética de Decimal256 e a conversão desses tipos para texto. #112477 (thevar1able).
  • A leitura de uma coluna Nested a partir de um tipo codificado em binário (Native, RowBinary com input_format_binary_decode_types_in_binary_format) não converte mais o tipo de volta em um nome de tipo para depois fazer o parsing novamente. Além disso, um nome de tipo Tuple aninhado malformado agora é reportado como erro de sintaxe, em vez de levar um tempo exponencial em relação à sua profundidade de aninhamento e falhar com TOO_SLOW_PARSING. #112560 (alexey-milovidov).
  • Aceleradas as consultas PromQL em tabelas TimeSeries: timeSeriesIdToGroup agora reutiliza o grupo da linha anterior quando linhas consecutivas têm o mesmo id de série, evitando a serialização do id e a busca em hash a cada linha. #113580 (nikitamikhaylov).

Outras melhorias de desempenho

  • Implementados um leitor e um escritor nativos para os formatos Arrow e ArrowStream que não usam a biblioteca Apache Arrow, evitando cópias e conversões de dados adicionais. Agora eles são o padrão (configurações input_format_arrow_use_native_reader e output_format_arrow_use_native_writer) e são mais rápidos tanto na leitura quanto na escrita. #106522 (alexey-milovidov).
  • Otimização de predicados nullIf(key, sentinel) = const para construir intervalos de chave e habilitar a poda por chave primária, por partição e por índice de exclusão. #107308 (adityaksolves).
  • O desempenho de `INTERSECT ALL` e `EXCEPT ALL` (o modo padrão de `INTERSECT` e `EXCEPT`) ficou várias vezes melhor, graças à indexação do multiconjunto pelo valor da linha em vez do cálculo do hash de cada linha com SipHash. #107649 (Algunenano).
  • As funções match, extract, extractAll, replaceRegexpOne e replaceRegexpAll ficaram mais rápidas para expressões regulares simples, que agora são compiladas para código nativo com LLVM. Esse comportamento é controlado pela nova configuração compile_regular_expressions (habilitada por padrão); padrões fora do subconjunto suportado recorrem de forma transparente ao mecanismo RE2. #108004 (alexey-milovidov).
  • A descompressão ZSTD em AArch64 (ARM) ficou mais rápida para colunas com pequenos deslocamentos de correspondência, como colunas de inteiros de largura fixa, graças à vetorização com NEON de cópias sobrepostas de deslocamento curto. Por exemplo, a descompressão de uma coluna UInt64 ficou até ~2,3x mais rápida no AWS Graviton 4. #108049 (alexey-milovidov).
  • A velocidade de descompressão LZ4 foi melhorada para colunas de tamanho fixo e baixa cardinalidade. #108175 (nickitat).
  • O desempenho de levenshteinDistance (e editDistance) foi melhorado para strings de comprimento médio em ARM, evitando alocações de heap por linha no caminho de código do algoritmo de Myers em blocos. #108185 (groeneai).
  • O parsing de números de ponto flutuante a partir de texto com precise_float_parsing = 1 ficou mais rápido, igualando ou superando o parser padrão em quase todas as entradas. Além disso, a biblioteca fast_float incluída foi atualizada para a v8.2.10. #108205 (Algunenano).
  • As funções de codificação e decodificação Base64 agora usam simdutf, o que melhora seu desempenho. #108333 (thevar1able).
  • Otimização de DISTINCT para chaves custosas de alta cardinalidade. #108366 (nihalzp).
  • O desempenho das funções matemáticas foi melhorado com a habilitação de otimizações do compilador que não preservam errno. #108628 (nickitat).
  • estimateCompressionRatio ficou mais rápido para colunas codificadas com T64, pois agora calcula o tamanho comprimido de forma analítica em vez de comprimir os dados. #109054 (rienath).
  • JOINs agora podem usar o índice de chave primária ou o índice de exclusão da tabela do lado esquerdo para podar grânulos #109085 (shankar-iyer).
  • Melhora o desempenho das funções geo H3 (h3ToGeoBoundary, h3ToGeo, h3CellAreaM2/h3CellAreaRads2, geoToH3) ao calcular seno e cosseno em conjunto e eliminar chamadas trigonométricas redundantes nas transformações de coordenadas. Os resultados permanecem inalterados (idênticos bit a bit). #109399 (alexey-milovidov).
  • Melhora em até 7 vezes o desempenho de comparações (<, >, <=, >=) de tipos inteiros largos (Int128, UInt128, Int256, UInt256 e tipos baseados neles, como Decimal128), bem como da conversão de inteiros com sinal para Int256 (até 7 vezes em dados com sinais mistos), ao tornar o código de comparação e de extensão de sinal livre de desvios (branchless). #109474 (raimannma).
  • Funções com um único argumento Nullable não constante agora compartilham o null map do argumento com o resultado, em vez de alocar e mesclar um novo. #110151 (raimannma).
  • Melhora em ~1,3-1,5x o desempenho das funções arrayMin e arrayMax sobre arrays numéricos, usando uma redução vetorizada em vez de um laço de comparação elemento a elemento. #110163 (raimannma).
  • Melhora o desempenho de DISTINCT quando o stream de entrada está ordenado por um prefixo das colunas do DISTINCT, por exemplo SELECT DISTINCT a, b FROM table ORDER BY a. Essas consultas ficam até 2,4 vezes mais rápidas. #110170 (nihalzp).
  • Caminhos de processamento em lote vetorizados para groupBitOr/groupBitAnd/groupBitXor e para a família de variância (varPop, varSamp, stddevPop, stddevSamp, skewPop, skewSamp, kurtPop, kurtSamp, covarPop, covarSamp, corr): até 4x mais rápidos com o combinador -If em condições imprevisíveis e até 3x mais rápidos para a família de variância sem ele. #110461 (raimannma).
  • Otimiza a análise do índice de texto. #110530 (CurtizJ).
  • Acelera o parsing de valores UUID a partir de texto (por exemplo, JSONExtract para LowCardinality(UUID), toUUID, CAST AS UUID) ao validar e converter dígitos hexadecimais em uma única passagem, em vez de duas. #110625 (groeneai).
  • Acelera a descompressão ZSTD em x86_64 para colunas com offsets de correspondência pequenos, como colunas de inteiros de largura fixa, vetorizando cópias sobrepostas de offset curto com SSSE3 pshufb (a contraparte x86_64 da otimização NEON para AArch64 de #108049). #110909 (thevar1able).
  • Acelera groupUniqArray para tipos numéricos em até 3x ao usar hashing CRC32 (como em uniqExact) e fazer o inline da inserção por linha. #110917 (raimannma).
  • Melhora a eficiência das estatísticas minmax e básicas de colunas de ponto flutuante. #111221 (cv4g).
  • Responde a consultas COUNT() diretamente a partir dos metadados de cardinalidade do índice de texto. #111494 (ahmadov).
  • Acelera min e max em tipos de 128 e 256 bits (Int128, UInt128, Int256, UInt256, Decimal128, Decimal256). Até 1,8x mais rápido para inteiros largos e até 3,4x mais rápido para decimais largos. #111965 (raimannma).
  • Corrige uma regressão de desempenho na ingestão de system.query_log. A construção das colunas map Settings e asynchronous_read_counters estava cerca de 6 vezes mais lenta do que antes, o que podia fazer com que SYSTEM FLUSH LOGS query_log excedesse seu tempo limite de 180 segundos em servidores que registram muitas consultas com muitas configurações alteradas. #112210 (groeneai).
  • Adiciona cache opcional para tokens ausentes nos índices de texto. #112742 (rorylshanks).
  • O logging assíncrono agora usa uma fila limitada lock-free: as threads que escrevem mensagens de log nunca ficam bloqueadas em um mutex nem acordam as threads de logging. #112803 (alexey-milovidov).
  • Usa o índice da chave primária para pointInPolygon quando o argumento de ponto é uma coluna-chave inteira do tipo Point (ou outra Tuple de dois elementos numéricos), por exemplo, pointInPolygon(coord, [...]) para uma tabela ordenada por coord. Antes, apenas a forma pointInPolygon((x, y), [...]) com duas colunas-chave escalares era analisada. #112956 (alexey-milovidov).
  • text_index_posting_list_apply_mode agora tem lazy como padrão, de modo que as consultas que usam índice de texto decodificam as listas de postings sob demanda, na granularidade de blocos empacotados e com um cursor, em vez de materializá-las antecipadamente em bitmaps para índices de texto com posting_list_codec definido. #113521 (CurtizJ).
  • Acelera as transformações vetorizadas de tags de TimeSeries, substituindo o remapeamento baseado em hash por indexação direta quando os IDs de grupos de tags ocupam um intervalo compacto. #114244 (fallintoplace).
  • Melhora o desempenho de merges de índices de texto. #114525 (CurtizJ).
  • Usa máscaras de presença compactas para operadores de conjunto do PromQL. #115224 (fallintoplace).
  • Ao anexar as tabelas de sistema, os metadados de cada tabela, incluindo a descrição completa das colunas, não são mais copiados duas vezes apenas para definir o comentário da tabela. #115490 (thevar1able).
  • Acelera as verificações de séries duplicadas para vetores de condição do PromQL compostos apenas por zeros. #115822 (fallintoplace).
  • Acelera toUTCTimestamp/to_utc_timestamp e fromUTCTimestamp/from_utc_timestamp em argumentos DateTime64, restaurando a vazão que tinham após correções anteriores de overflow. Os resultados permanecem inalterados. #115838 (groeneai).
  • Redução do custo fixo de inicialização da geração de dados aleatórios (rand, rand64, randomString, randomFixedString, generateUUIDv4, generateUUIDv7) em x86-64. A melhoria é perceptível quando os blocos são pequenos; os valores gerados permanecem inalterados. #116158 (Algunenano).
  • Agora é possível habilitar a simplificação antecipada por curto-circuito para and e or nativos durante a análise, por meio da configuração enable_function_early_short_circuit. Isso permite pular a execução de subconsultas escalares count() de linha única inalcançáveis, preservando a inferência de tipos normal e a validação semântica. #83505 (fhw12345).
  • Uso de uma única chamada de E/S de buffer para vetores trivialmente serializáveis #89842 (Ergus).
  • optimize_or_like_chain passa a ser habilitado por padrão. #94517 (alexey-milovidov).
  • Melhoria no desempenho da obtenção de um único registro de usuário em system.users quando o servidor possui muitos usuários. #96699 (alistairjevans).

Melhorias

Melhorias em consultas e SQL

  • CTEs materializadas referenciadas em múltiplos ramos de uma consulta UNION agora são materializadas uma única vez e compartilhadas entre todos os ramos. Antes, cada ramo recebia sua própria cópia da CTE, que era expandida inline e avaliada separadamente. #102107 (novikd).
  • O filtro de tempo de execução de JOIN passa a ser ignorado quando o lado de sondagem (probe) é estimado como pequeno. A nova configuração join_runtime_filter_min_probe_rows (padrão 1000) controla o limite #104860 (vdimir).
  • EXPLAIN [PLAN] actions=1, compact=1, pretty=1 passa a ser o padrão. #105036 (Fgrtue).
  • Redução da latência de cancelamento nas formas positivas de LIMIT BY (LimitByTransform, LimitBySortedStreamTransform): KILL QUERY e Ctrl+C agora interrompem o processamento dentro de um único bloco, em vez de aguardar a conclusão de toda a etapa. #106070 (rvasin).
  • Consultas com JOIN agora são suportadas com réplicas paralelas automáticas. #106073 (nickitat).
  • Adiciona uma nova métrica assíncrona UntrackedMemory (visível em system.asynchronous_metrics) que informa a memória já alocada por threads, mas ainda não contabilizada no contador global de rastreamento de memória. Cada thread acumula pequenas alocações localmente e as informa em lote. Isso ajuda a explicar discrepâncias entre MemoryTracking e o uso real de memória do processo. As mensagens de erro MEMORY_LIMIT_EXCEEDED agora também incluem a quantidade de memória não rastreada, facilitando entender por que uma consulta ou o servidor atingiu o limite de memória. #106386 (mstetsyuk).
  • Quando um INSERT falha porque a tabela de destino TO de uma visão materializada rejeita a escrita durante a construção do pipeline de insert (por exemplo, quando o destino é uma View ou não oferece suporte a transações), a mensagem de erro agora indica o nome da visão materializada e de sua tabela de destino, em vez de exibir apenas o erro bruto de armazenamento. #107234 (groeneai).
  • ALTER TABLE ... MODIFY COLUMN <col> Tuple(...) em uma Tuple nomeada agora altera apenas metadados quando somente subcampos são adicionados, com a mesma velocidade de um ADD COLUMN no nível superior. Disponível mediante SET allow_metadata_only_named_tuple_alter = 1. #107305 (amosbird).
  • Adicionada a configuração materialized_postgresql_use_extended_date_and_time_types, definida no momento da criação, para o motor de banco de dados MaterializedPostgreSQL. Por padrão (habilitada), colunas PostgreSQL date/timestamp são inferidas como Date32/DateTime64; defini-la como 0 no CREATE DATABASE faz com que sejam inferidos os tipos mais restritos Date/DateTime. A configuração não se aplica ao motor de tabela MaterializedPostgreSQL. #107428 (alexey-milovidov).
  • EXPLAIN PLAN agora marca as linhas de resultado estimadas de uma junção como aproximadas (~~...) quando a estimativa vem de uma dica ou de um fallback aleatório, e não de estatísticas da tabela, ajudando a identificar planos sem estatísticas confiáveis para a reordenação de junções baseada em custo. #107666 (vdimir).
  • INSERT em uma tabela MergeTree agora respeita o cancelamento da consulta e max_execution_time durante a escrita de muitas partes, em vez de possivelmente continuar em execução por muito tempo após ser encerrado. #107929 (al13n321).
  • arrayFold agora respeita o cancelamento de consultas e max_execution_time. Antes, um fold sobre um array muito longo (por exemplo, arrayFold(acc, x -> arrayPushFront(acc, x), range(number), emptyArrayUInt64())) executava todo o fold dentro de uma única chamada de função e não podia ser interrompido, de modo que KILL QUERY e os limites de tempo eram ignorados até o fold terminar. #108192 (groeneai).
  • Adicionados ProfileEvents para cada fase da pré-execução da consulta: QueryParseMicroseconds, QueryAnalysisMicroseconds, QueryPlanBuildMicroseconds e QueryPipelineBuildMicroseconds. Eles mostram onde o tempo é gasto antes da execução da consulta (parsing, análise, construção do plano de consulta e construção do pipeline) e estão disponíveis em system.query_log e system.events. #108282 (jrdi).
  • Operações ALTER TABLE que gerariam metadados de tabela maiores que max_query_size agora são rejeitadas de antemão, evitando que as tabelas não possam mais ser carregadas por componentes como a distribuição de DDL e a recuperação de réplicas. #108283 (lockie).
  • Adicionado ConstantJoin para junções cartesianas e junções com predicado constante planejadas pelo analisador, de modo que essas consultas não falham mais devido a uma configuração join_algorithm incompatível quando o analisador é usado. #108289 (antaljanosbenjamin).
  • Adicionada a coluna source a system.documentation, contendo o caminho do arquivo-fonte em que a documentação de cada entidade é definida. A tabela agora também documenta codecs de compressão, eventos de perfil, métricas atuais, métricas assíncronas e as próprias tabelas de sistema (com suas colunas), e a documentação das configurações passa a incluir o tipo e o valor default. #108346 (alexey-milovidov).
  • Se você fornecer filtros table e database no WHERE, system.iceberg_history listará apenas os bancos de dados correspondentes. Isso pode economizar tempo quando há muitos bancos de dados remotos não relacionados no servidor. #108492 (Diskein).
  • Parâmetros de consulta (substituições {name:Type}) agora podem ser usados como valores de configuração, tanto na cláusula SETTINGS de uma consulta (como SELECT ou INSERT) quanto em consultas SET independentes, por exemplo, SELECT ... SETTINGS max_threads = {threads:UInt64} e SET max_threads = {threads:UInt64}. #108760 (alexey-milovidov).
  • Permite calcular o benefício combinado dos índices de salto no EXPLAIN WHATIF. O resultado mostra a razão de dados, que corresponde à interseção do desempenho de todos os índices hipotéticos adequados existentes. #108934 (yariks5s).
  • Uma consulta com uma única CTE agora é formatada com a mesma quebra de linha e indentação de uma consulta com várias CTEs. Antes, WITH a AS (...) mantinha a CTE na mesma linha que WITH, enquanto duas ou mais CTEs colocavam WITH em uma linha própria, com cada CTE indentada. #109092 (groeneai).
  • Suporte ao Query Condition Cache para arquivos Parquet locais lidos pelo mecanismo de tabela File (antes, era suportado apenas para armazenamento de objetos e data lakes). #109247 (alexey-milovidov).
  • O Query Condition Cache para arquivos Parquet remotos (em armazenamento de objetos) agora usa o ETag como chave, além do caminho, para que a sobrescrita de um objeto no mesmo local não retorne mais resultados desatualizados do cache. #109310 (alexey-milovidov).
  • Uma referência não qualificada a uma chave de INNER JOIN igualada na condição ON (por exemplo, SELECT id FROM a INNER JOIN b ON a.id = b.id) não é mais reportada como identificador ambíguo, já que ambos os lados certamente contêm o mesmo valor. #109366 (alexey-milovidov).
  • As funções de distância transpostas sobre QBit (L2DistanceTransposed, cosineDistanceTransposed, dotProductTransposed e suas contrapartes quantizadas L2DistanceTransposedQuantized, cosineDistanceTransposedQuantized, dotProductTransposedQuantized) agora aceitam um vetor de referência mais longo que o número de dimensões pesquisadas, ignorando os elementos excedentes no final. Isso permite reutilizar um vetor de consulta de tamanho completo em uma busca com dimensões reduzidas (Matryoshka) sem precisar fatiá-lo antes. #109388 (alexey-milovidov).
  • Adicionada uma verificação de sanidade para garantir que uma consulta distribuída sempre carregue uma versão de cliente conhecida, lançando um erro lógico em vez de encaminhar silenciosamente uma versão zero para os shards remotos. Consultas iniciadas pelo servidor (flushes em segundo plano, consumidores de streaming, recarregamentos de dicionários, flushes de inserção assíncrona) agora informam a própria versão do servidor como versão do iniciador. #109408 (alexey-milovidov).
  • Este patch corrige o uso de nomes de coluna qualificados na cláusula WHERE de operações de mutação em tabelas com motores da família MergeTree. #109491 (Michicosun).
  • Adicionado suporte a funções de janela não particionadas (OVER (ORDER BY ...)) em planos de consulta distribuída (make_distributed_plan). Antes, qualquer consulta com função de janela falhava porque WindowStep não podia ser serializado para execução remota; janelas com PARTITION BY continuam sendo rejeitadas por enquanto. #109802 (VighneshPath).
  • Agora é possível alterar algumas configurações de autenticação do catálogo one-lake com ALTER DATABASE ... MODIFY SETTING = 'xxx'. #110019 (alesapin).
  • Uma subconsulta no lado direito de IN cuja única coluna é um array com uma dimensão a mais que o argumento esquerdo agora é interpretada como o conjunto dos elementos do array (como um literal de array ou uma função que retorna array), em vez de falhar com um erro confuso de incompatibilidade de tipos. Por exemplo, x IN (SELECT groupArray(x) FROM ...) agora funciona. #110169 (alexey-milovidov).
  • Consultas aceleradas por filtragem dinâmica TopK (ORDER BY ... LIMIT k) agora aproveitam melhor o cache de condições de consulta: o cache é preenchido mesmo quando a materialização tardia é aplicada, e essas consultas podem reutilizar entradas gravadas anteriormente por uma consulta comum com o mesmo predicado WHERE. #110507 (shankar-iyer).
  • SHOW CREATE TABLE (e SHOW CREATE VIEW / SHOW CREATE DICTIONARY) agora sugere uma tabela com nome semelhante na mensagem de erro quando a tabela solicitada não existe, assim como já acontece com consultas SELECT. #110633 (alexey-milovidov).
  • Adicionado o modificador STREAM BOUNDED, que lê apenas o primeiro snapshot de uma consulta em streaming e depois termina, em vez de se inscrever para receber atualizações. #110653 (SmitaRKulkarni).
  • Corrige o cache de resultados de consultas PromQL. O dialeto promql ignorava a verificação de funções não determinísticas e podia retornar resultados desatualizados ancorados em now(); já a Prometheus HTTP API (/api/v1/query, /api/v1/query_range) simplesmente nunca armazenava entradas no cache. #110887 (nikitamikhaylov).
  • EXPLAIN ANALYZE agora informa, para cada lado do join, a contagem de linhas, as taxas de correspondência, o fanout e o estado específico do algoritmo, como a memória da tabela hash e o spilling. Use matches = 1 para coletar métricas de correspondência que exigem controle adicional. #110892 (Fgrtue).
  • Corrigido um heap-use-after-free no executor de pipeline, encontrado pelo AST fuzzer, que podia derrubar o servidor quando uma consulta remove processadores em tempo de execução (por exemplo, FINAL com leituras lazy ou ordenação externa). #111017 (groeneai).
  • Corrige um use-after-free (falha de segmentação) quando uma consulta com snapshot de armazenamento compartilhado (configuração enable_shared_storage_snapshot_in_query) remove partes de dados do snapshot — por exemplo, uma subconsulta de streaming que lê a mesma tabela MergeTree que outra parte da consulta lê simultaneamente. #111192 (alexey-milovidov).
  • Adicionado suporte a planos de consulta distribuída (make_distributed_plan) para consultas cuja origem comprovadamente não produz linhas no momento do planejamento, como a leitura de uma tabela MergeTree vazia. Antes, essas consultas falhavam com SUPPORT_IS_DISABLED. #111941 (groeneai).
  • Corrigido o problema em que o query condition cache não era preenchido para granules eliminados por qualquer conjunção, exceto a última, de uma cláusula WHERE com múltiplas condições AND. #112083 (shankar-iyer).
  • Reduzido o pico de memória ao gravar colunas JSON com serialização de dados compartilhados em buckets (map_with_buckets e advanced): os dados compartilhados agora são divididos em buckets um de cada vez durante a gravação, em vez de todos os buckets serem materializados simultaneamente. O ganho é maior para colunas Array(JSON): no JSON escalar, os dados compartilhados são divididos por granule (limitados por index_granularity_bytes), então a economia é pequena; já um único granule de Array(JSON) pode conter muitas linhas aninhadas e, portanto, uma grande quantidade de dados compartilhados, e nesse caso a divisão de um bucket por vez reduz significativamente o pico de memória #112172 (Avogar).
  • O agendamento de reserva de memória (experimental) não remove mais uma alocação quando uma liberação de memória pendente já liberaria o espaço necessário para um aumento de reserva acima do limite: a decisão de remoção agora aguarda a aplicação das reduções em andamento, evitando que consultas sejam encerradas sem necessidade sob pressão de memória. #112299 (serxa).
  • SYSTEM DROP FILESYSTEM CACHE agora remove as chaves de metadados do cache em paralelo, acelerando a limpeza de grandes caches do sistema de arquivos. A nova configuração drop_cache_threads do cache de arquivos controla o número de workers de remoção e tem valor padrão 16; com o valor 1, a remoção é feita na própria thread da consulta. #112532 (kssenii).
  • Os modificadores de uma declaração de coluna - COMMENT, CODEC, STATISTICS, TTL, COLLATE, PRIMARY KEY e SETTINGS por coluna - agora podem ser escritos em qualquer ordem em CREATE TABLE, cada um deles no máximo uma vez. Antes, apenas uma ordem fixa era aceita e, por exemplo, x UInt64 CODEC(ZSTD) COMMENT 'text' gerava um erro de sintaxe. Em ALTER TABLE ... ADD COLUMN / MODIFY COLUMN, os modificadores compatíveis - COMMENT, CODEC, STATISTICS, TTL e SETTINGS por coluna - também podem ser escritos em qualquer ordem; SETTINGS por coluna em ADD COLUMN e um STATISTICS declarado em ADD COLUMN / MODIFY COLUMN agora são aplicados em vez de serem descartados silenciosamente, e COLLATE e PRIMARY KEY nesses comandos ALTER agora lançam uma exceção em vez de serem ignorados silenciosamente. #112788 (alexey-milovidov).
  • Uma consulta sobre uma tabela Merge (ou a função de tabela merge) que corresponde a muitas tabelas agora responde a KILL QUERY e max_execution_time enquanto os planos de consulta de cada tabela estão sendo construídos, e não apenas depois que o planejamento de todas as tabelas filhas termina. #113415 (alexey-milovidov).
  • Um SELECT de uma tabela Merge que excede max_execution_time com timeout_overflow_mode = 'break' agora interrompe a construção dos planos de consulta para as tabelas correspondentes restantes, em vez de executar a análise completa da consulta para cada tabela correspondente antes de parar. A consulta continua terminando sem erro, conforme documentado para esse modo. #113642 (groeneai).
  • Quando o tipo declarado de uma coluna e seus dados divergem durante uma leitura de MergeTree (procedência de tipos mista, por exemplo, após um ALTER TABLE ... MODIFY COLUMN cuja mutação ainda não terminou), o servidor agora reporta uma exceção clara indicando a coluna e ambas as estruturas, em vez de realizar um cast não verificado: antes, compilações de depuração e com sanitizers abortavam com um simples Bad cast from type A to B, sem indicar nenhuma coluna, e compilações de release percorriam silenciosamente memória incompatível. #114087 (alexey-milovidov).
  • ie_join passou a ser habilitado por padrão: o valor padrão de join_algorithm agora é direct,parallel_hash,hash,ie_join. Um JOIN cuja seção ON contém apenas condições de desigualdade (duas comparações <, <=, >, >= entre expressões das tabelas unidas) agora é executado com o algoritmo IEJoin baseado em ordenação, em vez de um CROSS JOIN com filtro, e junções LEFT/RIGHT/FULL/SEMI/ANTI com essas condições passam a ser compatíveis. Como ie_join é o último da lista, ele só é usado quando os outros algoritmos não se aplicam. #114327 (vdimir).
  • O contexto de rastreamento do OpenTelemetry agora é propagado para as fibers usadas no estabelecimento assíncrono de conexões e na execução remota de consultas (hedged requests, async_socket_for_remote, async_query_sending_for_remote). Os spans de consultas remotas em uma consulta distribuída agora são corretamente vinculados como filhos do span Connection::sendQuery do iniciador, em vez de serem anexados diretamente ao contexto de rastreamento fornecido pelo cliente, e cada execução de tarefa assíncrona gera seu próprio span. #114813 (diegomestre2).
  • DROP DATABASE agora remove as tabelas em ordem topológica reversa, considerando tanto as dependências de carregamento quanto as referenciais (antes, apenas as de carregamento), de modo que uma falha no meio de um DROP DATABASE não deixe uma tabela cujas dependências já foram removidas. #114952 (alexey-milovidov).
  • Suporte a operadores de correspondência de expressão regular no estilo do PostgreSQL: ~ (um alias para a função match), ~* (correspondência sem diferenciar maiúsculas de minúsculas), !~ e !~* (negações). Os comandos \d, \dt e \dv do psql agora funcionam quando conectados ao ClickHouse pelo protocolo de compatibilidade com PostgreSQL, e uma consulta com falha não encerra mais a conexão. #115066 (alexey-milovidov).
  • EXPLAIN WHATIF agora informa por que a estimativa empírica foi ignorada, em uma nova linha empirical_reason exibida quando empirical_status é unsupported. #115140 (yariks5s).
  • Quando nenhum algoritmo de junção habilitado pela configuração join_algorithm consegue executar um JOIN, a mensagem de erro agora informa os algoritmos tentados, além da rigidez e do tipo do JOIN que falhou, em vez de apenas indicar que nenhum deles funcionou. #115226 (elkinal).
  • Consultas de busca vetorial agora podem usar o índice de similaridade vetorial quando o vetor de referência é um literal de array de inteiros, por exemplo, ORDER BY L2Distance(vec, [1, 2]). Antes, essas consultas recorriam silenciosamente a uma varredura por força bruta. #115255 (rschu1ze).
  • BACKUP não deixa mais um arquivo de bloqueio no destino quando a tentativa que o criou falha antes de gravar qualquer coisa — seja ao reivindicar o destino, seja ao abrir um arquivo compactado. Como nenhum backup posterior conseguia corresponder a esse bloqueio, todas as novas tentativas para o mesmo destino falhavam até que o arquivo fosse excluído manualmente. Backups para destinos S3 e Azure também passam a criar o bloqueio de forma exclusiva, e um bloqueio pertencente a outro backup é reportado como um backup concorrente, e não como qualquer erro que o armazenamento tenha retornado. #115387 (jkartseva).
  • Um trace iniciado por amostragem (opentelemetry_start_trace_probability) agora é registrado nas informações de cliente da consulta, de modo que consultas secundárias remotas e distribuídas, bem como entradas de DDL, passem a integrar o mesmo trace em vez de iniciar traces separados. #115619 (diegomestre2).
  • Corrigido o CREATE TABLE para tabelas Iceberg baseadas no Amazon S3 Tables, que gerencia por conta própria as localizações das tabelas. #115652 (scanhex12).
  • A agregação adaptativa de GROUP BY (enable_adaptive_aggregator) agora avalia se vale a pena adiar chaves raras e volta ao algoritmo comum quando as chaves ou os argumentos de agregação são largos demais para que a cópia compense, de modo que agregações sobre colunas de string pesadas (por exemplo, min(URL) por usuário) são executadas com a mesma velocidade e consumo de memória do algoritmo comum. Adiciona adaptive_aggregator_freeze_threshold_bytes para limitar em bytes a tabela congelada de cada thread (a tabela é congelada pelo que for atingido primeiro: esse limiar ou o limiar de quantidade de chaves). #115755 (nihalzp).
  • Adiciona a configuração query_plan_aggregation_bucket_top_k (habilitada por padrão) para ativar ou desativar a otimização de plano que materializa apenas os n melhores grupos de cada bucket de dois níveis quando uma agregação final alimenta um ORDER BY sobre suas saídas com LIMIT n. A otimização agora também aparece na saída do EXPLAIN. #116124 (nihalzp).
  • Melhora o suporte a consultas DESCRIBE para visões parametrizadas. Adiciona suporte a visões parametrizadas em expressões escalares no novo analisador. #68978 (novikd).
  • Consultas como SELECT * FROM t WHERE id agora usarão o salto de índice (index skipping) na coluna id. #89603 (adityachopra29).
  • Adicionada a configuração query_plan_merge_expression_into_join, que permite mesclar etapas Expression em etapas JOIN durante a otimização de reordenação de junções. Com isso, a reordenação de junções passa a funcionar também em subconsultas que encapsulam junções (por exemplo, quando um JOIN está dentro de uma subconsulta com colunas calculadas), o que resulta em uma otimização melhor de árvores de junção complexas. #98533 (vdimir).
  • Adicionada a coluna is_wildcard à tabela system.grants, que indica se uma concessão usa correspondência de prefixo com wildcard (por exemplo, GRANT SELECT ON db*.*). Antes, não era possível distinguir em system.grants concessões com wildcard de concessões exatas sobre o mesmo nome. #98577 (il9ue).

Funções e tipos de dados

  • Adicionada uma nova configuração allow_lossy_numeric_supertype (desabilitada por padrão). Quando habilitada, if, multiIf, coalesce, ifNull, array e map aplicados a argumentos numéricos que não têm um tipo em comum sem perdas (por exemplo, um Decimal e um Float64, ou um Int64 e um Float64) passam a ser resolvidos para o supertipo numérico Float64 em vez de um Variant, permitindo que o resultado seja usado com funções de agregação como sum, avg, min e max. O nome da configuração agora é mencionado nas mensagens de erro correspondentes das funções de agregação. #107236 (groeneai).
  • O quantificador de array SOME / ALL (expr OP SOME(array) / expr OP ALL(array)) agora também oferece suporte aos predicados de comparação por palavra-chave IS DISTINCT FROM e IS NOT DISTINCT FROM, e aos predicados de busca em strings LIKE, ILIKE, NOT LIKE, NOT ILIKE e REGEXP, que são reescritos como arrayExists / arrayAll. #107454 (alexey-milovidov).
  • Adicionada a configuração input_format_json_max_object_size para limitar o tamanho de objetos JSON durante o parsing. #107669 (Avogar).
  • Corrigido um vazamento de memória que ocorria quando falhava a abertura de um banco de dados SQLite (por exemplo, quando a função de tabela sqlite ou o motor de banco de dados SQLite recebia um caminho que não podia ser aberto). #107807 (alexey-milovidov).
  • Adicionado suporte à função length para o tipo de dados QBit. Ela retorna a dimensão do vetor como uma constante. #108071 (alexey-milovidov).
  • Adicionado suporte a CAST de um QBit para um Array, reconstruindo o vetor original. Trata-se da operação inversa da conversão já existente de Array para QBit. #108072 (alexey-milovidov).
  • O motor de banco de dados, o motor de tabela e a função de tabela MySQL agora mapeiam os tipos de coluna espaciais do MySQL (LINESTRING, POLYGON, MULTILINESTRING, MULTIPOLYGON e o genérico GEOMETRY) para os tipos geométricos correspondentes do ClickHouse, em vez de String. Esse comportamento é controlado pela nova flag geometry da configuração mysql_datatypes_support_level, habilitada por padrão. POINT continua sendo sempre convertido para Point. A coluna genérica GEOMETRY é mapeada para o tipo abrangente Geometry; a leitura de um valor cujo subtipo não tem equivalente no ClickHouse (MULTIPOINT, GEOMETRYCOLLECTION) lança uma exceção no momento da leitura. #108944 (alexey-milovidov).
  • Passa a usar por padrão o algoritmo preciso (valor representável mais próximo) de parsing de números de ponto flutuante e aplica a configuração precise_float_parsing aos formatos de entrada (CSV, TSV, JSON, VALUES, …) e a literais numéricos, não apenas a toFloat*/CAST. Defina precise_float_parsing = 0 para restaurar o comportamento anterior, mais rápido em alguns casos, porém menos preciso. #109086 (Algunenano).
  • Adicionado suporte a reinterpret de um Array de elementos de tamanho fixo como String, a operação inversa do reinterpret já existente de String/FixedString como Array. #109383 (alexey-milovidov).
  • Permite CAST entre tipos QBit que diferem no tipo de elemento e/ou no stride, desde que a dimensão permaneça a mesma (por exemplo, CAST(x AS QBit(Float64, N)) a partir de um QBit(Float32, N)). Alterações apenas no stride não causam perda de dados; alterações no tipo de elemento seguem a semântica de conversão correspondente de Array (por exemplo, a conversão de Float32 para BFloat16 pode perder precisão, e accurateCast / accurateCastOrNull rejeitam linhas que não sejam exatamente representáveis). #109387 (alexey-milovidov).
  • As funções quantizeBFloat16ToInt8 e dequantizeInt8ToBFloat16 agora também aceitam argumentos Array e QBit, aplicando o codec Lloyd-Max ao vetor inteiro (e retornando Array/QBit do tipo de elemento correspondente), além das sobrecargas escalares já existentes. #109398 (alexey-milovidov).
  • O especificador de formato %f no estilo MySQL em parseDateTime / parseDateTime64 (e em suas variantes OrZero / OrNull) agora aceita de 1 a 6 dígitos fracionários, interpretados como microssegundos alinhados à esquerda, como no STR_TO_DATE do MySQL, em vez de exigir exatamente 6. Também foram corrigidas tabelas PrettyCompact desalinhadas nos exemplos da documentação das funções integradas. #109421 (alexey-milovidov).
  • A subestatística NullCount das estatísticas basic foi renomeada para DefaultCount: em vez de contar linhas NULL de uma coluna Nullable, build agora conta as linhas iguais ao valor padrão intrínseco do tipo da coluna por meio de IColumn::getNumberOfDefaultRows. #109977 (hanfei1991).
  • O tamanho do binário foi reduzido em cerca de 10,5 MB ao executar operações de comparação e aritméticas em pares de tipos mistos raramente usados (Decimal vs. inteiro de largura diferente, e pares envolvendo Int128/UInt128/Int256/UInt256) por meio de uma conversão para um tipo em comum, em vez de usar um kernel compilado dedicado para cada combinação de tipos. Pares do mesmo tipo, pares de uso comum e as operações plus/minus/multiply, limitadas por memória, mantêm seus kernels dedicados; resultados, tipos de resultado e casos excepcionais permanecem inalterados. #110131 (alexey-milovidov).
  • A leitura a partir do motor de tabela SQLite ou da função de tabela sqlite não ocupa mais um núcleo de CPU inteiro em espera ativa quando o banco de dados SQLite está bloqueado por outra conexão. Agora, a leitura fica ociosa enquanto aguarda a liberação do bloqueio e continua podendo ser cancelada. #110248 (groeneai).
  • Os valores de tempo decorrido, taxa e razão em mensagens de log e de exceção agora são arredondados para três dígitos, de modo que números como 1.345844286 sec. deixam de ser exibidos com precisão total. #110277 (alexey-milovidov).
  • Corrigidas as leituras do MergeTree em colunas String com um stream de tamanho separado quando as linhas iniciais são puladas, o que podia retornar dados incorretos ou ler além dos limites a partir do cache de substreams. Também foi corrigida a possibilidade de dados incorretos quando leituras concorrentes ou repetidas acessam um subobjeto JSON armazenado com serialização shared-data em mapa. #110471 (alexey-milovidov).
  • Adicionado suporte à cláusula SETTINGS para o motor de tabela PostgreSQL e a função de tabela postgresql (por exemplo, SETTINGS postgresql_connection_pool_size = 50), alcançando paridade de recursos com o motor MySQL. #110614 (alexey-milovidov).
  • As funções bitmaskToArray e bitmaskToList agora aceitam argumentos (U)Int128 e (U)Int256. A função bitPositionsToArray agora é executada em tempo proporcional ao número de bits definidos para argumentos inteiros grandes, e não mais à posição do bit definido mais alto. #110743 (raimannma).
  • Corrigido o tratamento, pelo codec GCD, de valores de largura fixa com sinal que contêm números negativos. Antes, o divisor era calculado diretamente a partir dos valores com sinal, o que podia impedir a identificação do divisor comum e reduzir significativamente a eficiência de compressão em colunas de inteiros e decimais com sinal. Agora, para tipos com sinal, o divisor é calculado a partir das magnitudes, preservando o comportamento existente para tipos sem sinal e para a descompressão. #113798 (kshcherbatov).
  • Funções de janela com PARTITION BY agora funcionam com make_distributed_plan. Quando a estrutura do plano permite, a janela é executada em paralelo entre buckets, cada um recebendo partições completas. #114111 (VighneshPath).
  • Agora é usada uma função de hash de 64 bits nos métodos de agregação externos de largura fixa com valores nullable (o que evita colisões catastróficas em agregações de cardinalidade muito alta). #114210 (nickitat).
  • x IN (subquery) sobre uma coluna LowCardinality agora retorna LowCardinality(UInt8) — o mesmo tipo que x IN (literal list). Antes, as duas formas retornavam tipos diferentes, e planos distribuídos com esse tipo de IN exigiam um caso especial na verificação de tipos do plano. #114229 (davenger).
  • Adicionado suporte à análise de inteiros que excedem o intervalo de 64 bits no tipo de dado JSON, em JSONExtract e em isValidJSON. Esses valores agora são lidos em tipos inteiros largos, como Int128/UInt256, em vez de causar a rejeição do documento inteiro. #114379 (Avogar).
  • Adicionado keyword como alias para o tokenizador de índice de texto array, para melhorar a compatibilidade com OpenSearch, Elasticsearch, SolR e Lucene. #115507 (rschu1ze).
  • As funções toDateOrNull, toDateTimeOrNull e toDateTime64OrNull agora aceitam argumentos de todos os tipos inteiros nativos (interpretados da mesma forma que em toDate, toDateTime e toDateTime64, com um argumento opcional de fuso horário) e retornam NULL para valores fora do intervalo do tipo de resultado. Por exemplo, toDateTimeOrNull(1583851242, 'Asia/Shanghai') retorna 2020-03-10 22:40:42 e toDateTimeOrNull(4294967296) retorna NULL. #79791 (jitendra1411).

Armazenamento, lagos de dados e armazenamento de objetos

  • Adicionadas métricas opcionais do Prometheus para a atividade de evicção do cache do sistema de arquivos (filesystem_cache_evictions_total, filesystem_cache_evicted_bytes_total, filesystem_cache_evicted_segment_hits, filesystem_cache_evicted_segment_size_bytes e suas variantes por usuário rotuladas com user_id), expostas por cache via system.dimensional_metrics, system.histogram_metrics e o endpoint do Prometheus. Elas são controladas pelas configurações de disco do cache expose_prometheus_eviction_metrics e expose_prometheus_eviction_metrics_per_user (ambas desativadas por padrão), que podem ser ativadas ou desativadas em tempo de execução via SYSTEM RELOAD CONFIG. #105020 (sacheendra).
  • O motor Alias agora oferece suporte à leitura com réplicas paralelas quando a tabela de destino usa um motor da família MergeTree. #107830 (nauu).
  • Limitado a max_inflight_parts_for_one_file o número de partes preparadas simultaneamente na cópia por leitura e escrita do Azure Blob Storage (usada por backups quando a cópia nativa não está disponível), evitando uso excessivo de memória quando muitos arquivos grandes são copiados em paralelo. #108232 (SmitaRKulkarni).
  • Suporte à coluna virtual _etag para o armazenamento HDFS #108255 (zhangyifan27).
  • Adicionadas as colunas settings e engine_settings a system.backups e system.backup_log. settings expõe as configurações específicas de backup/restauração solicitadas para uma operação (por exemplo, allow_s3_native_copy, deduplicate_files, structure_only), e engine_settings expõe as configurações efetivamente usadas pelo leitor/gravador do motor de backup (por exemplo, as configurações de requisição do S3, como allow_native_copy, que podem diferir do que foi solicitado após a mesclagem com a configuração do endpoint). Com isso, é possível ver com quais configurações uma operação BACKUP/RESTORE foi de fato executada. #108334 (jkartseva).
  • Adicionadas system.s3_queue_metadata e system.azure_queue_metadata para inspecionar o estado no Keeper das tabelas S3Queue e AzureQueue registradas, incluindo as contagens de arquivos processados, em processamento e com falha. #108522 (kssenii).
  • Reduzido em 2 a 2,5 vezes o uso de memória do cache de cabeçalhos de índice de texto. Agora cabem mais cabeçalhos de partes de dados no cache (configuração text_index_header_cache_size), o que reduz as leituras de disco em consultas de busca textual. #109332 (CurtizJ).
  • Adicionadas colunas de compatibilidade com MySQL às views do INFORMATION_SCHEMA: SCHEMATA.DEFAULT_COLLATION_NAME e DEFAULT_ENCRYPTION; TABLES.ENGINE e colunas MySQL relacionadas; e COLUMNS.COLUMN_KEY, PRIVILEGES, GENERATION_EXPRESSION, SRS_ID. Isso permite que clientes compatíveis com MySQL executem suas consultas de introspecção de catálogo sem esbarrar em UNKNOWN_IDENTIFIER. #109351 (alexey-milovidov).
  • Reduzido o uso de memória de tabelas MergeTree com muitas partes de dados, compartilhando entre as partes de uma tabela os metadados por parte derivados do schema (lista de colunas, descrições de colunas, serializações e subfluxos de colunas), em vez de copiá-los para cada parte. O efeito é maior em tabelas largas com muitas partes pequenas. #109816 (Algunenano).
  • Adicionada uma nova configuração use_projection_index_in_read_pools (desabilitada por padrão). Quando habilitada, os intervalos de marcas totalmente descartados pelo filtro de um índice de projeção são removidos dentro dos pools de leitura do MergeTree antes que as tarefas de leitura sejam criadas para eles, em vez de serem ignorados granule a granule durante a leitura. Isso evita criar tarefas de leitura e configurar leitores para dados que não serão lidos, além de manter o tamanho das tarefas de leitura medido em marcas remanescentes. #110291 (KochetovNicolai).
  • Reduzida a verbosidade dos diagnósticos de busca binária da chave primária por parte no MergeTree, rebaixando-os do logging de nível trace para o de nível test. #110324 (alexey-milovidov).
  • Corrigidas reconexões espúrias de conexões HTTP keep-alive em pool sobre TLS (HTTPS, S3). A verificação de conexões obsoletas usava poll no socket, o que reporta incorretamente como fechada uma conexão segura ativa que contém um registro TLS pós-handshake não lido (um session ticket ou KeyUpdate); agora ela usa um MSG_PEEK não bloqueante em sockets simples e SSL_peek/SSL_has_pending em sockets TLS, o que também detecta corretamente um encerramento TLS ordenado e um registro TLS que chegou apenas parcialmente. #110402 (alexey-milovidov).
  • Os catálogos OneLake agora podem usar refresh tokens OAuth para renovar access tokens. #110413 (alesapin).
  • Adicionado o ProfileEvent DuplicationDataHashComputations, que contabiliza os cálculos de hash de dados por coluna realizados durante a deduplicação de blocos inseridos via INSERT em tabelas *MergeTree. #111173 (valerypetrov).
  • O SST do índice UNIQUE KEY agora é gravado diretamente na parte por meio da abstração de armazenamento, em vez de passar antes por um arquivo temporário local. #111189 (JingYanchao).
  • Suporte a gravações concorrentes em tabelas Iceberg em disco local: o LocalObjectStorage agora implementa gravações condicionais, de modo que o compare-and-swap que publica um novo snapshot por meio de version-hint.text passa a funcionar nesse cenário e gravadores concorrentes não perdem mais as atualizações uns dos outros. #112556 (alexey-milovidov).
  • O cache de região de bucket do cliente S3 agora também funciona para catálogos de lago de dados; antes, cada requisição a eles resolvia a região novamente. #113330 (scanhex12).
  • Falhas de rede do lado do cliente no Azure (conexão redefinida/recusada, erros de DNS e TLS) agora são tratadas como erros de transporte e repetidas, em vez de aparecerem como um 500 sintético, assim como já ocorre no cliente S3. #115269 (arsenmuk).

Formatos e ingestão

  • Permite a compressão snappy na interface HTTP (Accept-Encoding: snappy) e adiciona a configuração snappy_mode para escolher entre o formato de bloco snappy do Hadoop e o formato de enquadramento snappy na E/S snappy genérica de file/url. #100752 (alexey-milovidov).
  • Adicionada a configuração input_format_csv_missing_nullable_as_empty_string (desabilitada por padrão). Quando habilitada, um valor ausente de Nullable(String) na entrada CSV é lido como uma String vazia em vez de NULL, independentemente de input_format_csv_empty_as_default. #107577 (alexey-milovidov).
  • Ao processar mensagens protobuf com input_format_protobuf_oneof_presence, não é mais exigida a correspondência exata das tags, o que permite alterações de schema. #109174 (ilejn).
  • Removido o leitor ORC legado baseado em Apache Arrow. O formato de entrada ORC agora sempre usa o decodificador nativo do ClickHouse (que já era o padrão). A configuração input_format_orc_use_fast_decoder está obsoleta (ainda é aceita, mas não tem efeito). #110074 (alexey-milovidov).
  • O motor Hive agora lê os metadados de arquivos ORC (índices min/max, contagens de linhas) com o leitor ORC nativo do ClickHouse em vez do adaptador ORC do Apache Arrow. #110086 (alexey-milovidov).

Segurança, acesso e observabilidade

  • Adicionada uma nova coluna skipping_indices_types à tabela system.tables. Ela contém os tipos distintos de índices de pulo de dados (data-skipping indices) definidos para cada tabela. #106388 (CurtizJ).
  • O valor automático de max_threads e de configurações semelhantes agora é exibido em system.settings como auto(8) em vez de 'auto(8)'; as aspas simples ao redor eram um artefato antigo embutido no valor. A compatibilidade entre versões é mantida: a forma legada entre aspas continua sendo aceita no parsing de configurações recebidas de servidores mais antigos. #108657 (alexey-milovidov).
  • Um valor default vazio de configuração agora é exibido como string vazia em system.documentation, em vez de backticks vazios. #108708 (alexey-milovidov).
  • A documentação de uma configuração em system.documentation — exibida pela página integrada /docs e pelo comando help — agora inclui o histórico de alterações do seu valor default: a versão em que a configuração foi introduzida e cada alteração posterior do valor default, com o valor anterior, o novo valor e o motivo da alteração. #112177 (alexey-milovidov).
  • A documentação de todas as instruções SQL (por exemplo, nome, sintaxe, descrição e exemplos) agora pode ser consultada na tabela de sistema system.statements. #115341 (rschu1ze).

Configurações e ajustes

  • Adicionada uma nova configuração de servidor memory_worker_rss_speculative_reserve_ratio (padrão 1.0, ou 0 em compilações com sanitizador), que faz o rastreador de memória global reservar especulativamente ratio * min(resident - previous_resident, resident - tracked) além do RSS observado a cada tick do MemoryWorker. Isso desloca o rastreador para cima quando o crescimento do RSS supera a contabilização do rastreador entre amostras, de modo que as alocações recebem MEMORY_LIMIT_EXCEEDED mais cedo e diminui a probabilidade de o OOM-killer do kernel ser acionado primeiro. Defina a razão como 0 para desabilitar a especulação. Compilações com sanitizador usam 0 por padrão porque, nelas, a diferença resident - tracked é dominada pela memória sombra do sanitizador. #104976 (alexey-milovidov).
  • O modo de aplicação preguiçoso (lazy) de posting lists do índice de texto deixou de ser experimental e pode ser selecionado com text_index_posting_list_apply_mode = 'lazy' sem allow_experimental_text_index_lazy_apply. A configuração de limiar de densidade foi renomeada de text_index_density_threshold para text_index_lazy_intersection_density_threshold. #108814 (CurtizJ).
  • A configuração merge_selector_enable_heuristic_to_lower_max_parts_to_merge_at_once agora vem habilitada por padrão: o seletor de mesclagem reduz automaticamente o número máximo de partes a mesclar de uma só vez com base em quão cheia está a partição. #110726 (Michicosun).
  • Os comandos de limpeza do PostgreSQL RESET, UNLISTEN e DISCARD agora são aceitos como operações sem efeito (no-ops) no PostgreSQL wire protocol, em vez de falharem com erro de sintaxe. Isso melhora a compatibilidade com drivers como o Skunk, que enviam RESET ALL e UNLISTEN * durante a configuração e a limpeza da conexão. #110780 (alexey-milovidov).
  • As funções de texto de IA (aiGenerate, aiClassify, aiExtract, aiTranslate) agora rejeitam respostas truncadas ou incompletas do provedor (por exemplo, quando o modelo atinge o limite max_tokens), em vez de retornar silenciosamente uma saída parcial. O comportamento segue a configuração ai_function_throw_on_error. #111830 (george-larionov).
  • Melhoria nas funções de precisão reduzida L2DistanceTransposedQuantized, cosineDistanceTransposedQuantized e dotProductTransposedQuantized, que agora reconstroem códigos p < 8QBit(Int8) com centroides de prefixo de média condicional gaussiana. A precisão total (p = 8) continua exata bit a bit; as distâncias aproximadas de precisão reduzida podem mudar, e os ganhos de recall/latência dependem da carga de trabalho. #111867 (skuznetsov).
  • A configuração write_snapshot_version agora pode ser recarregada a quente. #112150 (alesapin).
  • Adicionada observabilidade para as pilhas de fibras, usadas na comunicação assíncrona com réplicas remotas: profile events FiberStackAllocs, FiberStackAllocBytes, FiberStackAllocNanoseconds, FiberStackFreeNanoseconds e métricas FiberStacks, FiberStackBytes. #114541 (alexey-milovidov).
  • O protocolo Prometheus remote-write agora oferece suporte a inserções assíncronas: os dados de várias requisições remote-write simultâneas são agrupados em lotes antes de formar partes, conforme a configuração async_insert (habilitada por padrão; adicione async_insert=0 à URL do handler para manter o comportamento síncrono). Uma requisição só é confirmada depois que os dados são gravados em todas as tabelas internas da tabela TimeSeries de destino. #115688 (nikitamikhaylov).

Outras melhorias

  • Adicionadas duas configurações, shrink_over_allocated_columns_min_waste_ratio e shrink_over_allocated_columns_min_waste_bytes, que fazem com que INSERTs reduzam colunas superalocadas (cuja memória reservada excede a memória usada devido ao crescimento em potências de dois das colunas de comprimento variável) ao tamanho necessário antes da materialização e da gravação das partes, reduzindo o pico de uso de memória. Desativadas por padrão.. #112161 (Avogar).
  • A etapa de leitura de dados agora é totalmente ignorada em merges TTLDrop, evitando uso excessivo de memória, especialmente em alocações de buffers de leitura/prefetch. #105859 (Avogar).
  • Adicionado suporte a BFloat16 em dotProduct e melhorado o desempenho do produto escalar com processamento em lotes no caminho SIMD. #106569 (nickitat).
  • max_named_collection_num_to_throw, max_table_num_to_throw, max_replicated_table_num_to_throw, max_view_num_to_throw, max_dictionary_num_to_throw e max_database_num_to_throw agora podem ser alterados sem reiniciar o servidor. #106821 (UberDever).
  • A gravação em tabelas DeltaLake, controlada por allow_experimental_delta_lake_writes, foi promovida a Beta. #107034 (kssenii).
  • Adicionado o tipo de estatísticas de coluna uniq_v2, uma alternativa leve ao uniq baseada no sketch uniqCombined64. #107863 (hanfei1991).
  • Adicionados os ProfileEvents DistributedPlanRemoteTasks, DistributedPlanLocalExecution e DistributedPlanHostsUsed para monitorar a execução de make_distributed_plan. #107985 (shankar-iyer).
  • Requisições a catálogos REST de lagos de dados, como o OneLake, agora incluem um cabeçalho User-Agent do ClickHouse. #108117 (scanhex12).
  • MVTEncodeGeom agora ajusta a geometria à grade de pixels inteiros antes do recorte e recorta polígonos com wagyu, de modo que a saída recortada seja válida (anéis com autointerseção são corrigidos) e alinhada às bordas, em conformidade com o ST_AsMVTGeom do PostGIS. #108248 (saarthak2002).
  • Os três caches do índice de texto agora estão habilitados globalmente — antes, eram habilitados apenas dentro das consultas. Além disso, o tamanho do cache de listas de postings agora é zero (o que, na prática, o desativa novamente), pois as listas de postings são grandes e armazená-las em cache é custoso demais. #108274 (rschu1ze).
  • O endpoint do Prometheus (para configurações somente de métricas) e a coleta de métricas assíncronas agora são iniciados antes do carregamento das tabelas, para que as métricas possam ser observadas durante a fase de carregamento de metadados, que pode ser demorada. #108402 (cwurm).
  • Suporte a BFloat16 em funções matemáticas binárias #108442 (zhangyifan27).
  • As funções de distância vetorial transpostas L2DistanceTransposed, cosineDistanceTransposed e dotProductTransposed agora aplicam a otimização de leitura parcial de planos de bits a colunas Nullable(QBit), lendo apenas os planos de bits solicitados em vez da coluna inteira. #109358 (alexey-milovidov).
  • Suporte a arraySum, arrayAvg e arrayProduct para arrays de BFloat16. #109420 (alexey-milovidov).
  • As funções L1Normalize, L2Normalize, LinfNormalize e LpNormalize (e seus aliases) agora funcionam com arrays, e não apenas com tuplas, de forma consistente com L2Norm e as funções de distância. #110052 (alexey-milovidov).
  • As conexões do pool não recebem mais ping antes de cada uso. Isso elimina a ida e volta Ping-Pong que era acrescentada a cada conexão reutilizada, reduzindo a latência das consultas distribuídas e do clickhouse-benchmark. Uma conexão obsoleta do pool é detectada por meio de um poll com tempo limite zero (uma verificação não bloqueante que não acrescenta nenhuma ida e volta) e recuperada por reconexão. #110068 (alexey-milovidov).
  • Envio de listas grandes de partes para a análise de índice distribuída como escalares (evita possíveis falhas causadas por max_ast_elements/max_query_size e elimina a sobrecarga de parsing da AST) #110419 (azat).
  • Agora, ao clicar no logotipo da nuvem no Playground, o site do Clickhouse é aberto em uma nova aba, para que você não perca o progresso enquanto as consultas estão em execução. #110422 (williamhatcher).
  • Alteração do valor default de auto_statistics_types de basic, uniq para basic, uniq_v2 #110878 (hanfei1991).
  • Quando uma asserção de reentrância de RWLockImpl::getLock() é disparada (RWLock is already locked in exclusive mode / Cannot acquire exclusive lock while RWLock is already locked), a mensagem de erro agora informa os outros query_ids que detêm o bloqueio no momento e quantos bloqueios o query_id solicitante já possui, facilitando o diagnóstico desses erros de ordenação de bloqueios. #110971 (groeneai).
  • randomHadamardTransform agora calcula uma transformada exata, que preserva o comprimento, para qualquer comprimento de vetor cujo maior fator ímpar seja no máximo 64 (por exemplo, 3584 = 512 * 7, comum em modelos de embedding), ampliando as famílias anteriores 2^N, 2^k * {12, 20} e 2^k * 9. Uma transformada completa de um comprimento que não pode ser representado exatamente agora lança uma exceção, em vez de preencher silenciosamente com zeros até um vetor mais longo; passe output_dims para calcular uma projeção truncada de comprimento arbitrário. #111006 (alexey-milovidov).
  • Retorno do código HTTP 403 Forbidden (em vez de 500 Internal Server Error) para exceções ACCESS_DENIED na interface HTTP. #111043 (Schum-io).
  • UTMToGeo agora aceita, como quarto argumento, a letra da banda de latitude MGRS retornada por geoToUTM (além do indicador inteiro de hemisfério), permitindo que um resultado de geoToUTM faça a ida e volta diretamente por UTMToGeo. #111521 (alexey-milovidov).
  • MaterializedPostgreSQL agora preserva valores TOAST inalterados do PostgreSQL durante atualizações, em vez de substituí-los por valores default. #111552 (OrpheusAgent).
  • Adicionadas as configurações text_index_max_processed_tokens_before_flush e text_index_max_memory_usage_before_flush para controlar quando os construtores de índice de texto fazem flush de segmentos temporários. #111573 (rorylshanks).
  • Adicionado o modificador STREAM UNORDERED: dispensa a ordenação por ordem de commit em cada snapshot #111794 (SmitaRKulkarni).
  • Agora make_distributed_plan=1 desativa funcionalidades ainda não compatíveis.. #112463 (alesapin).
  • Sequências de escape ANSI não são mais gravadas em INTO OUTFILE quando o stdout é um tty #113252 (azat).
  • allow_experimental_delta_kernel_rs foi renomeado para allow_delta_kernel_rs. O nome antigo continua disponível como alias. #113476 (kssenii).
  • Adicionadas as configurações enable_alp_codec, enable_sz3_codec, enable_zxc_codec e enable_quantized_codec para habilitar individualmente cada codec de compressão experimental. #113824 (rienath).
  • Um estouro de pilha agora é reportado em vez de o processo encerrar silenciosamente: os handlers de sinais fatais passam a ser executados na pilha de sinais alternativa, de modo que SIGSEGV, SIGABRT, SIGILL, SIGBUS, SIGSYS, SIGFPE e SIGTRAP geram um stack trace mesmo quando a thread que causou a falha já esgotou sua pilha. #113927 (groeneai).
  • Adicionado suporte ao parâmetro lookback_delta da Prometheus HTTP API para consultas instantâneas e de intervalo. #113971 (fallintoplace).
  • As tabelas QueryRunner agora iniciam worker threads sob demanda e as liberam quando ficam ociosas, em vez de ocupar threads durante todo o ciclo de vida da tabela. #114522 (mstetsyuk).
  • Com esta alteração, ao usar os índices WHATIF, a execução de referência atendida por projeção reporta not_applicable para cada candidato em vez de fazer a instrução falhar. #114846 (yariks5s).
  • Otimização de cadeias de AND com múltiplas condições de comparação sobre a mesma expressão: detecta contradições (por exemplo, a < 3 AND a > 5 → false) e elimina condições redundantes (por exemplo, a = 3 AND a < 5 → a = 3). #99736 (wudidapaopao).

Correção de bugs

Correções de MergeTree, replicação e armazenamento

  • Corrigida uma condição de corrida entre ALTER TABLE ... RENAME COLUMN e um OPTIMIZE TABLE ... FINAL concorrente (ou qualquer mesclagem em segundo plano) no MergeTree que podia substituir silenciosamente os dados da coluna renomeada por valores default. A janela de corrida entre a publicação dos novos metadados em memória e o registro da mutação de renomeação em current_mutations_by_version agora é eliminada mantendo currently_processing_in_background_mutex bloqueado durante ambas as operações. #104822 (groeneai).
  • Corrigidos resultados incorretos de consultas ao usar GROUP BY com ORDER BY e arrayJoin na projeção. #101775 (Onyx2406).
  • Configurações inválidas de tamanho de upload do Azure (por exemplo, azure_min_upload_part_size = 0 ou azure_max_blocks_in_multipart_upload = 0) agora são rejeitadas logo no início com um erro claro, em vez de disparar uma exceção interna (second_size > 0) em um ponto profundo do caminho de escrita. Isso se aplica tanto às configurações de consulta quanto à configuração de disco do Azure. #103394 (statxc).
  • Agora é lançado BAD_ARGUMENTS em vez de LOGICAL_ERROR quando ALTER TABLE ... MOVE/REPLACE/ATTACH PARTITION é executado entre duas tabelas MergeTree com configurações de granularidade incompatíveis (uma adaptativa e outra não adaptativa). #103881 (groeneai).
  • Corrigido um LOGICAL_ERROR “Expected one block from input stream” lançado por KILL QUERY / KILL MUTATION / KILL PART_MOVE_TO_SHARD / KILL TRANSACTION quando a cláusula WHERE contém uma subconsulta por linha, ou quando max_block_size é pequeno o bastante para que o SELECT interno sobre a tabela system.* correspondente emita mais de um bloco. #104927 (groeneai).
  • Corrigido um vazamento em views materializadas atualizáveis (MATERIALIZED VIEW ... REFRESH ...) em que a tabela interna temporária que a tarefa de atualização substitui via EXCHANGE TABLES não podia ser removida se fosse maior que o max_table_size_to_drop do servidor. Cada atualização subsequente criava mais uma tabela interna temporária, sem conseguir limpar as anteriores, fazendo o diretório de dados da view crescer até esgotar o disco. O DROP interno da tarefa de atualização agora ignora max_table_size_to_drop e max_partition_size_to_drop; essas proteções continuam valendo para o DROP TABLE da própria view executado pelo usuário. #105106 (groeneai).
  • Corrigido um erro inesperado DATA_TYPE_CANNOT_BE_USED_IN_KEY em consultas ALTER que não podem alterar a sorting key (configurações, comentários, codecs, adição de uma coluna que não faz parte da chave etc.) em tabelas MergeTree que possuem um SimpleAggregateFunction (ou outro tipo permitido apenas com allow_suspicious_primary_key = 1) na sorting key. #105111 (groeneai).
  • OPTIMIZE ... DRY RUN interrompido por tempo limite de consulta (max_execution_time com timeout_overflow_mode = 'break') agora retorna TIMEOUT_EXCEEDED em vez de um erro lógico sobre rows_sources (que abortava o servidor em builds de depuração e com sanitizers). #107114 (groeneai).
  • Corrigido NOT_FOUND_COLUMN_IN_BLOCK ao ler arquivos com particionamento no estilo hive com use_hive_partitioning=1 e uma cláusula WHERE/PREWHERE que filtra uma coluna real (não virtual) quando uma coluna de partição hive também é selecionada. #107505 (groeneai).
  • Corrigidos resultados incorretos de consultas causados por poda incorreta de chave primária e de partição quando toStartOfDay, toStartOfISOYear, toDaysSinceYearZero, toRelativeSecondNum, toRelativeMinuteNum, toRelativeHourNum, toRelativeWeekNum, toRelativeDayNum, toMonthNumSinceEpoch ou toYearNumSinceEpoch é aplicada a uma coluna-chave Date32 contendo datas fora do intervalo que a função consegue representar (em particular, datas anteriores a 1970-01-01). Essas funções se declaram monotônicas para o índice primário, mas antes sofriam overflow com esses argumentos, de modo que o índice podia podar grânulos que de fato continham linhas correspondentes. Agora elas saturam nos limites do seu tipo de resultado e permanecem monotônicas em todo o intervalo de Date32, o que garante a poda correta. #108018 (nihalzp).
  • Corrigido o problema em que CREATE TABLE dst AS src SETTINGS ... (e variantes semelhantes com ORDER BY/PARTITION BY, mas sem um ENGINE explícito) descartava silenciosamente o motor da tabela de origem, as cláusulas de armazenamento (como o TTL da tabela e as chaves) e as configurações. Agora, o motor e as cláusulas de armazenamento não sobrescritas são herdados da tabela de origem, e as configurações especificadas são mescladas sobre as configurações da tabela de origem. #108085 (alexey-milovidov).
  • Corrigida a falha de INSERT em tabelas MergeTree com filesystem error: in rename: Permission denied em sistemas de arquivos baseados em Windows (WSL, CIFS/SMB, bind mounts do Docker Desktop), causada pelo gravador de partes, que deixava descritores de arquivo abertos durante a renomeação do diretório da parte. #108089 (alexey-milovidov).
  • Corrigido um travamento em tabelas MergeTree anexadas com um índice de salto legado hypothesis (um tipo de índice removido, mantido apenas para compatibilidade com ATTACH). Antes, um DELETE leve, um OPTIMIZE, um INSERT simples ou um SELECT filtrado nessa tabela falhava com ILLEGAL_INDEX (“Index of type ‘hypothesis’ is no longer supported”), e a mutação de DELETE era repetida indefinidamente. Agora, o índice obsoleto é tratado como inerte: ele é mantido intacto durante mesclagens/mutações, ignorado no insert e no planejamento de consultas, e ainda pode ser removido com ALTER TABLE ... DROP INDEX. #108217 (groeneai).
  • Corrigido o erro NOT_FOUND_COLUMN_IN_BLOCK (por exemplo, Column _part not found) ao selecionar colunas virtuais de uma tabela MergeTree com réplicas paralelas, inclusive via SELECT * com asterisk_include_virtual_columns = 1. #108451 (groeneai).
  • Corrigido o problema em que ATTACH PARTITION ... FROM rejeitava tabelas cujas chaves primárias são equivalentes, mas declaradas de forma diferente (uma com PRIMARY KEY explícita e a outra implícita a partir de ORDER BY). #108590 (jordiori).
  • join_any_take_last_row agora é respeitado por todos os caminhos de junção baseados em hash compatíveis, incluindo junções que usam despejo automático em disco. #108936 (antaljanosbenjamin).
  • Corrigido o erro NOT_FOUND_COLUMN_IN_BLOCK quando query_plan_optimize_lazy_final está habilitado em conjunto com um filtro WHERE parcialmente movido para PREWHERE (via optimize_move_to_prewhere_if_final). A otimização lazy FINAL não solicita mais ao armazenamento colunas de predicado calculadas no prewhere. #109073 (groeneai).
  • Corrigido o problema em que ALTER TABLE ... ADD PROJECTION sobre uma coluna ALIAS no nível da tabela deixava a tabela inutilizável (o INSERT seguinte falhava com UNKNOWN_IDENTIFIER, “Missing columns”) quando a sessão tinha optimize_respect_aliases = 0. #109091 (groeneai).
  • Corrigida uma asserção de ponteiro nulo (px != 0 em TreeRewriter::analyzeSelect, que abortava o servidor em builds de depuração e com sanitizers) ao executar ORDER BY ALL (ou GROUP BY ALL) sobre uma tabela com engine Merge em JOIN com outra tabela no analisador antigo (allow_experimental_analyzer = 0). #109139 (groeneai).
  • Corrigido um resultado incorreto de subconsultas EXISTS correlacionadas e de subconsultas escalares quando a correlação aparece apenas na projeção da subconsulta, junto com uma cláusula WHERE não correlacionada (a subconsulta podia ser avaliada como falsa / NULL para todas as linhas). Corrige https://github.com/ClickHouse/ClickHouse/issues/105760. #109186 (novikd).
  • Corrigido um bug em que a mesclagem de uma tabela MergeTree com projeções, com a configuração enable_block_number_column ou enable_block_offset_column habilitada, gerava partes de projeção contendo uma coluna espúria _block_number/_block_offset. Com isso, a parte de projeção mesclada deixava de corresponder à definição da projeção e às partes de projeção geradas por insert, e CHECK TABLE e OPTIMIZE ... DRY RUN a reportavam como corrompida (CORRUPTED_DATA). #109284 (groeneai).
  • Corrigido o erro UNKNOWN_IDENTIFIER ao executar ALTER TABLE ... RENAME/ADD/MODIFY COLUMN em uma tabela MergeTree que possui um índice min-max implícito sobre as colunas virtuais persistentes _block_number ou _block_offset (habilitado por add_minmax_index_for_block_number_column / add_minmax_index_for_block_offset_column). #109428 (groeneai).
  • Corrigida a remoção indevida de índices de salto de uma parte de dados (ou a falha de CHECK TABLE com UNEXPECTED_FILE_IN_DATA_PART) após uma mutação que reescreve a parte inteira, como ALTER TABLE ... DROP COLUMN de uma coluna MATERIALIZED, em uma parte Wide. #109616 (groeneai).
  • Corrigidos índices de salto (text, bloom_filter etc.) e projeções inativos após a materialização de atualizações leves com ALTER TABLE ... APPLY PATCHES. Antes, os arquivos de índice e de projeção que dependem de uma coluna atualizada por patch permaneciam inalterados, e as consultas que os utilizavam podiam retornar resultados incorretos (por exemplo, hasToken deixando de encontrar uma linha atualizada, ou uma projeção retornando agregados desatualizados após a remoção da parte de patch já aplicada). #109709 (groeneai).
  • Corrigida a falha, no meio da execução, de mutações que referenciam a coluna virtual _sample_factor, com o erro Unexpected const virtual column: _sample_factor, que deixava a mutação travada. Agora, a mutação lê essa coluna como 1, o mesmo valor retornado por uma consulta sem SAMPLE. #109813 (groeneai).
  • Corrigidos dois erros gerados quando uma consulta com GROUP BY GROUPING SETS (ou uma subconsulta escalar ou de mutação que contenha essa cláusula) é executada com force_aggregation_in_order = 1: Trying to get name of not a column: ExpressionList no analisador antigo (enable_analyzer = 0) e Memory bound merging of aggregated results is not supported for grouping sets. em uma consulta distribuída com enable_memory_bound_merging_of_aggregation_results = 1 no analisador. #109862 (groeneai).
  • Corrigidos três problemas com use_constant_folding_in_index_analysis: um erro lógico Invalid partition key size que podia abortar um SELECT que usasse uma projeção normal quando a tabela define part_minmax_index_columns = 'with_block_number_offset'; resultados incorretos (linhas descartadas silenciosamente) em filtros sobre uma chave de partição com módulo, como PARTITION BY id % 200; e uma falha (condição de corrida de dados) quando um índice text com tokenizador sparseGrams é consultado com um predicado LIKE em muitas partições com max_threads > 1. #109896 (groeneai).
  • Corrigidos resultados incorretos quando um índice de salto minmax é criado sobre uma coluna LowCardinality(Nullable(...)): predicados WHERE/PREWHERE/HAVING ... IS NULL repassados ao armazenamento descartavam todos os grânulos e retornavam 0 linhas, mesmo que a coluna contivesse NULLs. #110061 (groeneai).
  • Corrigida a lentidão de consultas ORDER BY ... LIMIT em tabelas Distributed quando prefer_localhost_replica seleciona uma réplica local. #110136 (EmeraldShift).
  • Corrigida uma exceção (UNION mode UNION_DEFAULT must be normalized) quando uma mutação DELETE ou ALTER UPDATE usava uma operação de conjunto (UNION/UNION ALL/UNION DISTINCT/EXCEPT/INTERSECT) dentro de uma subconsulta na condição WHERE ou em uma atribuição de UPDATE. #110196 (alexey-milovidov).
  • Corrigidos o desligamento lento do servidor e a falta de resposta de KILL MUTATION quando uma mutação com x IN (subquery) estava construindo o conjunto da subconsulta durante a análise da chave primária; agora a construção do conjunto é cancelada imediatamente. #110198 (alexey-milovidov).
  • Corrigida uma condição de corrida entre KILL TRANSACTION e ALTER TABLE ... UPDATE/DELETE executado dentro de uma transação: um rollback ocorrido entre o registro da mutação na transação e seu registro na tabela deixava uma entrada de mutação órfã, o que gerava um erro lógico (Cannot find transaction ... that has started mutation ...) em tarefas em segundo plano e bloqueava todas as mutações subsequentes das partes afetadas até a reinicialização do servidor. #110226 (tiandiwonder).
  • Corrigido o problema em que system.tables para um banco de dados DataLakeCatalog (Iceberg/Glue) abortava a consulta inteira, ou omitia tabelas silenciosamente, quando os metadados de uma única tabela não podiam ser resolvidos. Agora essa tabela continua listada pelo nome, com valores default/NULL nas colunas que dependem do objeto de armazenamento aberto (engine, total_rows etc.), independentemente de database_datalake_require_metadata_access. O acesso direto à tabela com problema continua reportando o erro. #110242 (groeneai).
  • A estimativa de cardinalidade para ordem de junção agora combina as estatísticas de colunas das partes que restam após o descarte por partição/PK, em vez de todas as partes ativas. Antes, uma consulta restrita a uma pequena partição era planejada com base nas estatísticas da tabela inteira (foi observada uma superestimação de linhas de 2500x, que invertia o lado de construção do hash join), e desabilitar as estatísticas, paradoxalmente, produzia um plano melhor. Também corrigido: o FINAL lazy era desabilitado silenciosamente para relações MergeTree sob um JOIN, porque o resultado memoizado da análise de índice do otimizador de ordem de junção era confundido com uma projeção aplicada. #110283 (skuznetsov-clickhouse).
  • ALTER TABLE ... MOVE/REPLACE PARTITION entre duas tabelas MergeTree com granularidade incompatível (uma adaptativa e outra não adaptativa) agora lança BAD_ARGUMENTS em vez de LOGICAL_ERROR. Como essa condição pode ser provocada pelo usuário, ela não deve aparecer como erro interno (que aborta o servidor em compilações de debug/sanitizer). #110535 (groeneai).
  • Corrige um TTL ... DELETE WHERE <cond> que nunca removia linhas que passavam a corresponder a <cond> devido a um ALTER TABLE ... UPDATE em uma coluna referenciada no WHERE. Agora, a mutação recalcula o TTL da linha, de modo que as linhas expiradas que passaram a corresponder à condição são excluídas em vez de serem mantidas silenciosamente. #110648 (groeneai).
  • Corrigido um LOGICAL_ERROR “Invalid partition key size: 0” que podia abortar um INSERT em uma tabela MergeTree particionada com non_replicated_deduplication_window habilitado, quando um lote de async insert era desduplicado apenas parcialmente (alguns insert_deduplication_tokens eram duplicados e outros eram novos). #110651 (groeneai).
  • Corrige o constant folding no novo analisador, que alterava silenciosamente o tipo de um valor constante Geometry. Geometry é um Variant nomeado cujas alternativas podem compartilhar o mesmo layout de armazenamento (LineString/Ring, MultiLineString/Polygon e os vazios), de modo que duas constantes resultantes do folding que diferiam apenas na alternativa eram reduzidas a uma só; por exemplo, uma constante MULTIPOLYGON EMPTY resultava em LINESTRING(). #110709 (groeneai).
  • Corrige um resultado incorreto (mesclagem fora de ordem) em consultas read-in-order nas quais distinct-in-order ou aggregation-in-order estende a leitura para um prefixo da chave de ordenação mais longo do que aquele para o qual o ORDER BY configurou a linha virtual de read-in-order. As colunas de ordenação extras da linha virtual eram preenchidas com valores padrão, o que podia desordenar o MergingSortedTransform (e abortar com um LOGICAL_ERROR em builds de depuração/sanitizer). #110725 (groeneai).
  • Propaga as funções ativas de uma consulta (SET ROLE / role=) para os nós remotos em leituras com réplicas paralelas e Distributed em um cluster com segredo entre servidores; antes, eram usadas as funções padrão do usuário, o que fazia com que as row policies fossem avaliadas de forma inconsistente com o iniciador. #110867 (evillique).
  • Corrigida uma condição de corrida rara em que um ALTER apenas de comentário ou apenas de configurações em uma tabela ReplicatedMergeTree podia descartar silenciosamente uma coluna adicionada por um ALTER ... ADD COLUMN concorrente, deixando uma réplica com uma estrutura de tabela desatualizada. #111029 (tiandiwonder).
  • Corrige o erro NUMBER_OF_COLUMNS_DOESNT_MATCH em um GROUP BY com uma agregação sobre uma tabela Merge que encapsula uma tabela Distributed, quando a chave de agrupamento é uma função de uma coluna e uma agregação lê essa mesma coluna (por exemplo, SELECT toString(g), min(g) FROM merge_over_distributed GROUP BY toString(g)). #111334 (groeneai).
  • Corrige o resultado incorreto de um FULL JOIN em uma tabela com engine Join (StorageJoin) com USING quando a chave da esquerda é Nullable e a chave do armazenamento não é: uma linha da esquerda sem correspondência com chave NULL retornava 0 em vez de NULL. #111371 (groeneai).
  • ALTER TABLE ... DETACH PARTITION/PART agora executa fsync no clone que cria em detached/ (a subárvore da parte mais a cadeia de diretórios até a raiz do disco) quando a configuração fsync_part_directory da tabela está habilitada, tanto para o armazenamento de partes Full (diretório) quanto Packed. Antes, o clone nunca passava por fsync, ao contrário da parte vazia de cobertura que remove as linhas do conjunto ativo; com isso, uma queda de energia logo após a confirmação podia destruir os dados desanexados no btrfs (as entradas de diretório não sincronizadas do clone eram revertidas, deixando detached/ vazio e nada para ATTACH). Controlado pela configuração existente fsync_part_directory; o comportamento padrão permanece inalterado. #111426 (groeneai).
  • Rejeita uma coluna Nullable(Nothing) (ou de qualquer outro tipo não permitido em tabelas) no momento do CREATE TABLE quando o esquema é inferido a partir do armazenamento (por exemplo, uma tabela remote()/Remote/Distributed sem colunas sobre uma view que executa SELECT NULL), em vez de persistir metadados que falham ao carregar na próxima reinicialização do servidor e impedem o carregamento de tabelas não relacionadas. #111487 (groeneai).
  • Corrige um LOGICAL_ERROR (Got read request from replica N for unknown stream ...) que podia abortar o servidor durante a leitura com réplicas paralelas quando a consulta é totalmente respondida por uma otimização de projeção (contagem exata, contagem minmax ou uma projeção armazenada agregada/normal que não seleciona nenhum intervalo) no iniciador. #111689 (groeneai).
  • Corrigido o INSERT particionado do DeltaLake (allow_experimental_delta_lake_writes=1), que corrompia valores de partição contendo caracteres de caminho e rejeitava NULL. Um valor como a/b era gravado silenciosamente como a, % gerava um arquivo de dados que não podia ser lido posteriormente e um valor de partição NULL falhava com NOT_IMPLEMENTED. Agora, os valores de partição são codificados com percent-encoding em um único segmento de caminho, o valor real é armazenado em partitionValues em vez de ser extraído novamente do caminho, e um valor de partição NULL (ou string vazia) é gravado como __HIVE_DEFAULT_PARTITION__ com uma entrada nula em partitionValues. #111793 (groeneai).
  • Corrigidos os erros lógicos Expected UInt64 column for __grouping_set, got BLOB e ColumnBLOB should be converted to a regular column before usage em uma consulta distribuída executada em um shard com enable_parallel_blocks_marshalling (habilitado por padrão), por exemplo, com GROUP BY GROUPING SETS em um cluster que possui uma réplica local, ou ao ler uma tabela Merge que abrange uma tabela local e uma tabela distribuída. BlocksMarshallingStep não é mais adicionado a planos cujos blocos são consumidos no mesmo processo. #111997 (groeneai).
  • Corrigido um LOGICAL_ERROR (Type mismatch when building statistics for column) durante uma mutação MergeTree de uma tabela cujo tipo de coluna foi alterado por um ALTER MODIFY COLUMN apenas de metadados (por exemplo, de Enum8 para Int8 ou de DateTime para UInt32) quando a coluna possui estatísticas. Agora, a mutação recalcula apenas as estatísticas das colunas que efetivamente reescreve e mantém as demais inalteradas; além disso, uma coluna reescrita por MATERIALIZE COLUMN, por um UPDATE de uma coluna da qual uma coluna MATERIALIZED depende ou por CLEAR COLUMN passa a ter suas estatísticas recalculadas, em vez de manter conteúdo desatualizado. #112009 (groeneai).
  • Corrige a ausência silenciosa de linhas quando uma consulta filtra por intDiv(constant, key) ou divide(constant, key). A análise de chave primária e de partição indica a direção errada de monotonicidade para uma constante dividida por uma coluna-chave, de modo que grânulos correspondentes são descartados e a consulta retorna menos linhas sem nenhum erro. Também corrige intDiv com um dividendo constante sem sinal cujo bit mais alto está ativado, deixa de declarar monotonicidade quando um operando Decimal faz com que a divisão seja calculada na largura nativa do decimal e impede que a análise de chave gere Cannot compare DB::IPv4 with long para uma consulta válida que divide uma constante IPv4/IPv6 por uma coluna-chave. #112156 (groeneai).
  • Corrige a classificação incorreta como visão comum de uma visão parametrizada cujo corpo SELECT usa INTERSECT/EXCEPT, ou uma cadeia de UNION que mistura UNION DISTINCT com UNION ALL. Essa visão era criada com sucesso, mas seus metadados não podiam ser lidos de volta: ao carregá-la, era lançado Invalid storage definition in metadata file, o que impedia permanentemente o carregamento da visão e abortava a inicialização de servidores de depuração ou com sanitizer. system.tables.parameterized_view_parameters também não exibia nenhum parâmetro para essas visões. #112211 (groeneai).
  • Corrige o problema em que max_execution_time e KILL QUERY eram ignorados enquanto uma consulta avaliava geohashesInBox. Essa consulta expandia todas as linhas de um bloco antes de poder ser interrompida, de modo que o cancelamento só surtia efeito minutos depois; agora a função verifica o limite de tempo da consulta à medida que percorre as linhas. Avaliações dentro de uma expressão de tabela persistida, como uma chave de ordenação, um índice de salto ou um PARTITION BY, não são cobertas por esta correção e são tratadas separadamente. #112273 (groeneai).
  • Corrige um erro lógico quando PREWHERE é usado em uma tabela Merge sobre outra tabela Merge ou sobre uma visão materializada com tipo de coluna diferente. Também corrige o problema em que uma política de linha era ignorada silenciosamente em tabelas que leem de servidores remotos (uma tabela Distributed ou uma tabela que encapsula uma), o que podia expor linhas que a política deveria ocultar; essas consultas agora são rejeitadas com o erro ILLEGAL_PREWHERE. Nesses casos, defina as políticas nas tabelas locais subjacentes de cada servidor remoto; observe que essa política ainda não é aplicada a leituras enviadas com serialize_query_plan = 1, o que é um bug distinto e preexistente. #112326 (PedroTadim).
  • Corrige a leitura de um índice secundário (de salto) desatualizado após uma alteração de tipo via ALTER TABLE ... MODIFY COLUMN cuja mutação nunca foi executada, por exemplo porque KILL MUTATION a removeu: os grânulos em disco haviam sido gravados com o tipo antigo, mas eram decodificados com o novo, gerando LOGICAL_ERROR, solicitando alocações de vários exabytes ou retornando silenciosamente um resultado incorreto. Também corrige um resultado incorreto de um índice sobre uma expressão cujo significado muda embora todos os bytes armazenados permaneçam idênticos, de modo que nenhuma mutação chega a ser criada: um MODIFY COLUMN que altera apenas o fuso horário de um DateTime, ou apenas um nome de tipo personalizado, como de UInt8 para Bool. Esse índice agora é ignorado para a parte afetada. #112484 (groeneai).
  • Corrige um LOGICAL_ERROR (Cannot add transform Resize to Pipes because it has no outputs) quando uma consulta que agrega dados de um cluster é executada com serialize_query_plan = 1 e réplicas paralelas baseadas em plano, causado pela etapa de mesclagem, que redimensionava o pipeline para zero fluxos. #112506 (groeneai).
  • Corrige um LOGICAL_ERROR (“Part … contains column … that is absent in table …”) quando uma réplica ReplicatedMergeTree aplica uma mutação a uma parte obtida de outra réplica antes de aplicar seu próprio ALTER ... ADD COLUMN pendente. Essa mutação agora é adiada até que a alteração de metadados seja aplicada. #112510 (groeneai).
  • Corrige os contadores de leitura (read_rows, read_bytes, ProfileEvents['SelectedRows'], ProfileEvents['SelectedBytes']) e as cotas READ_ROWS e READ_BYTES, que eram contabilizados em excesso em consultas cujo ORDER BY faz spill para o disco. As linhas relidas dos arquivos temporários da ordenação externa eram contadas novamente como leituras da origem, de modo que uma consulta com spill reportava mais do que realmente lia e podia ser rejeitada com QUOTA_EXCEEDED, mesmo permanecendo dentro de sua cota. #112645 (groeneai).
  • Corrige ProfileEvents['JoinResultRowCount'], que subnotificava o tamanho do resultado de um JOIN que faz spill para o disco. As linhas emitidas a partir de buckets adiados eram contadas apenas em JoinDelayedJoinedTransformRowCount e ficavam de fora do total. Os resultados das consultas sempre estiveram corretos; apenas o evento de perfil estava errado. #112673 (groeneai).
  • Corrige max_execution_time e KILL QUERY, que ficavam silenciosamente sem efeito em uma consulta distribuída durante o estabelecimento de conexões com réplicas. Agora, essa consulta é interrompida na próxima tentativa de conexão, em vez de percorrer todas as réplicas e novas tentativas restantes. #112689 (groeneai).
  • Corrigida a aplicação de ALTER em tabelas MergeTree enquanto uma mutação de alteração RENAME COLUMN incompleta ainda estava em andamento. Isso podia atualizar os metadados de armazenamento de forma incompatível e bloquear completamente as mutações posteriores. #112783 (Michicosun).
  • Corrige resultados incorretos de ORDER BY ao ler de uma tabela Merge sobre tabelas Distributed: linhas podiam ser retornadas fora de ordem, e linhas que deveriam constar no resultado podiam ficar de fora quando LIMIT era usado. #112931 (alexey-milovidov).
  • Corrigidos resultados incorretos quando o prefetch de leitura do sistema de arquivos está habilitado e uma coluna Nested é lida junto com uma subcoluna que foi removida e adicionada novamente, em tabelas com share_nested_offsets habilitado (o padrão). Essa consulta podia retornar valores default para uma coluna fisicamente presente que nunca foi afetada pelos ALTERs. No armazenamento de objetos, isso ocorre sem nenhuma configuração diferente do padrão, já que remote_filesystem_read_prefetch tem 1 como padrão; em discos locais, é necessário local_filesystem_read_prefetch = 1. Um defeito separado, independente do prefetch, ainda corrompe essas leituras quando um intervalo abrange vários blocos; esse problema não é tratado aqui. #112997 (groeneai).
  • Corrigido um erro lógico Pipeline stuck em consultas que distribuem dados por partição, como uma função de janela com PARTITION BY ou uma junção com join_algorithm = 'parallel_full_sorting_merge', quando o processamento downstream de um shard terminava enquanto um bloco havia sido distribuído apenas parcialmente. #113190 (groeneai).
  • Corrigido um travamento de instruções ALTER, OPTIMIZE, TRUNCATE e de manipulação de partições com alter_sync = 2 em ReplicatedMergeTree quando a tabela começa a ser desligada enquanto a instrução aguarda outra réplica, por exemplo, devido a um DROP DATABASE ... SYNC concorrente. Agora, essa instrução falha com UNFINISHED e também respeita max_execution_time e KILL QUERY. #113228 (groeneai).
  • Corrigido o erro Cannot insert element into Set (NOT_IMPLEMENTED) quando read_in_order_use_virtual_row está habilitado e uma consulta MergeTree com leitura em ordem combina WITH FILL ... INTERPOLATE com um filtro IN ou has. #113264 (groeneai).
  • Corrige um erro lógico (exceção) Chunk info was not set for chunk in MergingAggregatedTransform quando a configuração inject_random_order_for_select_without_order_by está habilitada e uma consulta de agregação lê de uma tabela Merge que contém um filho Distributed: o wrapper aleatório ORDER BY rand() não é mais injetado em consultas planejadas apenas até um estágio intermediário. #113266 (alexey-milovidov).
  • Corrigido o problema em que linhas nunca eram excluídas quando uma tabela MergeTree tinha duas ou mais regras TTL ... DELETE WHERE com expressão de tempo idêntica, diferindo apenas na condição WHERE. Após uma mesclagem de exclusão por TTL, o rows_where_ttl_info da parte era zerado, de modo que nenhuma outra mesclagem de TTL era agendada para ela e as linhas expiradas eram mantidas indefinidamente, sem nenhum erro ou mensagem de log. #113384 (groeneai).
  • Corrigido o problema em que max_execution_time e KILL QUERY eram ignorados enquanto uma consulta avaliava geohashesInBox, arrayFold, sleep, base58Decode, h3PolygonToCells ou h3PolygonToCellsWithContainment dentro de uma expressão armazenada nos metadados da tabela, como uma sorting key, um índice de exclusão ou uma chave PARTITION BY. #113456 (groeneai).
  • Corrigido um LOGICAL_ERROR (Reading from materialized CTE '...' before its materialization completed - DelayedPortsProcessor gate is missing in the query plan) gerado quando uma tabela Merge com mais de um filho lê uma CTE materializada referenciada pela consulta externa. #113558 (alexey-milovidov).
  • Corrige Logical error: 'Required output position N is out of range for pass-through inputs' em EXPLAIN ANALYZE sobre uma tabela Merge com vários filhos, um PREWHERE com coluna simples e um WHERE separado. #113725 (groeneai).
  • Corrige um erro lógico (Unexpected return type) quando um filtro sobre uma view cujo tipo de coluna difere do do armazenamento subjacente (por exemplo, information_schema.tables, em que engine é Nullable(String), sobre system.tables, em que é String) é propagado (pushdown) para o armazenamento. #113984 (alexey-milovidov).
  • Corrigido um erro Not-ready Set is passed as the second argument for function 'in' quando uma mutação cujo predicado contém IN (subquery) é cancelada, por exemplo, por KILL MUTATION ou DETACH DATABASE, enquanto o conjunto da subconsulta ainda está sendo construído. #114463 (groeneai).
  • ALTER TABLE ... DROP COLUMN de uma coluna usada na chave de ordenação, primária ou de partição agora falha com ALTER_OF_COLUMN_IS_FORBIDDEN e uma explicação, assim como já ocorre com ALTER TABLE ... CLEAR COLUMN. Antes, falhava com um erro confuso UNKNOWN_IDENTIFIER: Missing columns, proveniente do recálculo das expressões-chave. O mesmo vale para remover ou limpar um grupo Nested inteiro pelo seu prefixo comum quando uma coluna do grupo é usada em uma chave; antes, isso podia destruir silenciosamente os dados do grupo ou deixar uma mutação que nunca terminava. Remover uma coluna usada apenas em uma expressão TTL agora também informa qual expressão TTL é afetada #114468 (m7kss1).
  • Corrigido o problema em que uma coluna renomeada, removida e adicionada novamente em um único ALTER retornava os valores da coluna removida, em vez de seu próprio valor padrão, enquanto a mutação ainda estava pendente. #114601 (tiandiwonder).
  • Corrigida a leitura de uma subcoluna (.size0, .null, um elemento de tupla, String.size) por meio de uma tabela Merge quando a tabela subjacente declara a coluna pai como ALIAS. Essa leitura retornava o valor padrão do tipo e, quando a coluna pai era selecionada na mesma consulta, podia retornar o valor de uma coluna não relacionada. #114673 (groeneai).
  • Corrigida a ausência de linhas no resultado de um SELECT filtrado por pointInPolygon sobre uma chave primária MergeTree quando o argumento de polígono é um literal constante inválido e validate_polygons = 0. A análise da chave primária derivava a poda de granules a partir de um polígono que nunca havia sido validado e descartava granules que continham linhas correspondentes. #114710 (groeneai).
  • Corrigida a formatação de ALTER TABLE ... MATERIALIZE INDEX, MATERIALIZE STATISTICS e MATERIALIZE PROJECTION, que descartava a cláusula IF EXISTS, fazendo com que a consulta formatada fosse diferente da consulta interpretada. Além disso, quatro payloads JSON de AST de ALTER ... STATISTICS que o parser SQL não consegue produzir, e que eram formatados como um comando diferente, passaram a ser rejeitados. #115099 (groeneai).
  • Corrigida uma leitura fora dos limites dos hashes de dicionário em cache ao agregar ou fazer join sobre uma chave LowCardinality(String) cujo dicionário cresce durante a agregação, situação que podia ser acionada a partir de TTL ... GROUP BY. Isso podia gerar um hash incorreto e um heap-buffer-overflow reportado em compilações com sanitizador. #115604 (groeneai).
  • CREATE TABLE e ALTER TABLE agora rejeitam codecs com perdas, como SZ3, em colunas usadas na chave de partição. #115626 (groeneai).
  • A leitura por meio de uma tabela Merge que corresponde a uma tabela Alias cujo destino é uma view parametrizada não gera mais LOGICAL_ERROR: Table has no columns. (o que aborta o servidor em compilações de debug e com sanitizador). Essa tabela agora reporta STORAGE_REQUIRES_PARAMETER, o mesmo erro reportado pela própria view parametrizada. Qualquer outra tabela correspondente que não consiga fornecer colunas agora reporta UNSUPPORTED_METHOD em vez de um erro interno. #115896 (groeneai).
  • Corrigida a pré-visualização em tempo real de uma mutação pendente cuja expressão referencia _sample_factor. Com apply_mutations_on_fly = 1 e uma cláusula SAMPLE, a expressão era avaliada com o fator de amostragem da consulta de leitura em vez do valor persistido pela materialização em segundo plano. Com isso, as linhas pré-visualizadas divergiam do resultado materializado final, e um ALTER TABLE t DELETE WHERE _sample_factor > 1 pendente podia fazer com que uma leitura com SAMPLE não retornasse nenhuma linha. A coluna _sample_factor da própria consulta permanece inalterada. #115906 (groeneai).
  • Arquivos de estatísticas com versão de formato V3 agora são lidos em vez de rejeitados com ILLEGAL_STATISTICS. Esses arquivos foram produzidos apenas por compilações do master durante um curto intervalo, mas as partes que os continham ficavam totalmente ilegíveis e, em um disco somente leitura, ALTER TABLE ... MATERIALIZE STATISTICS não consegue regenerá-los. #116030 (alexey-milovidov).
  • Corrigido o erro Invalid number of columns in chunk pushed to OutputPort (LOGICAL_ERROR) quando uma consulta SELECT ... FROM t STREAM ... ORDER BY ... LIMIT n lia uma tabela com uma PROJECTION. A materialização tardia não é mais aplicada a leituras STREAM. #116187 (groeneai).
  • ALTER TABLE ATTACH PARTITION FROM não é mais replicado em bancos de dados replicados. #94835 (MikhailBurdukov).
  • Corrigido um aborto do servidor (em compilações com sanitizador) e uma perda silenciosa de dados durante a inicialização da tabela quando uma parte MergeTree transacional revertida se sobrepõe a uma parte confirmada. PartLoadingTree::add agora identifica corretamente qual das duas partes sobrepostas foi revertida, remove-a e reatribui seus filhos órfãos à parte confirmada, na ordem correta. #100992 (tuanpach).
  • Corrigido o problema em que indexOfAssumeSorted retornava resultados incorretos para colunas Array(LowCardinality(String)) em tabelas MergeTree. #101771 (Onyx2406).
  • Corrigidas exceções LOGICAL_ERROR ao ler tabelas de data lake Iceberg ou DeltaLake por caminhos que podem chegar ao pipeline de leitura sem um datalake_table_state fixado, como atualizações concorrentes de metadados Iceberg ou leituras merge sobre tabelas DeltaLake. #102033 (groeneai).
  • Corrigido o erro Logical error: Parsed partition value: ... doesn't match partition value for an existing part with the same partition ID: ... lançado por OPTIMIZE TABLE ... PARTITION ... (e outras consultas que resolvem um valor de partição por meio de convertFieldToTypeImpl) em tabelas com chave de partição do tipo Time. #106202 (groeneai).
  • Corrigido o problema em que uma parte de dados era marcada incorretamente como tendo uma projeção quebrada quando uma exclusão leve não deixava nenhuma parte de projeção — seja porque a projeção foi reconstruída com zero linhas de saída, seja porque foi descartada (lightweight_mutation_projection_mode = 'rebuild'/'drop'). Antes, esse estado quebrado desabilitava a otimização por projeção nas consultas sobre essa parte. #106273 (tiandiwonder).
  • Corrigido o problema em que os avisos de sobrecarga de memória/CPU/mutação em system.warnings ficavam um ciclo de métricas assíncronas atrasados (e ausentes no primeiro ciclo). #108035 (alexey-milovidov).
  • Corrigidas uma exceção LOGICAL_ERROR (ScatterExchangeStep should have one source shard, got 8) e linhas duplicadas ao consultar uma tabela Merge sobre tabelas Distributed ou views com a configuração experimental make_distributed_plan = 1. #108401 (groeneai).
  • Corrigidos um aborto do servidor (Sort order of blocks violated) durante uma mesclagem e leituras incorretas quando um elemento LowCardinality não anulável de uma coluna Nullable(Tuple(...)) é usado como subcoluna (por exemplo, como chave de ordenação). #108679 (groeneai).
  • Corrigido um crash no Base64Decode do SDK do Azure incorporado, acessível via azureBlobStorage() (e funções de tabela/armazenamento do Azure relacionados), quando a chave da conta não é um Base64 válido. Um byte >= 0x80 causava uma leitura fora dos limites da tabela de decodificação, e qualquer byte inválido causava um deslocamento à esquerda indefinido de um valor negativo (aborto com sanitizadores). Chaves inválidas agora são rejeitadas corretamente. #108716 (groeneai).
  • Corrigido um LOGICAL_ERROR (“New empty part is about to materialize but the directory already exist”) que podia abortar o servidor em compilações de depuração e com sanitizador quando um DROP/DETACH/MOVE/REPLACE PARTITION em uma tabela MergeTree era executado depois que uma operação semelhante anterior havia sido interrompida (por exemplo, por uma transação revertida ou um crash), deixando para trás um diretório tmp_empty_<part> inativo. Agora, o diretório inativo é recuperado em vez de causar falha. #108879 (groeneai).
  • Corrige uma projeção que retornava o valor padrão do tipo de uma coluna (por exemplo, 0) em vez do DEFAULT definido na DDL (por exemplo, -1) após a expiração do TTL da coluna em uma parte wide. #109013 (tiandiwonder).
  • Corrigida a falha de consultas ALTER em tabelas MergeTree criadas com uma configuração disk personalizada (SETTINGS disk = disk(...)). #109199 (Michicosun).
  • Corrige o aparecimento de linhas obsoletas e excluídas ao ler tabelas de um banco de dados MaterializedPostgreSQL por meio de uma tabela Merge. #109339 (vdimir).
  • Corrigida a leitura de tabelas Paimon particionadas por uma coluna BIGINT cujo valor não cabe em Int32. Esses valores de partição eram truncados (por exemplo, 9223372036854775807 virava -1), o que gerava um caminho de partição incorreto e resultava em um erro de sistema de arquivos. #109510 (groeneai).
  • Corrige um erro lógico (“Cannot determine row level filter; 0 columns deleted, 0 columns added”) ao ler de uma tabela Merge cuja tabela filha possui uma row policy com um filtro que consiste apenas em uma coluna existente (por exemplo, CREATE ROW POLICY ... USING flag). #109843 (groeneai).
  • O IcebergLocal informava Azure como tipo de armazenamento. #109872 (PedroTadim).
  • CHECK TABLE agora informa a corrupção real de uma parte de projeção cujos metadados não puderam ser carregados, em vez de um erro enganoso Columns doesn't match ... Expected: 0 columns. #110262 (Algunenano).
  • Corrigida a falha na inicialização do servidor para tabelas MergeTree em discos de armazenamento de objetos quando um arquivo txn_version.txt.tmp remanescente tem metadados corrompidos no nível do disco. #110519 (alexey-milovidov).
  • Corrigido o problema em que uma tabela MergeTree com uma projeção de _part_offset ou de ordem de commit não podia mais ser anexada após allow_part_offset_column_in_projections ou allow_commit_order_projection serem desabilitadas e a tabela ser desanexada ou o servidor ser reiniciado. Essas duas configurações só se aplicam no momento do CREATE e, portanto, deixaram de ser verificadas novamente no ATTACH. #110570 (groeneai).
  • Corrige um LOGICAL_ERROR raro (“Unexpected number of parts to remove from parts_queue”) que podia abortar o servidor em uma ReplicatedMergeTree quando duas operações de partição (por exemplo, duas consultas MOVE PARTITION / REPLACE PARTITION, ou uma concorrendo com um DROP_RANGE em segundo plano) cancelavam simultaneamente a verificação de partes em segundo plano em intervalos sobrepostos. #110738 (groeneai).
  • Corrigido um erro lógico Hash is not set for serialization que podia ocorrer quando uma coluna com um codec Quantized(...) estava aninhada em uma serialização reutilizável via pool, por exemplo, uma tabela Merge sobre fontes cuja coluna de mesmo nome tem tipos diferentes (mesclados em um Variant). #110776 (groeneai).
  • Corrigido um std::length_error (LOGICAL_ERROR) ao ler uma tabela MergeTree com um valor patológico de max_streams_for_merge_tree_reading (próximo do máximo de UInt64) em conjunto com allow_asynchronous_read_from_io_pool_for_merge_tree = 1. A configuração agora é limitada ao mesmo teto de max_threads. #110936 (groeneai).
  • Corrige um erro lógico Cannot calculate columns sizes when columns or checksums are not initialized durante a mesclagem de uma tabela MergeTree de coluna única cuja única coluna tem um TTL de coluna que expira por completo (com min_bytes_for_wide_part = 1). #111169 (groeneai).
  • Executa fsync nos arquivos de índice de texto de uma parte mesclada ou materializada quando min_rows_to_fsync_after_merge / min_compressed_bytes_to_fsync_after_merge / fsync_part_directory estão definidos. Antes, esses eram os únicos arquivos da parte que ficavam sem sincronização, de modo que uma queda de energia logo após uma mesclagem podia deixar uma parte confirmada, porém corrompida, e causar perda de dados. #111335 (groeneai).
  • Corrige OPTIMIZE TABLE ... MANIFEST para tabelas Iceberg quando as tuplas de partição do manifesto não correspondem à respectiva especificação de partição #111368 (SmitaRKulkarni).
  • Corrige uma leitura fora dos limites (release) / erro lógico (debug) na otimização de materialização tardia, além de um erro lógico em Pipe::unitePipes para tabelas Merge, quando a otimização de leitura direta a partir do índice de texto deixa uma coluna virtual de índice não utilizada no cabeçalho de leitura de uma tabela MergeTree com vários índices text. #111467 (groeneai).
  • Corrige um LOGICAL_ERROR (“Part level Min-Max index was constructed from unexpected columns set”) que podia abortar uma mesclagem em segundo plano em compilações de debug/com sanitizador depois que part_minmax_index_columns era reduzido (por exemplo, de with_block_number_offset de volta para partition_key_only). #111511 (groeneai).
  • Corrigida uma falha ao executar uma leitura STREAM (enable_streaming_queries = 1) em uma tabela com mais de uma partição e com uma row policy definida. Em compilações de debug e com sanitizador, ocorria o erro lógico Filter column ... not found in DAG outputs; em compilações de release, podia ocorrer segfault. #111572 (groeneai).
  • Corrigido um LOGICAL_ERROR (Cannot create part with type Compact and storage type Full because table does not support polymorphic parts) gerado quando uma tabela MergeTree carrega uma parte Compact preexistente enquanto suas configurações atuais desabilitam partes polimórficas (granularidade não adaptativa). Isso podia acontecer, por exemplo, quando uma tabela somente leitura compartilha um caminho em disco com outra tabela e recarrega suas partes via SYSTEM RESTART DISK ou na inicialização do servidor. Em compilações de debug e com sanitizador, a exceção aborta o servidor. #111626 (groeneai).
  • Com fsync_part_directory = 1, a renomeação de um diretório de parte do nome temporário para o nome final agora também se torna durável, por meio de fsync no diretório pai (e, em movimentações entre diretórios pais diferentes, também no diretório pai de origem). Antes, apenas o diretório movido recebia fsync, de modo que uma queda de energia logo após o commit de uma parte podia deixá-la ausente no disco, mesmo com seus arquivos já gravados, causando perda de linhas apesar de a configuração estar habilitada. #111861 (groeneai).
  • Corrigidos resultados incorretos e um LOGICAL_ERROR quando uma coluna Nullable(Tuple(...)) é selecionada junto com uma de suas subcolunas de elemento que carregam nulos (Variant, Dynamic ou LowCardinality) de uma tabela MergeTree. A leitura da subcoluna marcava como NULL as linhas que são NULL na tupla pai em uma coluna já compartilhada pelo cache de substreams, de modo que a leitura da coluna inteira obtinha valores deslocados. #111949 (groeneai).
  • Corrigido um problema em que hash joins perdiam suas otimizações pós-compilação (conversão para uma tabela hash fixa, o runtime filter compartilhado, reordenação de intervalos da right table) sempre que havia um limite automático de spill-to-disk configurado, o que é o padrão desde a versão 26.5. #111972 (alexey-milovidov).
  • Corrige resultados incorretos (linhas ausentes sem nenhum aviso) em hasAllTokens e em outras buscas de índice text com múltiplos tokens em compilações que não usam simdcomp (todos os alvos exceto x86_64 Linux, por exemplo, aarch64) quando text_index_posting_list_apply_mode = 'lazy'. O decodificador portátil de bitpacking não gravava os zeros decodificados para um bloco com largura de bits igual a zero, de modo que uma entrada localizada em um segmento de entrada única era descartada. O formato em disco não foi alterado, e os dados existentes são lidos corretamente após a correção. #112178 (groeneai).
  • Agora as operações falham, em vez de ignorar o erro, quando estatísticas corrompidas do MergeTree são carregadas. #112201 (skuznetsov-clickhouse).
  • Corrige a perda silenciosa de gravações Iceberg confirmadas no HDFS: um commit do Iceberg publica cada novo arquivo de metadados com uma gravação condicional, mas o HDFSObjectStorage descartava a condição e realizava uma sobrescrita simples, de modo que gravadores concorrentes recebiam todos a confirmação, enquanto o snapshot de um deles se tornava inacessível. Agora o HDFS recusa a gravação condicional; com isso, gravações Iceberg gerenciadas pelo armazenamento no HDFS, incluindo CREATE TABLE ... ENGINE = IcebergHDFS(...) com uma lista de colunas explícita, passam a falhar. As leituras não são afetadas. #112437 (groeneai).
  • Corrige o DELETE em tabelas KeeperMap, que excluía apenas as primeiras max_block_size linhas correspondentes, mas reportava a mutação como concluída com sucesso. Também corrige a falta de atomicidade do DELETE com keeper_map_strict_mode = 1: ele podia recorrer a remoções sem versionamento e excluir linhas atualizadas concorrentemente, além de aplicar as linhas correspondentes bloco a bloco, de modo que um conflito podia deixar a exclusão parcialmente aplicada. #112777 (alexey-milovidov).
  • Corrigido um problema em que um erro transitório do Azure Blob Storage no caminho de leitura ou mesclagem — um 403 Forbidden de propagação de permissões RBAC, uma falha de autenticação de credenciais ou um tempo limite de conexão reportado como 408 — era classificado incorretamente como não passível de nova tentativa e reportado como POTENTIALLY_BROKEN_DATA_PART (Code 740), gerando um falso alerta crítico para uma parte íntegra. Essas falhas transitórias agora são tratadas como passíveis de nova tentativa, e uma falha realmente persistente aparece como um erro comum do Azure, em vez de uma parte de dados supostamente corrompida. #112871 (arsenmuk).
  • Corrigido um problema em que listObjects, em um disco Azure Blob Storage com endpoint prefixado, retornava nomes de blobs incorretos em todas as páginas após a primeira, porque a paginação ignorava o contêiner do cliente que remove o prefixo do endpoint. Agora a paginação volta a passar pelo contêiner por meio do token de continuação, garantindo que os nomes de blobs de todas as páginas estejam corretos. #112872 (arsenmuk).
  • Corrige a perda do índice minmax por parte sobre _block_number e _block_offset após o recarregamento da tabela, quando a parte havia sido gerada por uma mutação que não reescreve a parte inteira. #112878 (alexey-milovidov).
  • Corrigida uma exceção (em compilações de release, um erro que impede a inicialização do servidor) quando um predicado de mutação usa a função de tabela merge sem um nome de banco de dados explícito. Agora é usado o banco de dados da tabela mutada, assim como já ocorre com nomes de tabelas. #113185 (alexey-milovidov).
  • Corrige resultados incorretos e um LOGICAL_ERROR ao ler uma subcoluna de um membro Nested removido e adicionado novamente junto com um membro existente do mesmo grupo, em uma tabela MergeTree com share_nested_offsets = 1. Os membros existentes retornavam valores de um bloco posterior sempre que a leitura abrangia mais de um bloco. #113225 (groeneai).
  • Corrige uma exceção aritmética em builds de depuração e com sanitizers ao ler de uma tabela Merge com um valor muito grande de max_streams_to_max_threads_ratio: o número de fluxos era truncado para 32 bits, de modo que múltiplos de 2^32 se tornavam zero. Além disso, passa a lançar PARAMETER_OUT_OF_BOUND em vez de invocar comportamento indefinido quando a multiplicação das contagens de fluxos de uma tabela Merge excede size_t, evita um overflow ao limitar os fluxos de MergeTree à quantidade de dados e rejeita uma leitura de tabela Merge cuja contagem agregada de origens excederia 65536. #113382 (alexey-milovidov).
  • Corrigidas as gravações no disco hdfs: elas falhavam com Parent directory doesn't exist porque as chaves de objeto geradas contêm um prefixo de diretório aninhado, mas, ao contrário dos armazenamentos de blobs, o HDFS tem diretórios reais e não cria o diretório pai ausente ao criar o arquivo.. #113396 (alexey-milovidov).
  • Corrigido o erro reportado quando as funções de tabela remote/remoteSecure ou os motores de tabela Remote/RemoteSecure recebem uma coleção nomeada inexistente junto com uma substituição key = value. Essa chamada era silenciosamente reinterpretada como uma chamada posicional, de modo que a substituição era analisada como uma expressão de dados e o erro reportado mencionava algo sem relação com o problema (por exemplo, Function with name merge does not exist para remote(collection, database = merge(...))). Agora o erro reportado indica a coleção nomeada ausente. #113510 (groeneai).
  • Corrigido um loop infinito em mesclagens em segundo plano e em OPTIMIZE quando merge_max_block_size_bytes era definido abaixo do byteSize() de uma coluna vazia. Uma coluna LowCardinality vazia ainda carrega seu dicionário, então o limite de bytes podia ser atingido antes mesmo que uma única linha fosse mesclada; a mesclagem passava então a produzir blocos vazios indefinidamente, consumindo 100% de um núcleo de CPU e sem nunca liberar seu slot no pool de segundo plano. #113585 (groeneai).
  • Corrigida uma mutação de uma parte Compact que produzia resultados diferentes dependendo de as informações de serialização da parte ainda estarem em memória ou terem sido recarregadas de serialization.json, quando a tabela usa serialization_info_version = 'basic'. Em ReplicatedMergeTree, isso fazia com que duas réplicas com uma parte de origem idêntica byte a byte gravassem partes mutadas diferentes, e a mutação falhava com CHECKSUM_DOESNT_MATCH. #113588 (groeneai).
  • Os backups agora reportam o erro subjacente de acesso ao arquivo de bloqueio, em vez de indicar incorretamente um backup concorrente, quando o armazenamento de destino não consegue ler o arquivo .lock. #113637 (kirillshokhin).
  • Corrigida uma condição de corrida entre as tarefas em segundo plano de uma tabela MergeTree (atualização de estatísticas, atualização de partes, carregamento de partes obsoletas/inesperadas) e a destruição da tabela. #113722 (alexey-milovidov).
  • Corrige UPDATE e DELETE leve que liam as tabelas erradas quando o banco de dados da tabela atualizada era diferente do banco de dados da sessão. A expressão da mutação agora é normalizada em relação ao banco de dados da tabela atualizada, tanto para a função de tabela merge, que usa implicitamente o banco de dados atual, quanto para identificadores de tabela não qualificados. Antes, esses nomes eram resolvidos em relação ao banco de dados da sessão, de modo que a instrução atualizava ou excluía silenciosamente linhas selecionadas de outra tabela. #113748 (groeneai).
  • Corrigida uma exceção ao ler uma tabela MergeTree por camadas de intervalo de chave primária quando uma camada produz um pipe vazio. #114177 (alexey-milovidov).
  • BACKUP, RESTORE e ENGINE = Backup agora autorizam o local do backup com base nos privilégios SOURCES do usuário, assim como já fazem s3(), file() e azureBlobStorage(). Antes, um usuário com BACKUP, mas sem SOURCES, podia gravar e ler backups em qualquer local acessível pelo servidor. Agora, gravar um backup exige a direção WRITE na fonte de destino (WRITE ON S3, WRITE ON AZURE, WRITE ON FILE), e lê-lo exige READ; destinos Disk(...) continuam restritos apenas por backups.allowed_disk. #114405 (groeneai).
  • Corrigida a leitura de uma tabela durante uma mutação em andamento: uma coluna MATERIALIZED podia retornar um valor desatualizado, e selecioná-la junto com uma coluna atualizada podia resultar em erro. #114561 (tiandiwonder).
  • Corrigido um erro lógico (Block structure mismatch) ao ler uma tabela Merge com make_distributed_plan habilitado sobre tabelas filhas com operações de conjunto internas. #114753 (alexey-milovidov).
  • OPTIMIZE TABLE em uma tabela de armazenamento de objetos cujo motor não implementa compactação informava sucesso sem fazer nada. Agora gera um erro, como todos os outros motores que não suportam a instrução. Isso afeta DeltaLake, Paimon, Hudi e os motores simples de armazenamento de objetos (S3, GCS, COSN, OSS, AzureBlobStorage, HDFS e URL baseado em armazenamento de objetos); Iceberg, que implementa compactação, não foi alterado. #114805 (groeneai).
  • Corrigido BAD_DATA_PART_NAME (“Trying to get part name in new format for old format version”) em uma ReplicatedMergeTree criada com a sintaxe posicional obsoleta via allow_deprecated_syntax_for_merge_tree. Uma mutação podia ser informada como concluída em uma réplica que não a havia aplicado, e a tabela podia permanecer somente leitura após uma reinicialização. #114980 (groeneai).
  • Corrigido Found patch part ... that intersects mutation with version ... (LOGICAL_ERROR) em tabelas com atualizações leves. Uma mesclagem de partes de patch podia gerar um patch cujo intervalo de versões de dados abrangia a versão de dados de uma parte existente; esse patch não podia ser aplicado nem ignorado, de modo que todas as operações posteriores na partição falhavam e a fila de replicação travava. Essas mesclagens não são mais atribuídas. #115064 (alexey-milovidov).
  • Corrigida a falha na inicialização do servidor quando um motor de banco de dados Backup faz referência a um backup que se tornou indisponível (por exemplo, quando seus arquivos foram excluídos ou o armazenamento subjacente está inacessível). Agora o banco de dados é carregado sem tabelas, em vez de impedir a inicialização de todo o servidor. #83188 (orloffv).
  • Corrigida a recuperação do logging após erro de disco cheio. Antes, quando o disco de log enchia, o ClickHouse entrava em estado de falha e inundava o syslog com mensagens de erro (podendo gravar mais de 100 GB/hora), sem nunca se recuperar, mesmo após a liberação de espaço em disco. Agora o sistema de logging se recupera automaticamente assim que há espaço em disco disponível, sem exigir a reinicialização do servidor. #93127 (jaehanbyun).
  • Corrigida uma falha (crash) no visitante de esquema do armazenamento DeltaLake. #97112 (kssenii).

Correções para lago de dados e armazenamento externo

  • Corrigida uma falha transitória Code: 499 ... InvalidPart (S3_ERROR) em uploads multipart no S3 (por exemplo, INSERT INTO ... hits_s3). O MinIO pode informar brevemente que uma parte recém-enviada está ausente em CompleteMultipartUpload; agora esse erro passa por novas tentativas, assim como o já tratado NoSuchKey, limitadas por s3_max_unexpected_write_error_retries. #109364 (groeneai).
  • ALTER TABLE ... DELETE e ALTER TABLE ... UPDATE em tabelas Iceberg cujo formato de arquivo de dados não é Parquet agora são rejeitados com um erro NOT_IMPLEMENTED claro, em vez de derrubar o servidor ou corromper silenciosamente a tabela. #105893 (groeneai).
  • Corrigido o erro Cannot add column ...: column with this name already exists em INSERT SELECT a partir de uma função de tabela como file, s3 ou input, quando a mesma coluna de origem é selecionada mais de uma vez. #105982 (crakjie).
  • Valores sensíveis passados como parâmetros de query string HTTP (por exemplo, a vinculação de parâmetros de consulta param_*, como param_secret_key/param_aws_secret_access_key, o parâmetro password ou parâmetros signature no estilo S3) não são mais gravados literalmente em system.text_log nem em spans do OpenTelemetry. A linha de log Request URI agora oculta os valores de parâmetros cujos nomes indiquem conteúdo sensível, substituindo-os por [HIDDEN]. #108475 (groeneai).
  • Corrigida a coluna virtual _etag dos motores de tabela S3Queue e AzureQueue: ela era declarada, mas nunca preenchida, de modo que SELECT _etag sempre retornava uma string vazia. Agora ela retorna o ETag do objeto, assim como o motor S3 e a função de tabela s3(). #108625 (groeneai).
  • Uma consulta que lê ou grava no S3 e é cancelada (por exemplo, por KILL QUERY) enquanto uma requisição ao S3 está em andamento agora é reportada como cancelada, em vez de gerar um erro enganoso de rede/S3. Em especial, um backup ou restauração para o S3 que for cancelado agora reporta BACKUP_CANCELLED/RESTORE_CANCELLED em system.backups. #108673 (jkartseva).
  • Corrigida a coluna virtual _tags do motor de tabela S3Queue: ela era declarada, mas nunca preenchida, de modo que SELECT _tags sempre retornava um map vazio. Agora ela retorna as tags do objeto, assim como o motor S3 e a função de tabela s3(). #108676 (groeneai).
  • Corrigido o problema em que SHOW TABLES e SELECT … FROM system.tables retornavam resultados diferentes para bancos de dados de catálogo do lago de dados: agora, as tabelas que o ClickHouse não consegue ler ficam ocultas de forma consistente em ambos. #109273 (SmitaRKulkarni).
  • Corrigido um abort do servidor (ou, em compilações de release, um arquivo de dados silenciosamente não finalizado) quando um INSERT em uma tabela Delta Lake (DeltaLakeLocal / deltaLake) falha depois que o sink já começou a gravar, por exemplo, quando a consulta de origem lança uma exceção no meio do insert ou quando a consulta é cancelada. #109328 (groeneai).
  • Corrigido Not found column or subcolumn c.null in block (e Bad cast from ColumnConst to ColumnNullable em compilações de debug/sanitizer) ao executar WHERE col IS NULL / IS NOT NULL em uma coluna Iceberg resultante de evolução de esquema, adicionada depois que arquivos de dados mais antigos foram gravados, com optimize_functions_to_subcolumns=1 (o padrão). #109515 (groeneai).
  • Corrige o erro Host is empty in S3 URI quando uma subconsulta escalar é usada como argumento de URL da função de tabela s3 (ou como argumento de qualquer outra função de tabela) em consultas CREATE TABLE ... AS SELECT: subconsultas escalares em argumentos de funções de tabela agora são avaliadas durante a análise da consulta. #110254 (CheSema).
  • Corrige um erro lógico (abort do servidor em builds de debug/sanitizer) quando um ALTER com múltiplos comandos, como UPDATE ..., DELETE ..., era executado em uma tabela Iceberg. Essas mutações agora são rejeitadas com um erro NOT_IMPLEMENTED explícito. #110347 (groeneai).
  • Corrige o problema em que tabelas Iceberg geravam IDs de campo duplicados após ALTER TABLE ... ADD COLUMN quando o schema inicial continha campos aninhados (Tuple/Array/Map). last-column-id agora registra o maior ID de campo atribuído, incluindo os filhos aninhados, de modo que uma coluna adicionada posteriormente não reutiliza mais um ID de campo aninhado e as leituras deixam de falhar com ICEBERG_SPECIFICATION_VIOLATION (Duplicate field id). #110884 (groeneai).
  • Corrige o problema em que DELETE/UPDATE em uma tabela Iceberg removia silenciosamente as linhas erradas (ou lançava NOT_FOUND_COLUMN_IN_BLOCK) quando a tabela continha arquivos de dados gravados tanto antes quanto depois de ALTER TABLE ... ADD COLUMN e optimize_move_to_prewhere estava habilitado. #111693 (groeneai).
  • Corrige o problema em que made_current_at em system.iceberg_history passava a ser 1970-01-01 para um snapshot retido após ALTER TABLE ... EXECUTE expire_snapshots em uma tabela Iceberg. Também corrige o problema em que system.iceberg_history não retornava nenhuma linha para uma tabela cujos metadados não possuem snapshot-log. #111781 (groeneai).
  • Corrige a corrupção de dados ao inserir em uma tabela Iceberg acessada por meio de uma MATERIALIZED VIEW. O arquivo de dados era gravado com base nos tipos de coluna definidos no CREATE do destino, e não no schema Iceberg atual dele; assim, um valor DateTime era armazenado como um int Avro simples e lido de volta como microssegundos, e, com DateTime64(0) ou DateTime64(9), o arquivo nem sequer podia ser lido. Como consequência, INSERT INTO <materialized view> em um destino cujo schema Iceberg é mais amplo do que as colunas declaradas da visão agora gera TYPE_MISMATCH em vez de gravar uma linha corrompida. #112359 (groeneai).
  • Corrige a gravação de tabelas Iceberg cujo schema contém uma tupla aninhada dentro de outra tupla. Os metadados publicados da tabela substituíam os nomes de campo da tupla interna por nomes posicionais 1, 2, …, de modo que, com o formato padrão Parquet, o INSERT falhava com INCORRECT_DATA e, com Avro, a coluna não podia ser lida de volta. #112480 (groeneai).
  • Corrige um deadlock que travava permanentemente um banco de dados Filesystem ou HDFS quando duas consultas resolviam o mesmo nome de tabela simultaneamente. Todas as consultas seguintes a esse banco de dados ficavam bloqueadas indefinidamente, sem possibilidade de interrupção, e era preciso reiniciar o servidor para recuperá-lo. #112495 (groeneai).
  • Corrige o problema em que tabelas DeltaLake retornavam menos linhas do que o esperado quando o predicado WHERE continha, sob um NOT, uma subexpressão que o tradutor de predicados do delta-kernel não consegue tratar. Essa subexpressão agora é informada ao delta-kernel como um predicado desconhecido explícito, e não como o fim do iterador de filhos, o que antes truncava silenciosamente a conjunção que a envolvia. #112652 (groeneai).
  • Corrigido o problema em que ALTER TABLE ... EXECUTE remove_orphan_files excluía um metadata/version-hint.text ativo de uma tabela Iceberg. A entrada desse arquivo no conjunto de alcançáveis era montada por concatenação de strings, presumindo uma barra final em um valor que nunca a tem; por isso, o arquivo de indicação real nunca era reconhecido como alcançável e acabava removido assim que ficava mais antigo que o limiar older_than. Com iceberg_use_version_hint = 1, a tabela deixava de poder ser lida. #113548 (groeneai).
  • Corrigido LOGICAL_ERROR ao filtrar uma coluna Iceberg que havia se tornado Nullable por meio de ALTER TABLE ... MODIFY COLUMN. #114521 (groeneai).
  • Corrigido um caso em que ATTACH TABLE com uma definição ENGINE = URL(...) não verificava a permissão TABLE ENGINE do motor para o qual o esquema de URL encaminha. Um usuário com apenas TABLE ENGINE ON URL conseguia anexar e depois ler uma tabela baseada em File, S3, AzureBlobStorage ou HDFS, algo que CREATE TABLE rejeita corretamente. #115914 (groeneai).
  • Corrigida a falha de requisições HTTP de saída (por exemplo, `aiGenerate`, função de tabela `url`, S3) com `No route to host` em hosts que anunciam tanto IPv4 quanto IPv6 quando apenas uma família de endereços é roteável. O pool de conexões HTTP agora recorre ao próximo endereço resolvido quando o primeiro falha com um erro de rede, em vez de propagar o erro logo na primeira requisição. #103786 (alexey-milovidov).
  • Agora é possível ler um array Avro de registros {key, value} com dois campos em uma coluna Map do ClickHouse. Essa é a codificação que o Iceberg e o Spark geram para um MAP<K, V> com chave que não é string (os maps nativos do Avro só aceitam chaves string). Antes, esse arquivo podia ser lido como Array(Tuple(key, value)), mas não como Map(K, V), o que falhava com Type Map(...) is not compatible with Avro array. #109289 (groeneai).
  • Corrigida a leitura de uma tabela Iceberg com um arquivo de metadados cujo número de versão contém apenas dígitos, mas excede o intervalo de inteiros de 32 bits (por exemplo, v99999999999999999999.metadata.json). Antes, esse nome gerava um std::out_of_range (STD_EXCEPTION) pouco informativo em vez de um erro BAD_ARGUMENTS claro. #109619 (groeneai).
  • Corrigido o nome dos arquivos de metadados Iceberg comprimidos com gzip. O ClickHouse os gravava como v{N}.gzip.metadata.json (o token HTTP Content-Encoding), enquanto a especificação do Iceberg espera a extensão gz, ou seja, v{N}.gz.metadata.json. Com isso, o Spark e outros leitores de catálogo Hadoop não encontravam os metadados gravados pelo ClickHouse. Agora o ClickHouse grava v{N}.gz.metadata.json e continua lendo o nome legado gzip para manter a compatibilidade retroativa. #109812 (groeneai).
  • Corrigido o problema em que uma tabela Iceberg com formato de escrita Avro serializava como obrigatório um campo declarado "required": false cujo tipo é list, map ou struct, sem a union ["null", T]. Com isso, o próprio esquema do arquivo de dados divergia dos metadados da tabela, e outros leitores Iceberg viam um campo obrigatório. Agora esse campo é gravado como a union ["null", T] que a especificação do Iceberg usa para campos opcionais. #112648 (groeneai).
  • Corrigido made_current_at em system.iceberg_history, que informava o momento mais antigo em que um snapshot se tornou atual, em vez do mais recente, quando o mesmo snapshot-id aparece mais de uma vez no snapshot-log do Iceberg (como ocorre após um rollback). #113598 (groeneai).
  • Corrigido um travamento de até uma hora em BACKUP/RESTORE ... TO S3, em discos GCS e na função de tabela s3 quando a coleção nomeada define http_client = 'gcp_oauth' e o endpoint de token OAuth2 do Google aceita a conexão, mas nunca responde. A requisição do bearer token não herda mais o tempo limite de requisição de transferência de dados do chamador; a espera pela resposta agora é limitada a 10 segundos, o mesmo limite aplicado à requisição STS AssumeRole. #115531 (groeneai).
  • Corrigido um erro lógico no cache do sistema de arquivos (Expected file ... not to exist) que podia ocorrer quando um download de cache em segundo plano falhava com uma exceção diferente de ErrnoException (por exemplo, durante a execução de OPTIMIZE em uma tabela Iceberg), deixando para trás um arquivo de cache órfão vazio. #110549 (groeneai).
  • Corrigido o problema em que caches configurados por um número máximo de entradas (política SLRU) deixavam silenciosamente de admitir novas entradas depois que essa quantidade de entradas tivesse sido acessada pelo menos duas vezes. Entre os caches afetados estão os caches de arquivos de metadados do Iceberg e do Paimon, o cache de metadados do Parquet, os caches de índice de texto, o cache de índice de similaridade vetorial, o cache de expressões compiladas e o cache de status de arquivos do ObjectStorageQueue. #115517 (groeneai).
  • Corrigidas leituras de tabelas Paimon que podiam falhar enquanto a indicação mutável snapshot/LATEST era substituída de forma concorrente. Indicações inválidas ou desatualizadas agora recorrem com segurança à listagem de snapshots. #112010 (JiaQiTang98).
  • Agora a exceção subjacente real é exibida quando um arquivo zip não pode ser descompactado porque o buffer de entrada (por exemplo, um buffer de leitura do S3 com restricted_seek = true) recusa um seek ou uma leitura solicitada pelo minizip. Antes, o erro real ficava escondido por trás da mensagem genérica Couldn't unpack zip archive: Code = -100 / Couldn't open zip archive. #105103 (groeneai).
  • Corrigida a escrita no Iceberg para metadados sem refs #106896 (AVMusorin).
  • Corrigida uma exceção ao inserir dados em uma tabela Iceberg cujos metadados foram criados por um mecanismo externo e omitem os arrays opcionais snapshots, metadata-log ou snapshot-log. Esses inserts agora são concluídos com sucesso em vez de falhar. #107473 (tiandiwonder).
  • Corrigido um erro ReadBuffer is canceled. Can't read from it. que podia ocorrer quando um upload para o S3 (por exemplo, um backup) era repetido após um erro de leitura transitório. #108573 (groeneai).
  • Corrigido um std::future_error (“The associated promise has been destructed prior to the associated state becoming ready”) que podia surgir, e abortar o servidor em builds de depuração/com sanitizador, quando falhava o agendamento da tarefa assíncrona final de conclusão do upload multipart do S3/Azure (por exemplo, com o pool de threads esgotado). Agora o erro real de agendamento é informado. #108730 (groeneai).
  • Corrigida a leitura de timestamps ORC posteriores a ~2262 em uma coluna DateTime64 com escala menos precisa que 9. O leitor ORC nativo convertia todo timestamp por meio de um intermediário fixo DateTime64(9), que causa overflow de Int64 na escala de nanossegundos, e rejeitava esses valores com VALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE, mesmo quando a escala DateTime64 solicitada (por exemplo, DateTime64(6), como a produzida pelo Iceberg) consegue representar o valor. Agora os timestamps são lidos diretamente na escala solicitada, e date_time_overflow_behavior é respeitado quando nem a escala de destino consegue comportar o valor. #109302 (groeneai).
  • A leitura de uma tabela Paimon cujo esquema contém um tipo aninhado sem suporte (por exemplo, um campo ROW) agora gera um erro BAD_ARGUMENTS claro, indicando o tipo sem suporte, em vez de um simples DB::Exception. (OK) com código de erro 0 e sem mensagem. #109762 (groeneai).
  • Corrigida a leitura de tabelas Iceberg particionadas mais de uma vez pela mesma coluna de origem (por exemplo, PARTITIONED BY (hours(ts), ts)). Antes, essas tabelas falhavam com Cannot add column ...: column with this name already exists (ILLEGAL_COLUMN). #109895 (groeneai).
  • Os arquivos de dados gravados pelo ClickHouse em tabelas Iceberg agora incorporam os IDs de campo do Iceberg nos formatos Avro (field-id) e ORC (atributos de tipo iceberg.id/iceberg.required), e as colunas String em ORC passam a ser gravadas como string ORC em vez de binário. Antes, apenas o Parquet incorporava IDs de campo; por isso, leitores em conformidade com a especificação (por exemplo, Spark/iceberg-java) retornavam silenciosamente NULLs em linhas Avro gravadas pelo ClickHouse após a renomeação de uma coluna e simplesmente não conseguiam ler arquivos ORC gravados pelo ClickHouse. #109994 (groeneai).
  • Corrigido o erro lógico ChunkInfoRowNumbers does not exist ao executar OPTIMIZE TABLE em uma tabela Iceberg que contém um arquivo de dados em formato diferente de Parquet (por exemplo, ORC) mais recente que todos os position delete files. #110107 (alexey-milovidov).
  • Corrigida a leitura de arquivos Parquet grandes a partir de entradas zip STORED não comprimidas via s3 e file. #110495 (Gudauu).
  • Uma falha ao iniciar um background schedule pool (por exemplo, o pool iceberg, quando o global thread pool está esgotado) não aborta mais o servidor: o erro agora é uma exceção recuperável. Além disso, consultar system.background_schedule_pool não cria mais esses pools como efeito colateral. #111209 (groeneai).
  • Corrigida a autenticação DLF no REST catalog do Paimon: a assinatura da requisição era calculada uma única vez e reutilizada, de modo que todas as requisições ao catálogo após a primeira falhavam com HTTP 401 e SHOW TABLES retornava uma lista vazia. Também foi corrigida a detecção de HTTP 404 nas verificações de existência de tabelas. #112015 (JiaQiTang98).
  • Corrigido um LOGICAL_ERROR (partitions_count > 0) ao particionar fragmentos de dados Iceberg esvaziados por position deletes, por exemplo, durante a compactação de uma tabela Iceberg particionada com arquivos de dados totalmente excluídos. #112432 (PedroTadim).
  • Corrigida a exclusão de objetos em lote no Azure, que não registrava eventos Delete em system.blob_storage_log quando a própria requisição do lote falhava, deixando o lote inteiro sem registro. Agora, um evento Delete é registrado para cada objeto quando ocorre uma falha no nível do lote. #112873 (arsenmuk).
  • Corrigida a leitura de tabelas Paimon particionadas por uma coluna TIMESTAMP com precisão superior a milissegundos, que falhava com scale 6 is not supported, only support scale <= 3. #113401 (JiaQiTang98).
  • Corrige uma falha ao ler uma tabela de lago de dados cujo schema declara uma coluna com nome vazio. Metadados Iceberg malformados são rejeitados com ICEBERG_SPECIFICATION_VIOLATION; um schema fornecido por um catálogo, Delta Lake ou Paimon é rejeitado com AMBIGUOUS_COLUMN_NAME. A verificação é incondicional; portanto, uma tabela Iceberg que apenas mantém um schema histórico não utilizado com um nome de campo vazio também se torna ilegível, em vez de abortar quando esse schema é lido. #114394 (groeneai).
  • A leitura de uma tabela Iceberg cujos metadados descrevem uma evolução de schema proibida pela especificação do Iceberg não aborta mais o servidor. Quatro violações da especificação em IcebergSchemaProcessor eram reportadas como LOGICAL_ERROR, que é tratado como falha de asserção, ou chegavam sem verificação a uma asserção fatal; agora elas geram ICEBERG_SPECIFICATION_VIOLATION. #114518 (groeneai).
  • Corrigido o problema em que a coluna virtual _time das funções de tabela url/urlCluster era sempre NULL em builds baseados em musl, causado pela análise não portável do cabeçalho HTTP Last-Modified. #111619 (thevar1able).
  • Corrigido o problema em que o servidor se recusava a iniciar após a criação de uma tabela com CREATE TABLE ... AS url('http://host/**/', ...) enquanto allow_experimental_url_wildcard_from_index_pages estava habilitado. Ao carregar os metadados dessa tabela, a verificação de recurso experimental era reavaliada e falhava com SUPPORT_IS_DISABLED, abortando a inicialização. #115095 (groeneai).
  • Uma tabela do motor de banco de dados URL não revela mais a um usuário sem a concessão de leitura da origem se um arquivo local existe: EXISTS TABLE, que exige apenas o privilégio SHOW TABLES, e a resolução de uma tabela não sondam mais o sistema de arquivos antes de a concessão ser confirmada. #113029 (alexey-milovidov).
  • Aplica query_masking_rules às mensagens anexadas via Exception::addMessage, para que credenciais codificadas em URL nos sufixos (in file/uri ...) de erros de jdbc()/odbc() não vazem quando houver regras de mascaramento configuradas. #106916 (gaurav0107).

Correções de formatos e de ingestão

  • Leituras sem schema de time32/time64 do Arrow (por exemplo, SELECT * FROM file(..., 'Arrow')) agora inferem Time64 em vez de DateTime64. Anteriormente, era inferido DateTime64. Qualquer processamento posterior que dependa do tipo inferido antigo deixará de funcionar após a atualização. Também adiciona suporte à exportação de Time/Time64 para Arrow, com o tipo de tempo apropriado do Apache Arrow selecionado conforme a precisão. #104316 (Maoyao233).
  • Corrigidos possíveis resultados incorretos ou leituras fora dos limites quando um INSERT é revertido após um erro no meio de um lote (por exemplo, em tabelas Buffer, inserções assíncronas ou nos motores Kafka/RabbitMQ/FileLog) enquanto a replicação lazy de colunas (enable_lazy_columns_replication) está ativa. #108935 (groeneai).
  • Corrigida uma inconsistência do parser em que uma lista de colunas de INSERT aceitava um seletor de colunas qualificado escrito como t.* LIKE '<pattern>' / t.* ILIKE '<pattern>', mas rejeitava sua forma canônica t.COLUMNS('<regexp>'), quebrando o round-trip de formatação da consulta (e abortando o servidor em builds de depuração/sanitizer). #109176 (groeneai).
  • Corrigida a falha com IncorrectEndpointError (HTTP 400) ao executar INSERT em uma tabela DataLakeCatalog do Microsoft Fabric / OneLake: as gravações do ADLS Gen2 (DFS) agora são direcionadas para o host de endpoint .dfs em vez do host .blob. Observação: com remote_url_allow_hosts, tanto o host .blob (leitura) quanto o host .dfs (gravação) do Fabric devem estar na lista de permissões para INSERT. #110290 (zlareb1).
  • Corrigidas as gravações por meio de funções de tabela de data lake (por exemplo, INSERT INTO FUNCTION icebergS3(...)) que produziam arquivos Parquet cujas colunas de string perdiam a anotação de tipo String, tornando os dados gravados ilegíveis para leitores externos, como o Spark. Essas gravações agora usam as mesmas configurações de formato que as gravações por meio do motor de tabela. #110465 (tiandiwonder).
  • Corrigido o problema em que system.session_log se tornava ilegível após um login via Arrow Flight: a coluna interface é um Enum8, mas o valor ArrowFlight estava ausente de sua enumeração, de modo que um login pelo protocolo Arrow Flight gravava o valor bruto 10 e qualquer SELECT que lesse essa linha lançava a exceção Unexpected value 10 in enum. #110758 (alexey-milovidov).
  • Corrige a inferência de esquema da família de formatos TSV, que inferia String para um valor decimal escrito com zero à esquerda, como 0.0 ou 0.5, enquanto CSV infere corretamente Float64. Além disso, uma primeira linha com esses valores era consumida como cabeçalho pela detecção automática de cabeçalho do TSV e desaparecia do resultado. Também corrige o TSKV, que inferia um tipo numérico para um valor escrito com uma sequência de escape, como x=1\x2E5, que depois não podia ser interpretado. Valores cujo zero à esquerda é preenchimento de um inteiro, como 007, continuam sendo inferidos como String, pois o parser de valores do TSV não consegue lê-los de volta. #112226 (groeneai).
  • Corrigida a inferência de esquema que propunha um tipo numérico para valores de texto que o parser de valores não consegue ler de volta. A inferência aceitava um expoente incompleto (1e+), uma mantissa ausente (.) ou um sinal repetido (++inf), que readFloatTextPrecise depois rejeitava com CANNOT_PARSE_NUMBER ao ler o schema inferido; em uma coluna Dynamic, isso resultava em erro no momento do INSERT. A inferência agora valida o número com o mesmo parser que o leitor de fato utiliza. Isso também elimina um caso em que o tipo inferido dependia de max_read_buffer_size e permite que formas válidas de expoente com zero à esquerda, como 0e5, sejam inferidas como Float64 em TSV, assim como já ocorre em CSV. Também corrige formas de expoente malformadas. #112453 (groeneai).
  • Corrige o problema em que KILL QUERY e max_execution_time eram ignorados por minutos enquanto um formato de entrada baseado em linhas interpretava um bloco. Os formatos de entrada baseados em linhas agora verificam o cancelamento da consulta a cada 8192 linhas, de modo que um insert encerrado (em particular um flush de async-insert em segundo plano, que interpreta até max_insert_block_size linhas por bloco) é interrompido imediatamente, em vez de continuar até o fim do bloco. #112646 (groeneai).
  • Corrigido o problema em que o tipo de coluna inferido dependia da ordem das consultas anteriores para uma origem cujo schema está em cache. Configurações que alteram um tipo inferido não faziam parte da chave do cache de inferência de esquema, de modo que o valor da primeira consulta determinava o tipo visto por todas as consultas seguintes: input_format_try_infer_exponent_floats, max_parser_depth, input_format_json_infer_array_of_dynamic_from_array_of_different_types e, para Parquet, também input_format_parquet_local_time_as_utc, input_format_parquet_allow_geoparquet_parser, input_format_parquet_skip_columns_with_unsupported_types_in_schema_inference e schema_inference_make_json_columns_nullable. Também registra o getter de chave de cache que faltava para Form e faz com que o getter de Template use a regra de escape do seu próprio formato de linha. #113533 (groeneai).
  • Corrigida a formatação de um argumento de subconsulta das funções de tabela view e viewIfPermitted quando a consulta externa possui uma cláusula SETTINGS no final. Essa consulta era formatada como view((SELECT ...)), que não pode ser interpretada de volta, fazendo com que a consulta falhasse na verificação interna de formatar-interpretar-formatar e gerasse Inconsistent AST formatting. #114658 (groeneai).
  • Corrige dados JSON detectados incorretamente como TSKV durante a detecção automática de formato. #106009 (Avogar).
  • A exportação de valores Time/Time64 fora de um horário do dia válido (negativos ou >= 24h) para o formato Arrow agora é rejeitada com um erro claro, em vez de gravar dados Arrow time32/time64 inválidos. #107179 (tiandiwonder).
  • Corrigida a leitura de arquivos Arrow, ArrowStream e ORC baseados em Arrow cuja coluna de timestamp tem como fuso horário um deslocamento UTC numérico fixo (por exemplo, +05:30, -08:00, 00:00) ou o marcador não IANA fixed, que antes falhava com Cannot load time zone ... (BAD_ARGUMENTS). #108633 (groeneai).
  • Serializa uma coluna Nullable(Tuple(...)) como um único campo CSV, em vez de achatá-la em colunas separadas. Antes, um valor não nulo era gravado como vários campos CSV, enquanto um NULL era um único \N, o que gerava uma contagem de colunas variável por linha e quebrava os cabeçalhos de CSVWithNames/CSVWithNamesAndTypes e os round-trips. #108959 (groeneai).
  • Corrigida uma alocação excessiva de memória durante a inferência de esquema do formato MsgPack: uma entrada corrompida ou gerada por fuzzing cujo cabeçalho de array/map/string/binary declara uma quantidade enorme de elementos não provoca mais uma única alocação de vários gigabytes (agora ela é rejeitada como entrada malformada). Isso corrige um abort allocation-size-too-big com sanitizadores e uma condição de falta de memória em compilações de release. #109019 (groeneai).
  • Corrigido um LOGICAL_ERROR ao gravar uma coluna LowCardinality(Time) no formato Arrow com output_format_arrow_low_cardinality_as_dictionary = 1. #109730 (groeneai).
  • Corrigida a leitura de um stream corrompido no formato Native cuja quantidade de tipos Dynamic ou de caminhos JSON/Object está próxima de SIZE_MAX: essa entrada malformada agora é rejeitada com um erro INCORRECT_DATA claro, em vez de um std::length_error não tratado. #110590 (alexey-milovidov).
  • Corrigido um LOGICAL_ERROR: Cannot sum Bools (abort do servidor em compilações de debug/sanitizador) ao mesclar estados de agregação de sumMap/sumMapWithOverflow/sumMapFiltered com valores Bool serializados no formato de estado antigo (versão 0). A mesma correção também resolve dois casos em que resultados incorretos eram gerados silenciosamente com estados Bool da versão 0: chaves de map do tipo Bool não eram deduplicadas entre estados, e a compactação de valores zero removia as entradas erradas. #110922 (groeneai).
  • Corrigida a função de tabela format, que lançava NOT_FOUND_COLUMN_IN_BLOCK quando a interpretação dos dados de entrada resultava em zero linhas (por exemplo, um JSON vazio ou um FeatureCollection GeoJSON sem features). Agora ela retorna um resultado vazio com as colunas corretas. #111428 (groeneai).
  • Agora é possível ler arquivos GeoParquet, Arrow e ArrowStream cuja coluna de geometria codificada em WKT usa uma palavra-chave de tipo que não está em maiúsculas (point(1 2)) ou um contêiner vazio (LINESTRING EMPTY, POLYGON(), POLYGON(())). Antes, a importação desses arquivos falhava com BAD_ARGUMENTS ou CANNOT_PARSE_NUMBER, embora as mesmas strings fossem interpretadas normalmente pela função readWKT. Isso também corrige a leitura de um arquivo que armazena a saída de wkt para uma geometria vazia, representada como LINESTRING(). #112020 (groeneai).
  • Corrigido o erro Unknown compression method lançado quando as indicações de compressão auto e none eram escritas com qualquer combinação de maiúsculas e minúsculas que não fosse tudo em minúsculas, por exemplo file('data.csv.gz', 'CSV', 'x String', 'AUTO'). Nomes de codecs como GZIP já eram aceitos sem diferenciar maiúsculas de minúsculas; agora as duas indicações especiais se comportam da mesma forma. #113631 (groeneai).
  • Corrigida a leitura de uma coluna Tuple cujo primeiro elemento é NULL nos formatos CustomSeparated, Regexp e Template com a regra de escape CSV. Nesses formatos, uma Tuple simples ocupa um campo por elemento, portanto o campo \N inicial corresponde a esse elemento, e não à coluna inteira. Antes, ele era consumido como a coluna inteira, deslocando os campos dos elementos restantes para as colunas seguintes, de modo que o CustomSeparated não conseguia ler a própria saída. #114471 (groeneai).
  • Corrigido o formato de entrada Regexp, que descartava silenciosamente o restante não interpretado de um campo correspondido, armazenando um valor truncado ou fabricado em vez de reportar um erro: v=-1 em UInt64 era lido como 0, e v=2020-01-01junk em Date era lido como 1975-07-14 com a regra JSON. Campos malformados agora são rejeitados com as regras Escaped, CSV e JSON, de forma consistente com os formatos aos quais, segundo a documentação, essas regras equivalem. Com Raw, um campo correspondido que contém uma tabulação agora é lido por inteiro, em vez de ser truncado na tabulação. #114520 (groeneai).
  • Corrigido um erro lógico Inconsistent AST formatting (aborto do servidor em compilações de depuração e com sanitizador) em expressões CREATE INDEX / CREATE HYPOTHETICAL INDEX que não sobreviviam a um ciclo completo de formatação-parsing-formatação, por exemplo CREATE HYPOTHETICAL INDEX i0 ON t0 ((a())) TYPE a e CREATE INDEX i0 ON t0 ((a, b).1) TYPE minmax. #109175 (groeneai).
  • Corrigido um erro lógico (Logical error: 'KeyCondition uses PREWHERE output') no leitor Parquet v3 que ocorria quando uma condição de chave no nível do formato referenciava uma coluna que não é lida do arquivo Parquet. #109267 (groeneai).
  • Corrigida uma exceção no HTTP handler predefinido quando um cabeçalho está ausente #108324 (vitlibar).
  • Corrigido um possível Logical error: 'ReadBuffer is canceled. Can't read from it.' quando um formato de entrada baseado em linhas (por exemplo, TSV/CSV) não conseguia interpretar a entrada e a leitura subjacente já havia sido cancelada (por exemplo, devido a um chunk HTTP malformado ou a um corpo truncado). A geração dos diagnósticos detalhados de parsing não lê mais de um buffer cancelado. #109708 (groeneai).
  • O formato Values não registra mais erros de parsing em system.errors e system.error_log quando o parsing em streaming recorre com sucesso ao parsing de expressões SQL. #111141 (pamarcos).
  • Corrigido o SYSTEM REFRESH em uma tabela RabbitMQ parada, que às vezes não conseguia consumir o backlog de mensagens enfileiradas. Um REFRESH concede exatamente um ciclo de streaming fora de ordem, mas esse ciclo podia retornar imediatamente com zero linhas porque o loop de entrega AMQP tinha acabado de ser iniciado de forma assíncrona, desperdiçando a única permissão e deixando as mensagens sem consumo até o próximo SYSTEM START. #111480 (groeneai).
  • Corrigido o problema em que uma tabela NATS com nats_stream definido deixava de consumir mensagens, silenciosamente, após a reinicialização do servidor NATS. A assinatura JetStream agora é restabelecida automaticamente, sem exigir DETACH TABLE e ATTACH TABLE. #112828 (groeneai).
  • Um valor absurdamente grande de kafka_num_consumers agora é rejeitado com um erro claro, em vez de causar uma falha de alocação dentro do motor de tabela Kafka. Antes, com kafka_disable_num_consumers_limit habilitado, esse valor gerava uma exceção std::length_error. #114764 (alexey-milovidov).
  • Servidor Arrow Flight: agora aceita credenciais de autenticação Basic codificadas em Base64 sem padding, como as enviadas por clientes Flight escritos em Go (por exemplo, o driver ADBC Flight SQL), e retorna um erro de autenticação adequado, em vez do genérico Unexpected error in RPC handling, quando o cabeçalho authorization está malformado. #115085 (alexey-milovidov).
  • Arrow Flight server: passa a rejeitar credenciais de autenticação Basic malformadas que omitem o separador entre nome de usuário e senha. #115347 (alexey-milovidov).

Correções em tipos de dado, funções e serialização

  • Corrige um erro lógico Stream <col>.variant_discr ... is not found (aborto do servidor em builds de depuração e com sanitizers) quando ALTER TABLE ... MODIFY COLUMN altera uma coluna para um tipo com subcolunas dinâmicas (por exemplo, de Variant para Dynamic) em uma tabela com partes Wide e a parte é lida ou mesclada posteriormente. #110204 (groeneai).
  • Corrigida a leitura de uma subcoluna de uma coluna Nullable(Tuple(...)) cujo elemento é um LowCardinality(T) não anulável quando a mesma consulta também lê a subcoluna pai. Em uma parte Compact, a subcoluna pai retornava valores incorretos, a consulta falhava com Unexpected return type from assumeNotNull ou o servidor era encerrado por uma asserção de proteção de string_view, porque a subcoluna extraída era desserializada em um buffer LowCardinality(Nullable(T)) cujos subfluxos eram então compartilhados com a leitura da subcoluna pai. #112232 (groeneai).
  • Corrigido um LOGICAL_ERROR “Not-ready Set is passed as the second argument for function globalNullIn” e a perda da mensagem de erro real da consulta, o que podia ocorrer quando a poda de partes baseada em estatísticas executava especulativamente uma subconsulta IN/GLOBAL IN durante a análise de índice e essa subconsulta falhava. #114121 (groeneai).
  • Corrigido o erro Cannot read all data of type FixedString ao ler a subcoluna product_quantization_codebook de uma coluna com o codec Quantized('product', ...). O codebook de cada parte é gravado após os dados de todos os grânulos e, portanto, não é delimitado por marcas; assim, uma leitura cujo intervalo de marcas terminava antes da marca final da parte podia lê-lo de forma incompleta. #112818 (alexey-milovidov).
  • O ClickHouse não grava mais partes cujo layout de Map contradiz os próprios metadados, no caso de um valor Map dentro de uma coluna Dynamic. Tabelas que diferiam apenas em map_serialization_version compartilhavam o mesmo objeto de serialização em cache, de modo que uma parte podia receber o layout de Map basic enquanto seus metadados declaravam with_buckets, e a leitura posterior falhava com LOGICAL_ERROR: Stream ...buckets_info ... is not found. Partes já gravadas dessa forma por versões anteriores continuam ilegíveis e precisam ser removidas. #113514 (groeneai).
  • Corrigido o problema em que ALP, FPC e GCD omitiam do hash do codec o parâmetro derivado do tipo. Em uma parte Compact, o gravador compartilha um fluxo comprimido para cada hash de codec distinto; por isso, duas colunas com larguras de valor diferentes sob o mesmo codec colidiam e compartilhavam um único objeto de codec com a largura errada. Com isso, inserções válidas eram rejeitadas com CANNOT_COMPRESS quando as larguras divergiam e, nos demais casos, uma das colunas era comprimida de forma menos eficiente do que deveria. #114189 (groeneai).
  • Corrige a poda de índice incorreta quando a sorting key de uma tabela envolve uma coluna Date em toDateTime (por exemplo, ORDER BY toDateTime(date_column)) e uma consulta filtra pela coluna original com uma comparação como WHERE date_column >= '...'. toDateTime(Date) sofre overflow para valores Date fora do intervalo de DateTime (após 2106-02-07), portanto a chave armazenada não é monotônica; o ClickHouse deixará de usar a poda por chave primária para essa combinação de chave/predicado, pois isso poderia descartar grânulos que contêm linhas correspondentes. #101814 (nihalzp).
  • Corrigida a falha de ALTER MODIFY COLUMN ao converter uma coluna Nullable para um tipo diferente com DEFAULT (por exemplo, Nullable(UInt8) → String,LowCardinality(String) ou Array(UInt8)). #102156 (il9ue).
  • Corrigido o escaping incorreto de literais SQL em StorageSQLite e na função de tabela sqlite() ao enviar predicados WHERE para o SQLite: aspas simples e caracteres de controle (\n, \r, \t, \) eram escapados com barras invertidas, que o SQLite não interpreta, o que causava erros de sintaxe ou resultados de consulta incorretos. Também foi corrigido o escaping de literais de string enviados ao PostgreSQL: strings aninhadas em listas IN mantinham o escaping do ClickHouse, e caracteres de controle eram enviados como sequências com barra invertida que o PostgreSQL interpreta como bytes diferentes. #104217 (tiandiwonder).
  • Corrigida a exceção NOT_FOUND_COLUMN_IN_BLOCK em consultas INNER JOIN ... ON arrayJoin(...) = ... quando query_plan_convert_join_to_in está habilitado e o SELECT referencia a coluna do array de origem. #104809 (tiandiwonder).
  • Corrigidas as expressões IN e NOT IN com operandos não constantes no lado direito que referenciam colunas da linha atual; além disso, o tratamento de tuplas no lado direito pelo novo analisador foi alinhado à semântica de IN já existente no ClickHouse. No analisador antigo, uma coluna de origem isolada no lado direito (x IN (arr)) continua sendo resolvida como nome de tabela e permanece fora do escopo. #104993 (niyue).
  • Corrigido o JOIN com tabelas EmbeddedRocksDB, Redis e KeeperMap, que podia retornar zero linhas silenciosamente quando DirectKeyValueJoin era usado com chaves String ou Nullable(String). #105253 (vdimir).
  • Corrigido um LOGICAL_ERROR (“Unexpected expression in JOIN ON section. Expected boolean (UInt8), got ‘Nothing’”) quando um predicado JOIN ... ON sem igualdade referencia uma coluna do tipo Nothing, como a gerada por ARRAY JOIN []. #106981 (groeneai).
  • Corrigido um erro lógico Inconsistent AST formatting que podia derrubar o servidor em builds de depuração e com sanitizers quando uma lambda com alias era usada como operando de um operador de acesso (elemento de tupla .N ou elemento de array []) em qualquer posição que não a primeira de uma lista de expressões, por exemplo, SELECT 1, ((p0, p1) -> p0 AS a7).4[3] FROM t. #107092 (groeneai).
  • Uma função de tabela de cluster (urlCluster, fileCluster, s3Cluster, …) aninhada em outra consulta distribuída, como clusterAllReplicas(..., urlCluster(...)), agora é rejeitada com um erro BAD_ARGUMENTS em vez de falhar com um erro lógico (Distributed task iterator is not initialized). #107107 (groeneai).
  • Corrigida a falha da função de tabela values com ARGUMENT_OUT_OF_BOUND ao usar um literal decimal que não pode ser representado exatamente em uma coluna de ponto flutuante de menor precisão (como 0.1 em uma coluna Float32), por exemplo, SELECT * FROM values('x Float32', 0.1). Esses valores agora são aceitos e convertidos para o valor representável mais próximo, de forma consistente com CAST e INSERT ... VALUES. #108055 (alexey-milovidov).
  • Corrigido o problema em que mapFilter, mapSort (e suas variantes) e mapConcat removiam LowCardinality dos tipos de chave e valor de um Map. Antes, mapFilter aplicado a uma coluna Map(LowCardinality(String), String) retornava Map(String, String), o que podia corromper os metadados de uma tabela criada via CREATE TABLE ... AS SELECT e fazer o CHECK TABLE falhar. #108057 (alexey-milovidov).
  • Corrigido um INSERT cancelado ou encerrado com KILL que continuava em execução por muito tempo durante a construção de um skip index (por exemplo, um índice set(0) ilimitado em uma coluna de alta cardinalidade). Agora, a construção do índice é interrompida imediatamente quando a consulta é cancelada. #108351 (tiandiwonder).
  • Corrigido um SELECT da função de tabela primes que não respondia ao cancelamento: com um step (ou limit) grande, a consulta podia continuar em execução por muito tempo após um KILL QUERY ou após atingir o tempo limite. Agora ela é interrompida imediatamente. #108353 (tiandiwonder).
  • Corrigido o parsing de nomes de tipos de dados que contêm a substring INT (por exemplo, um nome com formato de função, como quantileInterpolatedWeighted, usado na posição de um tipo de dados). Esses nomes eram confundidos com tipos inteiros do MySQL, e o primeiro grupo de argumentos (...) era consumido silenciosamente como modificador de largura de exibição, o que podia quebrar o round-trip de formatação da consulta. #108354 (groeneai).
  • Corrigida uma inconsistência em que um ARRAY JOIN malformado, seguido de uma vírgula e de uma lista de tabelas entre parênteses, era interpretado incorretamente como uma junção cruzada em vez de ser rejeitado. #108365 (Algunenano).
  • Corrigida uma exceção LOGICAL_ERROR (“Invalid action query tree node …”) que ocorria quando uma consulta distribuída deduplicava colunas ALIAS duplicadas estruturalmente idênticas e, ao mesmo tempo, referenciava uma função de tabela com um argumento de named collection no formato key = value (por exemplo, oss(s3_conn, filename = '...')). #108435 (groeneai).
  • Corrigido um erro lógico (uma exceção em builds de release e um abort do servidor em builds de debug e com sanitizers) que podia ocorrer em uma chamada de função com mais de um argumento LowCardinality sobre uma tabela distribuída, por exemplo, concatAssumeInjective((SELECT toLowCardinality('p')), s) usado como chave de GROUP BY com remote(). As mensagens eram Default functions implementation for LowCardinality is supported only with a single LowCardinality argument ou Expected the argument ... to have N rows, but it has M. #108871 (groeneai).
  • Corrigido o problema em que use_client_time_zone era ignorado para literais de string DateTime/DateTime64 interpretados no servidor (INSERT assíncrono, literais em SELECT). Agora, quando use_client_time_zone está habilitado, o cliente propaga seu fuso horário local como session_timezone, de modo que o parsing no servidor fique consistente com o caminho do INSERT síncrono. #109051 (groeneai).
  • Corrigido o problema em que max_execution_time (com timeout_overflow_mode = 'throw') às vezes nunca cancelava uma consulta: quando o monitor interno de tempo limite já estava aguardando uma consulta com prazo posterior, uma consulta com prazo anterior registrada depois podia passar totalmente despercebida e continuar em execução muito além do seu limite de tempo. #109792 (tiandiwonder).
  • Corrigido o erro NOT_FOUND_COLUMN_IN_BLOCK quando uma consulta sobre uma tabela Distributed usa _shard_num (ou shardNum()) que se torna Nullable (por exemplo, com FULL JOIN e join_use_nulls = 1) em conjunto com ORDER BY, com o analisador habilitado. #109798 (groeneai).
  • Corrigido o erro NOT_IMPLEMENTED (“Method getDataAt is not supported for Nullable(String)”) que podia ser lançado por uma junção com enable_join_runtime_filters = 1 (ativado por padrão desde a versão 26.2) quando a chave de junção do lado de construção era LowCardinality(Nullable(...)) com NULLs e o filtro de tempo de execução recorria ao seu filtro de Bloom. #109824 (groeneai).
  • Corrigida uma falha do servidor quando uma expressão lambda era passada onde uma função de ordem superior espera um valor concreto (por exemplo, o acumulador de arrayFold, como em arrayFold(lambda, arr, another_lambda)). Com enable_analyzer = 0, essas consultas agora são rejeitadas com ILLEGAL_TYPE_OF_ARGUMENT em vez de derrubar o servidor. #109840 (groeneai).
  • O alias unnest de arrayJoin agora é rejeitado em filtros de ROW POLICY, eliminando uma brecha em que essa política podia gerar um erro lógico column->size() == num_rows durante a leitura. #109973 (Algunenano).
  • Corrigido o problema em que índices de salto definidos em subcolunas Tuple não eram utilizados quando o campo era acessado via tupleElement(t, 'name'), tupleElement(t, N) ou t.N enquanto a tupla completa também era lida na mesma consulta (por exemplo, SELECT *). Todas essas formas agora descartam grânulos da mesma maneira que o acesso à subcoluna nomeada t.name. #110056 (groeneai).
  • Corrigido o erro BAD_GET ao comparar uma coluna Array(String) com um literal de array (arr = ['x']) quando a coluna possui um índice de exclusão text, tokenbf_v1 ou ngrambf_v1. Essa comparação agora é tratada pelo índice como uma varredura completa, em vez de fazer toda a consulta falhar. #110057 (groeneai).
  • Corrigido um erro ILLEGAL_COLUMN indevido em ALTER TABLE ... ADD COLUMN IF NOT EXISTS quando a coluna já existe no momento da aplicação. Isso acontecia quando a mesma coluna era adicionada duas vezes com IF NOT EXISTS em uma única instrução, ou quando um ALTER concorrente adicionava a coluna entre as fases de preparação e aplicação. #110080 (groeneai).
  • Corrigido um LOGICAL_ERROR (Bad cast from type ColumnLowCardinality to ColumnString) quando identity() (ou o resultado de uma subconsulta escalar) envolve um valor que contém um LowCardinality aninhado e a consulta usa WITH TOTALS/WITH ROLLUP. #110138 (groeneai).
  • Corrigido um erro NOT_FOUND_COLUMN_IN_BLOCK ao usar GROUP BY ALL sobre uma expressão de tupla junto com ORDER BY. #110206 (alexey-milovidov).
  • Corrigido um erro NOT_FOUND_COLUMN_IN_BLOCK ao executar INSERT em uma tabela que possui uma restrição CHECK que referencia uma subcoluna (como x.null de uma coluna Nullable ou arr.size0 de um Array). #110208 (alexey-milovidov).
  • Corrigidos resultados de consulta incorretos gerados pela otimização optimize_and_compare_chain (habilitada por padrão): uma condição derivada por transitividade de a < b AND b < c podia usar uma semântica de comparação diferente da das condições originais quando a cadeia misturava tipos com regras de conversão específicas para cada par (por exemplo, Enum vs String, Decimal vs Float64, FixedString de larguras diferentes). Agora, condições transitivas são derivadas apenas dentro de grupos de tipos que compartilham uma única ordem de comparação. #110621 (yariks5s).
  • Corrigido o problema em que optimize_injective_functions_in_group_by alterava os resultados de consultas com GROUP BY GROUPING SETS e GROUP BY ... WITH TOTALS. A configuração é documentada como preservadora de resultados, mas a eliminação de uma função injetiva de uma chave de agrupamento produzia um valor incorreto (ou descartava uma linha) para linhas em que essa chave não faz parte do conjunto agregado (um conjunto de GROUPING SETS do qual ela não é membro) ou para a linha de WITH TOTALS. O valor incorreto podia coincidir com um valor de chave real, tornando uma linha de superagregação indistinguível de um grupo real no mesmo conjunto de resultados. #110721 (groeneai).
  • Corrige um travamento do servidor ao multiplicar um estado de função de agregação median/quantile (baseada em ReservoirSampler) por uma constante inteira muito grande (por exemplo, medianState(x) * 18446744073709551615). A consulta deixava de responder ao cancelamento e podia ficar em execução indefinidamente. #110779 (groeneai).
  • Corrige uma falha (desreferência de ponteiro nulo durante a análise da consulta) quando getSubcolumn é chamada em um argumento JSON com o nome de uma subcoluna interna de dica de tipo, ou seja, um nome que começa com um marcador de tipo em crase. #110940 (groeneai).
  • Corrigido o problema em que map[key] retornava o valor de uma chave duplicada posterior em vez do da primeira. Quando uma coluna Map continha chaves duplicadas, o resultado de map[key] podia depender de linhas anteriores no mesmo bloco e da configuração optimize_functions_to_subcolumns, de modo que um SELECT e um WHERE sobre a mesma linha podiam divergir. #111246 (groeneai).
  • Corrige um erro lógico !rhs_literal->getValue().isNull() no otimizador de expressões lógicas quando uma cadeia AND compara uma coluna com uma constante de valor NULL de um tipo não Nullable (por exemplo, um Variant com valor NULL) com use_variant_default_implementation_for_comparisons = 0. #111292 (groeneai).
  • Corrigidos resultados incorretos quando uma consulta tem um índice de salto set e um predicado no formato (x AND <null-value>) OR y, em que o NULL é produzido por uma função (por exemplo, toInt64OrNull('x'), nullIf(1, 1), CAST(NULL AS Nullable(Int64))). Esse valor era encapsulado por __bitWrapperFunc e propagava NULL em vez da máscara “desconhecido”, de modo que o índice set podia descartar grânulos que, na verdade, correspondiam ao predicado, e a consulta retornava menos linhas do que deveria. #111604 (groeneai).
  • Corrige o problema em que CREATE TABLE/ALTER TABLE com o analisador aceitava uma expressão DEFAULT/MATERIALIZED de coluna que referencia uma coluna virtual, como _table ou _database. A inserção nessa tabela falhava com NOT_FOUND_COLUMN_IN_BLOCK, e uma coluna MATERIALIZED (que não pode ser fornecida explicitamente) impedia permanentemente inserções na tabela. Essas expressões agora são rejeitadas no momento da definição, assim como já ocorria sem o analisador. Colunas ALIAS (calculadas na leitura) e colunas EPHEMERAL (entradas de inserção não armazenadas) baseadas em colunas virtuais continuam funcionando. #111776 (groeneai).
  • Corrigido o erro UNKNOWN_QUERY_PARAMETER quando uma view parametrizada é chamada com um argumento cujo valor é uma subconsulta do tipo Array, Tuple ou LowCardinality, por exemplo, SELECT * FROM v(param = (SELECT groupArray(x) FROM t)). #111790 (groeneai).
  • Corrigidos três bugs nas reescritas do analisador que transformam uma cadeia de comparações em IN/NOT IN (x = c1 OR x = c2 OR ..., x != c1 AND x != c2 AND ... e has(const_array, x)). Para uma expressão Variant com use_variant_default_implementation_for_comparisons = 0, a reescrita alterava o tipo do resultado da expressão de UInt8 para Nullable(UInt8), o que gerava um LOGICAL_ERROR na verificação de validação da árvore de consulta em builds de depuração e com sanitizers. Para uma expressão com estrutura dinâmica (Dynamic, Array(Dynamic), JSON), a reescrita fazia uma consulta que funcionava falhar com Illegal type ... of argument of function in, porque IN rejeita esses argumentos. Em ambas as direções, também eram retornados resultados incorretos quando uma constante não é convertida sem perdas para o tipo da expressão, como uma constante DateTime com hora do dia comparada a uma coluna Date. #111924 (groeneai).
  • Corrigido o problema em que quantileDeterministic, quantilesDeterministic e medianDeterministic retornavam resultados diferentes para os mesmos dados a cada execução quando a consulta usa réplicas paralelas, uma tabela distribuída ou external aggregation, ou quando os estados são armazenados em uma tabela (inclusive dentro de um valor Dynamic). Estados gravados antes desta versão com a grafia de tipo sem versão mantêm o comportamento anterior, pois seu layout não pode ser alterado. #112052 (alexey-milovidov).
  • Corrige resultados incorretos causados por uma consulta de busca vetorial que contaminava o cache de condições de consulta. Uma consulta SELECT ... WHERE <condition> ORDER BY <distance function> LIMIT n em uma tabela com índice vector_similarity podia registrar grânulos como não correspondentes a <condition>, fazendo com que uma consulta comum SELECT ... WHERE <condition> executada depois na mesma tabela retornasse silenciosamente menos linhas. Leituras de busca vetorial não gravam mais no cache de condições de consulta. #112086 (groeneai).
  • Corrige o descarte de serialize_string_in_memory_with_zero_byte do plano de consulta serializado. Com serialize_query_plan = 1, um cluster executando com a configuração desabilitada podia divergir na representação em string em memória entre o iniciador e o nó que executa o plano desserializado, porque a configuração era lida na desserialização, mas nunca gravada na serialização e, portanto, sempre assumia seu valor padrão no nó executor. #112131 (groeneai).
  • Corrigido um resultado incorreto para um JOIN cuja expressão ON contém uma conjunção constante, por exemplo ON l.id = r.id AND CAST(NULL AS Nullable(UInt8)). A constante era descartada silenciosamente pela otimização do plano de consulta, de modo que a junção era executada como se ela não existisse: junções INNER, LEFT SEMI e RIGHT SEMI retornavam linhas correspondentes quando uma condição nunca verdadeira não deveria retornar nenhuma, e RIGHT ANTI não retornava nenhuma linha em vez de retornar todas. #112155 (vdimir).
  • Corrige resultados incorretos quando uma view parametrizada é chamada com um argumento que não é uma atribuição parameter = value. Com enable_analyzer = 0, e em EXPLAIN SYNTAX com as configurações padrão, chamadas como pv(concat(name, '!')), pv(name, 'a'), pv(name != 'a') e pv(tuple(name = 'a')) vinculavam silenciosamente um parâmetro da view a uma expressão não relacionada, em vez de reportar UNKNOWN_QUERY_PARAMETER, como faz o analisador. Essas chamadas agora são rejeitadas da mesma forma em ambos os caminhos de execução. #112194 (groeneai).
  • Corrige um bug em que um CREATE VIEW ou CREATE FUNCTION cuja definição chama substr, mid ou byteSlice em uma forma que a gramática de substring não consegue interpretar novamente era aceito, mas os metadados gravados pelo ClickHouse para ele não eram SQL válido. A leitura posterior dessa definição falhava com SYNTAX_ERROR e, na inicialização do servidor, interrompia o carregamento dos metadados, impedindo totalmente que o servidor fosse iniciado. Agora essas definições fazem a ida e volta corretamente, e os arquivos de metadados existentes no formato substring(x, a, b, c) voltam a ser legíveis, de modo que um servidor afetado inicia sem intervenção manual. #112195 (groeneai).
  • Corrigidos resultados incorretos, saída de ORDER BY em ordem errada e uma exceção BAD_TYPE_OF_FIELD quando a chave primária é um Array ou Tuple e a consulta aplica plus, minus, multiply, divide ou intDiv a ela. A aritmética sobre um valor composto é avaliada elemento a elemento, enquanto a comparação de valores compostos é lexicográfica; por isso, a análise da chave primária deixa de tratar essa expressão como monotônica. #112339 (groeneai).
  • Corrigido o erro Code: 62 ... You must not specify ANY or ALL for PASTE JOIN. (SYNTAX_ERROR) gerado por um servidor remoto quando uma consulta contendo PASTE JOIN é enviada a outro servidor, por exemplo, quando a tabela à esquerda é uma tabela Distributed ou uma função de tabela *Cluster. O formatador gerava ALL PASTE JOIN, uma grafia rejeitada pelo parser, de modo que o servidor de destino não conseguia interpretar a consulta recebida. #112404 (groeneai).
  • Corrige o problema em que uma lista de aliases de colunas, como (SELECT 1) AS t(x) ou WITH t(x) AS (SELECT 1), não ficava visível dentro da função de tabela view: uma referência a t.x falhava com UNKNOWN_IDENTIFIER, embora a mesma construção funcione fora de view. #112690 (groeneai).
  • Corrige um erro lógico na formatação de consultas quando uma cláusula ARRAY JOIN não contém expressões. Agora essa cláusula é rejeitada na análise sintática com SYNTAX_ERROR, de forma consistente com um USING vazio, em vez de ser aceita e formatada como um texto que não pode ser analisado novamente. #112699 (groeneai).
  • Corrigido o problema em que connectionId lançava Context has expired quando ações de expressão preparadas para uma subconsulta eram executadas após a liberação do contexto em que foram construídas. #112870 (clickgapai).
  • Corrige um erro lógico e resultados incorretos quando uma condição JOIN ON sem igualdade (non-equi), avaliada durante a junção, contém arrayJoin. Uma junção hash, parallel_hash ou grace_hash agora rejeita essa condição com INVALID_JOIN_ON_EXPRESSION. Quando a expansão depende de apenas um dos lados, mova-a para um ARRAY JOIN em uma subconsulta antes da junção; uma condição cujo argumento de arrayJoin lê colunas de ambos os lados precisa ser reestruturada. #112889 (groeneai).
  • Corrigido o problema em que geohashesInBox levava um tempo ilimitado para processar um retângulo de área zero, como geohashesInBox(0., 0., 180., 0., 12). Essa consulta retornava o único geohash correto, mas executava cerca de 5e8 iterações de laço vazias por linha e ignorava tanto max_execution_time quanto KILL QUERY. #112976 (groeneai).
  • Rejeita uma alteração de SETTINGS marcada como escrita sem valor quando ela contém um valor diferente de true, e nunca omite o valor desse tipo de alteração ao formatar uma consulta. Antes, um payload JSON de AST forjado podia executar uma configuração Bool com false, enquanto system.query_log e formatQueryFromJSON exibiam a forma sem valor. #113025 (alexey-milovidov).
  • Corrigido UNKNOWN_IDENTIFIER ao consultar uma VIEW cujos tipos de coluna declarados diferem dos tipos produzidos por sua consulta interna, por exemplo SELECT sum(length(arr)) FROM v, em que v declara arr Array(UInt8) sobre uma coluna String. Com o valor padrão optimize_functions_to_subcolumns = 1, o otimizador reescrevia length(arr) como uma leitura da subcoluna arr.size0 e repassava esse nome para a consulta interna, que não possui essa subcoluna. #113057 (groeneai).
  • Corrigido o cancelamento de leituras da função de tabela postgresql e do engine PostgreSQL. Cancelar enquanto a leitura ainda estava sendo iniciada podia causar uma condição de corrida no ponteiro da transação, e o cancelamento podia ser perdido por completo, deixando a consulta em execução até que o PostgreSQL a concluísse. Um cancelamento que chegue ao PostgreSQL antes de a instrução COPY começar a ser executada ainda pode ser descartado. #113150 (groeneai).
  • Corrigido um LOGICAL_ERROR (Next task callback is not set for query) quando uma view SQL SECURITY DEFINER ou SQL SECURITY NONE sobre uma função de tabela de cluster (s3Cluster, urlCluster, fileCluster) era lida como consulta secundária, por exemplo por meio de remote ou clusterAllReplicas. Esse aninhamento, que não é suportado, agora é rejeitado com um erro de consulta comum, em vez de abortar o servidor em compilações de depuração e com sanitizador. #113371 (groeneai).
  • Corrige um erro lógico IDENTIFIER is not a table expression quando uma função de tabela da família remote com um argumento view(...) é usada no lado esquerdo de um JOIN ... USING cuja chave é um alias da lista do SELECT, com analyzer_compatibility_join_using_top_level_identifier = 1. #113400 (groeneai).
  • Corrigido Not-ready Set is passed as the second argument for function 'in' quando uma consulta filtra system.databases pela coluna name com uma subconsulta dentro de indexHint, por exemplo SELECT count() FROM system.databases WHERE indexHint(name IN (SELECT 'foo')). Essa consulta era rejeitada com um LOGICAL_ERROR em compilações de release e abortava o servidor em compilações de depuração e com sanitizador. #113556 (groeneai).
  • Corrigido o problema em que uma consulta sobre uma coluna Variant ignorava max_execution_time e KILL QUERY. Chamar uma função com vários argumentos Variant resolvia a função uma vez para cada alternativa de cada argumento, e nenhum dos dois laços responsáveis por esse trabalho verificava o cancelamento, de modo que essa consulta só podia ser interrompida ao terminar. #113612 (groeneai).
  • Corrige a falha de ALTER TABLE ... MODIFY COLUMN com Cannot specify codec for column type ALIAS quando uma mesma instrução transforma uma coluna ALIAS em física (DEFAULT ou MATERIALIZED) e especifica um CODEC. #113853 (groeneai).
  • Corrigida uma falha do servidor ao fazer junção com uma expressão ON constante quando o lado direito contém um ARRAY JOIN. A leitura de uma coluna do lado direito replicada de forma lazy usava um ColumnReplicated já liberado. #113901 (groeneai).
  • Corrige um vazamento de memória com optimize_aggregation_in_order = 1 quando a sorting key da tabela é um prefixo estrito da chave do GROUP BY e é usada uma função de agregação cujo estado aloca memória no heap, como quantileDD. A memória do servidor crescia a cada consulta desse tipo até a reinicialização. #114010 (groeneai).
  • Corrigido o problema em que isProbablePrime em UInt128/UInt256 ignorava max_execution_time e KILL QUERY. Um bloco de valores largos era processado por completo dentro de uma única chamada de função, sem ponto de cancelamento, de modo que uma consulta podia continuar em execução por vários minutos após o prazo. #114032 (groeneai).
  • Corrigido o erro Code: 46. DB::Exception: Unknown function exists. (UNKNOWN_FUNCTION) lançado quando uma cláusula PREWHERE contém um predicado IN (subquery) e rewrite_in_to_join = 1 (ou make_distributed_plan = 1, que o habilita obrigatoriamente) está definido. A mesma consulta escrita com WHERE funcionava corretamente. #114067 (RohithPariki).
  • Corrigido um LOGICAL_ERROR em arrayAutocorrelation quando o argumento é um array não vazio cujo tipo de elemento é Nothing, por exemplo, SELECT arrayAutocorrelation([arrayMax([])]). Esse tipo de argumento agora é rejeitado com ILLEGAL_COLUMN. O literal de array vazio [] continua retornando []. #114249 (groeneai).
  • CREATE TABLE e ALTER TABLE agora rejeitam codecs com perdas, como SZ3, em colunas usadas na sorting key. #114531 (groeneai).
  • Corrigido um loop infinito e não cancelável nas funções hop e windowID quando a duração de um argumento de intervalo em segundos é múltipla de 2^32 (por exemplo, toIntervalDay(2147483648)): o overflow na subtração burlava a verificação de estouro de tempo e, com argumentos constantes, o loop era executado durante a análise, quando nem sequer era possível encerrar a consulta. O mesmo intervalo também podia deixar uma thread em segundo plano de uma WINDOW VIEW em loop indefinidamente; uma window view desse tipo agora é rejeitada na criação. #114607 (alexey-milovidov).
  • Corrige o erro lógico Not-ready Set is passed as the second argument for function 'in' em consultas com uma subconsulta IN que lê de um cluster remoto: a consulta agora falha com o erro real da subconsulta, como uma falha de conexão. #114983 (alexey-milovidov).
  • Corrigido um INSERT em uma tabela Log, TinyLog ou StripeLog que falha ao confirmar os tamanhos de arquivo registrados. Esse insert podia manter suas linhas na tabela mesmo tendo reportado um erro, ou deixar os arquivos de dados de uma coluna de array inconsistentes entre si. A leitura de uma tabela Log ou TinyLog cuja coluna de array não contém elementos, embora seus offsets indiquem o contrário, agora gera um erro que identifica a coluna, em vez de ler além do fim dos elementos. Uma coluna de elementos gravada parcialmente já era rejeitada. #115027 (groeneai).
  • Corrige TYPE_MISMATCH (“CAST AS Array can only be performed between same-dimensional array types”) em consultas com uma constante do tipo Array(Map(...)), como has([map('k', 'v')], m), executadas sobre uma tabela Distributed ou com réplicas paralelas. #115883 (alexey-milovidov).
  • Corrigidos resultados incorretos ao fazer junção com uma view ou view() cuja coluna projetada tem o mesmo nome de uma coluna de uma de suas próprias relações internas, por exemplo, SELECT expr(x.c0) AS c0 FROM a AS x, b AS y. O otimizador de ordem de junção incorporava essa expressão ao grafo de junção achatado e depois a aplicava duas vezes, fazendo com que a consulta retornasse silenciosamente valores distorcidos. Quando a expressão também alterava o tipo da coluna, a mesma causa produzia, em vez disso, AMBIGUOUS_COLUMN_NAME durante o planejamento. #116152 (groeneai).
  • Corrigida uma exceção em subconsultas correlacionadas quando colunas externas se tornam Nullable com group_by_use_nulls em ROLLUP/CUBE. #100365 (alexey-milovidov).
  • max_replication_lag_to_enqueue = 0 passa a ser rejeitado em bancos de dados Replicated. Esse valor tornava trivialmente verdadeira a verificação de dessincronização pós-recuperação e abortava o servidor com LOGICAL_ERROR em builds de depuração e com sanitizador. Agora, 0 é rejeitado durante a análise com BAD_ARGUMENTS, independentemente da origem (CREATE DATABASE ... SETTINGS, bloco de configuração do servidor <database_replicated>, reaplicação de ATTACH e reaplicação de metadados existentes durante a atualização). O menor valor válido é 1. #106006 (groeneai).
  • Proibida a criação de índice de salto minmax em colunas JSON (Object), para evitar a exceção NO_COMMON_TYPE ao inserir arrays de tipos mistos. Em vez disso, use subcolunas tipadas (por exemplo, INDEX idx json.field TYPE minmax). #106094 (linhaojie).
  • Corrigido o retorno de Dynamic em vez de String/UInt8 por JSON_QUERY/JSON_VALUE/JSON_EXISTS com argumentos Dynamic. #106877 (Avogar).
  • Corrigido um estouro de inteiro com sinal quando uma configuração de tempo limite de espera, como interactive_delay, era definida com um valor muito grande: a espera podia expirar imediatamente em vez de aguardar, e o servidor podia abortar sob o Undefined Behavior Sanitizer. #106961 (groeneai).
  • Corrigido um LOGICAL_ERROR (“Unsupported argument types”) na função geohashesInBox quando seus argumentos de coordenadas misturavam valores constantes e não constantes, ou quando uma coordenada era BFloat16. Argumentos Float32 que misturam valores constantes e não constantes agora funcionam, e argumentos BFloat16 são rejeitados com um erro claro. #107063 (groeneai).
  • Corrigido o cabeçalho de CSVWithNames e CSVWithNamesAndTypes, que tinha menos colunas que os dados quando output_format_csv_serialize_tuple_into_separate_columns está habilitado (o padrão). O cabeçalho (e a linha de tipos) agora achata colunas Tuple em seus campos folha, com nomes separados por ponto (por exemplo, t.a, t.b), de modo que o número de colunas do cabeçalho corresponda ao dos dados. Uma nova configuração, output_format_csv_header_serialize_tuple_into_separate_columns (padrão 1), controla esse comportamento e pode ser definida como 0 para restaurar o cabeçalho anterior com nome único. #107371 (groeneai).
  • Corrigido um vazamento de memória no mongo-c-driver empacotado, que podia ocorrer ao ler do MongoDB (por exemplo, por meio de um dicionário MongoDB ou da função de tabela mongodb) quando um erro de leitura passível de nova tentativa era seguido por uma falha na seleção de servidor para a nova tentativa. #107448 (groeneai).
  • Corrige um erro lógico (WhichDataType(const_type).isArray()) e o aborto do servidor durante a análise da chave primária quando pointInPolygon é chamada com um argumento de polígono constante de um tipo encapsulador, como Variant ou Dynamic (por exemplo, pointInPolygon((x, y), if(c, [(0, 0), ...], NULL))). #107589 (groeneai).
  • Corrigidos erros lógicos (Bad cast) causados pela remoção inconsistente de LowCardinality aninhado em colunas Variant e Dynamic, por exemplo em concat, format e na análise da chave primária. #107773 (Avogar).
  • Corrigida a interpretação dos parâmetros de comando de funções definidas pelo usuário do tipo executável, de modo que marcadores com nomes vazios ou inválidos não sejam mais aceitos como parâmetros. #107983 (goutamadwant).
  • Corrige accurateCastOrNull de uma Tuple cujo elemento é Dynamic/Variant: um NULL legítimo na origem era tratado como falha de conversão. Para um elemento de destino Nullable, um NULL na origem agora permanece como NULL no elemento (assim como ocorre com uma origem Tuple(Nullable(...)) simples); para um elemento de destino não Nullable, um NULL na origem agora torna nula a tupla inteira (assim como ocorre na referência sem Dynamic), em vez de produzir o valor default do elemento. Falhas de interpretação/estouro continuam tornando nula a tupla inteira. #108023 (groeneai).
  • A função de tabela mongodb agora aceita oid_columns passado como argumento nomeado (por exemplo, oid_columns='_id'), em vez de rejeitá-lo com BAD_ARGUMENTS. #108039 (alexey-milovidov).
  • Permite consultar um dicionário range_hashed ou complex_key_range_hashed que usa um intervalo do tipo DateTime64, Decimal ou de ponto flutuante com um argumento correspondente em dictGet/dictHas. Antes, essas consultas falhavam com must be convertible to Int64, e intervalos abertos em faixas Decimal/DateTime64 retornavam incorretamente o valor default. #108052 (alexey-milovidov).
  • Corrige um aborto do servidor (Logical error em IColumn::insertFrom) ao converter um Array(Dynamic) ou Array(Variant) para QBit com accurateCastOrNull, por exemplo, accurateCastOrNull(CAST(range(114), 'Array(Dynamic)'), 'QBit(Float32, 114)'). #108288 (groeneai).
  • Corrigida uma falha do servidor (Received signal 4, instrução ilegal) que podia ser provocada por um fluxo malformado ou dessincronizado do protocolo TCP nativo. O campo initial_address de ClientInfo agora é validado como um host:port numérico antes de ser interpretado, em vez de permitir que uma porta não numérica chegue à função getservbyname da libc, que é bloqueada. #108410 (groeneai).
  • Corrigida a alocação excessiva de memória ao desserializar estados de funções de agregação maliciosamente construídos para mannWhitneyUTest, rankCorr, largestTriangleThreeBuckets, quantileGK, sequenceMatch/sequenceCount e groupArrayIntersect. Um estado malformado podia declarar uma quantidade enorme de elementos e fazer o servidor tentar alocar dezenas de gigabytes a partir de poucos bytes de entrada; esses estados agora são rejeitados com TOO_LARGE_ARRAY_SIZE. #108465 (groeneai).
  • Corrigido um erro lógico (Bad cast from type DB::ColumnNullable to DB::ColumnString) e possíveis resultados incorretos ao usar group_by_use_nulls com uma chave de agrupamento constante LowCardinality em GROUPING SETS/ROLLUP/CUBE. #108771 (alexey-milovidov).
  • Corrigido TYPE_MISMATCH em mapFilter, mapSort, mapReverseSort, mapPartialSort e mapConcat quando um valor Map contém um Map aninhado com LowCardinality, por exemplo, mapFilter((k, v) -> 1, map('a'::LowCardinality(String), map('x'::LowCardinality(String), 'y'))). #108798 (groeneai).
  • Corrigido um LOGICAL_ERROR (“Inconsistent AST formatting”) que abortava o servidor em compilações de debug e com sanitizador ao formatar um tipo de dado Tuple que mistura elementos nomeados e não nomeados (por exemplo, Tuple(a UInt8, UInt16)). #108915 (groeneai).
  • JSONExtract agora respeita cast_string_to_date_time_mode ao converter valores JSON do tipo string para DateTime/DateTime64, de forma consistente com CAST. #109252 (Utkal059).
  • Corrigido o uso de IN com uma coluna de array simples como argumento à direita, que retornava silenciosamente um resultado incorreto (sempre falso) ou lançava uma exceção; agora x IN arr se comporta como has(arr, x). #109416 (alexey-milovidov).
  • Corrigido um LOGICAL_ERROR em arrayFold aplicado a um argumento Array(LowCardinality(T)) não constante (por exemplo, arrayFold((acc, x) -> acc + x, materialize([1, 2, 3]::Array(LowCardinality(Int64))), toInt64(0))), que falhava com “Arguments of ‘plus’ have incorrect data types” (o que abortava o servidor em compilações de debug e com sanitizador). #109462 (groeneai).
  • Corrigida uma exceção ILLEGAL_COLUMN em conv com a conversão correta de argumentos FixedString para String. #109771 (hp77-creator).
  • Corrigidos resultados incorretos em leituras de funções de tabela com FINAL / SAMPLE quando serialize_query_plan = 1 e corrigida a chave de cache de estatísticas da tabela hash de agregação para funções de tabela (antes, todas as funções de tabela compartilhavam uma única entrada de pré-alocação). #109847 (azat).
  • Corrigida a análise de valores numéricos 1/0 como valores Bool dentro de tipos contêiner (por exemplo, Array(Bool), Tuple(Bool, ...)). Antes, [1,0] falhava com CANNOT_READ_ARRAY_FROM_TEXT, enquanto [true,false] funcionava. #109976 (groeneai).
  • Corrigido o erro NOT_IMPLEMENTED (Method getDataAt is not supported for Nullable(String) in case if value is NULL) quando um índice text é construído sobre Array(LowCardinality(Nullable(String))) (incluindo campos Nested armazenados dessa forma) e um array indexado contém um elemento NULL. Elementos NULL de arrays agora são ignorados durante a construção do índice, assim como já ocorria com Array(Nullable(String)). #110055 (groeneai).
  • Corrigidos resultados incorretos de subBitmap, bitmapSubsetInRange e bitmapSubsetLimit para bitmaps ainda armazenados na representação pequena, incluindo valores de elementos UInt64 e Int64 acima de 2^32, que eram truncados para 32 bits. As comparações em funções de bitmap sobre tipos de elemento com sinal agora usam consistentemente o valor sem sinal do tipo de elemento; assim, em um bitmap Int8, o elemento -1 é comparado como 255, e não como o valor com extensão de sinal 4294967295. Isso também corrige bitmapMin, bitmapMax, bitmapContains e bitmapTransform em bitmaps que já ultrapassaram a representação pequena. Consultas que passavam limiares com extensão de sinal precisam ser ajustadas: em um bitmap Int8, bitmapSubsetInRange(bm, 4294967168, 4294967296) passa a ser bitmapSubsetInRange(bm, 128, 256). Também foram corrigidos o groupNumericIndexedVector, que retornava resultados diferentes para colunas de índice Int8 e Int16 em relação a tipos de índice mais largos, e o numericIndexedVectorGetValue, que retornava 0 para índices negativos. A documentação das funções de bitmap foi corrigida, incluindo as funções de subconjunto, que eram descritas como usando indexação a partir de 1, e o suporte a valores com sinal em bitmapBuild / bitmapToArray. #110072 (RamiDarwiche).
  • Corrigidos caminhos de overflow com sinal indefinido na aritmética de intervalos em WITH FILL STEP do tipo intervalo e nas funções de intervalo de data/hora add* / subtract* com deltas extremos, tornando determinísticos os valores extremos de intervalo em vez de depender de overflow com sinal. Também foi corrigido um travamento de WITH FILL do tipo intervalo com um passo YEAR muito grande, que antes fazia o calendário retroceder. #110158 (groeneai).
  • Corrigida uma explosão de tempo quadrático (e a falta de resposta a max_execution_time) na agregação em ordem ao agrupar por várias chaves cuja ordenação é apenas um prefixo da chave de agrupamento. #110159 (alexey-milovidov).
  • Corrigidas comparações que antes lançavam ILLEGAL_TYPE_OF_ARGUMENT quando os operandos não tinham um supertipo comum mínimo. Arrays como Array(Int64) vs Array(UInt64) e Array(Int256) vs Array(UInt256) agora podem ser comparados lexicograficamente com =, !=, <, <=, >, >=, IS DISTINCT FROM e IS NOT DISTINCT FROM. Comparações compatíveis com NULL, como isDistinctFrom / isNotDistinctFrom, agora também comparam por valor pares numéricos ou decimais compatíveis que não sejam arrays, em vez de lançar erro. Comparações de igualdade também passam a funcionar para arrays com elementos Tuple(Nullable(...)) aninhados. #110245 (diegomestre2).
  • Corrigido um overflow de inteiro com sinal (UBSan) ao converter um valor DateTime64 extremo (por exemplo, INT64_MIN) para Time/Time64 em um fuso horário com deslocamento negativo. #110451 (groeneai).
  • A conversão de valores de ponto flutuante fora do intervalo (BFloat16, Float32, Float64) e de valores UInt64 acima de Int64::max() para DateTime e Time agora satura de forma confiável nos limites do intervalo em todas as arquiteturas (antes, o resultado de uma conversão fora do intervalo dependia da arquitetura e podia sofrer wrap-around em x86-64), e valores não finitos (NaN, inf) agora lançam uma exceção em vez de produzir um resultado arbitrário. A mesma correção foi aplicada ao caminho de conversão de float para Date de toDate e às conversões de UInt64 e de inteiros largos ((U)Int128, (U)Int256) para Date e Date32, que podiam retornar um dia anterior à época em vez de saturar. A conversão de um número para Time agora satura no intervalo do tipo para qualquer tipo numérico de origem (antes, valores vindos de inteiros sem sinal estreitos ou de inteiros largos eram armazenados sem limitação e só eram limitados ao serem exibidos), e o cast preciso para Time não rejeita mais os valores negativos suportados por Time, nem satura silenciosamente os valores que não cabem nele. O cast preciso de um número para Date32 (accurateCast, accurateCastOrNull) não satura mais silenciosamente um valor fora do intervalo ou não finito; em vez disso, lança uma exceção ou retorna NULL, como já acontecia com Date e DateTime, e as variantes OrDefault retornam o valor default de Date32 para esse tipo de entrada. O cast preciso de um número de ponto flutuante não inteiro para Date, Date32, DateTime ou Time agora é rejeitado em vez de ser truncado silenciosamente. Também foi corrigida a documentação da função toDateTime32, que exibia por engano exemplos de toDateTime64 e descrevia o intervalo de valores de DateTime64. #110459 (alexey-milovidov).
  • Corrigida a falha da inferência de esquema com Map cannot have a key of type LowCardinality(Nullable(String)) ao ler arquivos ORC cujas chaves de map usam codificação por dicionário — incluindo arquivos ORC gravados pelo Spark e arquivos gravados pelo próprio ClickHouse com output_format_orc_dictionary_key_size_threshold habilitado. #110492 (tiandiwonder).
  • Corrigido um erro lógico (Function node with name '...' is not resolved as ordinary function) que podia ocorrer com optimize_or_like_chain habilitado quando uma função de agregação ou de janela aparecia no lado esquerdo de um LIKE/ILIKE/match dentro de uma cadeia de OR. #110641 (groeneai).
  • Corrigido um overflow de inteiro com sinal em toStartOfInterval ao usar uma contagem extrema de intervalo MONTH, WEEK ou DAY com valores Date/Date32/DateTime64. #110688 (groeneai).
  • Corrigido o problema em que readWKT e readWKTPoint retornavam coordenadas não inicializadas (versão escalar) ou desatualizadas de uma linha anterior (versão vetorizada) para POINT EMPTY. POINT EMPTY agora é rejeitado com CANNOT_PARSE_TEXT, já que um Point do ClickHouse é um Tuple(Float64, Float64) fixo, sem representação vazia. #110692 (groeneai).
  • Corrigido o problema em que flipCoordinates perdia o tipo Geometry: para um argumento Geometry, o resultado volta a ser do tipo Geometry em vez do Variant(...) subjacente, podendo ser passado diretamente para funções como areaCartesian. #110694 (groeneai).
  • Corrigida a serialização WKB não canônica de um polígono vazio: wkb(POLYGON EMPTY) agora emite numRings = 0 em vez de um anel espúrio com zero pontos, de modo que a ida e volta WKB de um polígono vazio padrão preserva a identidade. #110796 (groeneai).
  • Valores numéricos 1/0 na análise de Bool em JSON agora respeitam a configuração allow_special_bool_values. Antes, uma entrada JSON como {"v":1} para Variant(Bool, UInt32) era lida como Bool mesmo com allow_special_bool_values_inside_variant = 0, porque os parsers de Bool em JSON ignoravam a configuração e Bool tem prioridade de desserialização em Variant maior que os tipos inteiros. #110835 (groeneai).
  • Corrigido throwIf(notLike(col, pattern)) (e outros usos de throwIf sobre uma função), que lançava exceção incondicionalmente quando col era LowCardinality. A implementação padrão de LowCardinality executava throwIf sobre todo o dicionário, que sempre contém o valor default reservado, mesmo quando nenhuma linha o referencia; assim, um valor diferente de zero nessa posição não utilizada fazia throwIf lançar exceção para dados que não satisfazem a condição. #110864 (groeneai).
  • Corrigida uma falha quando uma função de agregação com o combinador -Tuple era usada com RESPECT NULLS e produzia um estado intermediário (-State, agregação distribuída, WITH ROLLUP/WITH CUBE). A função combinada recebia o nome da variante de estado errada, de modo que seu tipo AggregateFunction serializado era resolvido para um layout em memória incompatível ao ser serializado e desserializado novamente. #110930 (groeneai).
  • Corrigido o erro Nested type LineString cannot be inside Nullable type (ILLEGAL_TYPE_OF_ARGUMENT) ao ler uma coluna espacial nullable do MySQL (LINESTRING, POLYGON, MULTILINESTRING, MULTIPOLYGON, MULTIPOINT ou o genérico GEOMETRY) por meio da função de tabela mysql ou dos motores de tabela/banco de dados MySQL. Essas colunas agora passam a usar Nullable(String) como fallback, armazenando o valor tal como o MySQL o retorna (um prefixo SRID de 4 bytes seguido pelo payload WKB). POINT continua sendo mapeado para Nullable(Point). #110943 (groeneai).
  • Corrige a serialização Native de wrappers SimpleAggregateFunction que contêm estados de agregação versionados ao se comunicar com pares de versões mais antigas. #110997 (groeneai).
  • Corrige o erro CANNOT_CONVERT_TYPE para constantes do tipo Variant (incluindo Geometry) em consultas distribuídas e em consultas com réplicas paralelas. #111136 (fm4v).
  • Corrige um LOGICAL_ERROR (“Lambda resolved type … is not equal to type from actions DAG …”) quando o corpo do lambda de uma função de ordem superior é um if/multiIf com condição constante que mistura um ramo com literal Bool e um ramo de comparação UInt8, por exemplo, arrayFilter(p -> multiIf(false, true, p = 'ALL'), ['ALL']). #111245 (groeneai).
  • Corrigido um overflow de inteiro com sinal em toStartOfInterval com intervalos de subsegundos: para valores DateTime64 situados a menos de um intervalo do limite inferior de Int64, o resultado arredondado dava a volta silenciosamente e virava um valor positivo sem sentido; agora a função lança uma exceção DECIMAL_OVERFLOW. #111370 (alexey-milovidov).
  • Corrigida uma exceção (CANNOT_CONVERT_TYPE ou um erro lógico) em consultas distribuídas que usam o combinador -Tuple com um modificador RESPECT NULLS / IGNORE NULLS sob combinadores aninhados, por exemplo, anyRespectNullsStateTuple(...) IGNORE NULLS. #111570 (alexey-milovidov).
  • Corrige uma tentativa de interpretação de texto de FixedString que deixa bytes parcialmente anexados na coluna quando a interpretação falha, o que pode causar o erro lógico Sizes of nested column and null map of Nullable column are not equal durante a serialização de colunas Variant/Array/Nullable ou deslocar silenciosamente os bytes do resultado. #111908 (groeneai).
  • Corrige uma exceção e dados ignorados silenciosamente ao ler uma subcoluna dinâmica (um caminho dentro de uma coluna JSON ou Dynamic) por meio de uma tabela Buffer. #111948 (alexey-milovidov).
  • Corrigida a complexidade quadrática em countSubstringsCaseInsensitiveUTF8, que fazia a função levar minutos em um haystack de poucos megabytes com muitas correspondências. O deslocamento de caracteres de cada correspondência agora é mantido de forma incremental, em vez de ser recontado desde o início da linha. #112003 (groeneai).
  • Corrigido um estouro de inteiro com sinal na sobrecarga de três argumentos de toStartOfInterval: para um argumento origin próximo ao limite inferior de Int64, a função retornava um valor com wrap-around em vez de reportar um erro. #112045 (alexey-milovidov).
  • Proíbe estados de agregação em parâmetros de funções de tabela, pois eles não têm nenhum suporte. #112087 (PedroTadim).
  • Corrigida a função de tabela values, que renderizava como 1/0, em vez de true/false, uma constante Bool não literal (por exemplo, CAST(true, 'Nullable(Bool)')) inserida em uma coluna String/textual. #112308 (yakov-olkhovskiy).
  • Corrige um erro lógico (que provoca abort em builds de depuração e com sanitizador) quando finalizeAggregation é aplicada a uma coluna cujos estados de agregação vêm de funções diferentes que compartilham a mesma representação de estado, mas finalizam em tipos diferentes — por exemplo, quantileState e quantilesState(0.9) combinados por um UNION ou produzidos via arrayReduce. Essas consultas agora geram um erro normal em vez de travar. #112662 (zainulabidin302).
  • Corrigido o parsing de inteiros que não cabem no tipo de destino em Poco::NumberParser, usado para ler números JSON. Esses números eram interpretados silenciosamente como um valor incorreto (por exemplo, 18446744073709551617 virava 1) em vez de serem rejeitados, e um número UInt64 acima do máximo de Int64 não sobrevivia a uma conversão de ida e volta entre AST e JSON. #112904 (alexey-milovidov).
  • Corrigida a conversão de uma constante Bool no lado direito de IN para um lado esquerdo String como '1'/'0' em vez dos valores canônicos 'true'/'false' (agora consistente com CAST e com a função de tabela values). #113051 (yakov-olkhovskiy).
  • Corrige a formatação inconsistente da AST de viewIfPermitted: uma função normalmente escrita como operador (por exemplo, not) no ramo ELSE da forma de função de tabela, e a forma de expressão viewIfPermitted(...) sendo formatada incorretamente com ELSE. #113652 (alexey-milovidov).
  • Corrige comportamento indefinido e resultados incorretos em avg sobre Date/DateTime/DateTime64/Time/Time64: a média agora é calculada de forma exata no espaço de inteiros, corrigindo tanto o overflow no limite de Int64 (UB, resultado incorreto em x86) quanto a perda de precisão de Float64 acima de 2^53 (visível na escala de nanossegundos). #113912 (alexey-milovidov).
  • Corrige um vazamento de memória no codec de compressão experimental SZ3: quando a compressão de dados pouco compressíveis ou corrompidos falhava com uma exceção, buffers temporários de trabalho permaneciam alocados. #113916 (alexey-milovidov).
  • Corrige o problema em que hasAny, hasAll, has, indexOf, mapContainsKey, mapContainsValue e mapContains retornavam menos linhas do que o esperado, ou falhavam com TOO_LARGE_STRING_SIZE, quando um índice bloom_filter era consultado com uma constante FixedString. O índice calculava o hash da forma preenchida da constante, enquanto a função compara a forma não preenchida, o que fazia com que um grânulo correspondente fosse ignorado. #114089 (alexey-milovidov).
  • Corrige o problema em que min e max em colunas DateTime64 retornavam resultados incorretos quando a agregação era compilada via JIT e os dados continham timestamps anteriores a 1970. is_signed não era especializado para DateTime64 e Time64, que derivam de Decimal64; assim, o código gerado comparava as contagens de ticks como inteiros sem sinal, e um timestamp anterior a 1970 vencia em max e perdia em min. #114168 (groeneai).
  • Corrige o problema em que arrayExists(x -> x = needle, arr) retornava um resultado incorreto, ou falhava com TOO_LARGE_STRING_SIZE, quando o elemento do array e o needle eram de tipos de string diferentes (por exemplo, um needle String comparado a um elemento Array(FixedString(N))). A otimização optimize_rewrite_array_exists_to_has, habilitada por padrão, reescrevia essa chamada como has, que não faz a comparação com preenchimento de zeros como = faz. #114496 (groeneai).
  • Corrige a avaliação do índice de texto para o operador LIKE/ILIKE aplicado sobre contêineres Map ou JSON. #114544 (ahmadov).
  • Corrige comportamento indefinido e resultados incorretos nos limites em quantile e quantiles para valores DateTime64 e Decimal largos. #114919 (alexey-milovidov).
  • Corrige o problema em que if e multiIf retornavam um valor positivo grande em vez de um negativo quando um ramo Time era combinado com Time64, DateTime ou DateTime64 e a expressão era compilada via JIT. #115146 (groeneai).
  • Corrige o problema em que timezoneOffset (alias timeZoneOffset) retornava um deslocamento errado em exatamente um dia para fusos horários cujo deslocamento em relação ao UTC difere do deslocamento em 1970-01-01 por um dia inteiro, como Pacific/Kiritimati e Pacific/Apia após cruzarem a linha internacional de data, e para a maioria dos fusos antes de 1970. Isso também corrige parseDateTime, parseDateTimeOrNull, parseDateTime64, parseDateTimeInJodaSyntax, EXTRACT(TIMEZONE_HOUR / TIMEZONE_MINUTE ...), o %z de formatDateTime, toUTCTimestamp e fromUTCTimestamp, que utilizam esse deslocamento. #115332 (groeneai).
  • Corrigido o erro Code: 349. Cannot convert NULL value to non-Nullable type quando um predicado has ou notHas contém um elemento de array NULL e a chave primária é do tipo String, Array(String) ou Map(String, String). Também foram corrigidos resultados incorretos quando esse elemento é um Dynamic ou Variant contendo NULL. Agora o NULL é descartado do conjunto durante a análise da chave, como já acontecia com outros tipos de chave. #115647 (groeneai).
  • Corrigido o problema em que cast_keep_nullable não preservava a nulabilidade quando o tipo de destino era LowCardinality. Converter um valor que admite NULL para LowCardinality(T) lançava CANNOT_INSERT_NULL_IN_ORDINARY_COLUMN em vez de produzir LowCardinality(Nullable(T)). #115851 (groeneai).

Correções de índices e do cache de consultas

  • Corrigida a leitura de subcolunas de uma coluna que tem uma expressão DEFAULT e não está materializada em uma parte (por exemplo, após ALTER TABLE ADD COLUMN ou durante ALTER TABLE MATERIALIZE COLUMN): a subcoluna era preenchida com os valores padrão do tipo em vez do resultado da expressão DEFAULT, e as funções de distância vetorial transpostas (cosineDistanceTransposed e outras) aplicadas a essas colunas QBit falhavam com o erro SIZES_OF_ARRAYS_DONT_MATCH. #110636 (alexey-milovidov).
  • Corrigida a exceção Not-ready Set is passed as the second argument, que podia ocorrer quando a construção do set de uma subconsulta IN durante a análise da chave primária falhava silenciosamente (por exemplo, por timeout da subconsulta com overflow_mode = 'break'), fazendo com que o set nunca fosse construído para o pipeline da consulta. #107924 (alexey-milovidov).
  • Corrigida a falha de um SELECT com NOT_FOUND_COLUMN_IN_BLOCK em uma tabela que possui um índice de exclusão de dados do tipo set quando uma política de linha a filtra usando uma condição sempre verdadeira combinada com uma verificação em uma coluna não indexada. #107971 (tiandiwonder).
  • getClientHTTPHeader agora é corretamente tratada como não determinística, de modo que seu resultado deixa de ser reutilizado indevidamente pelo cache de resultados de consultas. #108029 (alexey-milovidov).
  • Corrigidos resultados incorretos quando o cache de condições de consulta (use_query_condition_cache = 1) reutilizava uma exclusão de marcas derivada de índices de exclusão em uma consulta que executava um conjunto diferente de índices de salto, por exemplo com use_skip_indexes = 0, ignore_data_skipping_indices ou um modo diferente de use_skip_indexes_for_disjunctions. As entradas de cache derivadas de índices de exclusão agora têm como chave o conjunto efetivo de índices de salto executados, enquanto as entradas do cache de condições de consulta em nível de linha continuam reutilizáveis em todos esses casos. #108548 (groeneai).
  • Corrigido um travamento em que uma consulta que lia pelo cache do sistema de arquivos podia continuar aguardando um download em andamento mesmo após ser cancelada com KILL QUERY, e em que remover uma view materializada atualizável, ou executar SYSTEM STOP VIEW nela, ficava bloqueado quando sua atualização estava presa nessa espera. #109116 (murphy-4o).
  • Corrigidos resultados de consulta incorretos causados pelo descarte indevido de grânulos pelo índice de chave primária em tabelas com uma coluna de chave em ordem inversa (DESC) quando as partes não têm marca final (granularidade não adaptativa, index_granularity_bytes = 0). #109901 (nihalzp).
  • Corrigidos o erro lógico Expected CommonSubplanReferenceStep to reference CommonSubplanStep, o erro Subplan cannot be used to build pipeline e o erro lógico Trying to extract chunk from ChunkBuffer before all inputs are finished em IN (subquery) quando a subconsulta contém uma subconsulta correlacionada e o set é construído durante a análise de índices. #110491 (alexey-milovidov).
  • Corrigido o erro NOT_FOUND_COLUMN_IN_BLOCK nas funções de distância transpostas sobre colunas QBit (como cosineDistanceTransposed) chamadas com um vetor de referência constante ou obtido de uma subconsulta escalar quando réplicas paralelas estão habilitadas. #110729 (alexey-milovidov).
  • Corrigido um problema em que o índice de texto não era usado quando sua expressão continha uma comparação com string vazia, como arrayFilter(s -> s != '', ...), porque a configuração optimize_empty_string_comparisons reescreve a comparação para notEmpty apenas no lado da consulta. #112115 (Ergus).
  • As colunas não são mais removidas quando referenciadas tanto nas condições de filtro PREWHERE quanto nas de WHERE, mesmo que sejam reescritas como uma coluna virtual de índice de texto. #114460 (ahmadov).
  • Corrigido o erro lógico Multi-block postings must be compressed em consultas sobre tabelas com índice de texto no modo lazy de aplicação de posting-list, quando a consulta era cancelada durante a leitura. #114636 (CurtizJ).
  • Corrigidos resultados incorretos quando uma cláusula WHERE continha uma expressão NULL dentro de um NOT, por exemplo, SELECT count() FROM t WHERE NOT (id >= 20 AND NULL). A análise de índice tratava essa condição como comprovadamente verdadeira para todo o intervalo, de modo que o filtro era ignorado: count() retornava linhas que a consulta rejeita, e ALTER TABLE ... DELETE com essa condição removia linhas que deveriam ter sido mantidas. #115152 (groeneai).
  • Corrigido um LOGICAL_ERROR (Join is supported only for pipelines with one output port) em um JOIN full_sorting_merge com query_plan_join_shard_by_pk_ranges habilitado quando um dos dois lados fica sem nenhuma parte após a poda — pela chave primária, pelas estatísticas de coluna ou porque a tabela está vazia. #115352 (alexey-milovidov).
  • Desabilitado o cache de condições de consulta para filtros sobre _part_starting_offset #115358 (azat).
  • Corrigido LOGICAL_ERROR: Index with name auto_minmax_index_<column> already exists quando uma única instrução ALTER TABLE combinava RENAME COLUMN com outro comando, como MODIFY SETTING, em uma tabela com índices minmax implícitos (add_minmax_index_for_numeric_columns e similares). Além disso, renomear uma coluna comum não faz mais com que um DROP COLUMN subsequente falhe com UNKNOWN_IDENTIFIER, nem que um ADD COLUMN subsequente fique sem seu índice implícito. #116063 (groeneai).
  • Um padrão LIKE/NOT LIKE sem curingas (%, _) agora usa um intervalo exato da chave primária e, assim, lê o mesmo número de grânulos que o predicado =/!= equivalente, em vez de um intervalo de prefixo mais amplo. #107077 (groeneai).
  • Corrigidos um LOGICAL_ERROR (Invalid binary search result in MergeTreeSetIndex) e a ausência de poda de índice em builds de release quando uma condição IN/NOT IN na chave primária envolve a chave em intDiv por uma constante e a chave é um inteiro sem sinal cujos valores ultrapassam o limite com sinal do tipo de resultado de intDiv (por exemplo, intDiv(uint64_column, -9223372036854775807)). #107586 (groeneai).
  • Corrigido o retorno de resultado vazio por numericIndexedVectorPointwiseMultiply ao multiplicar por um vetor composto apenas de uns com uma configuração de bits BSI diferente. #108027 (alexey-milovidov).
  • Corrigido um heap-buffer-overflow ao construir um índice de texto com positions = 1 sobre muitos tokens curtos distintos. #108659 (groeneai).
  • As expressões preprocessor e postprocessor de um índice de texto agora podem referenciar colunas ALIAS. #110014 (Ergus).
  • Ignora a otimização de busca vetorial quando LIMIT ... WITH TIES é usado, pois a otimização restringe a busca ANN a exatamente n candidatos, o que faz com que as linhas empatadas com a n-ésima linha sejam descartadas. #110453 (tamish560).
  • Corrigido o problema em que o índice de texto não era usado para ILIKE quando o índice é definido sobre uma expressão em vez de uma coluna simples (por exemplo, assumeNotNull(col) com um pré-processador lower(...)). Essas consultas agora usam o índice em vez de ler todos os grânulos. #110595 (ahmadov).
  • Corrige um LOGICAL_ERROR (LazyMaterializingTransform: Number of rows in lazy chunk N does not match number of offsets M) que podia ocorrer em consultas de busca vetorial com vector_search_with_rescoring = 1 em conjunto com materialização preguiçosa quando havia empate entre várias distâncias. #111003 (groeneai).
  • Rejeita vetores cuja magnitude ao quadrado sofre overflow para infinito ao usar um índice vector_similarity com quantização i8 (antes, esses vetores provocavam comportamento indefinido no usearch e geravam dados inválidos silenciosamente). #111085 (groeneai).
  • Corrigidas leituras de dados inativos em disks plain_rewritable com o page cache habilitado. #111105 (Michicosun).
  • Corrigidos resultados incorretos de count() e linhas descartadas quando uma chave ou índice de exclusão minmax String (ou FixedString mais estreito) é filtrado por uma comparação com uma constante FixedString mais larga, por exemplo, toFixedString('abc', 257) = string_col. A poda por chave primária e por minmax construía o intervalo a partir da constante preenchida com NUL e ignorava indevidamente grânulos correspondentes. #111106 (groeneai).
  • Corrigida a leitura de arquivos Parquet cujo índice de offset não começa na linha 0. Esse tipo de arquivo podia fazer com que o leitor Parquet nativo retornasse linhas incorretas ou reportasse LOGICAL_ERROR em vez de INCORRECT_DATA. Agora, o índice de offset é validado no momento da leitura. #114530 (groeneai).

Correções de segurança, acesso, backup e restauração

  • RESTORE agora executa fsync nos arquivos das partes restauradas quando a tabela de destino tem fsync_after_insert habilitado, de modo que uma parte restaurada fica tão protegida contra queda de energia quanto uma parte inserida. Antes, os arquivos restaurados eram apenas gravados e fechados (sem fsync), então uma queda de energia logo após o RESTORE retornar RESTORED podia deixar as partes corrompidas e a tabela vazia. #111378 (groeneai).
  • Corrige um problema de segurança em que um cliente TCP não autenticado podia sondar a existência de tabelas e o status de replicação por meio da porta entre servidores. #99854 (tiandiwonder).
  • Corrigido o DELETE FROM (exclusão leve), que exigia o privilégio ALTER UPDATE além de ALTER DELETE. Um usuário que tenha recebido apenas ALTER DELETE agora pode executar DELETE FROM, conforme documentado. #107491 (tiandiwonder).
  • Corrigido o CREATE TABLE ... AS SELECT em bancos de dados Atomic, que deixava para trás uma tabela vazia quando a consulta falhava — por exemplo, quando o usuário não tinha acesso a uma tabela referenciada em uma subconsulta. Antes, uma nova tentativa informava que a tabela já existia, em vez de exibir o erro original. Agora a tabela é criada por meio de uma tabela temporária e só fica visível depois de totalmente preenchida. #108048 (alexey-milovidov).
  • Corrigido um LOGICAL_ERROR (No available columns) ao executar SELECT count() (ou outras consultas triviais) em uma tabela na qual o usuário tem acesso SELECT apenas a uma coluna ALIAS. #108056 (alexey-milovidov).
  • Corrige um problema em que requisições não autenticadas podiam fazer o ClickHouse resolver nomes de host fornecidos em cabeçalhos de endereço de cliente encaminhados. O ClickHouse agora aceita apenas endereços IP numéricos nesses cabeçalhos. Valores inválidos são ignorados na atribuição de cota por endereço encaminhado, sem resolução de DNS. Quando auth_use_forwarded_address está habilitado, endereços encaminhados inválidos são rejeitados durante a autenticação. As rejeições são registradas em log no nível debug. #111060 (otselnik).
  • Corrige o problema em que SQL SECURITY DEFINER (e SQL SECURITY NONE) não era respeitado em views parametrizadas quando o analisador estava desabilitado (enable_analyzer = 0). Antes, consultar uma view desse tipo como um usuário sem privilégios na tabela subjacente falhava com ACCESS_DENIED, embora a mesma view funcionasse com o analisador habilitado. #111458 (groeneai).
  • Corrigido um defeito nas integrações MySQL em que a substituição de uma credencial TLS de uma coleção nomeada por um valor vazio de ssl_ca_pem/ssl_cert_pem/ssl_key_pem era aceita quando a coleção armazenava a credencial na forma de conteúdo, descartando silenciosamente a CA ou o certificado do cliente configurado em vez de rejeitar a substituição. #113947 (alexey-milovidov).
  • Corrigido o EXPLAIN ANALYZE, que perdia as estatísticas de junção de uma view declarada com SQL SECURITY DEFINER ou SQL SECURITY NONE cujo corpo contém um JOIN. Em builds de debug e com sanitizers, a consulta era abortada com o erro lógico JoinStep analyzed without the analyze mode. #115156 (groeneai).
  • Corrige RESTORE ... AS <new name>, que deixava a lista REFRESH ... DEPENDS ON de uma view materializada atualizável apontando para o banco de dados original. A view restaurada era atualizada em resposta a uma tabela que ela não lia mais, ignorava as atualizações da sua própria tabela pai e parava completamente de ser atualizada quando o banco de dados original era removido. #115689 (groeneai).
  • Corrigida uma exceção LOGICAL_ERROR durante o backup de um banco de dados Replicated que está sendo removido e recriado simultaneamente; esses backups agora falham de forma limpa com CANNOT_GET_REPLICATED_DATABASE_SNAPSHOT. #100651 (alexey-milovidov).
  • GRANT role TO role aplicado à mesma função agora é rejeitado com BAD_ARGUMENTS, em vez de criar silenciosamente uma entrada autorreferencial em system.role_grants. #103315 (zxuhan).
  • O BACKUP de um banco de dados MaterializedPostgreSQL não trava mais indefinidamente com “Table … were created or changed its definition during scanning” e agora de fato faz o backup dos dados da tabela (delegado ao ReplacingMergeTree subjacente), que podem ser restaurados como um ReplacingMergeTree independente. #107433 (alexey-milovidov).
  • Permite EXISTS <dictionary> para um usuário que tem apenas o privilégio SHOW DICTIONARIES sobre o dicionário (antes era necessário SHOW TABLES). #108084 (alexey-milovidov).
  • Corrigida a limpeza de um BACKUP ... TO Memory(...) que falha antes da finalização: o backup com falha permanecia registrado, impedindo a reutilização do seu nome. #109947 (jkartseva).
  • Corrigido um erro lógico ReadBuffer is canceled. Can't read from it. (abort do servidor em compilações de debug/sanitizador) que podia ocorrer ao ler um arquivo zip (por exemplo, durante um RESTORE a partir de um backup zip) depois que uma leitura anterior do mesmo arquivo falhava no meio do stream. #110197 (groeneai).
  • Corrige uma corrupção de heap, que podia causar o crash do servidor durante o desligamento, provocada pelo método const AccessRights::getFilters, que modificava uma árvore de direitos de acesso compartilhada por consultas simultâneas. #112692 (groeneai).

Execução distribuída, tabelas, views e dicionários

  • Corrigido um erro espúrio Inconsistent AST formatting em ALTER TABLE ... MOVE PART ... TO SHARD '<path>'. O formatador de consultas descartava a palavra-chave SHARD, de modo que a consulta reformatada não podia ser interpretada novamente, gerando um LOGICAL_ERROR (uma exceção tratada em compilações de release e um abort em compilações de depuração e com sanitizers). #109060 (groeneai).
  • Corrigido um erro lógico (!part.empty()) quando uma tabela Distributed definida com um nome de banco de dados remoto vazio é usada em um JOIN com distributed_product_mode = 'local'. #110677 (groeneai).
  • Corrigido o retorno de linhas incorretas por DISTINCT com LIMIT/OFFSET ordenado quando a indicação de limite de parada antecipada do DISTINCT não conseguia delimitar o início do resultado: um LIMIT negativo (retornava o início em vez do final), um LIMIT/OFFSET fracionário (a fração só é resolvida após uma leitura completa) e um OFFSET isolado sem LIMIT (o final após o deslocamento era descartado). Por exemplo, SELECT DISTINCT intDiv(x, 100) FROM t ORDER BY intDiv(x, 100) LIMIT -1 em uma tabela com várias partes retornava o menor valor distinto em vez do maior. #111326 (groeneai).
  • Corrige o caso em que um alias após uma subconsulta em DESCRIBE TABLE não era aceito pelo parser e resultava em erro de sintaxe. Corrige https://github.com/ClickHouse/ClickHouse/issues/100031. #100205 (yariks5s).
  • Corrigido um abort do servidor (Logical error: 'Block structure mismatch') que podia ocorrer durante um INSERT concorrente enquanto um ALTER RENAME COLUMN estava em andamento em um banco de dados Atomic com lazy_load_tables = 1 após DETACH DATABASE / ATTACH DATABASE. #104852 (groeneai).
  • Corrige a corrupção de nomes de colunas e a exceção BAD_ARGUMENTS causadas pela configuração inject_random_order_for_select_without_order_by. Com a configuração habilitada, SELECTs com várias colunas não falham mais, e os nomes das colunas de saída (por exemplo, em CREATE TABLE AS SELECT, CREATE VIEW AS SELECT, JSONEachRow) são preservados em vez de serem substituídos por aliases internos __subquery_column_<UUID>. #105896 (groeneai).
  • Corrige a indicação confusa “Maybe you meant X?” após uma reinicialização do servidor (ou DETACH/ATTACH DATABASE), em que executar DROP em uma tabela já removida sugeria como alternativa o próprio nome recém-removido. As tarefas de carregamento assíncrono agora são removidas de DatabaseOrdinary::startup_table e load_table ao desanexar. #106238 (groeneai).
  • Corrige os motores de tabela e de banco de dados MaterializedPostgreSQL para que uma única tabela ou banco de dados possa ser replicado a partir de um schema PostgreSQL diferente do padrão (materialized_postgresql_schema), inclusive quando há tabelas com o mesmo nome em vários schemas do mesmo banco de dados (antes, elas compartilhavam uma publication e um replication slot e interferiam umas nas outras). #107425 (alexey-milovidov).
  • Corrigidos os erros NO_SUCH_COLUMN_IN_TABLE quando uma consulta com réplicas paralelas seleciona uma coluna ALIAS de uma tabela enviada como tabela temporária de GLOBAL JOIN, MULTIPLE_EXPRESSIONS_FOR_ALIAS quando ambos os lados de um JOIN distribuído declaram uma coluna ALIAS com o mesmo nome, e UNKNOWN_IDENTIFIER quando uma tabela Distributed declara uma coluna ALIAS baseada em outra coluna ALIAS, inclusive como chave de JOIN USING. #107700 (yakov-olkhovskiy).
  • Corrigido um overflow de inteiro com sinal quando uma view materializada atualizável faz retentativas de uma atualização que falhou com refresh_retries definido como um valor muito grande (próximo ao máximo de Int64). O overflow podia abortar o servidor em compilações com o sanitizador de comportamento indefinido. #108005 (groeneai).
  • Corrigida uma exceção (CANNOT_PARSE_TEXT) ao carregar um dicionário com chave composta cujas colunas-chave não são as primeiras colunas na definição do dicionário, com uma fonte de dados ClickHouse local que usa uma consulta explícita. As colunas de origem agora são associadas à estrutura do dicionário pelo nome, e não pela posição. #108053 (alexey-milovidov).
  • Corrigido um crash (desreferência de ponteiro nulo) ao consultar uma tabela Hive sem cláusula WHERE, por exemplo, SELECT * FROM hive_table. #108094 (alexey-milovidov).
  • Corrigido um crash do servidor (falha de segmentação) que podia ocorrer quando uma consulta distribuída referenciava uma CTE MATERIALIZED ainda não materializada como tabela externa e a fonte remota era criada sob demanda (fonte adiada). O crash era causado pela desreferência de um Logger nulo dentro de RemoteQueryExecutor::sendExternalTables(). #108547 (groeneai).
  • Corrigido um erro lógico (Equal values are not contiguous within the range assumed to be sorted) ao executar DISTINCT sobre uma leitura STREAM (SELECT DISTINCT ... FROM table STREAM). As otimizações de leitura em ordem não são mais aplicadas a leituras STREAM, que produzem linhas na ordem de commit, e não na ordem da chave de ordenação. #108568 (groeneai).
  • Corrigida uma exceção (Cannot find sharding key column e, em compilações debug/com sanitizador, um abort do servidor) quando a chave de sharding de uma tabela Distributed é uma expressão que o analisador reduz a uma constante, por exemplo, if(1, toInt32(id), toInt32(id) + 1), com optimize_skip_unused_shards = 1. #108737 (groeneai).
  • Corrigido um abort do servidor (LOGICAL_ERROR / asserção em compilações debug e com sanitizador) quando um INSERT ... SELECT por meio de uma tabela Alias é cancelado sem exceção, por exemplo, com timeout_overflow_mode = 'break'. #108783 (groeneai).
  • Corrigido um abort do servidor (LOGICAL_ERROR / asserção em compilações debug e com sanitizador) quando um INSERT ... SELECT em uma tabela TimeSeries é cancelado sem exceção, por exemplo, com timeout_overflow_mode = 'break'. #108796 (tiandiwonder).
  • Corrigida a falha ocasional de consultas distribuídas com UNEXPECTED_PACKET_FROM_SERVER (“expected TablesStatusResponse, got ProfileInfo”) quando uma conexão deixada fora de sincronia por uma consulta cancelada anteriormente era reutilizada do pool. #108854 (alexey-milovidov).
  • Corrigido um LOGICAL_ERROR (CTE '...' does not have query tree, but was not planned yet) quando uma CTE MATERIALIZED é referenciada em mais de uma posição da árvore de junção (por exemplo, duas subconsultas em junção, ou uma subconsulta em junção mais uma subconsulta escalar no WHERE) em uma consulta sobre uma tabela Distributed. A consulta agora é executada em vez de lançar a exceção (que abortava o servidor em compilações debug/com sanitizador). #108924 (groeneai).
  • Corrige um problema de segurança de memória em que um trabalho assíncrono agendado a partir do processamento de uma visão materializada podia continuar usando a contabilização em nível de consulta mesmo após o término da consulta. #108988 (filimonov).
  • Corrige um LOGICAL_ERROR (“Cannot find __grouping_set column in header of MergingAggregatedTransform with grouping sets”, ou “Chunk info was not set for chunk in MergingAggregatedTransform”) que podia ocorrer, sem o analyzer, em um UNION ALL/INTERSECT/EXCEPT em que um ramo usa GROUP BY GROUPING SETS com réplicas paralelas e outro ramo usa FINAL. #109003 (groeneai).
  • Corrige a falha de CREATE TABLE ... AS SELECT FROM s3Cluster(...) (e de outras funções de tabela de cluster, como fileCluster/urlCluster) com NOT_FOUND_COLUMN_IN_BLOCK dentro de um banco de dados Replicated. #109266 (groeneai).
  • Corrigido um erro (NOT_FOUND_COLUMN_IN_BLOCK, ou std::bad_function_call em versões mais antigas) ao executar CREATE TABLE ... ON CLUSTER ... AS SELECT com leitura de uma tabela Distributed em um cluster com dois ou mais shards. #109407 (alexey-milovidov).
  • Corrigido um erro interno confuso (Method getResultType is not supported for TABLE query tree node) quando uma expressão de tabela era usada como argumento esquerdo do operador IN; agora essas consultas retornam uma mensagem de erro clara. #109412 (alexey-milovidov).
  • Corrige um erro lógico Bad cast from type DB::FunctionNode to DB::ConstantNode (que abortava o servidor em compilações de debug/com sanitizador) ao executar SELECT ... ORDER BY ... WITH FILL em uma tabela Distributed com um valor baixo de optimize_const_name_size. #109938 (groeneai).
  • Corrige um LOGICAL_ERROR (Left and right columns have same names) no otimizador de ordem de junções que podia ser disparado por uma junção com vírgula sobre uma view de múltiplas tabelas quando query_plan_merge_expression_into_join está habilitado. #110227 (groeneai).
  • Corrige um raro Logical error: 'No more packets are available.' gerado em uma consulta distribuída válida com LIMIT, que abortava o servidor em compilações de debug e com sanitizador. #110334 (groeneai).
  • Corrigido um bug do parser em que COMMENT era interpretado incorretamente como um alias implícito quando uma consulta SELECT terminava logo após um identificador de tabela simples (por exemplo, ... FROM t COMMENT 'x'), o que causava um erro de sintaxe enganoso em vez de aplicar o comentário à view/tabela. #110372 (adityaksolves).
  • Corrigido um resultado incorreto em que length() (e a dimensão de QBit) em uma coluna FixedString retornava 0 em vez do tamanho fixo N com réplicas paralelas quando a consulta tinha um filtro seletivo. #110427 (groeneai).
  • Corrige o erro NOT_FOUND_COLUMN_IN_BLOCK em consultas com uma subconsulta em FROM quando réplicas paralelas são executadas no modo custom_key_sampling / custom_key_range. Antes, essas consultas (por exemplo, SELECT * FROM (SELECT id, k, v FROM t WHERE id < 20) ORDER BY k) falhavam com Not found column __table2.id in block .... #110690 (groeneai).
  • Corrige Logical error: 'clock' (em compilações de depuração/sanitizer o servidor é encerrado; em compilações de lançamento ocorre um travamento infinito) ao executar EXPLAIN ANALYZE sobre uma consulta com uma leitura de streaming (FROM ... STREAM) que não é uma expressão de tabela simples de nível superior: aninhada em uma subconsulta (por exemplo, dentro de WHERE ... IN (...) ou de uma CTE) ou oculta por trás de uma view comum ou parametrizada. Agora, EXPLAIN ANALYZE rejeita essas consultas com NOT_IMPLEMENTED, da mesma forma que já rejeitava uma leitura de streaming de nível superior. #110935 (groeneai).
  • Corrige a resolução de nomes de coluna totalmente qualificados, como db.table.column, no analisador para tabelas que têm o mesmo nome do seu banco de dados. #110976 (alexey-milovidov).
  • Corrige os erros NOT_FOUND_COLUMN_IN_BLOCK / THERE_IS_NO_COLUMN (e, em alguns lançamentos, resultados incorretos sem nenhum aviso) em um RIGHT JOIN quando parallel_replicas_min_number_of_rows_per_replica está definido e uma coluna da tabela à esquerda é projetada. #111332 (groeneai).
  • Corrige uma condição de corrida em UDFs executáveis, no mecanismo de tabela executable e em dicionários executáveis, em que um fcntl sobre um descritor de arquivo já fechado podia corromper um descritor não relacionado de uma consulta concorrente (removendo O_NONBLOCK), o que podia fazer consultas travarem indefinidamente. #111779 (Algunenano).
  • Corrige um LOGICAL_ERROR (“Invalid number of rows in Chunk”) — e, em compilações reforçadas, um aborto relacionado causado por acesso fora dos limites — em ORDER BY ... WITH FILL ... INTERPOLATE sobre uma tabela Distributed com dois ou mais shards, sobre clusterAllReplicas ou sobre réplicas paralelas com chave personalizada, inclusive com resultados vazios. Agora, WITH FILL é aplicado apenas no nó que produz o resultado final, o que também corrige a duplicação das linhas de preenchimento geradas entre shards/réplicas. #111919 (yakov-olkhovskiy).
  • Corrige o travamento permanente de DROP TABLE ... SYNC quando uma consulta sobre system.replicas havia sido encerrada antes que suas solicitações de status fossem processadas. #112164 (evillique).
  • Corrige uma exceção LOGICAL_ERROR (Block structure mismatch in joined block stream) em uma junção de múltiplas tabelas cujas duas subjunções não produzem nenhuma coluna de saída, por exemplo SELECT count() FROM t1, t2, t3, t4 WHERE (t1.b = t2.b) AND (t3.a = t4.a) com query_plan_optimize_join_order_limit definido como 0 ou 1. #112205 (groeneai).
  • Corrige o erro lógico Cannot add step Expression to QueryPlan because it has incompatible header with root step JoinLazyColumnsStep em consultas com FINAL, um filtro PREWHERE, um LIMIT pequeno e make_distributed_plan = 1, quando as colunas selecionadas são listadas em uma ordem diferente da ordem das colunas da tabela. A materialização tardia substituía um nó do plano sem preservar o cabeçalho de saída desse nó, o que deixava o plano de consulta inconsistente. #112303 (groeneai).
  • Corrige resultados incorretos e um erro lógico quando um argumento que deve ser constante, como a escala de toDecimal32 ou o fuso horário de toDateTime, vem de uma subconsulta escalar e o analisador antigo está em uso. Esse argumento era analisado como se seu valor fosse zero ou vazio, de modo que o tipo de resultado declarado não correspondia ao valor calculado, e CREATE VIEW e CREATE MATERIALIZED VIEW persistiam um tipo de coluna incorreto. #112492 (groeneai).
  • Corrige um erro lógico e um registro de dependência incorreto quando o corpo de uma VIEW comum referencia uma tabela ou dicionário por meio de um parâmetro de consulta, como em CREATE VIEW v AS SELECT x FROM {db:Identifier}.t. Essa view não registra mais uma dependência referencial em uma tabela de mesmo nome no banco de dados atual, de modo que tabelas não relacionadas voltam a poder ser removidas. #112704 (groeneai).
  • Corrige um erro lógico quando o motor de tabela Join é usado no lado direito de um JOIN cuja seção ON contém uma condição que referencia colunas de ambas as tabelas, por exemplo ON (t.key = j.key) AND (t.a < j.a). Essa consulta agora é rejeitada com uma exceção clara, em vez de gerar required columns: ... but not found any in left table ou std::bad_variant_access. #112815 (groeneai).
  • Corrigidos um comportamento indefinido e um erro silencioso de agendamento quando uma tarefa em segundo plano é agendada com um atraso muito grande, por exemplo, por uma view materializada atualizável com um período REFRESH AFTER enorme. Os atrasos agora são limitados ao maior valor representável, em vez de causarem overflow. #113041 (groeneai).
  • Corrigido o erro reportado quando um INSERT assíncrono em uma tabela Distributed precisa de um diretório de fila cujo nome excede o limite de 255 bytes do sistema de arquivos (o que pode ocorrer com use_compact_format_in_distributed_parts_names = 0). Antes, era gerado um LOGICAL_ERROR para um shard com internal_replication e, nos demais casos, um Code: 1001. std::exception sem identificação da origem; agora ambos reportam ARGUMENT_OUT_OF_BOUND, informando a tabela, o cluster e o limite. #113083 (groeneai).
  • UNDROP TABLE agora pode ser interrompido por KILL QUERY enquanto aguarda que as consultas em execução liberem a tabela removida. #113263 (alexey-milovidov).
  • Corrigidos um travamento permanente de DROP TABLE e um vazamento de memória após a falha de uma consulta que usava uma CTE materializada. A tabela ficava presa na fila de remoção até que o servidor fosse reiniciado. #113397 (tiandiwonder).
  • Corrige uma falha de segmentação e um LOGICAL_ERROR (No host found for exchange stream final_result__0_0) quando uma subconsulta define distributed_plan_execute_locally em sua própria cláusula SETTINGS com make_distributed_plan ativo. O plano distribuído e o código que o executa liam a configuração de dois contextos diferentes e podiam divergir, fazendo com que o iniciador construísse um pipeline contraditório. #113422 (groeneai).
  • Corrigido um problema em que um CREATE TABLE ... AS SELECT cujo SELECT de preenchimento falhava não podia ser encerrado quando database_atomic_wait_for_drop_and_detach_synchronously estava habilitado: o DROP interno de limpeza da tabela temporária aguardava a fila de remoção em segundo plano e ignorava tanto KILL QUERY quanto max_execution_time. #113504 (groeneai).
  • Corrige resultados incorretos e, em builds com asserções habilitadas, uma falha de asserção em um JOIN com um dicionário cuja cláusula ON possui uma condição de não igualdade envolvendo ambas as tabelas, como ON (t.key = d.key) AND (t.a * 10 < d.a), quando join_use_nulls está habilitado. A condição era avaliada sobre uma coluna lida com um tipo incompatível, de modo que as linhas podiam corresponder de forma arbitrária. #113534 (alexey-milovidov).
  • Corrigido o problema em que uma view parametrizada perdia seu banco de dados quando uma consulta que a referenciava sem qualificação era enviada a um shard, fazendo com que o shard resolvesse o nome com base no seu próprio banco de dados padrão. Dependendo do conteúdo desse banco de dados, a consulta falhava com UNKNOWN_FUNCTION ou retornava silenciosamente linhas de outra view. Afeta IN, JOIN e remote() por meio de uma tabela Distributed. #113550 (groeneai).
  • Corrigido o erro Unsupported JOIN keys of type keys256 in StorageJoin ao ler uma tabela com engine Join cuja chave é composta (várias colunas) ou um único valor de 16/32 bytes, como UUID, Int256 ou FixedString(4). Essa tabela podia ser criada, receber gravações e ser usada em junções, mas nunca podia ser lida com SELECT. #113578 (groeneai).
  • Corrigido o erro lógico Sending a distributed query with unknown (zero) client version quando uma tabela Distributed sem estrutura sobre um shard remoto é anexada ou carregada a partir de metadados gravados por uma versão mais antiga do servidor. #113675 (alexey-milovidov).
  • Corrigido um LOGICAL_ERROR quando um SELECT usava o modificador STREAM em uma tabela nomeada em conjunto com réplicas paralelas no modo de tarefas de leitura. Com uma CTE materializada usada como set de IN em PREWHERE, o servidor lançava Reading from materialized CTE ... DelayedPortsProcessor gate is missing in the query plan (um abort do servidor em compilações debug e com sanitizador). Uma tabela com STREAM agora é rejeitada quando réplicas paralelas são solicitadas: com enable_parallel_replicas = 2, a consulta falha com SUPPORT_IS_DISABLED; com 1, ela é executada sem réplicas paralelas, exatamente como já acontece com FINAL. #113754 (groeneai).
  • Corrigida a complexidade quadrática na análise do argumento de endereço das funções de tabela remote, mysql e similares: um endereço muito longo (por exemplo, um FixedString preenchido com zeros do tamanho de um megabyte) fazia a consulta travar durante a análise, sem possibilidade de cancelamento. #113918 (alexey-milovidov).
  • Corrigido um erro espúrio Failed to drop temporary table after refresh. Table ... is left behind and requires manual cleanup. registrado no log quando a atualização de uma view materializada atualizável é cancelada (por exemplo, por um desligamento do servidor) enquanto database_atomic_wait_for_drop_and_detach_synchronously está habilitado. Na verdade, a tabela temporária era removida, portanto nenhuma limpeza manual era necessária. #113957 (groeneai).
  • Corrigida a ausência de uma linha em system.query_views_log para uma visão materializada que falha durante a coleta de suas dependências com materialized_views_ignore_errors habilitado. Em compilações debug e com sanitizador, isso também abortava o servidor com std::out_of_range em vez de registrar a view. #114064 (groeneai).
  • Corrigidos resultados inconsistentes quando um filtro sobre uma coluna não chave da tabela da direita era empurrado para abaixo de um ANY INNER JOIN. #114313 (kirillshokhin).
  • Corrigido o vazamento de uma tabela interna _tmp_replace_* por CREATE OR REPLACE e a falha de CREATE OR REPLACE VIEW com NOT_IMPLEMENTED quando ignore_drop_queries_probability está definido. Os DROPs emitidos internamente são etapas de uma única instrução do usuário, portanto a injeção de falhas em DROP deixou de se aplicar a eles. #114420 (groeneai).
  • Corrigido um LOGICAL_ERROR ao ler uma tabela Delta Lake cujo metaData.partitionColumns referencia uma coluna que não está declarada em metaData.schemaString. Esses metadados agora são rejeitados com BAD_ARGUMENTS no leitor delta-kernel e com INCORRECT_DATA no leitor legado sempre que a tabela ou seu schema é lido a partir de um snapshot, e não apenas quando a consulta contém um predicado. #114538 (groeneai).
  • Corrigido o problema em que as estatísticas de tabelas hash — e, com elas, a pré-alocação de tabelas hash de agregação — eram desativadas de forma silenciosa e permanente para todo o servidor quando uma consulta que usava a otimização lazy de FINAL (query_plan_optimize_lazy_final) era a primeira agregação executada após a inicialização do servidor. #114597 (alexey-milovidov).
  • Corrigido o vazamento da tabela de destino descartada na rotação de uma view materializada atualizável quando ignore_drop_queries_probability está habilitado. O DROP emitido por uma atualização para limpar o destino anterior faz parte da própria atualização, e não é um DROP solicitado pelo usuário; por isso, a injeção de falhas deixou de se aplicar a ele. #114622 (groeneai).
  • Corrigido o problema em que ANY RIGHT JOIN e SEMI RIGHT JOIN com várias condições combinadas com OR na seção ON retornavam algumas linhas da tabela da direita duas vezes e perdiam as correspondências de outras. Um ANY LEFT JOIN escrito explicitamente também era afetado, pois o planejador pode inverter as tabelas e executá-lo como ANY RIGHT JOIN. #114676 (vdimir).
  • Corrige um LOGICAL_ERROR (Cannot find input column ... on its position in inputs of expression actions DAG) quando uma consulta tem um JOIN acima de uma tabela cuja coluna com índice de texto é usada tanto por um predicado de busca textual em PREWHERE quanto por um em WHERE. #114771 (groeneai).
  • Corrige o erro NOT_FOUND_COLUMN_IN_BLOCK em todo INSERT em uma tabela que declara STATISTICS(...) em uma coluna ALIAS ou EPHEMERAL, o que tornava essas tabelas read-only. #115231 (groeneai).
  • Corrige dictGet e suas variantes em consultas distribuídas: um nome de dicionário não qualificado agora é vinculado ao banco de dados atual do iniciador, em vez de ser resolvido com base no banco de dados atual de cada shard, onde ou não era encontrado ou apontava para outro dicionário com o mesmo nome. #115541 (alexey-milovidov).
  • Corrigido um bug em que restaurar um banco de dados ou uma tabela com um novo nome removia os aliases de tabela do corpo das views armazenadas, fazendo com que a leitura de uma view restaurada falhasse com UNKNOWN_IDENTIFIER. #115645 (groeneai).
  • Corrige o LOGICAL_ERROR “Reading from materialized CTE ‘X’ before its materialization completed - DelayedPortsProcessor gate is missing in the query plan” quando uma CTE MATERIALIZED é lida dentro de uma subconsulta IN sobre uma tabela Distributed. #115740 (groeneai).
  • Corrige o erro BAD_ARGUMENTS “Dictionary not found” em dictGet após um DETACH DICTIONARY … PERMANENTLY rejeitado pela verificação de dependências (HAVE_DEPENDENT_OBJECTS). Agora o dicionário continua totalmente utilizável quando o detach é rejeitado. #105259 (groeneai).
  • Corrigido um Logical error: 'removed' (aborto do servidor em builds de depuração) na fila de remoção de tabelas em segundo plano. O erro podia ser acionado quando o mesmo UUID explícito era reutilizado em várias consultas CREATE OR REPLACE TABLE, o que colocava na fila mais de uma tabela removida com esse mesmo UUID. #107031 (groeneai).
  • Corrigido um problema em que o MaterializedPostgreSQL interrompia a replicação de um banco de dados inteiro (com LOGICAL_ERROR: Columns number mismatch) quando a estrutura de uma única tabela replicada era alterada enquanto o servidor estava desligado. Agora, apenas a tabela afetada é ignorada e pode ser recuperada com DETACH/ATTACH. #107427 (alexey-milovidov).
  • Corrigido um desequilíbrio grave na distribuição de trabalho com réplicas paralelas quando o cluster contém réplicas inativas (por exemplo, entradas obsoletas deixadas após o escalonamento automático). Essas réplicas não são mais contabilizadas pelo coordenador de leitura, de modo que o trabalho é balanceado entre as réplicas online em vez de se concentrar em uma só. #107805 (alexey-milovidov).
  • Corrigido um travamento de SYSTEM RELOAD DICTIONARIES (e RELOAD DICTIONARY) quando muitos dicionários MySQL definidos em XML compartilhavam um único pool de conexões via share_connection. Esses pools agora respeitam connection_pool_size e connection_wait_timeout (padrão de 5 segundos) definidos na configuração, assim como os dicionários definidos por meio de coleções nomeadas. #108083 (alexey-milovidov).
  • Tentativas esgotadas de DDL distribuído replicado executado pelo líder não bloqueiam mais permanentemente as consultas DDL ON CLUSTER subsequentes. #108505 (ahaanlimaye).
  • Corrigida uma possível falha (use-after-free) quando SYSTEM FLUSH DISTRIBUTED é executado simultaneamente com DROP TABLE da mesma tabela Distributed. #108684 (groeneai).
  • Corrigido um LOGICAL_ERROR (local_replica_plan_reading_step->getAnalyzedResult() == nullptr) no planejador automático de réplicas paralelas, que podia ocorrer quando automatic_parallel_replicas_mode estava habilitado em conjunto com parallel_replicas_min_number_of_rows_per_replica maior que 0. #109011 (groeneai).
  • Corrigido um LOGICAL_ERROR (creation_csn is not set while removal_csn is set to 1) que podia ser lançado quando um TRUNCATE não transacional era executado simultaneamente com uma transação não confirmada que havia inserido dados na mesma tabela. Nesse caso, o TRUNCATE não remove mais partes criadas por transações ainda não confirmadas. #109598 (tuanpach).
  • Motores de banco de dados externos (por exemplo, PostgreSQL) não aplicam mais pushdown de comparações de intervalo (>=, >, <=, <) em colunas UUID. O ClickHouse e os bancos de dados externos ordenam UUIDs de forma diferente, e por isso o pushdown dessas comparações descartava silenciosamente linhas do resultado; agora esses predicados são avaliados pelo próprio ClickHouse. #109833 (vismaytiwari).
  • Corrigida uma falha do servidor no motor de banco de dados MaterializedPostgreSQL que podia ocorrer quando uma tabela era desanexada (ou tinha sua estrutura alterada) enquanto ainda aguardava sincronização na fila. #110596 (alexey-milovidov).
  • Corrigido um problema em que o tipo de uma coluna EPHEMERAL era reescrito pelas query_masking_rules do servidor. Uma regra que correspondia a um trecho dentro do tipo fazia com que CREATE TABLE armazenasse o tipo errado ou falhasse. #112048 (alexey-milovidov).
  • Corrige um underflow sem sinal na verificação do comprimento do nome da tabela que permitia criar uma tabela que nunca poderia ser removida. Quando o nome do banco de dados com escape atingia 214 bytes, o limite calculado para o nome de arquivo metadata_dropped sofria wraparound, de modo que o CREATE TABLE era aceito e o DROP TABLE ou DROP DATABASE subsequente falhava com File name too long. Esse tipo de nome agora é rejeitado com ARGUMENT_OUT_OF_BOUND, o mesmo erro já retornado logo abaixo desse limite. #112527 (groeneai).
  • Corrigido o RENAME TABLE, que verificava o comprimento máximo do nome da tabela com base no banco de dados de origem em vez do banco de dados de destino. Renomear uma tabela para um banco de dados com nome longo podia gerar uma tabela que o DROP TABLE não conseguia remover, e renomear uma tabela para fora desse banco de dados era rejeitado indevidamente. #113019 (groeneai).
  • Corrige a coluna views em query_log, que ficava sempre vazia em inserts em uma tabela Alias cujo destino aciona visões materializadas. #113076 (eclbg).
  • Expressões inválidas de parallel_replicas_custom_key, como tuple() ou (x, y), agora são rejeitadas com ILLEGAL_TYPE_OF_COLUMN_FOR_FILTER em vez de provocar leitura além do fim da lista de tipos da chave personalizada. #113359 (nickitat).
  • Corrigido o RENAME DATABASE, que aceitava um nome de destino longo o suficiente para impossibilitar a remoção das tabelas do banco de dados. A verificação do comprimento do nome da tabela agora é executada independentemente de check_table_dependencies e também abrange tabelas desanexadas, que nunca eram verificadas e, por isso, eram afetadas mesmo com as configurações padrão. #113557 (groeneai).
  • Ao usar inserts em segundo plano em tabelas com o engine Distributed, os atrasos causados por erros repetidos no envio de dados para shards remotos agora diminuem assim que os erros são resolvidos. Antes, o atraso só aumentava e nunca era redefinido. #87378 (Blackmorse).
  • Rejeita handshakes do protocolo nativo que usam o USER_INTERSERVER_MARKER para um cluster desconhecido ou para um cluster configurado sem <secret>. Antes, esse handshake permitia que um cliente não autenticado entrasse no modo entre servidores e utilizasse pacotes de protocolo de pré-autenticação (por exemplo, TablesStatusRequest) apoiados por um fake_interserver_context, obtendo informações sobre tabelas locais sem comprovar que conhecia o secret do cluster. #99675 (MillaFleurs).

Correções de SQL, do analisador e de JOIN

  • Corrige a substituição de parâmetros de consulta dentro das definições de uma cláusula WINDOW nomeada. Antes, os parâmetros nesse ponto permaneciam silenciosamente sem substituição, e um parâmetro Identifier não definido podia causar a exceção Logical error: '!part.empty()' durante EXPLAIN SYNTAX. #110506 (alexey-milovidov).
  • Corrige uma falha rara do servidor quando views materializadas atualizáveis são removidas ou substituídas de forma concorrente. Um ponteiro nulo era desreferenciado em RefreshTask::doScheduling quando outra thread definia a view da tarefa como nullptr enquanto o código de escalonamento havia liberado temporariamente seu mutex. #105588 (groeneai).
  • Corrige o resultado incorreto de uma view definida com EXCEPT ou INTERSECT cujo operando é uma cadeia UNION, após DETACH/ATTACH ou reinicialização do servidor. O formatador omitia os parênteses em torno dos filhos UNION de INTERSECT/EXCEPT, de modo que o SQL armazenado era reanalisado com a precedência invertida. #105935 (groeneai).
  • Corrigidos resultados incorretos (linhas duplicadas) em SELECT DISTINCT sobre um GROUP BY com WITH CUBE, WITH ROLLUP ou GROUPING SETS nas mesmas chaves. A otimização query_plan_remove_redundant_distinct deixa de remover o DISTINCT nesses casos, pois os modificadores de agrupamento emitem linhas extras com as colunas-chave preenchidas com valores padrão, que podem coincidir com valores reais de grupo. #107072 (groeneai).
  • Corrige um resultado incorreto em um OUTER JOIN quando o filtro WHERE é uma conjunção que contém um termo constante (por exemplo, p AND 1, ou WHERE p QUALIFY NULL, em que QUALIFY NULL é mesclado ao WHERE). O termo constante podia ser empurrado para o lado não preservado da junção e removido do filtro pós-junção; assim, a junção produzia linhas sem correspondência com as colunas desse lado preenchidas com valores padrão, e essas linhas passavam indevidamente pelo filtro. #107084 (groeneai).
  • Corrige um LOGICAL_ERROR (“Cannot find input column … on its position in inputs of expression actions DAG”) que abortava o servidor em uma subconsulta escalar correlacionada sobre uma fonte que projetava o mesmo identificador de coluna duas vezes (por exemplo, SELECT number, *) quando correlated_subqueries_default_join_kind = 'left'. #107112 (groeneai).
  • Corrige um LOGICAL_ERROR (aborto do servidor em builds de debug/sanitizer) quando um JOIN usa o operador de comparação null-safe (<=> / IS NOT DISTINCT FROM) e uma das chaves é uma subconsulta escalar, por exemplo, ... JOIN t2 ON (SELECT x FROM t1) <=> t2.k, com o analisador antigo (enable_analyzer = 0). Agora, esse tipo de consulta retorna um erro comum NOT_FOUND_COLUMN_IN_BLOCK em vez de um erro lógico. #108123 (groeneai).
  • Corrigidas as exceções LOGICAL_ERROR (Join is supported only for pipelines with one output port) e NOT_IMPLEMENTED (MergeJoinAlgorithm is not implemented for strictness Semi) quando join_algorithm = 'full_sorting_merge' era usado em uma junção SEMI/ANTI, incluindo junções geradas pela descorrelação de uma subconsulta correlacionada EXISTS. O full_sorting_merge agora rejeita combinações de strictness/kind que não consegue executar, de modo que o planejador recorre a outro algoritmo habilitado ou informa que a junção não pode ser executada. #108658 (groeneai).
  • Corrigido um bug em que a linha WITH TOTALS de um JOIN podia conter valores default (como 0) em vez dos valores constantes provenientes de uma subconsulta constante em um dos lados da junção. O resultado incorreto ocorria apenas com algumas ordens de junção ou com a configuração query_plan_join_swap_table. #108807 (vdimir).
  • Corrigido um abort na inicialização (Cannot allocate ThreadStack, EINVAL) em compilações com glibc executadas em CPUs com pilha de sinais de tamanho grande (por exemplo, Intel Sapphire Rapids / Granite Rapids com um kernel compatível com AMX), em que o tamanho da pilha alternativa de sinais não era arredondado para um múltiplo do tamanho de página antes de aligned_alloc. #108813 (groeneai).
  • Corrigido um erro lógico Block structure mismatch in JoinStep (abort do servidor em compilações de debug/sanitizador) quando uma subconsulta correlacionada é descorrelacionada em uma junção e a relação de origem contém o mesmo nome de coluna mais de uma vez, por exemplo, WITH t AS (SELECT number, * FROM numbers(3)) SELECT *, (SELECT t.number WHERE t.number >= 0) FROM t com correlated_subqueries_default_join_kind = 'right'. #109114 (groeneai).
  • Corrigido CREATE USER ... HOST LIKE 'a', 'b' (e o equivalente ALTER USER), que mantinha silenciosamente apenas o primeiro pattern. Agora, todos os patterns HOST LIKE especificados são armazenados na lista de hosts permitidos do usuário. #109187 (groeneai).
  • Corrigido um resultado inesperado de ANY JOIN com uma condição ON constante (por exemplo, t1 ANY INNER JOIN t2 ON 1): a consulta retornava o produto cartesiano completo em vez do resultado da junção ANY #109207 (vdimir).
  • Corrigido o limite global max_rows_in_join / max_bytes_in_join, que não era aplicado ao algoritmo de junção parallel_hash; com isso, uma consulta com join_overflow_mode = 'throw' podia ser concluída silenciosamente em vez de gerar SET_SIZE_LIMIT_EXCEEDED. #109488 (m-selmi).
  • Corrigida a perda silenciosa de dados quando um INSERT ... VALUES em um stream com múltiplas consultas é seguido por um comentário SQL no final (por exemplo, VALUES (1) -- comment) no caminho de parsing de insert em linha do lado do servidor (send_table_structure_on_insert_with_inline_data = 0). O comentário final era lido como dados de linha além do ; de término, fazendo com que as consultas seguintes no stream fossem ignoradas silenciosamente. #109643 (groeneai).
  • Corrigido o PREWHERE adiado com optimize_move_to_prewhere = 1 quando o PREWHERE é executado após o FINAL: as condições WHERE não são mais movidas para antes de uma row policy adiada, o que podia alterar os resultados das consultas. #109703 (yariks5s).
  • Corrigido um LOGICAL_ERROR (query tree node does not have valid source node) quando uma CTE recursiva resolvia um identificador de um escopo externo como uma coluna correlacionada (com allow_experimental_correlated_subqueries = 1). Agora, essas consultas retornam um erro UNSUPPORTED_METHOD claro. #109863 (groeneai).
  • Corrigido um overflow de inteiro com sinal quando ORDER BY ... WITH FILL salta uma lacuna muito grande em uma coluna Int64/UInt64 (por exemplo, um passo de 2 em uma lacuna próxima de 2^63). O overflow constituía comportamento indefinido sob sanitizadores e causava wraparound silencioso em compilações de release. #109937 (groeneai).
  • Corrigido um erro lógico Invalid number of rows in Chunk quando o alvo de um INTERPOLATE é um alias de uma coluna WITH FILL com o analisador antigo (enable_analyzer = 0). Essas consultas agora são rejeitadas com um erro claro INVALID_WITH_FILL_EXPRESSION. #110103 (groeneai).
  • Corrigido um erro lógico (Unexpected number of columns in result sample block) quando um filtro contendo uma subconsulta correlacionada (por exemplo, exists((SELECT ...))) é otimizado com convert_query_to_cnf ou optimize_and_compare_chain. #110187 (alexey-milovidov).
  • Uma subconsulta EXISTS correlacionada e aninhada que referencia uma coluna de um escopo além da consulta externa imediata (pulando um escopo intermediário) agora falha com um erro claro NOT_IMPLEMENTED, em vez de um erro interno NOT_FOUND_COLUMN_IN_BLOCK. #110310 (groeneai).
  • Corrigidos resultados incorretos de subconsultas escalares correlacionadas quando a consulta externa tem valores duplicados na coluna correlacionada e a subconsulta é descorrelacionada pelo caminho de CROSS JOIN. Antes, agregações como count() e sum() eram multiplicadas pelo número de duplicatas. Isso afeta o recurso experimental allow_experimental_correlated_subqueries. #110311 (groeneai).
  • Corrigido o problema em que ORDER BY ... WITH FILL não respeitava max_execution_time e demorava a ser cancelado ao gerar um intervalo de preenchimento grande (especialmente com INTERPOLATE). #110332 (alexey-milovidov).
  • A otimização lazy de FINAL (query_plan_optimize_lazy_final, desabilitada por padrão) deixa de ser aplicada quando a consulta lê os dados na ordem da sorting key, pois o plano substituto não produz linhas nessa ordem, enquanto o plano acima pode já depender dela após a otimização de leitura em ordem, o que poderia gerar resultados ordenados incorretamente. Ela também deixa de ser aplicada quando umLIMIT menor que o número de linhas a serem lidas se aplica diretamente à etapa de leitura, caso em que a passagem obrigatória de construção do conjunto impediria o encerramento antecipado. #110576 (KochetovNicolai).
  • O flush de inserção assíncrona em segundo plano agora é interrompido imediatamente quando encerrado com KILL QUERY; antes, o flush de um payload grande em buffer continuava o parsing até o fim e ignorava o cancelamento. #110652 (tiandiwonder).
  • Corrigidos resultados incorretos de GROUP BY ... optimize_aggregation_in_order e DISTINCT ... optimize_distinct_in_order aplicados sobre uma junção partial_merge. A otimização de leitura em ordem era propagada através de PartialMergeJoin, que reordena a entrada esquerda pela chave de junção e, portanto, não preserva a ordem original do fluxo esquerdo, fazendo com que as linhas fossem agrupadas incorretamente. #110671 (groeneai).
  • Corrigido um caso em que, ao usar aliases de coluna de CTE com consultas INTERSECT ou EXCEPT, por exemplo WITH t (a, b) AS (SELECT 1, 2 INTERSECT SELECT 1, 2) SELECT a, b FROM t, a consulta falhava com o erro UNKNOWN_IDENTIFIER. #110885 (yariks5s).
  • Corrigido um LOGICAL_ERROR: ReadBuffer is canceled. Can't read from it. que podia ocorrer em uma junção grace_hash quando a leitura de blocos despejados em disco falhava no meio do processo enquanto várias threads compartilhavam o leitor. #111056 (groeneai).
  • Corrige um bug em que a materialização das colunas do lado direito durante *_hash JOINs usava o fuso horário incorreto. #111074 (yariks5s).
  • Corrige instruções CREATE com uma cláusula COMMENT para que gerem um erro de sintaxe quando o literal de string do comentário estiver ausente, em vez de aceitar silenciosamente uma consulta analisada incorretamente (por exemplo, CREATE VIEW v COMMENT AS SELECT 1 não cria mais uma view sem comentário). #111159 (tiandiwonder).
  • Corrige um LOGICAL_ERROR (Reading from materialized CTE '...' before its materialization completed - DelayedPortsProcessor gate is missing in the query plan) quando uma CTE materializada reutilizada (enable_materialized_cte) é lida em um ramo cuja saída WITH TOTALS ou extremes é descartada, incluindo agregação externa, INSERT ... SELECT, operações de conjunto e EXPLAIN ANALYZE. #111194 (groeneai).
  • Corrige join_algorithm = 'full_sorting_merge', que preenchia as linhas sem correspondência de um LEFT/RIGHT/FULL/ASOFJOIN com um zero bruto em vez do valor padrão do tipo da coluna. Para uma coluna Enum (cujo padrão é seu primeiro elemento, e não 0), isso gerava resultados incorretos (um filtro sobre o valor preenchido descartava as linhas sem correspondência, fazendo com que uma junção externa se comportasse silenciosamente como uma junção interna) e um erro UNKNOWN_ELEMENT_OF_ENUM quando a coluna era selecionada. #111197 (groeneai).
  • Corrige resultados incorretos de SummingMergeTree (e CoalescingMergeTree) com FINAL quando optimize_move_to_prewhere_if_final = 1 e a cláusula WHERE é uma condição booleana implícita sobre uma coluna da chave de ordenação (por exemplo, WHERE k). A coluna-chave era retornada somada entre as partes não mescladas, em vez de ser preservada. #111342 (groeneai).
  • Corrige um erro lógico (Unexpected number of columns in result sample block) que podia ocorrer em um RIGHT/FULL JOIN quando o lado esquerdo contém uma coluna duplicada com o mesmo nome (por exemplo, 1 AS b, 1 AS b) que se mantém após um UNION ALL. #111554 (groeneai).
  • Corrige uma falha do cliente ao formatar uma consulta EXECUTE AS cuja AST tem um filho substituído (como faz o AST fuzzer). ASTExecuteAsQuery agora detém a posse de seus filhos target_user e subquery, em vez de manter ponteiros sem posse para children. #111725 (groeneai).
  • Corrige resultados incorretos quando query_plan_join_swap_table inverte um ANY JOIN com join_any_take_last_row = 1: o ClickHouse agora mantém a ordem original dos lados da junção, para que ANY JOIN continue retornando a última linha correspondente. #112458 (vdimir).
  • Corrige a exceção Context has expired quando getClientHTTPHeader é usado dentro de uma subconsulta. #112533 (alexey-milovidov).
  • Corrige resultados incorretos em um JOIN cuja cláusula ON contém uma condição mista, ou seja, um resíduo de não igualdade entre os dois lados, como ON (t1.key = t2.key) AND (t1.a * 10 < t2.a). Apenas a família hash avalia esse tipo de condição, mas full_sorting_merge, partial_merge e a junção direta de chave-valor declaravam ser capazes de executar essas junções e depois ignoravam silenciosamente o resíduo, retornando linhas a mais. Agora esses algoritmos recusam essas junções, e um algoritmo hash é usado no lugar. #112831 (groeneai).
  • Corrigidos resultados incorretos em uma junção por vírgula ou CROSS cujo WHERE compara colunas de duas tabelas por meio de uma expressão não determinística, como rand. Uma consulta desse tipo podia retornar linhas que contradiziam sua própria cláusula WHERE, porque a reescrita da junção como uma junção INNER movia a expressão para a chave de junção, onde ela é avaliada novamente para cada linha de cada lado. #112938 (groeneai).
  • Corrigida uma lentidão quadrática ao interpretar uma consulta PromQL com uma longa sequência final de caracteres não reconhecidos (por exemplo, um valor FixedString preenchido com bytes NUL): a interpretação de uma entrada inválida da ordem de megabytes mantinha uma thread ocupada por dezenas de minutos e não podia ser cancelada, pois ocorre durante a análise da consulta. Agora o parser para no primeiro erro. #112944 (alexey-milovidov).
  • Corrigido o comportamento de intDiv sobre uma coluna não constante com o divisor constante -1, que causava silenciosamente o estouro (wrap) na divisão do menor número com sinal (por exemplo, intDiv(-9223372036854775808, -1)) em vez de lançar a exceção ILLEGAL_DIVISION, como fazem os demais caminhos de execução. Esse estouro silencioso também podia produzir resultados incorretos de ORDER BY/DISTINCT, porque a otimização de leitura em ordem trata corretamente intDiv por uma constante negativa como monotônica, e o valor estourado violava a ordenação resultante. #113048 (alexey-milovidov).
  • Corrigido o erro UNKNOWN_IDENTIFIER com enable_analyzer = 0 quando um WHERE faz referência a uma coluna produzida por untuple dentro de uma subconsulta, por exemplo SELECT t.keys FROM (SELECT untuple(arrayJoin(m)) AS t FROM ...) WHERE t.values > 0. A reescrita de enable_optimize_predicate_expression empurrava esse predicado para dentro da subconsulta como um HAVING, onde o nome ainda não existe. #113760 (groeneai).
  • Corrigidos resultados incorretos em JOIN com join_algorithm = 'partial_merge' quando o lado direito contém totais: o lado direito podia ficar sem mesclagem, de modo que junções LEFT substituíam correspondências reais por valores default e junções INNER/RIGHT não retornavam nenhuma linha. No caminho de linhas não unidas de RIGHT/FULL, o mesmo estado desreferenciava um ponteiro nulo, o que derrubava o servidor. #113936 (groeneai).
  • Corrigidos resultados incorretos em SELECT DISTINCT com um LIMIT que precisa ler toda a entrada: LIMIT n WITH TIES descartava linhas empatadas, exact_rows_before_limit = 1 informava um rows_before_limit_at_least truncado e GROUP BY ... WITH TOTALS calculava a linha de totais a partir de apenas um prefixo do fluxo. #114025 (groeneai).
  • Corrigido um LOGICAL_ERROR (“Unexpected number of kept output positions after removing unused columns from ReadFromMergeTree”) gerado por um SELECT ... FINAL cujo PREWHERE usa uma coluna de que o FINAL precisa para a mesclagem (ver, is_deleted, sign), mas que não seleciona essa coluna. #114746 (groeneai).
  • Corrigido um problema de ciclo de vida no flush de INSERT assíncrono, no processamento de visões materializadas e em EXPLAIN ANALYZE, que podia acessar um estado de rastreamento de consulta já expirado. #114940 (azat).
  • Corrigido o comportamento de CREATE QUOTA e ALTER QUOTA, que descartavam silenciosamente todos os blocos FOR INTERVAL, exceto o último, quando a vírgula separadora entre os intervalos era omitida. Uma instrução desse tipo era executada com sucesso sem instalar nenhum dos limites anteriores. Agora os intervalos voltam a ser acumulados, como acontecia antes de 2020. #115320 (groeneai).
  • Corrigido o problema em que randConstant retornava dois valores diferentes em uma única consulta quando suas chamadas tinham aliases diferentes. Segundo a documentação, randConstant mantém um único valor para toda a consulta, e SELECT randConstant() = randConstant() já retornava 1, mas adicionar aliases, como em SELECT randConstant() AS a, randConstant() AS b, produzia dois valores sem nenhuma relação entre si. #115384 (alexey-milovidov).
  • Corrigido o problema em que SELECT count() nunca terminava, ou retornava uma contagem de linhas fictícia, em um arquivo MsgPack ou ProtobufList corrompido. O fast path de optimize_count_from_files contava as linhas sem exigir que a posição de leitura avançasse, de modo que um arquivo ProtobufList de dois bytes gerava bilhões de linhas e nunca retornava. Esse tipo de entrada agora é rejeitado com o mesmo erro emitido pelo caminho de leitura comum. #115884 (groeneai).
  • Corrigido o problema em que broken_data_files em system.distribution_queue e a métrica BrokenDistributedFilesToInsert sempre informavam 0: ao varrer a fila de async-insert na inicialização, DistributedAsyncInsertDirectoryQueue::initializeFilesFromDisk contabilizava os bytes corrompidos, mas nunca incrementava o contador de arquivos corrompidos. #92124 (squalfof).

Outras correções de bugs

  • Consultas secundárias executadas como parte de consultas internas agora serão registradas como consultas internas. #108506 (mstetsyuk).
  • Corrige o preenchimento de uma coluna DEFAULT ausente em uma parte com o valor padrão do tipo em vez da expressão DEFAULT quando a condição PREWHERE era dividida em várias etapas de leitura. #111795 (yariks5s).
  • Cotas indexadas por normalized_query_hash agora contabilizam todos os recursos (read_rows, read_bytes, result_rows, result_bytes, execution_time, written_bytes, errors) por padrão de consulta, assim como os contadores de número de consultas, em vez de contabilizá-los em um único bucket compartilhado por usuário. #107681 (alexey-milovidov).
  • Corrigido o problema em que o connect_timeout e os tempos limite de leitura e escrita do MySQL não surtiam efeito: uma tentativa de conexão a um servidor MySQL sem resposta podia ficar travada por mais de dois minutos mesmo com connect_timeout = 1, porque os sinais periódicos do sampling query profiler reiniciavam continuamente o prazo interno de poll do cliente MySQL. #109592 (tiandiwonder).
  • Corrigido o problema em que o tempo limite de espera por bloco de streaming inserts (input_format_max_block_wait_ms) podia nunca expirar enquanto o query profiler estava ativo: o poll do descritor de arquivo reiniciava com o tempo limite completo após cada sinal do profiler, de modo que uma fonte de entrada travada podia adiar indefinidamente o flush do bloco parcial, em vez de executá-lo ao atingir o limite de espera. #109602 (tiandiwonder).
  • Corrigido um LOGICAL_ERROR (std::length_error) quando uma consulta com a configuração experimental make_distributed_plan = 1 usava um valor muito grande de distributed_plan_default_reader_bucket_count ou distributed_plan_default_shuffle_join_bucket_count. Esses valores agora são rejeitados com INVALID_SETTING_VALUE. #109770 (groeneai).
  • Corrige distinct_overflow_mode = 'break': DISTINCT agora retorna o resultado parcial acumulado até o limite e para de ler a fonte, conforme documentado. Antes, o fragmento que ultrapassava max_rows_in_distinct / max_bytes_in_distinct era descartado (gerando resultados truncados ou vazios) e a consulta continuava lendo e inserindo no hash set até o fim da entrada, o que podia resultar em MEMORY_LIMIT_EXCEEDED. #110075 (skuznetsov-clickhouse).
  • Corrige o problema em que optimize_aggregation_in_order ignorava o cancelamento de consultas. AggregatingInOrderTransform agora verifica o cancelamento durante a agregação de um fragmento, de modo que uma consulta interrompida por KILL QUERY ou por max_execution_time (no modo padrão timeout_overflow_mode = 'throw') para imediatamente, em vez de processar o fragmento inteiro até o fim. #110104 (groeneai).
  • Corrigido um abort do servidor (em builds de debug e com sanitizador) quando um valor de uma fonte PostgreSQL da família mysql/postgresql/sqlite é lido em um tipo declarado no qual não pode ser analisado (por exemplo, uma coluna text declarada como Int32). Essa incompatibilidade de tipos agora é reportada como um erro de consulta, em vez de abortar o servidor. #110264 (groeneai).
  • Corrigido um abort do servidor ao analisar certas consultas PRQL (SET dialect = 'prql'). Um panic dentro do compilador prqlc abortava o processo em vez de ser reportado como um erro de consulta. #110316 (groeneai).
  • Corrige NOT_FOUND_COLUMN_IN_BLOCK quando uma row policy e additional_table_filters referenciam a mesma coluna, que não é selecionada de outra forma pela consulta. #111099 (groeneai).
  • Corrigido um travamento em randChiSquared, randStudentT, randFisherF e randBinomial com parâmetros extremos. A consulta não podia ser interrompida por max_execution_time nem por KILL QUERY. Esses parâmetros agora são rejeitados mesmo quando max_rand_distribution_parameter ou max_rand_distribution_trials está definido como 0, e max_rand_distribution_trials não pode mais ser elevado acima do seu valor default de 10^9 para randBinomial. #111909 (alexey-milovidov).
  • Corrige connection_pool_max_wait_ms para que seu valor default documentado, 0, signifique um tempo limite infinito. Uma consulta que encontrava o pool de conexões cheio ficava tentando novamente em um loop contínuo, consumindo CPU e registrando No free connections in pool. Waiting 0 ms. a cada iteração. Agora ela aguarda até que uma conexão seja devolvida ao pool. #112380 (groeneai).
  • Corrige replaceOne, replaceAll, replaceRegexpOne e replaceRegexpAll, que ignoravam max_execution_time e KILL QUERY. Uma única chamada agora verifica se houve cancelamento durante o processamento, de modo que uma substituição de longa duração sobre um valor grande ou sobre um grande número de linhas é interrompida, em vez de ocupar uma thread do servidor até terminar. Como essa chamada não tem resultado parcial para retornar, com timeout_overflow_mode = 'break' ela reporta o estouro do prazo como erro: sempre que há constant folding e, no pipeline, sempre que esse ponto de verificação é alcançado antes da verificação entre blocos do executor, que continua interrompendo a consulta silenciosamente. #112483 (groeneai).
  • Corrigidos countSubstrings, countSubstringsCaseInsensitive e countSubstringsCaseInsensitiveUTF8, que ignoravam KILL QUERY e max_execution_time: uma chamada sobre muitas linhas ou muitas correspondências podia continuar em execução por minutos após o cancelamento da consulta. #113369 (groeneai).
  • Corrige um possível travamento da consulta (por receive_timeout segundos) quando ela termina muito rapidamente no iniciador. #113551 (nickitat).
  • Corrige countMatches e countMatchesCaseInsensitive, que ignoravam max_execution_time e KILL QUERY ao contar as correspondências de um único valor grande, o que mantinha uma consulta cancelada em execução por minutos. Com um argumento constante, a chamada ocorre durante a análise da consulta, portanto não existe pipeline para cancelá-la. #113886 (groeneai).
  • Uma consulta podia ser cancelada até 1 ms antes de seu max_execution_time ter decorrido, falhando com a mensagem contraditória Timeout exceeded: elapsed 999.672 ms, maximum: 1000 ms. #114559 (alexey-milovidov).
  • Corrigida uma leitura fora dos limites em pointInPolygon com um polígono constante cuja caixa delimitadora é ilimitada, por exemplo, quando uma coordenada atinge +-DBL_MAX. Esse polígono agora é rejeitado com BAD_ARGUMENTS, e um polígono com um anel vazio é tratado como sem interior. Antes, a consulta podia retornar um resultado incorreto ou abortar o servidor em builds com hardening ou sanitizadores habilitados. #115035 (groeneai).
  • Corrige uma condição de corrida que podia fazer uma consulta STREAM BOUNDED retornar menos linhas do que as confirmadas antes de seu início, geralmente nenhuma. #115543 (alexey-milovidov).
  • Corrige o erro Unknown identifier gerado durante a otimização do plano de consulta com make_distributed_plan = 1 quando a coluna de ordenação de uma consulta com função de janela passa por uma etapa Expression que não a menciona. #115890 (groeneai).
  • Corrigido o problema em que h3kRing, h3HexRing, h3Line e h3ToChildren ignoravam max_execution_time e KILL QUERY ao expandir um bloco de linhas. #115893 (alexey-milovidov).
  • Corrigido o erro NOT_FOUND_COLUMN_IN_BLOCK no leitor nativo Parquet V3 (decorrente de uma regressão anterior) quando um PREWHERE tinha conjunções que compartilhavam uma expressão intermediária comum. #107059 (groeneai).
  • Corrige um travamento ao gravar Parquet com output_format_parquet_parallel_encoding habilitado (o padrão) e max_threads maior que 1. Se o codificador não conseguisse agendar uma thread adicional, seu contador de threads ativas sofria underflow e a gravação podia ficar parada indefinidamente, em vez de ser concluída ou reportar um erro. #112959 (groeneai).
  • Corrigida a alocação ilimitada de memória ao ler um arquivo Parquet cujos metadados Thrift declaram um comprimento de contêiner ou de string maior que os próprios metadados. Esse comprimento agora é rejeitado, em vez de gerar uma alocação. #113212 (groeneai).
  • Corrige uma exceção std::out_of_range (Logical error: 'std::exception. Code: 1001, type: std::out_of_range', que também aborta o servidor em builds de depuração e com sanitizador) no leitor Parquet v3 quando uma coluna necessária apenas para a avaliação de filtros era agendada para decodificação depois que seu slot de saída já havia sido descartado. #113956 (groeneai).
  • Corrige data races em profile events e no rastreador de memória. #112466 (mstetsyuk).
  • Corrige uma possível data race teórica em profile events ao usar a configuração trace_profile_events_list para gravar stack traces de determinados profile events em system.trace_log. #113553 (mstetsyuk).
  • Corrigido o problema em que intDivOrNull, moduloOrNull e positiveModuloOrNull retornavam 0 em vez de NULL, e intDivOrNull e intDivOrZero lançavam uma exceção em vez de retornar NULL / 0, quando a divisão resulta em uma exceção de ponto flutuante (divisão por zero ou INT_MIN / -1), inclusive para argumentos mistos com e sem sinal. #101976 (yariks5s).
  • Corrigido IS DISTINCT FROM para valores Array e Map comparados com NULL. #103162 (ylw510).
  • Corrigido groupConcat quando as formas paramétrica e de dois argumentos são combinadas, por exemplo, groupConcat(',', 2)(x, '/'): o parâmetro de limite de linhas era descartado silenciosamente, de modo que todas as linhas eram retornadas em vez da quantidade solicitada; agora o delimitador do segundo argumento substitui corretamente o parâmetro. #104882 (yariks5s).
  • Corrige bugs ao usar CAST de unidades de intervalo menores para maiores. #105058 (yariks5s).
  • Corrigido um erro lógico (Assertion 'row < chunk.getNumRows()' failed) em consultas LIMIT ... WITH TIES executadas com o pipeline de leitura em ordem (optimize_read_in_order = 1 e read_in_order_use_virtual_row_per_block = 1). #105102 (groeneai).
  • Corrige Logical error: 'Pipeline stuck' em consultas que usam enable_sharding_aggregator = 1 em conjunto com um UNION ALL e max_streams_for_union_step menor que a largura do pipeline. BufferedShardByHashTransform agora finaliza as portas de saída de filas vazias assim que sua entrada se esgota e continua lendo a entrada quando uma porta vazia solicitada não tem nada a drenar, mesmo que uma fila irmã tenha atingido o limite de contrapressão. #106251 (groeneai).
  • Corrigido o problema em que removeDirectory em discos de armazenamento de objetos plain (como s3_plain) removia todos os arquivos de um diretório não vazio como se a remoção fosse recursiva. Agora, remover um diretório não vazio falha com CANNOT_RMDIR, e a remoção recursiva trata o conteúdo explicitamente. #106281 (RinChanNOWWW).
  • Corrigido o problema em que funções definidas pelo usuário executable_pool configuradas com <lifetime> não detectavam alterações no script subjacente. Antes, apenas SYSTEM RELOAD FUNCTIONS relia um script editado; os recarregamentos periódicos de <lifetime> continuavam executando a versão antiga. #107087 (groeneai).
  • Corrigida uma condição de corrida (data race) no coletor de rastreamento global do servidor entre uma worker thread que iniciava seu profiler e o desligamento do servidor. #107307 (groeneai).
  • Corrigido um raro encerramento abrupto do servidor durante o desligamento (std::future_error, “The associated promise has been destructed prior to the associated state becoming ready”), causado pelo descarte de uma tarefa agendada por meio de threadPoolCallbackRunnerUnsafe da fila do pool de threads antes de sua execução. #107383 (groeneai).
  • Corrigido um erro lógico de FileLog (Last stored last_written_position in meta file ... is bigger than current last_written_pos) que podia ocorrer quando um arquivo monitorado era excluído e recriado reutilizando o mesmo inode. #107617 (groeneai).
  • Corrigido o problema em que toTime64 e CAST(... AS Time64) não restringiam valores fora da faixa ao intervalo válido de Time64 nos modos de overflow saturate e ignore, o que podia gerar valores exibidos de forma idêntica, mas considerados diferentes na comparação. #108028 (alexey-milovidov).
  • Corrigido o tratamento incorreto de asserções de largura zero (\b, ^, $) nas funções de regexp “match all” extractAll, extractAllGroupsVertical, extractAllGroupsHorizontal, countMatches e splitByRegexp. Por exemplo, extractAll('new york is the greatest', '\b(\w)') agora retorna corretamente a primeira letra de cada palavra, e não todas as letras. #108047 (alexey-milovidov).
  • Corrige resultados incorretos ao usar hasToken em índices de texto com tokenizador diferente de splitByNonAlpha. #108066 (rschu1ze).
  • Corrige o problema em que toStartOfInterval e dateTrunc retornavam um valor arredondado em vez do início do intervalo que o contém quando a entrada tinha precisão maior que a unidade do intervalo; por exemplo, toStartOfInterval(toDateTime64('2023-10-09 10:11:12.000999', 6), INTERVAL 1 millisecond) retornava 10:11:12.001 em vez de 10:11:12.000. A sobrecarga com origem explícita também era afetada. #108186 (yariks5s).
  • Corrigidas as funções replaceRegexpOne e replaceRegexpAll para que . corresponda a caracteres de nova linha por padrão, de forma consistente com as demais funções de expressão regular. #108265 (linjiayu1025-collab).
  • Corrige a avaliação duplicada das condições de UPDATE/DELETE leves. #108323 (ofeliacode).
  • Corrige arrayPartialSort() com um argumento de limite não constante. #108327 (vitlibar).
  • Corrigidas as funções de expressão regular (match, extract, extractAll, replaceRegexpOne, replaceRegexpAll etc.), que retornavam silenciosamente resultados incorretos quando o pattern continha um byte NUL (\0). O NUL agora é tratado como um byte literal comum, de forma consistente com o RE2. #108427 (alexey-milovidov).
  • Corrige changeYear/changeMonth/changeDay/changeHour/changeMinute/changeSecond aplicadas a um argumento DateTime64(N), que criavam a coluna de resultado com a escala padrão fixa no código (3) em vez de N. Os valores eram calculados na escala N, mas o objeto da coluna declarava escala 3, o que o deixava estruturalmente inconsistente com seu tipo. #108551 (groeneai).
  • Corrige um LOGICAL_ERROR (“Trying to extract chunk from ChunkBuffer before all inputs are finished”) quando uma operação de conjunto (INTERSECT / UNION ALL / EXCEPT) combina ramificações que usam subconsultas correlacionadas e correlated_subqueries_default_join_kind = 'left'. #108554 (groeneai).
  • Corrigidos bugs de DateTime64 em changeYear, changeMonth, changeDay, changeHour, changeMinute e changeSecond: entradas com precisão de nanossegundos (escala 9) não lançam mais DECIMAL_OVERFLOW, e entradas com frações de segundo anteriores à época Unix agora retornam o segundo de calendário correto. #108681 (takumihara).
  • Evita saída excessiva no log do servidor e uma mensagem de erro grande demais ao compilar uma expressão regular muito extensa (por exemplo, um pattern de LIKE ou match com centenas de milhares de wildcards); esses patterns agora falham com um erro CANNOT_COMPILE_REGEXP claro. #108821 (Algunenano).
  • Corrige reinterpret(x, 'Decimal128(scale)') (e destinos Decimal32/Decimal64/Decimal256/DateTime64), que produzia uma coluna de resultado com a escala interna de origem em vez da escala de destino solicitada quando a origem e o destino tinham o mesmo tipo físico. Os valores estavam corretos, mas o objeto da coluna ficava estruturalmente inconsistente com seu tipo declarado. #108878 (groeneai).
  • Corrigido comportamento indefinido ao converter em string um tipo de pacote de protocolo fora do intervalo válido (por exemplo, nas mensagens de erro “Unexpected packet from server” / “Received … packet”) em uma conexão dessincronizada ou submetida a fuzzing. #108885 (groeneai).
  • Corrige changeYear/changeMonth/changeDay/changeHour/changeMinute/changeSecond sobre DateTime64(N), que construíam a coluna de resultado com a escala padrão fixa 3 em vez de N, e timeSlots sobre DateTime64, que ignorava a escala do argumento opcional Size em seu tipo de retorno declarado. Em ambos os casos, era produzida uma coluna cuja escala física divergia do tipo declarado, o que causava um LOGICAL_ERROR (writeSlice expects same column types) quando o resultado era passado para arrayPushBack/arrayPushFront/arrayConcat; além disso, timeSlots com a maior escala em Size retornava timestamps incorretos. #108994 (groeneai).
  • Corrige incrementos não monotônicos de ProfileEvents #109180 (azat).
  • Corrige proporções de SAMPLE com um expoente cuja magnitude causa overflow em Int32 (por exemplo, SAMPLE 1e-3000000000), que eram tratadas silenciosamente como SAMPLE 1. #109197 (Algunenano).
  • Corrigidos dois bugs no caminho DateTime64 de toUTCTimestamp/fromUTCTimestamp (e de seus aliases to_utc_timestamp/from_utc_timestamp) e de toTime64. O primeiro era um overflow de inteiro com sinal próximo à fronteira de Int64 (agora o cálculo é feito em Int128 e limitado ao intervalo representável). O segundo era um resultado incorreto para valores fracionários negativos próximos a uma fronteira de deslocamento de fuso horário: a separação dos segundos truncava em direção a zero, de modo que timezoneOffset() inspecionava o segundo seguinte e podia escolher o lado errado de uma mudança de horário de verão/deslocamento. #109738 (groeneai).
  • Corrigido um erro lógico (column->size() == num_rows) quando uma expressão de filtro de row policy usa arrayJoin; esses filtros agora são rejeitados. #109753 (Algunenano).
  • Corrigido generateRandomStructure(), que ocasionalmente produzia uma string de estrutura inválida com dois tipos de dados concatenados (por exemplo, Decimal32(7)IPv4) quando o aninhamento de tipos excedia o limite interno de profundidade, o que impedia a análise do resultado. #109928 (groeneai).
  • Corrigida a propagação de configurações de consulta em accurateCastOrDefault e a preservação de NULLs de origem codificados por Dynamic e Variant. #109946 (Avogar). #114912 (alexey-milovidov).
  • Corrige max_bytes_in_distinct e max_bytes_in_set: chaves do tipo string são armazenadas em uma arena que não era contabilizada pelas verificações de limite, de modo que DISTINCT / IN sobre chaves string podiam reter memória acima do limite de bytes em até todo o conteúdo das chaves (sem limite em relação ao comprimento da chave). Os limites agora levam a arena em conta, conforme a documentação; consultas com chaves string próximas de um limite de bytes podem passar a atingi-lo mais cedo (corretamente). #110120 (skuznetsov-clickhouse).
  • Corrigida a leitura de arquivos Npy com dimensões internas de tamanho zero, para que as linhas materializadas e os resultados de count() otimizados e não otimizados coincidam. #110146 (qiuyanjun888).
  • Corrige um erro lógico (abort do servidor em compilações de depuração/sanitizer) quando as funções indexHint/ignore/isZeroOrNull recebem um argumento cujo tipo é resolvido como Nothing, por exemplo, dentro de expressões como indexHint(assumeNotNull(materialize(NULL))). #110192 (groeneai).
  • Corrige a leitura de arquivos em discos plain_rewritable depois que um caminho existente era reescrito com conteúdo de tamanho diferente: os metadados em memória mantinham o tamanho de arquivo desatualizado, o que podia fazer as leituras falharem com UNEXPECTED_END_OF_FILE. #110304 (thevar1able).
  • Rejeita valores de vector_search_index_fetch_multiplier abaixo de 1.0 para evitar resultados vazios na busca ANN quando a contagem de busca calculada é truncada para zero. #110452 (tamish560).
  • Corrige um erro esporádico Cannot parse string ... as UInt64 ... While executing ValuesBlockInputFormat que podia ocorrer ao inserir valores cujas expressões contêm uma conversão numérica, como initializeAggregation('sumState', 0::UInt64). #110637 (groeneai).
  • Corrigido o readWKT, que rejeitava strings WKT com espaços em branco no início (por exemplo, readWKT(' POINT(1 2)')), embora elas sejam aceitas pelos leitores tipados readWKTPoint/readWKTPolygon/… e pela gramática WKT. #110706 (groeneai).
  • Corrige uma falha do servidor (divisão inteira por zero) quando uma cota com intervalo de duração zero (por exemplo, CREATE QUOTA q FOR INTERVAL 0 SECOND MAX queries = 1000) era consumida. Agora, uma duração de intervalo de cota não positiva é rejeitada na criação da cota. #110846 (PedroTadim).
  • Corrigida uma falha em compilações FIPS ao usar uma chave SSH Ed25519 (CREATE USER ... IDENTIFIED WITH ssh_key ... TYPE 'ssh-ed25519', ou uma chave desse tipo em users.xml). O Ed25519 não é aprovado pelo FIPS; agora essas chaves são rejeitadas com um erro LIBSSH_ERROR claro. #110891 (thevar1able).
  • As funções de distância transpostas sobre QBit (cosineDistanceTransposed, L2DistanceTransposed, dotProductTransposed) agora usam uma reconstrução limitada de baixa precisão de um valor truncado para precision planos de bits, em vez de reconstruí-lo na borda inferior da célula grosseira (com os bits descartados preenchidos com zero). O preenchimento com zero enviesava todo valor reconstruído em direção a zero e era degenerado em baixa precisão: para QBit(BFloat16) com precisão 1, apenas o bit de sinal sobrevive, de modo que todo valor era reconstruído como ±0.0 e a distância era a mesma constante para todas as linhas, sem nenhuma informação útil para ranqueamento. A reconstrução agora depende de quais bits são descartados: códigos Int8 brutos são reconstruídos no centro de sua célula (correspondendo à reconstrução Lloyd-Max que o caminho ...TransposedQuantized já usava); um valor de ponto flutuante com precisão 1 passa a ser uma quantização de sinal adequada; um valor de ponto flutuante que mantém todo o expoente e descarta apenas bits da mantissa é reconstruído no ponto médio limitado dentro de sua própria binade (enquanto um zero genuíno ou ±0.0 permanece exatamente zero e a célula não finita é isolada para que ±inf continue exatamente infinito; veja a nota abaixo sobre a célula ambígua de NaN); e, enquanto bits do expoente ainda estão sendo truncados, a borda inferior limitada é mantida, de modo que uma precision menor troca exatidão por velocidade sem inflar uma magnitude em várias ordens de grandeza. Os resultados com precisão total permanecem inalterados. #110911 (alexey-milovidov).
  • Corrigida uma leitura fora dos limites no leitor ORC nativo durante a inferência de esquema de um arquivo ORC corrompido cuja árvore de tipos declara mais colunas do que o número de codificações de coluna no rodapé da stripe. Agora o arquivo é rejeitado com CANNOT_EXTRACT_TABLE_STRUCTURE, em vez de abortar o servidor em compilações de debug/sanitizador. #110967 (groeneai).
  • Cada chave SSH agora conta individualmente para o limite max_authentication_methods_per_user, de modo que o limite seja aplicado de forma consistente, independentemente da sintaxe. Antes, várias chaves em um único método ssh_key contavam como uma só. #111181 (TheMC47).
  • Catálogos REST do Iceberg agora reportam credenciais expiradas com o erro subjacente, em vez de reportar silenciosamente UNKNOWN_TABLE. #111379 (alesapin).
  • Corrige o retorno de coordenadas não inicializadas (escalar) ou da linha anterior (vetorizado) por readWKTPoint/readWKT para um ponto vazio com marcação de dimensão, como POINT M EMPTY. Essas entradas agora são rejeitadas com CANNOT_PARSE_TEXT, de forma consistente com POINT EMPTY. #111517 (groeneai).
  • A criação de estatísticas minmax agora emite um aviso em vez de lançar uma exceção. #111785 (hanfei1991).
  • Mantém randBinomial utilizável com as probabilidades degeneradas 0 e 1 para qualquer número de tentativas. #112021 (alexey-milovidov).
  • Corrigido o problema em que system.s3_queue_settings reportava valores incorretos para bucketing_mode, partitioning_mode, partition_regex e partition_component. #112300 (bharatnc).
  • Reporta a posição correta de erros em consultas PromQL. #112494 (fallintoplace).
  • SYSTEM DISABLE FAILPOINT agora rejeita um nome de fail point inexistente, gerando BAD_ARGUMENTS, como SYSTEM ENABLE FAILPOINT já fazia. Antes, um nome digitado incorretamente reportava sucesso, mas mantinha habilitado o fail point pretendido, sem nenhuma indicação de que nada havia sido desativado. #112680 (groeneai).
  • Corrige uma leitura com tipo incorreto de uma subcoluna de elemento Nested cuja coluna foi removida e adicionada novamente. Selecionar essa subcoluna junto com sua própria coluna pai retornava o elemento inteiro na posição da subcoluna, enquanto o bloco ainda declarava o tipo do elemento, o que gerava valores arbitrários em compilações de release e um erro lógico em compilações de depuração e com sanitizador. #112769 (groeneai).
  • Rejeita durações PromQL cujas unidades estejam repetidas ou fora da ordem da maior para a menor. #112954 (fallintoplace).
  • Corrigido comportamento indefinido (ponteiro nulo passado para memcpy) em replaceRegexpOne/replaceRegexpAll quando a string de substituição referencia um grupo de captura que não participou da correspondência, por exemplo, replaceRegexpAll('abc', '(a)|(b)', '\\2'). #113012 (alexey-milovidov).
  • Corrige uma incompatibilidade em que índices de texto criados no ClickHouse 26.3 com o tokenizador unicode_word não podiam ser carregados em versões posteriores #113061 (rschu1ze).
  • Rejeita code points substitutos (surrogates) Unicode inválidos em sequências de escape de strings PromQL. #113203 (fallintoplace).
  • Rejeita sequências de escape inválidas entre delimitadores em strings PromQL. #113587 (fallintoplace).
  • Corrige o retorno de um valor arbitrário por theilsU em um quadro de janela, em vez de 0, quando o primeiro argumento é constante dentro do quadro. #113691 (alexey-milovidov).
  • Corrigido o código de erro informado para algumas colunas malformadas serializadas por Replicated e recebidas pelo protocolo nativo: agora elas são rejeitadas com INCORRECT_DATA em vez de LOGICAL_ERROR (que encerrava o servidor em compilações de depuração e com sanitizadores). #114186 (Avogar).
  • Corrige literais Time64 e constantes de listas IN incorretos, frequentemente com o sinal invertido, produzidos quando a mudança de escala de um Decimal64 de escala menor excedia os limites de Int64. Essa conversão agora informa DECIMAL_OVERFLOW, assim como o ramo DateTime64 e o CAST explícito. #114546 (groeneai).
  • Adiciona suporte a nomes de métricas e rótulos entre aspas em seletores PromQL. #114551 (fallintoplace).
  • Corrigido o problema que fazia tabelas ReplicatedMergeTree permanecerem em modo read-only indefinidamente após uma tentativa de inicialização malsucedida executada pela thread de anexação. A nova tentativa de reinicialização agora é agendada corretamente, restabelecendo a recuperação automática e suas verificações de sessão. #114802 (azat).
  • timeSeriesRange e timeSeriesFromGrid geravam um erro DECIMAL_OVERFLOW indevido para marcas de tempo anteriores a 1970 porque as marcas de tempo de início e fim eram lidas como valores sem sinal. Além disso, para marcas de tempo DateTime/UInt32, o passo era silenciosamente truncado para seus 32 bits menos significativos. Agora todos os cálculos são feitos em Int64. #114815 (vitlibar).
  • Corrigida uma possível exceção em inserções assíncronas após uma consulta falhar com MEMORY_LIMIT_EXCEEDED. Também foi corrigido async_insert_queue_flush_on_shutdown para que seja feito o flush dos insert enfileirados durante o desligamento do servidor. #114839 (azat).
  • Corrigida uma exceção out_of_range gerada como um erro interno Code: 1001 quando um pattern de sequenceMatch, sequenceCount ou sequenceMatchEvents contém o número de evento 0, por exemplo, sequenceMatch('(?0)'). Esse pattern agora é rejeitado com BAD_ARGUMENTS. Uma condição temporal contendo apenas um sinal, como sequenceMatch('(?1)(?t>+)(?2)'), era silenciosamente tratada como (?t>0) e agora é rejeitada com SYNTAX_ERROR. #115056 (groeneai).
  • Corrigida a mensagem de erro de geoToH3 que indicava a posição e o tipo incorretos do argumento quando uma coordenada não era Float64. Com a configuração padrão geotoh3_argument_order = 'lat_lon', a mensagem apontava para o outro argumento e exibia o tipo dele. #115503 (groeneai).
  • Corrige caracteres de escape inválidos com barra invertida nos índices text, tokenbf_v1 e ngrambf_v1. #115634 (ahmadov).
  • Corrige um problema que impedia o servidor de iniciar quando a variável de ambiente TZ estava vazia. #68921 (ardenwick).
Última modificação em 14 de outubro de 2026