Alterações incompatíveis com versões anteriores
Alterações em consultas, funções e sintaxe
- Para views cujo corpo é um
SELECTsimples sobre uma única tabelaDistributed, toda a consulta externa agora é enviada aos shards (nova configuraçãooptimize_trivial_view_pushdown_to_distributed, habilitada por padrão). Isso altera o comportamento observável dessas views:FINALeSAMPLEespecificados na referência à view agora são propagados para a tabela local do shard em vez de serem ignorados, eextremesnão é retornado em clusters com um único shard. Definaoptimize_trivial_view_pushdown_to_distributed = 0para restaurar o comportamento anterior. #101791 (simonmichal). - As partes de patch de
UPDATEleve 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, mantenhapatch_parts_version = 'v1'ou use a configuraçãocompatibilityaté que todas as réplicas tenham sido atualizadas. #103182 (CurtizJ). AggregatingMergeTreeagora 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 aplicamGROUP BYou filtros sobre elas. Definaallow_dimensions_outside_sorting_key = 1para 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_hashesoucompatible_double_hashes). Para fazer o upgrade a partir de uma versão que usava um valor legado, primeiro execute uma versão que suportecompatible_double_hashes(que grava tanto os hashes legados quanto os unificados). Para tabelas replicadas, mantenha-a em execução por pelo menosreplicated_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 comnon_replicated_deduplication_window> 0, essa janela é baseada em contagem, e não em tempo; portanto, executecompatible_double_hashespor pelo menos essa quantidade de inserts. Em seguida, remova a configuração (ou defina-a comonew_unified_hash) antes de fazer o upgrade para esta versão. #108361 (CheSema). - A configuração
use_legacy_to_timeagora é0por padrão, de modo quetoTimeconverte valores para o tipo de dadosTimeem vez de converter uma data com hora em uma data fixa. O comportamento legado continua disponível por meio da funçãotoTimeWithFixedDateou definindouse_legacy_to_time = 1. #108729 (alexey-milovidov). - Os models Naive Bayes (usados por
naiveBayesClassifier) agora são configurados como um dicionário com o layoutNAIVE_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.binserializados), que não é mais suportada — os models existentes devem ser recriados como dicionários. Três novas funções foram adicionadas junto comnaiveBayesClassifier:naiveBayesClassifierWithProbretorna a classe prevista junto com sua probabilidade,naiveBayesClassifierWithAllProbsretorna todas as classes com suas respectivas probabilidades, enaiveBayesNgramstokeniza 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_threadsfoi alterado de1(sem paralelismo) paraauto, que corresponde ao número de núcleos de CPU disponíveis para o servidor (reduzido sob pressão de memória por meio demax_insert_threads_min_free_memory_per_thread). Com isso,INSERT SELECTpassa a ser paralelizado por padrão, e o lado de escrita de umINSERTsimples 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, definamax_insert_threadscomo1ou definacompatibilitypara uma versão anterior a26.8. #109000 (alexey-milovidov). #109006 (alexey-milovidov). - A leitura de um
Tuplesimples em CSV agora considera um campo por elemento em todas as posições, de modo que um\Nno campo de um elemento de nível superior corresponde a esse elemento, einput_format_null_as_defaultse aplica a ele. Antes, um\Ninicial 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 umTuplesimples inteiro: agora faltam os elementos restantes e a linha é rejeitada. Já para umTuplede 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 doDEFAULTda coluna. Definainput_format_csv_deserialize_separate_columns_into_tuple = 0para voltar a ler esse campo como a coluna inteira. #109744 (groeneai). - Adicionada a cláusula
VALID FOR <interval>aCREATE USEReALTER USERcomo forma abreviada deVALID 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 formaVALID UNTIL. A colunavalid_untilda tabelasystem.usersagora tem o tipoArray(DateTime64(0))em vez deArray(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 SYNTAXagora retorna a consulta reformatada como um único registroString(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 ...)retorna1). Esse comportamento é controlado pela nova opçãosingle_record, cujo padrão é1; definasingle_record = 0para restaurar a saída anterior, com um registro por linha. Os outros tipos deEXPLAIN(PLAN/PIPELINE/AST) mantêm a saída em árvore, linha a linha. #110479 (alexey-milovidov).- A função
hasColumnInTablenão aceita mais os argumentos opcionaishostname,usernameepasswordpara verificar uma coluna em um servidor remoto arbitrário; resta apenas a formahasColumnInTable(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
PostgreSQLeMaterializedPostgreSQLagora respeitam a configuraçãoremote_url_allow_hostsdo servidor, assim como já faziam o motor de tabelaPostgreSQL, a função de tabelapostgresqle os dicionários criados via DDL. A política é aplicada emCREATE DATABASEe emATTACH DATABASEexecutados pelo usuário: seremote_url_allow_hostsestiver configurado no seu servidor, a criação ou anexação de um banco de dadosPostgreSQLouMaterializedPostgreSQLque aponte para um host fora da lista de permissões passa a ser rejeitada comUNACCEPTABLE_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
ArroweArrowStream. A implementação nativa do ClickHouse, padrão desde a versão 26.7, passa a ser a única. As configuraçõesinput_format_arrow_use_native_readereoutput_format_arrow_use_native_writerestão obsoletas: ainda são aceitas, mas não têm efeito; assim, uma consulta que as definia como0para 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 comCREATE NAMED COLLECTION, como argumento de consulta ou em uma consultaCREATE 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âmetrosssl_ca_pem,ssl_cert_pemessl_key_pem, que são mascarados nos logs e em consultasSHOW, assim como as senhas. #112070 (alexey-milovidov). disable_insertion_and_mutationagora impede o consumo em segundo plano de tabelasKafka,RabbitMQeNATS, mas continua permitindo gravações diretas no armazenamento externo. TabelasKafka2,NATSeRabbitMQbloqueadas por essa configuração não inicializam consumidores paraSELECTdireto. A configuraçãomessage_queue_disable_insertion, introduzida recentemente, agora exige a reinicialização do servidor. #113660 (cwurm).- Um
PARTITION BYouORDER BYde janela sobre uma colunaAggregateFunctionagora é rejeitado comILLEGAL_COLUMN, como já acontecia com umORDER BYde nível superior sobre esse tipo de coluna. Antes, essa consulta era aceita por pelo menos um dos analisadores, e oPARTITION BYde janela particionava de forma diferente dependendo demax_threads. A rejeição também abrange um estado aninhado emArray,Tuple,Map,VariantouSimpleAggregateFunction.SimpleAggregateFunctionsobre um tipo comum,QBit, bem comoGROUP BYeDISTINCTsobre 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égiosSYSTEM DROP CACHEem 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 executasseSYSTEM SYNC FILESYSTEM CACHE ON CLUSTERsem possuirSYSTEM SYNC FILESYSTEM CACHE. #114042 (groeneai). - O motor de tabela
NATSaceita credenciais em linha na nova configuraçãonats_credentials(a mesma carga útil de um arquivo.creds) e não aceita maisnats_credential_filevia 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 comonats.credential_filena própria configuração do servidor. Uma consulta pode substituir esse caminho configurado pornats_credentialsem 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/zipxpassa a ser rejeitado para backups armazenados em armazenamento de objetos — destinos diretosS3(...)/AzureBlobStorage(...)e destinosDisk(...)com S3 ou Azure como backend —, tanto paraBACKUPquanto paraRESTORE. 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, comotar.gz. #101770 (Onyx2406). - O intervalo suportado de
DateTime64foi 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 comoInt64(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/DateTimeemJSONEachRowe 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 formatoValues,CASTetoDateTime64. Antes, um número com parte fracionária (por exemplo,1703363853.035) era rejeitado comCANNOT_PARSE_INPUT_ASSERTION_FAILED, e um inteiro simples (por exemplo,1703363853) era lido como o valor bruto escalado de umDateTime64, produzindo um timestamp1970-.... Esta é uma alteração incompatível com versões anteriores para inteiros sem aspas fornecidos a colunasDateTime64; 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
ALPagora executa a aritmética de escalonamento deFloat32emFloat64, 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étricaOSUserTimeCPUcom um map do número do núcleo de CPU para o valor (o mesmo vale para as demais métricasOS*TimeCPU*,CPUFrequencyMHz_*,Temperature*,EDAC*,Block*_*,Network(Receive|Send)*_*,Disk*_*,*BlobsQueueEstimateeAsyncLogging*QueueSize).system.asynchronous_metricstem uma nova colunakey_values Map(LowCardinality(String), Float64)(a colunavalueéNaNpara essas métricas),system.asynchronous_metric_logas registra como uma linha por chave usando uma nova colunakey, o endpoint Prometheus as exporta com um rótulo (por exemplo,ClickHouseAsyncMetrics_BlockReadBytes{device="sda"}) e oMetricsTransmitterdo Graphite as envia como<prefix>.<Metric>.<key>. Se o seu monitoramento lê os nomes antigos das métricas, definaasynchronous_metrics_key_values_modecomolegacy_namespara mantê-los, ou comobothdurante a migração; aplique essa configuração de servidor comSYSTEM 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,dateTimeToSnowflakeedateTime64ToSnowflake, obsoletas há muito tempo. Elas foram declaradas obsoletas já na v24.6 em favor desnowflakeIDToDateTime,snowflakeIDToDateTime64,dateTimeToSnowflakeIDedateTime64ToSnowflakeID, que devem ser usadas em seu lugar. A configuraçãoallow_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
Date32foi ampliado de[1900-01-01, 2299-12-31]para[0000-01-01, 9999-12-31], igualando-se ao deDateTime64. 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éricatoDate32(N), valores em[120530, 2932896]passam a ser interpretados como números de dias (datas de2300-01-01a9999-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 de0000-01-01e timestamps posteriores a9999-12-31são saturados nos novos limites. #111534 (alexey-milovidov).
Outras alterações incompatíveis com versões anteriores
arrayIntersectearraySymmetricDifferencenã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]earraySymmetricDifference([1], [2], [1, 1])retorna[2, 1]em vez de[2]. No caso dearraySymmetricDifference, 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,arrayIntersectpassa 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.arrayUnionnão é afetado. #113021 (alexey-milovidov).- O tipo de estatísticas de coluna
minmaxfoi marcado como obsoleto. #108680 (hanfei1991). - Corrigida a verificação de acesso para
SYSTEM PREWARM PRIMARY INDEX CACHE ... ON CLUSTER, que exigia incorretamente o privilégioSYSTEM PREWARM MARK CACHEem vez deSYSTEM PREWARM PRIMARY INDEX CACHE. #109198 (Algunenano). - Corrigido o problema em que
SYSTEM STOP/START CLEANUPeSYSTEM STOP/START VIRTUAL PARTS UPDATE ON CLUSTERexigiamSYSTEM PULLING REPLICATION LOGem vez deSYSTEM 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 quedata/**/file.txtnão correspondia adata/file.txt(zero níveis de diretório). #97676 (alexey-milovidov).
Novos recursos
Funções e tipos de dados
- Adicionadas as funções
parseQueryToJSONeformatQueryFromJSONpara serializar e desserializar ASTs como JSON, além de um dialect experimentalclickhouse_json, habilitado porenable_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çãostem. #100611 (Ergus). - Adicionado suporte aos operadores pós-fixos
AT TIME ZONEeAT LOCALdo SQL padrão como açúcar sintático paratoTimeZone. A expressãoexpr AT TIME ZONE zoneagora equivale atoTimeZone(expr, zone), eexpr AT LOCALequivale atoTimeZone(expr, timeZone()). #106092 (lvzhipin03). - O motor de tabela
URLe a função de tabelaurlagora fazem o encaminhamento para o backend apropriado com base no esquema da URL:file://é atendido pelo motorFile,s3:///gs:///gcs:///oss://peloS3,az:///azure:///abfss:///abfs://peloAzureBlobStorage,hdfs://peloHDFSehttp(s)://pelo motorURL, como antes. A configuraçãourl_baseé aplicada antes do encaminhamento por esquema. Apenas os esquemas S3 resolvidos pelosurl_scheme_mapperspadrã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çãos3. #106093 (alexey-milovidov). - Adicionada a função
dotProductTransposed(aliasscalarProductTransposed), que calcula o produto interno aproximado entre uma colunaQBite um vetor de referência, complementando as funções já existentesL2DistanceTransposedecosineDistanceTransposed. #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
Int8no tipo de dadoQBit, 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
mergedJSONPatchpara 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 valoresxxHash64compatíveis com o Spark para entradasStringeNULLusando a semente42e retornaInt64. #108436 (lalitium). - Adicionada a função
digits(n, offset[, length]), que retorna o número contido emnque começa no índiceoffset(1-indexed)e temlengthdígitos. Selengthnão for informado, a função retorna o número do deslocamento até o final. #109012 (1000ms). - Adicionada a função aritmética
sqrpara calcular o quadrado de um número. #109061 (lalitium). - Adicionadas as funções de distância transpostas quantizadas
cosineDistanceTransposedQuantized,L2DistanceTransposedQuantizededotProductTransposedQuantized, que operam sobre umQBit(Int8)de códigos Lloyd-Max dequantizeBFloat16ToInt8, 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ãoFloat32(uma consultaFloat64tem a precisão reduzida); já uma referênciaArray(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 dedictGetHierarchy(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 tabelaMergeTree, quantos blocos comprimidos usam cada codec. #109623 (rienath). - Adicionada a função
notHas, a negação dehaspara arrays, maps e JSON. Quando o conjunto pesquisado é um array constante,notHas(constant_array, x)é reescrito comox NOT IN constant_arrayporoptimize_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 comoNOT IN. #109926 (nihalzp). - Adicionado o tipo de dado geoespacial
MultiPoint, armazenado comoArray(Point)e incluído no tipoGeometry. #109951 (davidmenggx). - As funções
arrayElement(o operadorvec[n]) earraySliceagora funcionam com o tipo de dadoQBit:qbit[n]retorna o n-ésimo elemento do vetor em precisão total, earraySlice(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
splitByRegexppara índices de texto e para a funçãotokens. Ele divide a entrada em tokens usando uma expressão regular como separador, por exemplotokenizer = splitByRegexp('[^\p{L}\p{N}#+]+'), o que permite preservar tokens com caracteres especiais, comoC++ouC#, que outros tokenizadores quebrariam. #110002 (Ergus). - Adicionadas as funções
geometryIntersectCartesianegeometryIntersectSpherical, que indicam se duas geometrias se intersectam. Ao contrário depolygonsIntersectCartesian/polygonsIntersectSpherical, elas aceitam qualquer tipo de dado geométrico (Point,LineString,MultiLineString,Ring,Polygon,MultiPolygon), incluindo o tipo genéricoGeometry, e os dois argumentos podem ser de tipos diferentes. #110062 (alexey-milovidov). - O leitor ORC nativo agora oferece suporte ao
uniontypedo ORC, mapeando-o para o tipoVariantdo ClickHouse (antes, essas colunas eram rejeitadas comUnsupported ORC type). #110078 (alexey-milovidov). - O formato de saída ORC nativo agora pode gravar o tipo
Variantdo ClickHouse, mapeando-o para umuniontypedo ORC (antes, a operação falhava comILLEGAL_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),JSONEachPacketBase64eJSONEachPacketString(um objeto JSON por pacote, com dados codificados em base64 ou como string). #110127 (alexey-milovidov). - Adicionados a função de tabela
bigquerye o motor de tabelaBigQuerypara 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 retornaUInt8para uso emWHERE,PREWHEREeJOIN ... ON. #110594 (ylw510). - Suporte a conexões TLS/SSL com o PostgreSQL no motor de tabela
PostgreSQL, na função de tabelapostgresql, nos motores de banco de dadosPostgreSQLeMaterializedPostgreSQLe nos dicionáriosPostgreSQL: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
postgresqle o motor de tabelaPostgreSQLagora podem ser usados para se conectar a outro servidor ClickHouse pelo protocolo PostgreSQL (quando se usa um nome de tabela; a variantequery(...)ainda não é compatível). Adicionadas as funções de compatibilidade com o PostgreSQLformat_typeecurrent_setting. #110760 (alexey-milovidov). - Nova função
aiSimilarityque calcula a similaridade semântica entre dois textos usando um modelo de embedding. Retorna umNullable(Float32)no intervalo[-1, 1], em que1significa que os textos são idênticos, ouNULLse um operando forNULL/vazio ou se a geração do seu embedding falhar. #110777 (davidmenggx). - Adicionados os motores de banco de dados
RemoteeRemoteSecure, que fornecem acesso em tempo real às tabelas de um banco de dados em um servidor ClickHouse remoto, encaminhando para ele as consultasSELECTeINSERT. Eles são os equivalentes, de ClickHouse para ClickHouse, dos motores de banco de dadosMySQLePostgreSQL. #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 consultaSELECTpode 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áusulaFROM, a cláusulaSELECTagora é opcional e assumeSELECT *por padrão. #111151 (alexey-milovidov). - Adicionada a função de agregação
ginipara 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 colunattransforma o resultado de uma consulta em uma animação, com a escala de tempo detdefinida poroutput_format_image_time_multiplier_secondseoutput_format_image_time_divisor_seconds; jáoutput_format_image_streaming_animationpermite 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_timeasystem.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
bucketedparasystem.metric_log, que armazena todas as métricas em uma única colunaMap(Enum16(...), Int64)usando a serialização deMapem buckets, com 128 buckets, além de uma colunaALIASpor 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, umMapcom chavesEnumagora pode ser indexado pelo nome em string do valor do enum, por exemplo,map['name']. #115380 (alexey-milovidov). - Adicionado o tokenizador
chinesepara a funçãotokense para os índices de texto doMergeTree. 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 granularidadescoarse_grained(padrão) efine_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 colunaTuplede forma independente e retorna umaTuplecom os resultados, preservando os nomes dos elementos:sumTuple(t)parat = (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-ForEachaplicado 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
RemoteeRemoteSecure, equivalentes persistentes das funções de tabelaremoteeremoteSecure. Agora, além deCREATE TABLE ... AS remote(...), também é possível usarCREATE TABLE ... ENGINE = Remote('addresses', db, table, ...). #106189 (alexey-milovidov). - Adicionado
EXPLAIN ANALYZEpara 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 CANCELeSYSTEM REFRESH, independentes de motor, e suas variantes... ALL BACKGROUND, que valem para todo o servidor, para controlar a atividade em segundo plano de tabelasKafka,RabbitMQ,NATS,S3Queue/AzureQueuee de views materializadas atualizáveis por meio de uma interface unificada. Para views materializadas atualizáveis, eles funcionam como aliases dos comandosSYSTEM ... VIEWexistentes. 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çãonats_wait_for_flush_interval(padrãofalse, 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çãonats_commit_on_selectfaz com que umSELECTdireto 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,postgresqlesqliteaceitem 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 comoquery('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 tabelaQueryRunnerrepresentam 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
GROUPSpara 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 frameGROUPS, os limites contam grupos de pares inteiros — conjuntos de linhas com valores iguais na chaveORDER BY—, de modo queN PRECEDING/N FOLLOWINGsignificamNgrupos de pares antes/depois do grupo de pares da linha atual, em vez de linhas físicas (ROWS) ou distâncias entre valores doORDER BY(RANGE). #108653 (nihalzp). - O
CREATE MATERIALIZED VIEW ... POPULATEsimples 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çãomaterialized_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íliaMergeTreeeMemory); outras origens, assim comoCREATE OR REPLACE/REPLACEe visões criadas em bancos de dadosReplicated, mantêm o preenchimento legado não atômico.POPULATEagora também pode ser usado em conjunto comTOpara preencher retroativamente a tabela de destino. #108715 (alexey-milovidov). ALTER USER,ALTER ROLEeALTER SETTINGS PROFILEagora aceitamSET name = valuecomo alias paraMODIFY SETTING name = value. Essa forma altera configurações individuais diretamente, mantendo as demais, ao contrário da cláusulaSETTINGSsem 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 exprpara 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
ONtenha duas comparações de desigualdade (<,<=,>,>=) entre as tabelas da junção, habilitado ao adicionarie_joinà configuraçãojoin_algorithm. Os tipos suportados sãoALL INNER/LEFT/RIGHT/FULL JOINeSEMI/ANTILEFT/RIGHT JOIN. Anteriormente, essas consultas eram executadas como umCROSS JOINcom filtro (apenasINNER), 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 seuquery_idemsystem.processesesystem.query_log. Destina-se a consultas longas, comoINSERT ... SELECT,CREATE TABLE … AS SELECTouCREATE 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
Icebergagora oferece suporte ao Snowflake Horizon Catalog comcatalog_type = 'horizon', permitindo leituras e gravações em tabelasIceberggerenciadas pelo Snowflake. #114547 (melvynator). - Adicionada a configuração
skip_unavailable_shards_mode(também disponível como configuração do motorDistributed) para controlar quais exceções de um shard remoto são ignoradas silenciosamente quandoskip_unavailable_shardsestá 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,s3etc. #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çõesmin_bytes_for_full_part_storage,min_rows_for_full_part_storageemin_level_for_full_part_storagee 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_credentialsao 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 textoLazySimpleSerDedo Apache Hive. Os campos são separados por\x01, as linhas pela nova configuraçãoformat_hive_text_rows_delimiter(padrão\n), e os valores aninhados deArray,MapeTupleusam a lista de separadores do Hive. A saída é voltada para oLazySimpleSerDepadrão do Hive e não é simétrica à entradaHiveTextdo ClickHouse no caso de valores aninhados ou delimitadores de linha personalizados. #107582 (alexey-milovidov). - Adicionado o formato de saída
GeoJSONpara gravar documentos GeoJSONFeatureCollectioncom uma feature por linha. A nova configuraçãoformat_geojson_validate_geometry(habilitada por padrão) valida as geometrias GeoJSON na leitura e na gravação; o formato de entradaGeoJSONagora infereidcomoNullable(String), diferenciando IDs ausentes ounullde strings vazias. #108065 (nihalzp).
Configurações, acesso e observabilidade
- Adicionada uma página integrada de busca na documentação, disponível no caminho
/docsda interface HTTP, que oferece busca instantânea na tabelasystem.documentatione 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 quandouse_split_cacheestá 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 TIESparaLIMITnegativo. #100930 (nihalzp). - Adicionadas as configurações de restauração
restore_table_data,restore_access_entitieserestore_functions, que oferecem controle granular sobre o que é restaurado. Elas podem sobrescreverstructure_onlypara categorias específicas — por exemplo,structure_only=true, restore_access_entities=truerestaura 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_loadna definição do dicionário, sobrescrevendo a configuração global de servidordictionaries_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 aarrayMap(i -> arr[i], indexes). #108371 (ucasfl). - Adicionadas as funções
geoToUTM,UTMToGeo,geoToMGRSeMGRSToGeopara conversão entre coordenadas geográficas WGS84 e os sistemas de coordenadas UTM e MGRS. #108939 (alexey-milovidov). - Adicionados os comandos
SYSTEM UNLOAD DICTIONARYeSYSTEM UNLOAD DICTIONARIESpara 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
icupara índices de texto e para as funçõestokens,hasAnyTokensehasAllTokens, 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 doLZ4e a doZSTD. #110620 (alexey-milovidov). - Adicionada a configuração
s3_base, que permite resolver URLs relativas nas funções de tabelas3,s3Cluster,gcseosse no motor de tabelaS3em relação a uma URL base do S3. Adicionado também o motor de banco de dadosURL, 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 motorURL, 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_IAMcomo valor suportado parakafka_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 emCREATE 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 comoATTACH 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 modoexecutable_pool. #105131 (alexey-milovidov). - As requisições da Prometheus Query API para
/api/v1/querye/api/v1/query_rangeagora são registradas emsystem.query_logcom as métricasread_rowseread_bytes. #106611 (JTCunning). - Suporte a leituras com plano de consulta distribuído para
SELECT ... FINALem tabelas da família MergeTree quandomake_distributed_planestá 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 consultaSELECTúnica resultante. O recurso vem desabilitado por padrão e pode ser habilitado com a configuraçãoallow_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 comUNIONpassam a ser paralelizadas semparallel_replicas_allow_view_over_mergetree. Consultas que usamIN (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çãoai_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_queryagora tem o valor padrão1000) 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, incluindoSEMI/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 apenasQUERY_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 comoJOIN. 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 porrewrite_in_to_joinfoi 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 umLIMITé 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 toIntervalNanosecondquando uma consulta PromQL usaoffsetdentro de um seletor de intervalo, por exemplo,rate(m[2m] offset 5m). #114997 (nikitamikhaylov). - Adiciona suporte à agregação
GROUPING SETSem planos distribuídos gerados pelo otimizador Cascades (make_distributed_plan = 1, enable_cascades_optimizer = 1). #115426 (davenger). - Tabelas
TimeSeriesagora podem manter uma tabela de “amostras recentes”: quando a nova configuração de motorrecent_samples_ttl_secondsé diferente de zero, o motor cria uma cópia com TTL da tabela samples (particionada porrecent_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 consultatime_series_prefer_recent_samples_table. #115441 (nikitamikhaylov). - Planos de consulta distribuídos (
make_distributed_plan) agora interrompem imediatamente as etapas upstream idle depois que umLIMITé atingido: um sink de exchange idle lêNoMoreDataNeededassim 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_basedestá habilitado. #115788 (devcrafter). - Adicionado o Cascades, um otimizador experimental baseado em custo para planos de consulta distribuídos, habilitado por
enable_cascades_optimizer = 1em conjunto commake_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
ReaderExecutorexperimental (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
ReaderExecutorexperimental (use_reader_executor, desabilitado por padrão). #110029 (CheSema). - Adicionada a configuração experimental de
MergeTreeallow_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
ReaderExecutorexperimental (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
Icebergagora está disponível por meio deOPTIMIZE TABLE ... MANIFEST, reduzindo o número de arquivos de metadados. O recurso é controlado pela configuraçãoallow_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 emserialization.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 colunasFloat32/Float64(e arrays desses tipos). Ele requerallow_experimental_codecs. #108788 (alexey-milovidov). - Corrigida a leitura de dados comprimidos com o codec experimental
SZ3('ALGO_LORENZO_REG', ...), que antes falhava comCORRUPTED_DATA, e evitado comportamento indefinido ao comprimir valores de ponto flutuante não finitos (NaNe infinitos) com o codec experimentalSZ3. #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, usandovector(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 comon(), 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 BYquandoparallel_replicas_plan_basedestá 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 erroUnknown function __topKFilteremORDER BYsobre 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
ATTACHou uma reinicialização do servidor): as partes não perdem mais suas subcolunas do codecQuantized, 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
TimeSeriesnão aplica mais o codecGorillaàs colunasvaluecriadas automaticamente na tabela interna de amostras; agora elas usamCODEC(ZSTD(1))por padrão. Colunas declaradas explicitamente mantêm os codecs definidos pelo usuário. O padrão da colunatimestamppermanece inalterado (CODEC(DoubleDelta, ZSTD(1))). #112110 (nikitamikhaylov). #114790 (nikitamikhaylov). - Adiciona suporte a
ROLLUP,CUBE,GROUPING SETSe à funçãogroupingem consultas executadas commake_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 deonelake_client_ideonelake_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_bytespara índices de salto empacotados emskp_idx.packed(viapacked_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 dedistributed_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_maxeround. #111870 (valerypetrov). - PromQL:
quantilecom um nível de quantil fora de [0, 1] agora retorna -Inf/+Inf/NaN, como no Prometheus, em vez de lançar um erro, ehistogram_quantileagora ignora séries de entrada cujo rótuloleesteja ausente ou seja não analisável, também como no Prometheus. #111871 (valerypetrov). - PromQL: implementadas as funções
changes()eresets(). #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_numnão faz mais o servidor abortar comstd::length_errorquando as configurações experimentaismake_distributed_planeenable_cascades_optimizerestão habilitadas. Agora, essa quantidade de nós é rejeitada comINVALID_SETTING_VALUE. #115398 (groeneai). - Implementa o endpoint
/api/v1/seriesda Prometheus HTTP API para tabelasTimeSeries: seletores de sériesmatch[](valores repetidos formam uma união), um intervalo de tempostart/endopcional e um parâmetrolimitopcional. #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 umLIMIT, 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_independentlypor padrão. Quando uma chave deGROUP 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_rowpor 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áximomax_threadspartes, 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çõesALLficam tão pequenas quanto as de junçõesANYpara todos os tipos de chave. Em benchmarks com grandes consultas de junçãoparallel_hash— junçõesINNEReANYde tabelas com 100 a 300 milhões de linhas em chavesUInt64eString, 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çõesINNERem chavesUInt64foram 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
hashusada na primeira execução da consulta porparallel_hashnas 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
DISTINCTem tabelasMergeTreeparticionadas, mantendo as linhas de cada partição em um único stream, de modo que oDISTINCTpreliminar de cada stream opere sobre um conjunto disjunto de chaves, em vez de o mesmo conjunto de chaves aparecer em váriosDISTINCTs preliminares. Isso se aplica quando a expressão de partição é uma função determinística das colunas doDISTINCTe 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çãoforce_distinct_partitions_independently, desabilitada por padrão). A mesma disjunção por partição é propagada pelas etapasExpression,FiltereARRAY JOINaté os consumidores finaisDISTINCT,LIMIT BYeGROUP BY, para que eles também possam dispensar a mesclagem. Controlado pelas novas configuraçõesallow_distinct_partitions_independently(habilitada por padrão) emax_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
ONtambé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 JOINnã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 sizeparaL2 cache size, de modo que o prefetch seja habilitado assim que a tabela hash deixar de caber no L2. Isso corrige uma regressão emGROUP BYeJOINsobre 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, incluindoquantile*,uniq*egroupArray, ficaram mais rápidas comOVER ()eOVER (ORDER BY ... RANGE ...). A funçãocume_disttambém ficou mais rápida, e janelas que usamPARTITION BYouORDER BYagora 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
HashSetem vez deHashMap(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 queparallel_hash). JunçõesASOFrecorrem a um únicofull_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 quandoquery_plan_join_shard_by_pk_rangesestá habilitado. O resultado não é ordenado. #109005 (alexey-milovidov). - As estatísticas de coluna agora são materializadas no
INSERTpor padrão quando o tamanho ativo atual da tabela somado ao tamanho do bloco gravado não ultrapassa o valor da nova configuraçãomaterialize_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
uniqCombinedem agregações sem chave. #109794 (CurtizJ). - Otimizadas as funções de agregação
uniqHLL12euniqCombined. #109831 (CurtizJ). - Paralelizado o processamento de linhas sem correspondência no algoritmo de junção
parallel_hashem 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 BYda janela. Um predicado desse tipo escrito após a janela (umWHEREexterno envolvendo uma subconsulta com janela, ou uma conjunção emQUALIFY) 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, umWHEREque 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 emINNER(ouLEFT/RIGHT) e aplica a poda pela chave primária, assim como acontece comjoin_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,uniqExacteuniqHLL12em agregações sem chave. #110150 (CurtizJ). - Um
JOINcuja condiçãoONé constantemente falsa (por exemplo,ON 1 = 2,ON NULLou uma condição que se reduz a falso, comoa.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çãoquery_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 consultasGROUP BYcujas 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
Stringagora usam uma representação de tabela hash menor, melhorando cargas de trabalho deGROUP BYcom uso intensivo de strings. A nova configuraçãoenable_packed_string_keys_in_aggregationvem habilitada por padrão; desabilitá-la, ou definircompatibilityabaixo de26.8, restaura o caminho legadoStringHashTable, 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_tablequando 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
RIGHTeFULLcom o algoritmoparallel_hashquando o lado direito contém chaves de junçãoNULLou linhas filtradas pela expressãoON, evitando a reconstrução dos mapas de nulos. #111258 (m-selmi). - Novo algoritmo adaptativo para
GROUP BYparalelo (controlado pela configuraçãoenable_adaptive_aggregator, habilitada por padrão): cada thread agrega em sua própria tabela hash até que ela atinjaadaptive_aggregator_freeze_thresholdchaves 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/
Objectarmazenados em dados compartilhados (usado, por exemplo, poruniq/uniqExactsobre uma coluna JSON e por chaves deGROUP BY/DISTINCTcom hash), evitando a reconstrução de umColumnDynamicpara 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
ORna 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 = 0para 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, umORDER BY ... LIMITsobre umLEFT JOINlido em ordem deixa de informar a tabela inteira como o número de linhas que pretende ler e, portanto, não aciona maismax_rows_to_readcomread_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 BYdurante mesclagens. O agregador era construído passandomin_chunk_bytes_for_parallel_parsing(um limiar em bytes, padrão de 10 MiB) na posição que esperamin_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 JOINnão é mais perdida quando um plano de consulta é serializado. Comserialize_query_plan = 1, o nó que executava um fragmento de plano remoto ignoravaenable_lazy_columns_replicatione sempre materializava todas as cópias replicadas, embora essa configuração seja habilitada por padrão. #112330 (groeneai). - Uma igualdade no
WHEREagora é mesclada à condição doJOINquando seus operandos têm tipos diferentes, mas um supertipo comum, comoInt32eNullable(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
Arraycujos elementos contêm valoresJSONem dados compartilhados, por exemplo, umArray(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 ONcom 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çãoquery_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
Mergesobre muitas tabelas com estruturas diferentes. Antes, essas consultas podiam passar minutos no planejamento sem responder amax_execution_timeouKILL QUERY. #113140 (alexey-milovidov). - Corrigida uma regressão de desempenho em que uma agregação sem chaves de
GROUP BYserializava, 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 comoSELECT 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,bottomkelimitkagora 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áriaO(time_steps * series^2). Consultas sobre métricas de alta cardinalidade que antes falhavam comMEMORY_LIMIT_EXCEEDEDagora 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*ToGridpor 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 deor) 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;topksobreratefica 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, definause_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 BYcurtas 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
MergeTreeparticionadas, 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 colunasPARTITION BYda janela e está sujeito à mesma heurística de custo usada emGROUP BY/DISTINCTpor partição (partições suficientes em relação amax_threads, sem partição dominante). Controlado pelas novas configuraçõesallow_window_partitions_independently(habilitada por padrão),force_window_partitions_independentlyemax_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*ToGridem sequências de amostras consecutivas que caem no mesmo bucket da grade, acelerando em 1,2-2x a etapa de ingestão de amostras detimeSeriesRateToGride funções relacionadas em dados de séries temporais ordenados. #115041 (nikitamikhaylov). - Uma agregação sem chaves de
GROUP BYnão distribui mais sua saída de linha única paramax_threadsstreams; 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*ToGridusam o caminho vetorizado de classificação de amostras para grades de ponto único, etimeSeriesIdToGrouppreenche sua coluna de resultado diretamente. #115267 (nikitamikhaylov). - Um
JOINcuja seçãoONtem várias igualdades combinadas comORnã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,SEMIouANTIquando o lado direito repete as mesmas chaves de junção muitas vezes: a junção não relê mais a configuraçãojoin_any_take_last_rowda memória a cada linha do lado direito. #115820 (nickitat). - Acelera
GROUP BYsem funções de agregação sobre chavesString,FixedStringeLowCardinality: 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 ... LIMITeGROUP BY ... LIMITcom 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çãoenable_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_threadspartes, 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.bboxpara ignorar páginas irrelevantes dentro dos grupos de linhas. Também generaliza o pushdown de predicados espaciais por meio deIFunctionBase::isSpatialPredicate()e adiciona umGeoFilterque 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,MinMaxe índices de salto doMergeTreeincorpora 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)comPARTITION BY a. #104582 (Michicosun). - Aplica o posicionamento exato de linhas em consultas de busca vetorial com
vector_search_with_rescoringantes 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 etapasSortingeFilter, substituindo o argumento largoString/FixedStringpelo 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çãoquery_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 chamadastatpor 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
pointInPolygoncom 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_logno 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 popcountO(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_queueMergeTreepara usar opcionalmente a fila de ordenação em lote nas mesclagens comuns doMergeTree, 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
WITHou repetem a mesma subexpressão muitas vezes (por exemplo, cadeias profundamente aninhadas deif/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
ANDde comparações ou com cadeias muito grandes: a otimizaçãooptimize_and_compare_chainagora é limitada por um orçamento de trabalho (nova configuraçãooptimize_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 deActionsDAGdo caminho geral. #109049 (ahmadov). - Removido um gargalo de thread única em
ShuffleSendStepdo 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 únicoScatterByPartitionTransform. #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
QBitcom 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 BYquando o predicado referencia apenas as colunas-chave deLIMIT BYe a cláusula mantém pelo menos uma linha por grupo não vazio (LIMIT n BYcomn >= 1eOFFSET 0). Isso permite que esses predicados (escritos como umWHEREexterno envolvendo uma subconsultaLIMIT 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 formasOFFSET,LIMIT 0 BYouLIMIT BYnegativo. #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 deDecimaleFloat32/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 INdo 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 arquivoskp_idx.packedpor 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). Definapacked_skip_index_max_bytes = 0para manter o layout independente por arquivo. 2)compute_exact_num_defaults_for_sparse_columnsjunto comoptimize_trivial_count_with_sparsity_filter: contadores exatos denum_defaultspor coluna são persistidos e usados para responder aSELECT 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 sinalizadorexact_num_defaultsemserialization.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). randomHadamardTransformde 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 comrandomHadamardTransformantes de compará-lo com uma colunaQBit. #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_mutationsvem 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 kagora 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
Tupleem arquivos Parquet e ORC. Um predicado comoWHERE tup.1 = 555555sobrefile(),s3()ouurl()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
TimeSeriescom um intervalo contínuo de chave primária emiddurante a análise de índice, em vez de uma grande condiçãoid 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/querye/api/v1/query_rangeda Prometheus HTTP API agora avaliam uma única vez uma subconsulta PromQL compartilhada por várias etapas do plano, como as funções de tabelaprometheusQueryeprometheusQueryRangejá faziam. Antes, uma requisição feita comenable_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
MergeTreeordenada portoUnixTimestamp(ou outra conversão para inteiro) de uma colunaDateTime64, 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 comotoInt64(ts) >= cem uma tabela ordenada pela colunaDateTime64bruta agora usa a chave primária. #114413 (alexey-milovidov). - Acelera a execução de
INsobre 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,h3PolygonToCellseh3PolygonToCellsWithContainmentconstroem 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) = valueagora é resolvido por constant folding diretamente em um filtro de chave (key_expr = const,key_expr IN [...]ouWHERE 0), em vez de ser reescrito como uma subconsultaIN (SELECT ... FROM dictionary(...)), e o caminho constante dedictGetKeysagora é 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áximomerge_tree_coarse_index_granularitypassos, 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 BYeLIMITemVIEWs sobre tabelas distribuídas agora usam a otimização de mesclagem de fluxos ordenados. OORDER BY/LIMITexterno é 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 tabelaMergeTreecomORDER BY (id, event_time)ePARTITION BY toYYYYMM(event_time), o ClickHouse usará o índice minmax de partição emevent_timedurante a análise de índice da chave primária para tomar decisões mais precisas de poda de granules. Controlado pela nova configuraçãouse_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 —
DISTINCTem ordem,LIMIT BYem ordem,LIMIT BYnegativo em ordem e os joinsfull_sorting_mergeepartial_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çãoinput_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/s3e para o codec GZIP do Parquet. #108074 (alexey-milovidov). - Aceleração das funções
trimLeft/trimRight/trimBothcom espaço em branco padrão (e seus aliasesltrim/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_streampara reduzir o excesso de streams de leitura e a sobrecarga do pipeline em varredurasMergeTreelocais 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
JSONcujos dados compartilhados contêm muitos caminhos esparsos. Ao achatar os dados compartilhados em colunas por caminho,flattenAndBucketSharedDataPathsnã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
Stringcomo um stream separado de offsets cumulativos de bytes (o mesmo layout queArrayusa 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 colunasStringcom 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 formatosNativeeBufferspor meio das novas configuraçõesoutput_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
FINALque leem na ordem da chave primária (ORDER BYsobre um prefixo da sorting key) com umLIMITpequeno não usam maissplit_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 asnlinhas que restam após oLIMIT. Em um arquivo Parquet de 200 MB no S3,SELECT k, s ... ORDER BY k DESC LIMIT 10lê 3,3 MB em vez de 171 MB (51x menos E/S, 8x mais rápido). Controlada pela nova configuraçãoquery_plan_optimize_lazy_materialization_for_object_storage(habilitada por padrão; também requerquery_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ão4) 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
MergeTreecujas sorting keys são todas constantes. #113899 (perfloop-agent). - A materialização lazy para consultas
ORDER BY ... LIMIT nagora também se aplica a arquivos Parquet locais lidos com a função de tabelafilee o mecanismo de tabelaFile: as colunas que não são necessárias para ordenação e filtragem são lidas apenas para asnlinhas que restam após oLIMIT. A segunda leitura de um arquivo remanescente falha de forma segura com o novo erroFILE_CHANGED_DURING_READse o arquivo tiver sido modificado entre as duas passagens. Controlada pela nova configuraçãoquery_plan_optimize_lazy_materialization_for_file(habilitada por padrão). Também corrige a falhaNot found column or subcolumn ... in blockna materialização lazy para armazenamento de objetos quando uma subcoluna solicitada (por exemplo, de uma colunaJSON) era adiada. #114262 (alexey-milovidov). - Acelera a construção do set para
IN (subquery)em tabelasMergeTreeparticionadas, 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çãoforce_creating_set_partitions_independently(desabilitada por padrão) ignora essa verificação. Controlada pela nova configuraçãoallow_creating_set_partitions_independently(habilitada por padrão). #114645 (nihalzp). - Marca como
table_readonlyas tabelas de log do sistemaMergeTreenão replicadas, rotacionadas e sem TTL, para evitar operações desnecessárias em segundo plano. A configuraçãotable_readonlyMergeTreeagora também suprime todo o trabalho em segundo plano em uma tabelaMergeTreesimples — 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 PARTITIONeMOVE PARTITION ... TO TABLEcom destino à tabela), além dos inserts, mutações eOPTIMIZEque ela já rejeitava. Com isso, uma tabelatable_readonlycom 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 SNAPSHOTao 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
Decimalcomo texto está muito mais rápida — até 190 vezes para umDecimal256com escala grande e cerca de 1,6 vez para umDecimal64. 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 detoDecimalString, que descartava o “vai um” da parte fracionária:toDecimalString(toDecimal64('9.995', 3), 2)retornava9.00e agora retorna10.00. #112457 (thevar1able). - Melhorado o desempenho do algoritmo de junção
partial_mergeem chavesFixedString, 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
replaceAllereplaceRegexpAllquando 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:ssno 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 debasicparabest_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(aliasestime_bucket,date_bin) ficou até 5x mais rápida para intervalosSECOND,MINUTEeHOUR. #109729 (raimannma). - As funções
arraySortearrayReverseSortestão várias vezes mais rápidas com arrays numéricos (incluindoDecimaleDateTime64) quando chamadas sem lambda. #109832 (raimannma). addDays,addWeeks,subtractDaysesubtractWeeksficaram mais rápidas com valoresDateTimeeDateTime64em 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 comDeltaaté 20% mais rápidas. #110189 (raimannma). - Aceleradas as funções de busca em strings (
like,position,match,countSubstrings,hasTokenetc.) em colunasEnumcom 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/replaceOnee 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
DynamiceObjectcom muitas variantes dinâmicas ou caminhos JSON. #110583 (cv4g). estimateCompressionRatiomais rápido com o codecNONE#111107 (rienath).- Aceleradas a ordenação e outras operações baseadas em comparação em colunas
JSONcujos caminhos são armazenados em shared data. Antes, cada comparação de valores materializava uma colunaDynamictemporária e executava uma desserialização binária completa dos dois lados, deixando oORDER BYnessas colunas extremamente lento. #111894 (groeneai). - A divisão de inteiros de 256 bits (
Int256,UInt256eDecimal256) 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 afetaintDiv,modulo, a aritmética deDecimal256e a conversão desses tipos para texto. #112477 (thevar1able). - A leitura de uma coluna
Nesteda partir de um tipo codificado em binário (Native,RowBinarycominput_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 tipoTupleaninhado malformado agora é reportado como erro de sintaxe, em vez de levar um tempo exponencial em relação à sua profundidade de aninhamento e falhar comTOO_SLOW_PARSING. #112560 (alexey-milovidov). - Aceleradas as consultas PromQL em tabelas TimeSeries:
timeSeriesIdToGroupagora 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
ArroweArrowStreamque não usam a biblioteca Apache Arrow, evitando cópias e conversões de dados adicionais. Agora eles são o padrão (configuraçõesinput_format_arrow_use_native_readereoutput_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) = constpara 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,replaceRegexpOneereplaceRegexpAllficaram 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çãocompile_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
UInt64ficou 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(eeditDistance) 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 = 1ficou mais rápido, igualando ou superando o parser padrão em quase todas as entradas. Além disso, a bibliotecafast_floatincluí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
DISTINCTpara 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). estimateCompressionRatioficou mais rápido para colunas codificadas comT64, 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,UInt256e tipos baseados neles, comoDecimal128), bem como da conversão de inteiros com sinal paraInt256(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
Nullablenã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
arrayMinearrayMaxsobre 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
DISTINCTquando o stream de entrada está ordenado por um prefixo das colunas do DISTINCT, por exemploSELECT 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/groupBitXore 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-Ifem 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
UUIDa partir de texto (por exemplo,JSONExtractparaLowCardinality(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
groupUniqArraypara tipos numéricos em até 3x ao usar hashing CRC32 (como emuniqExact) 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
minemaxem 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 mapSettingseasynchronous_read_countersestava cerca de 6 vezes mais lenta do que antes, o que podia fazer com queSYSTEM FLUSH LOGS query_logexcedesse 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
pointInPolygonquando o argumento de ponto é uma coluna-chave inteira do tipoPoint(ou outraTuplede dois elementos numéricos), por exemplo,pointInPolygon(coord, [...])para uma tabela ordenada porcoord. Antes, apenas a formapointInPolygon((x, y), [...])com duas colunas-chave escalares era analisada. #112956 (alexey-milovidov). text_index_posting_list_apply_modeagora temlazycomo 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 composting_list_codecdefinido. #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_timestampefromUTCTimestamp/from_utc_timestampem argumentosDateTime64, 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
andeornativos durante a análise, por meio da configuraçãoenable_function_early_short_circuit. Isso permite pular a execução de subconsultas escalarescount()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_chainpassa 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
UNIONagora 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ão1000) controla o limite #104860 (vdimir). EXPLAIN [PLAN] actions=1, compact=1, pretty=1passa 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 entreMemoryTrackinge o uso real de memória do processo. As mensagens de erroMEMORY_LIMIT_EXCEEDEDagora 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
INSERTfalha porque a tabela de destinoTOde uma visão materializada rejeita a escrita durante a construção do pipeline de insert (por exemplo, quando o destino é umaViewou 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 umaTuplenomeada agora altera apenas metadados quando somente subcampos são adicionados, com a mesma velocidade de umADD COLUMNno nível superior. Disponível medianteSET 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 dadosMaterializedPostgreSQL. Por padrão (habilitada), colunas PostgreSQLdate/timestampsão inferidas comoDate32/DateTime64; defini-la como0noCREATE DATABASEfaz com que sejam inferidos os tipos mais restritosDate/DateTime. A configuração não se aplica ao motor de tabelaMaterializedPostgreSQL. #107428 (alexey-milovidov). EXPLAIN PLANagora 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).INSERTem uma tabelaMergeTreeagora respeita o cancelamento da consulta emax_execution_timedurante a escrita de muitas partes, em vez de possivelmente continuar em execução por muito tempo após ser encerrado. #107929 (al13n321).arrayFoldagora respeita o cancelamento de consultas emax_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 queKILL QUERYe os limites de tempo eram ignorados até o fold terminar. #108192 (groeneai).- Adicionados
ProfileEventspara cada fase da pré-execução da consulta:QueryParseMicroseconds,QueryAnalysisMicroseconds,QueryPlanBuildMicrosecondseQueryPipelineBuildMicroseconds. 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 emsystem.query_logesystem.events. #108282 (jrdi). - Operações
ALTER TABLEque gerariam metadados de tabela maiores quemax_query_sizeagora 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
ConstantJoinpara 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çãojoin_algorithmincompatível quando o analisador é usado. #108289 (antaljanosbenjamin). - Adicionada a coluna
sourceasystem.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
tableedatabaseno WHERE,system.iceberg_historylistará 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áusulaSETTINGSde uma consulta (comoSELECTouINSERT) quanto em consultasSETindependentes, por exemplo,SELECT ... SETTINGS max_threads = {threads:UInt64}eSET 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 queWITH, enquanto duas ou mais CTEs colocavamWITHem 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 JOINigualada na condiçãoON(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,dotProductTransposede suas contrapartes quantizadasL2DistanceTransposedQuantized,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 porqueWindowStepnão podia ser serializado para execução remota; janelas comPARTITION BYcontinuam 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
INcuja ú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 predicadoWHERE. #110507 (shankar-iyer). SHOW CREATE TABLE(eSHOW 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 consultasSELECT. #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
promqlignorava a verificação de funções não determinísticas e podia retornar resultados desatualizados ancorados emnow(); já a Prometheus HTTP API (/api/v1/query,/api/v1/query_range) simplesmente nunca armazenava entradas no cache. #110887 (nikitamikhaylov). EXPLAIN ANALYZEagora 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. Usematches = 1para 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,
FINALcom 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 tabelaMergeTreeque 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 tabelaMergeTreevazia. Antes, essas consultas falhavam comSUPPORT_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
WHEREcom múltiplas condiçõesAND. #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 CACHEagora remove as chaves de metadados do cache em paralelo, acelerando a limpeza de grandes caches do sistema de arquivos. A nova configuraçãodrop_cache_threadsdo 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 KEYeSETTINGSpor coluna - agora podem ser escritos em qualquer ordem emCREATE 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. EmALTER TABLE ... ADD COLUMN/MODIFY COLUMN, os modificadores compatíveis -COMMENT,CODEC,STATISTICS,TTLeSETTINGSpor coluna - também podem ser escritos em qualquer ordem;SETTINGSpor coluna emADD COLUMNe umSTATISTICSdeclarado emADD COLUMN/MODIFY COLUMNagora são aplicados em vez de serem descartados silenciosamente, eCOLLATEePRIMARY KEYnesses comandosALTERagora 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 tabelamerge) que corresponde a muitas tabelas agora responde aKILL QUERYemax_execution_timeenquanto 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
SELECTde uma tabelaMergeque excedemax_execution_timecomtimeout_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 umALTER TABLE ... MODIFY COLUMNcuja 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 simplesBad 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_joinpassou a ser habilitado por padrão: o valor padrão dejoin_algorithmagora édirect,parallel_hash,hash,ie_join. UmJOINcuja seçãoONconté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 umCROSS JOINcom filtro, e junçõesLEFT/RIGHT/FULL/SEMI/ANTIcom essas condições passam a ser compatíveis. Comoie_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 spanConnection::sendQuerydo 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 DATABASEagora 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 umDROP DATABASEnã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çãomatch),~*(correspondência sem diferenciar maiúsculas de minúsculas),!~e!~*(negações). Os comandos\d,\dte\dvdopsqlagora 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 WHATIFagora informa por que a estimativa empírica foi ignorada, em uma nova linhaempirical_reasonexibida quandoempirical_statuséunsupported. #115140 (yariks5s).- Quando nenhum algoritmo de junção habilitado pela configuração
join_algorithmconsegue executar umJOIN, 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). BACKUPnã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 destinosS3eAzuretambé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 TABLEpara 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. Adicionaadaptive_aggregator_freeze_threshold_bytespara 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 osnmelhores grupos de cada bucket de dois níveis quando uma agregação final alimenta umORDER BYsobre suas saídas comLIMIT n. A otimização agora também aparece na saída doEXPLAIN. #116124 (nihalzp). - Melhora o suporte a consultas
DESCRIBEpara visões parametrizadas. Adiciona suporte a visões parametrizadas em expressões escalares no novo analisador. #68978 (novikd). - Consultas como
SELECT * FROM t WHERE idagora usarão o salto de índice (index skipping) na colunaid. #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à tabelasystem.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 emsystem.grantsconcessõ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,arrayemapaplicados a argumentos numéricos que não têm um tipo em comum sem perdas (por exemplo, umDecimale umFloat64, ou umInt64e umFloat64) passam a ser resolvidos para o supertipo numéricoFloat64em vez de umVariant, permitindo que o resultado seja usado com funções de agregação comosum,avg,minemax. 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-chaveIS DISTINCT FROMeIS NOT DISTINCT FROM, e aos predicados de busca em stringsLIKE,ILIKE,NOT LIKE,NOT ILIKEeREGEXP, que são reescritos comoarrayExists/arrayAll. #107454 (alexey-milovidov). - Adicionada a configuração
input_format_json_max_object_sizepara 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
sqliteou o motor de banco de dadosSQLiterecebia um caminho que não podia ser aberto). #107807 (alexey-milovidov). - Adicionado suporte à função
lengthpara o tipo de dadosQBit. Ela retorna a dimensão do vetor como uma constante. #108071 (alexey-milovidov). - Adicionado suporte a
CASTde umQBitpara umArray, reconstruindo o vetor original. Trata-se da operação inversa da conversão já existente deArrayparaQBit. #108072 (alexey-milovidov). - O motor de banco de dados, o motor de tabela e a função de tabela
MySQLagora mapeiam os tipos de coluna espaciais do MySQL (LINESTRING,POLYGON,MULTILINESTRING,MULTIPOLYGONe o genéricoGEOMETRY) para os tipos geométricos correspondentes do ClickHouse, em vez deString. Esse comportamento é controlado pela nova flaggeometryda configuraçãomysql_datatypes_support_level, habilitada por padrão.POINTcontinua sendo sempre convertido paraPoint. A coluna genéricaGEOMETRYé mapeada para o tipo abrangenteGeometry; 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_parsingaos formatos de entrada (CSV, TSV, JSON, VALUES, …) e a literais numéricos, não apenas atoFloat*/CAST. Definaprecise_float_parsing = 0para restaurar o comportamento anterior, mais rápido em alguns casos, porém menos preciso. #109086 (Algunenano). - Adicionado suporte a
reinterpretde umArrayde elementos de tamanho fixo comoString, a operação inversa doreinterpretjá existente deString/FixedStringcomoArray. #109383 (alexey-milovidov). - Permite
CASTentre tiposQBitque 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 umQBit(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 deArray(por exemplo, a conversão deFloat32paraBFloat16pode perder precisão, eaccurateCast/accurateCastOrNullrejeitam linhas que não sejam exatamente representáveis). #109387 (alexey-milovidov). - As funções
quantizeBFloat16ToInt8edequantizeInt8ToBFloat16agora também aceitam argumentosArrayeQBit, aplicando o codec Lloyd-Max ao vetor inteiro (e retornandoArray/QBitdo tipo de elemento correspondente), além das sobrecargas escalares já existentes. #109398 (alexey-milovidov). - O especificador de formato
%fno estilo MySQL emparseDateTime/parseDateTime64(e em suas variantesOrZero/OrNull) agora aceita de 1 a 6 dígitos fracionários, interpretados como microssegundos alinhados à esquerda, como noSTR_TO_DATEdo MySQL, em vez de exigir exatamente 6. Também foram corrigidas tabelasPrettyCompactdesalinhadas nos exemplos da documentação das funções integradas. #109421 (alexey-milovidov). - A subestatística
NullCountdas estatísticasbasicfoi renomeada paraDefaultCount: em vez de contar linhasNULLde uma colunaNullable,buildagora conta as linhas iguais ao valor padrão intrínseco do tipo da coluna por meio deIColumn::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 (
Decimalvs. inteiro de largura diferente, e pares envolvendoInt128/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çõesplus/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
SQLiteou da função de tabelasqlitenã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
MergeTreeem colunasStringcom 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 subobjetoJSONarmazenado com serialização shared-data em mapa. #110471 (alexey-milovidov). - Adicionado suporte à cláusula
SETTINGSpara o motor de tabelaPostgreSQLe a função de tabelapostgresql(por exemplo,SETTINGS postgresql_connection_pool_size = 50), alcançando paridade de recursos com o motorMySQL. #110614 (alexey-milovidov). - As funções
bitmaskToArrayebitmaskToListagora aceitam argumentos(U)Int128e(U)Int256. A funçãobitPositionsToArrayagora é 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 BYagora funcionam commake_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 colunaLowCardinalityagora retornaLowCardinality(UInt8)— o mesmo tipo quex IN (literal list). Antes, as duas formas retornavam tipos diferentes, e planos distribuídos com esse tipo deINexigiam 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, emJSONExtracte emisValidJSON. Esses valores agora são lidos em tipos inteiros largos, comoInt128/UInt256, em vez de causar a rejeição do documento inteiro. #114379 (Avogar). - Adicionado
keywordcomo alias para o tokenizador de índice de textoarray, para melhorar a compatibilidade com OpenSearch, Elasticsearch, SolR e Lucene. #115507 (rschu1ze). - As funções
toDateOrNull,toDateTimeOrNulletoDateTime64OrNullagora aceitam argumentos de todos os tipos inteiros nativos (interpretados da mesma forma que emtoDate,toDateTimeetoDateTime64, com um argumento opcional de fuso horário) e retornamNULLpara valores fora do intervalo do tipo de resultado. Por exemplo,toDateTimeOrNull(1583851242, 'Asia/Shanghai')retorna2020-03-10 22:40:42etoDateTimeOrNull(4294967296)retornaNULL. #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_bytese suas variantes por usuário rotuladas comuser_id), expostas por cache viasystem.dimensional_metrics,system.histogram_metricse o endpoint do Prometheus. Elas são controladas pelas configurações de disco do cacheexpose_prometheus_eviction_metricseexpose_prometheus_eviction_metrics_per_user(ambas desativadas por padrão), que podem ser ativadas ou desativadas em tempo de execução viaSYSTEM RELOAD CONFIG. #105020 (sacheendra). - O motor
Aliasagora oferece suporte à leitura com réplicas paralelas quando a tabela de destino usa um motor da famíliaMergeTree. #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
_etagpara o armazenamento HDFS #108255 (zhangyifan27). - Adicionadas as colunas
settingseengine_settingsasystem.backupsesystem.backup_log.settingsexpõ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), eengine_settingsexpõe as configurações efetivamente usadas pelo leitor/gravador do motor de backup (por exemplo, as configurações de requisição do S3, comoallow_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çãoBACKUP/RESTOREfoi de fato executada. #108334 (jkartseva). - Adicionadas
system.s3_queue_metadataesystem.azure_queue_metadatapara inspecionar o estado no Keeper das tabelasS3QueueeAzureQueueregistradas, 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_NAMEeDEFAULT_ENCRYPTION;TABLES.ENGINEe colunas MySQL relacionadas; eCOLUMNS.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 emUNKNOWN_IDENTIFIER. #109351 (alexey-milovidov). - Reduzido o uso de memória de tabelas
MergeTreecom 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 doMergeTreeantes 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
pollno 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 ouKeyUpdate); agora ela usa umMSG_PEEKnão bloqueante em sockets simples eSSL_peek/SSL_has_pendingem 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
LocalObjectStorageagora implementa gravações condicionais, de modo que o compare-and-swap que publica um novo snapshot por meio deversion-hint.textpassa 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
S3agora 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
500sinté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çãosnappy_modepara escolher entre o formato de bloco snappy do Hadoop e o formato de enquadramento snappy na E/S snappy genérica defile/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 deNullable(String)na entrada CSV é lido como umaStringvazia em vez deNULL, independentemente deinput_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_decoderestá 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à tabelasystem.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_threadse de configurações semelhantes agora é exibido emsystem.settingscomoauto(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/docse pelo comandohelp— 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ão1.0, ou0em compilações com sanitizador), que faz o rastreador de memória global reservar especulativamenteratio * min(resident - previous_resident, resident - tracked)além do RSS observado a cada tick doMemoryWorker. 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 recebemMEMORY_LIMIT_EXCEEDEDmais cedo e diminui a probabilidade de o OOM-killer do kernel ser acionado primeiro. Defina a razão como0para desabilitar a especulação. Compilações com sanitizador usam0por padrão porque, nelas, a diferençaresident - 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'semallow_experimental_text_index_lazy_apply. A configuração de limiar de densidade foi renomeada detext_index_density_thresholdparatext_index_lazy_intersection_density_threshold. #108814 (CurtizJ). - A configuração
merge_selector_enable_heuristic_to_lower_max_parts_to_merge_at_onceagora 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,UNLISTENeDISCARDagora 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 enviamRESET ALLeUNLISTEN *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 limitemax_tokens), em vez de retornar silenciosamente uma saída parcial. O comportamento segue a configuraçãoai_function_throw_on_error. #111830 (george-larionov). - Melhoria nas funções de precisão reduzida
L2DistanceTransposedQuantized,cosineDistanceTransposedQuantizededotProductTransposedQuantized, que agora reconstroem códigosp < 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_versionagora 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,FiberStackFreeNanosecondse métricasFiberStacks,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; adicioneasync_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 tabelaTimeSeriesde destino. #115688 (nikitamikhaylov).
Outras melhorias
- Adicionadas duas configurações,
shrink_over_allocated_columns_min_waste_ratioeshrink_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
BFloat16emdotProducte 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_throwemax_database_num_to_throwagora podem ser alterados sem reiniciar o servidor. #106821 (UberDever).- A gravação em tabelas
DeltaLake, controlada porallow_experimental_delta_lake_writes, foi promovida a Beta. #107034 (kssenii). - Adicionado o tipo de estatísticas de coluna
uniq_v2, uma alternativa leve aouniqbaseada no sketchuniqCombined64. #107863 (hanfei1991). - Adicionados os ProfileEvents
DistributedPlanRemoteTasks,DistributedPlanLocalExecutioneDistributedPlanHostsUsedpara 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-Agentdo ClickHouse. #108117 (scanhex12). MVTEncodeGeomagora ajusta a geometria à grade de pixels inteiros antes do recorte e recorta polígonos comwagyu, 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 oST_AsMVTGeomdo 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,cosineDistanceTransposededotProductTransposedagora aplicam a otimização de leitura parcial de planos de bits a colunasNullable(QBit), lendo apenas os planos de bits solicitados em vez da coluna inteira. #109358 (alexey-milovidov). - Suporte a
arraySum,arrayAvgearrayProductpara arrays deBFloat16. #109420 (alexey-milovidov). - As funções
L1Normalize,L2Normalize,LinfNormalizeeLpNormalize(e seus aliases) agora funcionam com arrays, e não apenas com tuplas, de forma consistente comL2Norme 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-Pongque era acrescentada a cada conexão reutilizada, reduzindo a latência das consultas distribuídas e doclickhouse-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_typesdebasic, uniqparabasic, 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 outrosquery_ids que detêm o bloqueio no momento e quantos bloqueios oquery_idsolicitante já possui, facilitando o diagnóstico desses erros de ordenação de bloqueios. #110971 (groeneai). randomHadamardTransformagora 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 anteriores2^N,2^k * {12, 20}e2^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; passeoutput_dimspara calcular uma projeção truncada de comprimento arbitrário. #111006 (alexey-milovidov).- Retorno do código HTTP
403 Forbidden(em vez de500 Internal Server Error) para exceçõesACCESS_DENIEDna interface HTTP. #111043 (Schum-io). UTMToGeoagora aceita, como quarto argumento, a letra da banda de latitude MGRS retornada porgeoToUTM(além do indicador inteiro de hemisfério), permitindo que um resultado degeoToUTMfaça a ida e volta diretamente porUTMToGeo. #111521 (alexey-milovidov).MaterializedPostgreSQLagora preserva valoresTOASTinalterados 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_flushetext_index_max_memory_usage_before_flushpara 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=1desativa 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_rsfoi renomeado paraallow_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_codeceenable_quantized_codecpara 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,SIGFPEeSIGTRAPgeram 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_applicablepara 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 COLUMNe umOPTIMIZE TABLE ... FINALconcorrente (ou qualquer mesclagem em segundo plano) noMergeTreeque 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 emcurrent_mutations_by_versionagora é eliminada mantendocurrently_processing_in_background_mutexbloqueado durante ambas as operações. #104822 (groeneai). - Corrigidos resultados incorretos de consultas ao usar GROUP BY com ORDER BY e
arrayJoinna projeção. #101775 (Onyx2406). - Configurações inválidas de tamanho de upload do Azure (por exemplo,
azure_min_upload_part_size = 0ouazure_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_ARGUMENTSem vez deLOGICAL_ERRORquandoALTER TABLE ... MOVE/REPLACE/ATTACH PARTITIONé executado entre duas tabelasMergeTreecom 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 porKILL QUERY/KILL MUTATION/KILL PART_MOVE_TO_SHARD/KILL TRANSACTIONquando a cláusulaWHEREcontém uma subconsulta por linha, ou quandomax_block_sizeé pequeno o bastante para que oSELECTinterno sobre a tabelasystem.*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 viaEXCHANGE TABLESnão podia ser removida se fosse maior que omax_table_size_to_dropdo 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 ignoramax_table_size_to_dropemax_partition_size_to_drop; essas proteções continuam valendo para oDROP TABLEda própria view executado pelo usuário. #105106 (groeneai). - Corrigido um erro inesperado
DATA_TYPE_CANNOT_BE_USED_IN_KEYem consultasALTERque 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 tabelasMergeTreeque possuem umSimpleAggregateFunction(ou outro tipo permitido apenas comallow_suspicious_primary_key = 1) na sorting key. #105111 (groeneai). OPTIMIZE ... DRY RUNinterrompido por tempo limite de consulta (max_execution_timecomtimeout_overflow_mode = 'break') agora retornaTIMEOUT_EXCEEDEDem vez de um erro lógico sobrerows_sources(que abortava o servidor em builds de depuração e com sanitizers). #107114 (groeneai).- Corrigido
NOT_FOUND_COLUMN_IN_BLOCKao ler arquivos com particionamento no estilo hive comuse_hive_partitioning=1e uma cláusulaWHERE/PREWHEREque 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,toMonthNumSinceEpochoutoYearNumSinceEpoché aplicada a uma coluna-chaveDate32contendo datas fora do intervalo que a função consegue representar (em particular, datas anteriores a1970-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 deDate32, o que garante a poda correta. #108018 (nihalzp). - Corrigido o problema em que
CREATE TABLE dst AS src SETTINGS ...(e variantes semelhantes comORDER BY/PARTITION BY, mas sem umENGINEexplícito) descartava silenciosamente o motor da tabela de origem, as cláusulas de armazenamento (como oTTLda 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
INSERTem tabelasMergeTreecomfilesystem error: in rename: Permission deniedem 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 comATTACH). Antes, umDELETEleve, umOPTIMIZE, umINSERTsimples ou umSELECTfiltrado nessa tabela falhava comILLEGAL_INDEX(“Index of type ‘hypothesis’ is no longer supported”), e a mutação deDELETEera 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 comALTER 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 tabelaMergeTreecom réplicas paralelas, inclusive viaSELECT *comasterisk_include_virtual_columns = 1. #108451 (groeneai). - Corrigido o problema em que
ATTACH PARTITION ... FROMrejeitava tabelas cujas chaves primárias são equivalentes, mas declaradas de forma diferente (uma comPRIMARY KEYexplícita e a outra implícita a partir deORDER BY). #108590 (jordiori). join_any_take_last_rowagora é 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_BLOCKquandoquery_plan_optimize_lazy_finalestá habilitado em conjunto com um filtroWHEREparcialmente movido paraPREWHERE(viaoptimize_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 PROJECTIONsobre uma colunaALIASno nível da tabela deixava a tabela inutilizável (oINSERTseguinte falhava comUNKNOWN_IDENTIFIER, “Missing columns”) quando a sessão tinhaoptimize_respect_aliases = 0. #109091 (groeneai). - Corrigida uma asserção de ponteiro nulo (
px != 0emTreeRewriter::analyzeSelect, que abortava o servidor em builds de depuração e com sanitizers) ao executarORDER BY ALL(ouGROUP BY ALL) sobre uma tabela com engineMergeem JOIN com outra tabela no analisador antigo (allow_experimental_analyzer = 0). #109139 (groeneai). - Corrigido um resultado incorreto de subconsultas
EXISTScorrelacionadas e de subconsultas escalares quando a correlação aparece apenas na projeção da subconsulta, junto com uma cláusulaWHEREnão correlacionada (a subconsulta podia ser avaliada como falsa /NULLpara todas as linhas). Corrige https://github.com/ClickHouse/ClickHouse/issues/105760. #109186 (novikd). - Corrigido um bug em que a mesclagem de uma tabela
MergeTreecom projeções, com a configuraçãoenable_block_number_columnouenable_block_offset_columnhabilitada, 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, eCHECK TABLEeOPTIMIZE ... DRY RUNa reportavam como corrompida (CORRUPTED_DATA). #109284 (groeneai). - Corrigido o erro
UNKNOWN_IDENTIFIERao executarALTER TABLE ... RENAME/ADD/MODIFY COLUMNem uma tabela MergeTree que possui um índice min-max implícito sobre as colunas virtuais persistentes_block_numberou_block_offset(habilitado poradd_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 TABLEcomUNEXPECTED_FILE_IN_DATA_PART) após uma mutação que reescreve a parte inteira, comoALTER TABLE ... DROP COLUMNde uma colunaMATERIALIZED, em uma parteWide. #109616 (groeneai). - Corrigidos índices de salto (
text,bloom_filteretc.) e projeções inativos após a materialização de atualizações leves comALTER 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,hasTokendeixando 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 erroUnexpected const virtual column: _sample_factor, que deixava a mutação travada. Agora, a mutação lê essa coluna como1, o mesmo valor retornado por uma consulta semSAMPLE. #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 comforce_aggregation_in_order = 1:Trying to get name of not a column: ExpressionListno analisador antigo (enable_analyzer = 0) eMemory bound merging of aggregated results is not supported for grouping sets.em uma consulta distribuída comenable_memory_bound_merging_of_aggregation_results = 1no analisador. #109862 (groeneai). - Corrigidos três problemas com
use_constant_folding_in_index_analysis: um erro lógicoInvalid partition key sizeque podia abortar umSELECTque usasse uma projeção normal quando a tabela definepart_minmax_index_columns = 'with_block_number_offset'; resultados incorretos (linhas descartadas silenciosamente) em filtros sobre uma chave de partição com módulo, comoPARTITION BY id % 200; e uma falha (condição de corrida de dados) quando um índicetextcom tokenizadorsparseGramsé consultado com um predicadoLIKEem muitas partições commax_threads > 1. #109896 (groeneai). - Corrigidos resultados incorretos quando um índice de salto
minmaxé criado sobre uma colunaLowCardinality(Nullable(...)): predicadosWHERE/PREWHERE/HAVING ... IS NULLrepassados 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 ... LIMITem tabelasDistributedquandoprefer_localhost_replicaseleciona uma réplica local. #110136 (EmeraldShift). - Corrigida uma exceção (
UNION mode UNION_DEFAULT must be normalized) quando uma mutaçãoDELETEouALTER UPDATEusava uma operação de conjunto (UNION/UNION ALL/UNION DISTINCT/EXCEPT/INTERSECT) dentro de uma subconsulta na condiçãoWHEREou em uma atribuição deUPDATE. #110196 (alexey-milovidov). - Corrigidos o desligamento lento do servidor e a falta de resposta de
KILL MUTATIONquando uma mutação comx 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 TRANSACTIONeALTER TABLE ... UPDATE/DELETEexecutado 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.tablespara um banco de dadosDataLakeCatalog(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_rowsetc.), independentemente dedatabase_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 PARTITIONentre duas tabelas MergeTree com granularidade incompatível (uma adaptativa e outra não adaptativa) agora lançaBAD_ARGUMENTSem vez deLOGICAL_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 umALTER TABLE ... UPDATEem uma coluna referenciada noWHERE. 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 umINSERTem uma tabelaMergeTreeparticionada comnon_replicated_deduplication_windowhabilitado, quando um lote de async insert era desduplicado apenas parcialmente (algunsinsert_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é umVariantnomeado cujas alternativas podem compartilhar o mesmo layout de armazenamento (LineString/Ring,MultiLineString/Polygone os vazios), de modo que duas constantes resultantes do folding que diferiam apenas na alternativa eram reduzidas a uma só; por exemplo, uma constanteMULTIPOLYGON EMPTYresultava emLINESTRING(). #110709 (groeneai). - Corrige um resultado incorreto (mesclagem fora de ordem) em consultas read-in-order nas quais
distinct-in-orderouaggregation-in-orderestende a leitura para um prefixo da chave de ordenação mais longo do que aquele para o qual oORDER BYconfigurou 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 oMergingSortedTransform(e abortar com umLOGICAL_ERRORem 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
ALTERapenas de comentário ou apenas de configurações em uma tabelaReplicatedMergeTreepodia descartar silenciosamente uma coluna adicionada por umALTER ... ADD COLUMNconcorrente, deixando uma réplica com uma estrutura de tabela desatualizada. #111029 (tiandiwonder). - Corrige o erro
NUMBER_OF_COLUMNS_DOESNT_MATCHem umGROUP BYcom uma agregação sobre uma tabelaMergeque encapsula uma tabelaDistributed, 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 JOINem uma tabela com engineJoin(StorageJoin) comUSINGquando a chave da esquerda éNullablee a chave do armazenamento não é: uma linha da esquerda sem correspondência com chaveNULLretornava0em vez deNULL. #111371 (groeneai). ALTER TABLE ... DETACH PARTITION/PARTagora executa fsync no clone que cria emdetached/(a subárvore da parte mais a cadeia de diretórios até a raiz do disco) quando a configuraçãofsync_part_directoryda 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, deixandodetached/vazio e nada paraATTACH). Controlado pela configuração existentefsync_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 doCREATE TABLEquando o esquema é inferido a partir do armazenamento (por exemplo, uma tabelaremote()/Remote/Distributedsem colunas sobre uma view que executaSELECT 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
INSERTparticionado do DeltaLake (allow_experimental_delta_lake_writes=1), que corrompia valores de partição contendo caracteres de caminho e rejeitavaNULL. Um valor comoa/bera gravado silenciosamente comoa,%gerava um arquivo de dados que não podia ser lido posteriormente e um valor de partiçãoNULLfalhava comNOT_IMPLEMENTED. Agora, os valores de partição são codificados com percent-encoding em um único segmento de caminho, o valor real é armazenado empartitionValuesem vez de ser extraído novamente do caminho, e um valor de partiçãoNULL(ou string vazia) é gravado como__HIVE_DEFAULT_PARTITION__com uma entrada nula empartitionValues. #111793 (groeneai). - Corrigidos os erros lógicos
Expected UInt64 column for __grouping_set, got BLOBeColumnBLOB should be converted to a regular column before usageem uma consulta distribuída executada em um shard comenable_parallel_blocks_marshalling(habilitado por padrão), por exemplo, comGROUP BY GROUPING SETSem um cluster que possui uma réplica local, ou ao ler uma tabelaMergeque abrange uma tabela local e uma tabela distribuída.BlocksMarshallingStepnã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çãoMergeTreede uma tabela cujo tipo de coluna foi alterado por umALTER MODIFY COLUMNapenas de metadados (por exemplo, deEnum8paraInt8ou deDateTimeparaUInt32) 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 porMATERIALIZE COLUMN, por umUPDATEde uma coluna da qual uma colunaMATERIALIZEDdepende ou porCLEAR COLUMNpassa 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)oudivide(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 corrigeintDivcom um dividendo constante sem sinal cujo bit mais alto está ativado, deixa de declarar monotonicidade quando um operandoDecimalfaz com que a divisão seja calculada na largura nativa do decimal e impede que a análise de chave gereCannot compare DB::IPv4 with longpara uma consulta válida que divide uma constanteIPv4/IPv6por uma coluna-chave. #112156 (groeneai). - Corrige a classificação incorreta como visão comum de uma visão parametrizada cujo corpo
SELECTusaINTERSECT/EXCEPT, ou uma cadeia deUNIONque misturaUNION DISTINCTcomUNION ALL. Essa visão era criada com sucesso, mas seus metadados não podiam ser lidos de volta: ao carregá-la, era lançadoInvalid 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_parameterstambém não exibia nenhum parâmetro para essas visões. #112211 (groeneai). - Corrige o problema em que
max_execution_timeeKILL QUERYeram ignorados enquanto uma consulta avaliavageohashesInBox. 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 umPARTITION 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 COLUMNcuja mutação nunca foi executada, por exemplo porqueKILL MUTATIONa removeu: os grânulos em disco haviam sido gravados com o tipo antigo, mas eram decodificados com o novo, gerandoLOGICAL_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: umMODIFY COLUMNque altera apenas o fuso horário de umDateTime, ou apenas um nome de tipo personalizado, como deUInt8paraBool. 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 comserialize_query_plan = 1e 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éplicaReplicatedMergeTreeaplica uma mutação a uma parte obtida de outra réplica antes de aplicar seu próprioALTER ... ADD COLUMNpendente. 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 cotasREAD_ROWSeREAD_BYTES, que eram contabilizados em excesso em consultas cujoORDER BYfaz 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 comQUOTA_EXCEEDED, mesmo permanecendo dentro de sua cota. #112645 (groeneai). - Corrige
ProfileEvents['JoinResultRowCount'], que subnotificava o tamanho do resultado de umJOINque faz spill para o disco. As linhas emitidas a partir de buckets adiados eram contadas apenas emJoinDelayedJoinedTransformRowCounte ficavam de fora do total. Os resultados das consultas sempre estiveram corretos; apenas o evento de perfil estava errado. #112673 (groeneai). - Corrige
max_execution_timeeKILL 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
ALTERem tabelasMergeTreeenquanto uma mutação de alteraçãoRENAME COLUMNincompleta 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 BYao ler de uma tabelaMergesobre tabelasDistributed: linhas podiam ser retornadas fora de ordem, e linhas que deveriam constar no resultado podiam ficar de fora quandoLIMITera 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 comshare_nested_offsetshabilitado (o padrão). Essa consulta podia retornar valores default para uma coluna fisicamente presente que nunca foi afetada pelosALTERs. No armazenamento de objetos, isso ocorre sem nenhuma configuração diferente do padrão, já queremote_filesystem_read_prefetchtem1como padrão; em discos locais, é necessáriolocal_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 stuckem consultas que distribuem dados por partição, como uma função de janela comPARTITION BYou uma junção comjoin_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,TRUNCATEe de manipulação de partições comalter_sync = 2emReplicatedMergeTreequando a tabela começa a ser desligada enquanto a instrução aguarda outra réplica, por exemplo, devido a umDROP DATABASE ... SYNCconcorrente. Agora, essa instrução falha comUNFINISHEDe também respeitamax_execution_timeeKILL QUERY. #113228 (groeneai). - Corrigido o erro
Cannot insert element into Set(NOT_IMPLEMENTED) quandoread_in_order_use_virtual_rowestá habilitado e uma consultaMergeTreecom leitura em ordem combinaWITH FILL ... INTERPOLATEcom um filtroINouhas. #113264 (groeneai). - Corrige um erro lógico (exceção)
Chunk info was not set for chunk in MergingAggregatedTransformquando a configuraçãoinject_random_order_for_select_without_order_byestá habilitada e uma consulta de agregação lê de uma tabelaMergeque contém um filhoDistributed: o wrapper aleatórioORDER 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
MergeTreetinha duas ou mais regrasTTL ... DELETE WHEREcom expressão de tempo idêntica, diferindo apenas na condiçãoWHERE. Após uma mesclagem de exclusão por TTL, orows_where_ttl_infoda 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_timeeKILL QUERYeram ignorados enquanto uma consulta avaliavageohashesInBox,arrayFold,sleep,base58Decode,h3PolygonToCellsouh3PolygonToCellsWithContainmentdentro de uma expressão armazenada nos metadados da tabela, como uma sorting key, um índice de exclusão ou uma chavePARTITION 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 tabelaMergecom 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'emEXPLAIN ANALYZEsobre uma tabelaMergecom vários filhos, umPREWHEREcom coluna simples e umWHEREseparado. #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 queengineéNullable(String), sobresystem.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émIN (subquery)é cancelada, por exemplo, porKILL MUTATIONouDETACH DATABASE, enquanto o conjunto da subconsulta ainda está sendo construído. #114463 (groeneai). ALTER TABLE ... DROP COLUMNde uma coluna usada na chave de ordenação, primária ou de partição agora falha comALTER_OF_COLUMN_IS_FORBIDDENe uma explicação, assim como já ocorre comALTER TABLE ... CLEAR COLUMN. Antes, falhava com um erro confusoUNKNOWN_IDENTIFIER: Missing columns, proveniente do recálculo das expressões-chave. O mesmo vale para remover ou limpar um grupoNestedinteiro 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ãoTTLagora 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
ALTERretornava 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 tabelaMergequando a tabela subjacente declara a coluna pai comoALIAS. 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
SELECTfiltrado porpointInPolygonsobre uma chave primária MergeTree quando o argumento de polígono é um literal constante inválido evalidate_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 STATISTICSeMATERIALIZE PROJECTION, que descartava a cláusulaIF EXISTS, fazendo com que a consulta formatada fosse diferente da consulta interpretada. Além disso, quatro payloads JSON de AST deALTER ... STATISTICSque 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 deTTL ... GROUP BY. Isso podia gerar um hash incorreto e um heap-buffer-overflow reportado em compilações com sanitizador. #115604 (groeneai). CREATE TABLEeALTER TABLEagora rejeitam codecs com perdas, comoSZ3, em colunas usadas na chave de partição. #115626 (groeneai).- A leitura por meio de uma tabela
Mergeque corresponde a uma tabelaAliascujo destino é uma view parametrizada não gera maisLOGICAL_ERROR: Table has no columns.(o que aborta o servidor em compilações de debug e com sanitizador). Essa tabela agora reportaSTORAGE_REQUIRES_PARAMETER, o mesmo erro reportado pela própria view parametrizada. Qualquer outra tabela correspondente que não consiga fornecer colunas agora reportaUNSUPPORTED_METHODem 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. Comapply_mutations_on_fly = 1e uma cláusulaSAMPLE, 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 umALTER TABLE t DELETE WHERE _sample_factor > 1pendente podia fazer com que uma leitura comSAMPLEnão retornasse nenhuma linha. A coluna_sample_factorda própria consulta permanece inalterada. #115906 (groeneai). - Arquivos de estatísticas com versão de formato
V3agora são lidos em vez de rejeitados comILLEGAL_STATISTICS. Esses arquivos foram produzidos apenas por compilações domasterdurante um curto intervalo, mas as partes que os continham ficavam totalmente ilegíveis e, em um disco somente leitura,ALTER TABLE ... MATERIALIZE STATISTICSnão consegue regenerá-los. #116030 (alexey-milovidov). - Corrigido o erro
Invalid number of columns in chunk pushed to OutputPort(LOGICAL_ERROR) quando uma consultaSELECT ... FROM t STREAM ... ORDER BY ... LIMIT nlia uma tabela com umaPROJECTION. A materialização tardia não é mais aplicada a leiturasSTREAM. #116187 (groeneai). ALTER TABLE ATTACH PARTITION FROMnã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::addagora 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
indexOfAssumeSortedretornava resultados incorretos para colunasArray(LowCardinality(String))em tabelas MergeTree. #101771 (Onyx2406). - Corrigidas exceções
LOGICAL_ERRORao ler tabelas de data lakeIcebergouDeltaLakepor caminhos que podem chegar ao pipeline de leitura sem umdatalake_table_statefixado, como atualizações concorrentes de metadadosIcebergou leiturasmergesobre tabelasDeltaLake. #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 porOPTIMIZE TABLE ... PARTITION ...(e outras consultas que resolvem um valor de partição por meio deconvertFieldToTypeImpl) em tabelas com chave de partição do tipoTime. #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.warningsficavam 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 tabelaMergesobre tabelasDistributedou views com a configuração experimentalmake_distributed_plan = 1. #108401 (groeneai). - Corrigidos um aborto do servidor (
Sort order of blocks violated) durante uma mesclagem e leituras incorretas quando um elementoLowCardinalitynão anulável de uma colunaNullable(Tuple(...))é usado como subcoluna (por exemplo, como chave de ordenação). #108679 (groeneai). - Corrigido um crash no
Base64Decodedo SDK do Azure incorporado, acessível viaazureBlobStorage()(e funções de tabela/armazenamento do Azure relacionados), quando a chave da conta não é um Base64 válido. Um byte>= 0x80causava 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 umDROP/DETACH/MOVE/REPLACE PARTITIONem 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óriotmp_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 doDEFAULTdefinido na DDL (por exemplo,-1) após a expiração doTTLda coluna em uma parte wide. #109013 (tiandiwonder). - Corrigida a falha de consultas
ALTERem tabelasMergeTreecriadas com uma configuraçãodiskpersonalizada (SETTINGS disk = disk(...)). #109199 (Michicosun). - Corrige o aparecimento de linhas obsoletas e excluídas ao ler tabelas de um banco de dados
MaterializedPostgreSQLpor meio de uma tabelaMerge. #109339 (vdimir). - Corrigida a leitura de tabelas Paimon particionadas por uma coluna
BIGINTcujo valor não cabe emInt32. Esses valores de partição eram truncados (por exemplo,9223372036854775807virava-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
Mergecuja 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 TABLEagora informa a corrupção real de uma parte de projeção cujos metadados não puderam ser carregados, em vez de um erro enganosoColumns doesn't match ... Expected: 0 columns. #110262 (Algunenano).- Corrigida a falha na inicialização do servidor para tabelas
MergeTreeem discos de armazenamento de objetos quando um arquivotxn_version.txt.tmpremanescente 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_offsetou de ordem de commit não podia mais ser anexada apósallow_part_offset_column_in_projectionsouallow_commit_order_projectionserem 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_ERRORraro (“Unexpected number of parts to remove from parts_queue”) que podia abortar o servidor em umaReplicatedMergeTreequando duas operações de partição (por exemplo, duas consultasMOVE PARTITION/REPLACE PARTITION, ou uma concorrendo com umDROP_RANGEem 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 serializationque podia ocorrer quando uma coluna com um codecQuantized(...)estava aninhada em uma serialização reutilizável via pool, por exemplo, uma tabelaMergesobre fontes cuja coluna de mesmo nome tem tipos diferentes (mesclados em umVariant). #110776 (groeneai). - Corrigido um
std::length_error(LOGICAL_ERROR) ao ler uma tabela MergeTree com um valor patológico demax_streams_for_merge_tree_reading(próximo do máximo deUInt64) em conjunto comallow_asynchronous_read_from_io_pool_for_merge_tree = 1. A configuração agora é limitada ao mesmo teto demax_threads. #110936 (groeneai). - Corrige um erro lógico
Cannot calculate columns sizes when columns or checksums are not initializeddurante a mesclagem de uma tabelaMergeTreede coluna única cuja única coluna tem umTTLde coluna que expira por completo (commin_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_directoryestã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 ... MANIFESTpara tabelasIcebergquando 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::unitePipespara tabelasMerge, 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 tabelaMergeTreecom vários índicestext. #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 quepart_minmax_index_columnsera reduzido (por exemplo, dewith_block_number_offsetde volta parapartition_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ógicoFilter 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 tabelaMergeTreecarrega uma parteCompactpreexistente 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 viaSYSTEM RESTART DISKou 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_ERRORquando uma colunaNullable(Tuple(...))é selecionada junto com uma de suas subcolunas de elemento que carregam nulos (Variant,DynamicouLowCardinality) de uma tabelaMergeTree. A leitura da subcoluna marcava comoNULLas linhas que sãoNULLna 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
hasAllTokense em outras buscas de índicetextcom múltiplos tokens em compilações que não usamsimdcomp(todos os alvos exceto x86_64 Linux, por exemplo, aarch64) quandotext_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
HDFSObjectStoragedescartava 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, incluindoCREATE TABLE ... ENGINE = IcebergHDFS(...)com uma lista de colunas explícita, passam a falhar. As leituras não são afetadas. #112437 (groeneai). - Corrige o
DELETEem tabelasKeeperMap, que excluía apenas as primeirasmax_block_sizelinhas correspondentes, mas reportava a mutação como concluída com sucesso. Também corrige a falta de atomicidade doDELETEcomkeeper_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 Forbiddende propagação de permissões RBAC, uma falha de autenticação de credenciais ou um tempo limite de conexão reportado como408— era classificado incorretamente como não passível de nova tentativa e reportado comoPOTENTIALLY_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_numbere_block_offsetapó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
mergesem 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_ERRORao ler uma subcoluna de um membroNestedremovido e adicionado novamente junto com um membro existente do mesmo grupo, em uma tabelaMergeTreecomshare_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
Mergecom um valor muito grande demax_streams_to_max_threads_ratio: o número de fluxos era truncado para 32 bits, de modo que múltiplos de2^32se tornavam zero. Além disso, passa a lançarPARAMETER_OUT_OF_BOUNDem vez de invocar comportamento indefinido quando a multiplicação das contagens de fluxos de uma tabelaMergeexcedesize_t, evita um overflow ao limitar os fluxos deMergeTreeà quantidade de dados e rejeita uma leitura de tabelaMergecuja contagem agregada de origens excederia 65536. #113382 (alexey-milovidov). - Corrigidas as gravações no disco
hdfs: elas falhavam comParent directory doesn't existporque 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/remoteSecureou os motores de tabelaRemote/RemoteSecurerecebem uma coleção nomeada inexistente junto com uma substituiçãokey = 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 namemergedoes not exist pararemote(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
OPTIMIZEquandomerge_max_block_size_bytesera definido abaixo dobyteSize()de uma coluna vazia. Uma colunaLowCardinalityvazia 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 usaserialization_info_version = 'basic'. EmReplicatedMergeTree, 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 comCHECKSUM_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
UPDATEeDELETEleve 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 tabelamerge, 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
MergeTreepor camadas de intervalo de chave primária quando uma camada produz um pipe vazio. #114177 (alexey-milovidov). BACKUP,RESTOREeENGINE = Backupagora autorizam o local do backup com base nos privilégiosSOURCESdo usuário, assim como já fazems3(),file()eazureBlobStorage(). Antes, um usuário comBACKUP, mas semSOURCES, podia gravar e ler backups em qualquer local acessível pelo servidor. Agora, gravar um backup exige a direçãoWRITEna fonte de destino (WRITE ON S3,WRITE ON AZURE,WRITE ON FILE), e lê-lo exigeREAD; destinosDisk(...)continuam restritos apenas porbackups.allowed_disk. #114405 (groeneai).- Corrigida a leitura de uma tabela durante uma mutação em andamento: uma coluna
MATERIALIZEDpodia 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 tabelaMergecommake_distributed_planhabilitado sobre tabelas filhas com operações de conjunto internas. #114753 (alexey-milovidov). OPTIMIZE TABLEem 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 afetaDeltaLake,Paimon,Hudie os motores simples de armazenamento de objetos (S3,GCS,COSN,OSS,AzureBlobStorage,HDFSeURLbaseado 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 umaReplicatedMergeTreecriada com a sintaxe posicional obsoleta viaallow_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
Backupfaz 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 emCompleteMultipartUpload; agora esse erro passa por novas tentativas, assim como o já tratadoNoSuchKey, limitadas pors3_max_unexpected_write_error_retries. #109364 (groeneai). ALTER TABLE ... DELETEeALTER TABLE ... UPDATEem tabelas Iceberg cujo formato de arquivo de dados não éParquetagora são rejeitados com um erroNOT_IMPLEMENTEDclaro, em vez de derrubar o servidor ou corromper silenciosamente a tabela. #105893 (groeneai).- Corrigido o erro
Cannot add column ...: column with this name already existsemINSERT SELECTa partir de uma função de tabela comofile,s3ouinput, 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_*, comoparam_secret_key/param_aws_secret_access_key, o parâmetropasswordou parâmetrossignatureno estilo S3) não são mais gravados literalmente emsystem.text_lognem em spans do OpenTelemetry. A linha de logRequest URIagora oculta os valores de parâmetros cujos nomes indiquem conteúdo sensível, substituindo-os por[HIDDEN]. #108475 (groeneai). - Corrigida a coluna virtual
_etagdos motores de tabelaS3QueueeAzureQueue: ela era declarada, mas nunca preenchida, de modo queSELECT _etagsempre retornava uma string vazia. Agora ela retorna o ETag do objeto, assim como o motorS3e a função de tabelas3(). #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 reportaBACKUP_CANCELLED/RESTORE_CANCELLEDemsystem.backups. #108673 (jkartseva). - Corrigida a coluna virtual
_tagsdo motor de tabelaS3Queue: ela era declarada, mas nunca preenchida, de modo queSELECT _tagssempre retornava um map vazio. Agora ela retorna as tags do objeto, assim como o motorS3e a função de tabelas3(). #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
INSERTem 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(eBad cast from ColumnConst to ColumnNullableem compilações de debug/sanitizer) ao executarWHERE col IS NULL/IS NOT NULLem uma coluna Iceberg resultante de evolução de esquema, adicionada depois que arquivos de dados mais antigos foram gravados, comoptimize_functions_to_subcolumns=1(o padrão). #109515 (groeneai). - Corrige o erro
Host is empty in S3 URIquando uma subconsulta escalar é usada como argumento de URL da função de tabelas3(ou como argumento de qualquer outra função de tabela) em consultasCREATE 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
ALTERcom múltiplos comandos, comoUPDATE ..., DELETE ..., era executado em uma tabela Iceberg. Essas mutações agora são rejeitadas com um erroNOT_IMPLEMENTEDexplícito. #110347 (groeneai). - Corrige o problema em que tabelas Iceberg geravam IDs de campo duplicados após
ALTER TABLE ... ADD COLUMNquando o schema inicial continha campos aninhados (Tuple/Array/Map).last-column-idagora 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 comICEBERG_SPECIFICATION_VIOLATION(Duplicate field id). #110884 (groeneai). - Corrige o problema em que
DELETE/UPDATEem uma tabela Iceberg removia silenciosamente as linhas erradas (ou lançavaNOT_FOUND_COLUMN_IN_BLOCK) quando a tabela continha arquivos de dados gravados tanto antes quanto depois deALTER TABLE ... ADD COLUMNeoptimize_move_to_prewhereestava habilitado. #111693 (groeneai). - Corrige o problema em que
made_current_atemsystem.iceberg_historypassava a ser1970-01-01para um snapshot retido apósALTER TABLE ... EXECUTE expire_snapshotsem uma tabela Iceberg. Também corrige o problema em quesystem.iceberg_historynão retornava nenhuma linha para uma tabela cujos metadados não possuemsnapshot-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 noCREATEdo destino, e não no schema Iceberg atual dele; assim, um valorDateTimeera armazenado como umintAvro simples e lido de volta como microssegundos, e, comDateTime64(0)ouDateTime64(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 geraTYPE_MISMATCHem 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ãoParquet, oINSERTfalhava comINCORRECT_DATAe, comAvro, a coluna não podia ser lida de volta. #112480 (groeneai). - Corrige um deadlock que travava permanentemente um banco de dados
FilesystemouHDFSquando 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
DeltaLakeretornavam menos linhas do que o esperado quando o predicadoWHEREcontinha, sob umNOT, 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_filesexcluía ummetadata/version-hint.textativo 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 limiarolder_than. Comiceberg_use_version_hint = 1, a tabela deixava de poder ser lida. #113548 (groeneai). - Corrigido
LOGICAL_ERRORao filtrar uma coluna Iceberg que havia se tornadoNullablepor meio deALTER TABLE ... MODIFY COLUMN. #114521 (groeneai). - Corrigido um caso em que
ATTACH TABLEcom uma definiçãoENGINE = URL(...)não verificava a permissãoTABLE ENGINEdo motor para o qual o esquema de URL encaminha. Um usuário com apenasTABLE ENGINE ON URLconseguia anexar e depois ler uma tabela baseada emFile,S3,AzureBlobStorageouHDFS, algo queCREATE TABLErejeita 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
arrayAvro de registros{key, value}com dois campos em uma colunaMapdo ClickHouse. Essa é a codificação que o Iceberg e o Spark geram para umMAP<K, V>com chave que não é string (os maps nativos do Avro só aceitam chaves string). Antes, esse arquivo podia ser lido comoArray(Tuple(key, value)), mas não comoMap(K, V), o que falhava comType 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 umstd::out_of_range(STD_EXCEPTION) pouco informativo em vez de um erroBAD_ARGUMENTSclaro. #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 HTTPContent-Encoding), enquanto a especificação do Iceberg espera a extensãogz, 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 gravav{N}.gz.metadata.jsone continua lendo o nome legadogzippara manter a compatibilidade retroativa. #109812 (groeneai). - Corrigido o problema em que uma tabela Iceberg com formato de escrita
Avroserializava como obrigatório um campo declarado"required": falsecujo tipo élist,mapoustruct, 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_atemsystem.iceberg_history, que informava o momento mais antigo em que um snapshot se tornou atual, em vez do mais recente, quando o mesmosnapshot-idaparece mais de uma vez nosnapshot-logdo 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 tabelas3quando a coleção nomeada definehttp_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 STSAssumeRole. #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 deErrnoException(por exemplo, durante a execução deOPTIMIZEem 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/LATESTera 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éricaCouldn'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-logousnapshot-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
DateTime64com escala menos precisa que 9. O leitor ORC nativo convertia todo timestamp por meio de um intermediário fixoDateTime64(9), que causa overflow deInt64na escala de nanossegundos, e rejeitava esses valores comVALUE_IS_OUT_OF_RANGE_OF_DATA_TYPE, mesmo quando a escalaDateTime64solicitada (por exemplo,DateTime64(6), como a produzida pelo Iceberg) consegue representar o valor. Agora os timestamps são lidos diretamente na escala solicitada, edate_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 erroBAD_ARGUMENTSclaro, indicando o tipo sem suporte, em vez de um simplesDB::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 comCannot 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 tipoiceberg.id/iceberg.required), e as colunasStringem ORC passam a ser gravadas comostringORC 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 existao executarOPTIMIZE TABLEem 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
Parquetgrandes a partir de entradas zipSTOREDnão comprimidas vias3efile. #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, consultarsystem.background_schedule_poolnã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 dadosIcebergesvaziados por position deletes, por exemplo, durante a compactação de uma tabelaIcebergparticionada 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_logquando 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
Paimonparticionadas por uma colunaTIMESTAMPcom precisão superior a milissegundos, que falhava comscale 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 comAMBIGUOUS_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
IcebergSchemaProcessoreram reportadas comoLOGICAL_ERROR, que é tratado como falha de asserção, ou chegavam sem verificação a uma asserção fatal; agora elas geramICEBERG_SPECIFICATION_VIOLATION. #114518 (groeneai). - Corrigido o problema em que a coluna virtual
_timedas funções de tabelaurl/urlClusterera sempreNULLem builds baseados em musl, causado pela análise não portável do cabeçalho HTTPLast-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/**/', ...)enquantoallow_experimental_url_wildcard_from_index_pagesestava habilitado. Ao carregar os metadados dessa tabela, a verificação de recurso experimental era reavaliada e falhava comSUPPORT_IS_DISABLED, abortando a inicialização. #115095 (groeneai). - Uma tabela do motor de banco de dados
URLnã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égioSHOW 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 viaException::addMessage, para que credenciais codificadas em URL nos sufixos(in file/uri ...)de erros dejdbc()/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/time64do Arrow (por exemplo,SELECT * FROM file(..., 'Arrow')) agora inferemTime64em vez deDateTime64. Anteriormente, era inferidoDateTime64. Qualquer processamento posterior que dependa do tipo inferido antigo deixará de funcionar após a atualização. Também adiciona suporte à exportação deTime/Time64para 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 tabelasBuffer, inserções assíncronas ou nos motoresKafka/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
INSERTaceitava um seletor de colunas qualificado escrito comot.* LIKE '<pattern>'/t.* ILIKE '<pattern>', mas rejeitava sua forma canônicat.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 executarINSERTem uma tabelaDataLakeCatalogdo Microsoft Fabric / OneLake: as gravações do ADLS Gen2 (DFS) agora são direcionadas para o host de endpoint.dfsem vez do host.blob. Observação: comremote_url_allow_hosts, tanto o host.blob(leitura) quanto o host.dfs(gravação) do Fabric devem estar na lista de permissões paraINSERT. #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 tipoString, 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_logse tornava ilegível após um login via Arrow Flight: a colunainterfaceé umEnum8, mas o valorArrowFlightestava ausente de sua enumeração, de modo que um login pelo protocolo Arrow Flight gravava o valor bruto10e qualquerSELECTque lesse essa linha lançava a exceçãoUnexpected value 10 in enum. #110758 (alexey-milovidov). - Corrige a inferência de esquema da família de formatos
TSV, que inferiaStringpara um valor decimal escrito com zero à esquerda, como0.0ou0.5, enquantoCSVinfere corretamenteFloat64. Além disso, uma primeira linha com esses valores era consumida como cabeçalho pela detecção automática de cabeçalho doTSVe desaparecia do resultado. Também corrige oTSKV, que inferia um tipo numérico para um valor escrito com uma sequência de escape, comox=1\x2E5, que depois não podia ser interpretado. Valores cujo zero à esquerda é preenchimento de um inteiro, como007, continuam sendo inferidos comoString, pois o parser de valores doTSVnã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), quereadFloatTextPrecisedepois rejeitava comCANNOT_PARSE_NUMBERao ler o schema inferido; em uma colunaDynamic, 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 demax_read_buffer_sizee permite que formas válidas de expoente com zero à esquerda, como0e5, sejam inferidas comoFloat64em TSV, assim como já ocorre em CSV. Também corrige formas de expoente malformadas. #112453 (groeneai). - Corrige o problema em que
KILL QUERYemax_execution_timeeram 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_sizelinhas 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_typese, paraParquet, tambéminput_format_parquet_local_time_as_utc,input_format_parquet_allow_geoparquet_parser,input_format_parquet_skip_columns_with_unsupported_types_in_schema_inferenceeschema_inference_make_json_columns_nullable. Também registra o getter de chave de cache que faltava paraForme faz com que o getter deTemplateuse 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
vieweviewIfPermittedquando a consulta externa possui uma cláusulaSETTINGSno final. Essa consulta era formatada comoview((SELECT ...)), que não pode ser interpretada de volta, fazendo com que a consulta falhasse na verificação interna de formatar-interpretar-formatar e gerasseInconsistent 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/Time64fora de um horário do dia válido (negativos ou>= 24h) para o formatoArrowagora é rejeitada com um erro claro, em vez de gravar dados Arrowtime32/time64inválidos. #107179 (tiandiwonder). - Corrigida a leitura de arquivos
Arrow,ArrowStreameORCbaseados 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 IANAfixed, que antes falhava comCannot 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 umNULLera um único\N, o que gerava uma contagem de colunas variável por linha e quebrava os cabeçalhos deCSVWithNames/CSVWithNamesAndTypese 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 abortallocation-size-too-bigcom sanitizadores e uma condição de falta de memória em compilações de release. #109019 (groeneai). - Corrigido um
LOGICAL_ERRORao gravar uma colunaLowCardinality(Time)no formatoArrowcomoutput_format_arrow_low_cardinality_as_dictionary = 1. #109730 (groeneai). - Corrigida a leitura de um stream corrompido no formato
Nativecuja quantidade de tiposDynamicou de caminhosJSON/Objectestá próxima deSIZE_MAX: essa entrada malformada agora é rejeitada com um erroINCORRECT_DATAclaro, em vez de umstd::length_errornã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 desumMap/sumMapWithOverflow/sumMapFilteredcom valoresBoolserializados 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 estadosBoolda versão 0: chaves de map do tipoBoolnã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çavaNOT_FOUND_COLUMN_IN_BLOCKquando a interpretação dos dados de entrada resultava em zero linhas (por exemplo, um JSON vazio ou umFeatureCollectionGeoJSON 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 comBAD_ARGUMENTSouCANNOT_PARSE_NUMBER, embora as mesmas strings fossem interpretadas normalmente pela funçãoreadWKT. Isso também corrige a leitura de um arquivo que armazena a saída dewktpara uma geometria vazia, representada comoLINESTRING(). #112020 (groeneai). - Corrigido o erro
Unknown compression methodlançado quando as indicações de compressãoautoenoneeram escritas com qualquer combinação de maiúsculas e minúsculas que não fosse tudo em minúsculas, por exemplofile('data.csv.gz', 'CSV', 'x String', 'AUTO'). Nomes de codecs comoGZIPjá 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
Tuplecujo primeiro elemento éNULLnos formatosCustomSeparated,RegexpeTemplatecom a regra de escapeCSV. Nesses formatos, umaTuplesimples ocupa um campo por elemento, portanto o campo\Ninicial 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 oCustomSeparatednã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=-1emUInt64era lido como0, ev=2020-01-01junkemDateera lido como1975-07-14com a regraJSON. Campos malformados agora são rejeitados com as regrasEscaped,CSVeJSON, de forma consistente com os formatos aos quais, segundo a documentação, essas regras equivalem. ComRaw, 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õesCREATE INDEX/CREATE HYPOTHETICAL INDEXque não sobreviviam a um ciclo completo de formatação-parsing-formatação, por exemploCREATE HYPOTHETICAL INDEX i0 ON t0 ((a())) TYPE aeCREATE 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
Valuesnão registra mais erros de parsing emsystem.errorsesystem.error_logquando o parsing em streaming recorre com sucesso ao parsing de expressões SQL. #111141 (pamarcos). - Corrigido o
SYSTEM REFRESHem uma tabelaRabbitMQparada, 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óximoSYSTEM START. #111480 (groeneai). - Corrigido o problema em que uma tabela
NATScomnats_streamdefinido deixava de consumir mensagens, silenciosamente, após a reinicialização do servidor NATS. A assinaturaJetStreamagora é restabelecida automaticamente, sem exigirDETACH TABLEeATTACH TABLE. #112828 (groeneai). - Um valor absurdamente grande de
kafka_num_consumersagora é rejeitado com um erro claro, em vez de causar uma falha de alocação dentro do motor de tabelaKafka. Antes, comkafka_disable_num_consumers_limithabilitado, esse valor gerava uma exceçãostd::length_error. #114764 (alexey-milovidov). - Servidor Arrow Flight: agora aceita credenciais de autenticação
Basiccodificadas 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éricoUnexpected error in RPC handling, quando o cabeçalhoauthorizationestá 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) quandoALTER TABLE ... MODIFY COLUMNaltera uma coluna para um tipo com subcolunas dinâmicas (por exemplo, deVariantparaDynamic) 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 é umLowCardinality(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 comUnexpected return type from assumeNotNullou o servidor era encerrado por uma asserção de proteção destring_view, porque a subcoluna extraída era desserializada em um bufferLowCardinality(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 functionglobalNullIn” 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 subconsultaIN/GLOBAL INdurante a análise de índice e essa subconsulta falhava. #114121 (groeneai). - Corrigido o erro
Cannot read all data of type FixedStringao ler a subcolunaproduct_quantization_codebookde uma coluna com o codecQuantized('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
Mapcontradiz os próprios metadados, no caso de um valorMapdentro de uma colunaDynamic. Tabelas que diferiam apenas emmap_serialization_versioncompartilhavam o mesmo objeto de serialização em cache, de modo que uma parte podia receber o layout de Mapbasicenquanto seus metadados declaravamwith_buckets, e a leitura posterior falhava comLOGICAL_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,FPCeGCDomitiam 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 comCANNOT_COMPRESSquando 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
DateemtoDateTime(por exemplo,ORDER BY toDateTime(date_column)) e uma consulta filtra pela coluna original com uma comparação comoWHERE date_column >= '...'.toDateTime(Date)sofre overflow para valoresDatefora do intervalo deDateTime(após2106-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 COLUMNao converter uma colunaNullablepara um tipo diferente comDEFAULT(por exemplo,Nullable(UInt8)→String,LowCardinality(String)ouArray(UInt8)). #102156 (il9ue). - Corrigido o escaping incorreto de literais SQL em
StorageSQLitee na função de tabelasqlite()ao enviar predicadosWHEREpara 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 listasINmantinham 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_BLOCKem consultasINNER JOIN ... ON arrayJoin(...) = ...quandoquery_plan_convert_join_to_inestá 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
JOINcom tabelasEmbeddedRocksDB,RediseKeeperMap, que podia retornar zero linhas silenciosamente quandoDirectKeyValueJoinera usado com chavesStringouNullable(String). #105253 (vdimir). - Corrigido um
LOGICAL_ERROR(“Unexpected expression in JOIN ON section. Expected boolean (UInt8), got ‘Nothing’”) quando um predicadoJOIN ... ONsem igualdade referencia uma coluna do tipoNothing, como a gerada porARRAY JOIN []. #106981 (groeneai). - Corrigido um erro lógico
Inconsistent AST formattingque 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.Nou 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, comoclusterAllReplicas(..., urlCluster(...)), agora é rejeitada com um erroBAD_ARGUMENTSem vez de falhar com um erro lógico (Distributed task iterator is not initialized). #107107 (groeneai). - Corrigida a falha da função de tabela
valuescomARGUMENT_OUT_OF_BOUNDao usar um literal decimal que não pode ser representado exatamente em uma coluna de ponto flutuante de menor precisão (como0.1em uma colunaFloat32), 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 comCASTeINSERT ... VALUES. #108055 (alexey-milovidov). - Corrigido o problema em que
mapFilter,mapSort(e suas variantes) emapConcatremoviamLowCardinalitydos tipos de chave e valor de umMap. Antes,mapFilteraplicado a uma colunaMap(LowCardinality(String), String)retornavaMap(String, String), o que podia corromper os metadados de uma tabela criada viaCREATE TABLE ... AS SELECTe fazer oCHECK TABLEfalhar. #108057 (alexey-milovidov). - Corrigido um
INSERTcancelado ou encerrado comKILLque continuava em execução por muito tempo durante a construção de um skip index (por exemplo, um índiceset(0)ilimitado em uma coluna de alta cardinalidade). Agora, a construção do índice é interrompida imediatamente quando a consulta é cancelada. #108351 (tiandiwonder). - Corrigido um
SELECTda função de tabelaprimesque não respondia ao cancelamento: com umstep(oulimit) grande, a consulta podia continuar em execução por muito tempo após umKILL QUERYou 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, comoquantileInterpolatedWeighted, 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 JOINmalformado, 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 colunasALIASduplicadas estruturalmente idênticas e, ao mesmo tempo, referenciava uma função de tabela com um argumento de named collection no formatokey = 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
LowCardinalitysobre uma tabela distribuída, por exemplo,concatAssumeInjective((SELECT toLowCardinality('p')), s)usado como chave deGROUP BYcomremote(). As mensagens eramDefault functions implementation for LowCardinality is supported only with a single LowCardinality argumentouExpected the argument ... to have N rows, but it has M. #108871 (groeneai). - Corrigido o problema em que
use_client_time_zoneera ignorado para literais de stringDateTime/DateTime64interpretados no servidor (INSERTassíncrono, literais emSELECT). Agora, quandouse_client_time_zoneestá habilitado, o cliente propaga seu fuso horário local comosession_timezone, de modo que o parsing no servidor fique consistente com o caminho doINSERTsíncrono. #109051 (groeneai). - Corrigido o problema em que
max_execution_time(comtimeout_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_BLOCKquando uma consulta sobre uma tabelaDistributedusa_shard_num(oushardNum()) que se tornaNullable(por exemplo, comFULL JOINejoin_use_nulls = 1) em conjunto comORDER 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 comenable_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 eraLowCardinality(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 emarrayFold(lambda, arr, another_lambda)). Comenable_analyzer = 0, essas consultas agora são rejeitadas comILLEGAL_TYPE_OF_ARGUMENTem vez de derrubar o servidor. #109840 (groeneai). - O alias
unnestdearrayJoinagora é rejeitado em filtros de ROW POLICY, eliminando uma brecha em que essa política podia gerar um erro lógicocolumn->size() == num_rowsdurante a leitura. #109973 (Algunenano). - Corrigido o problema em que índices de salto definidos em subcolunas
Tuplenão eram utilizados quando o campo era acessado viatupleElement(t, 'name'),tupleElement(t, N)out.Nenquanto 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 nomeadat.name. #110056 (groeneai). - Corrigido o erro
BAD_GETao comparar uma colunaArray(String)com um literal de array (arr = ['x']) quando a coluna possui um índice de exclusãotext,tokenbf_v1oungrambf_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_COLUMNindevido emALTER TABLE ... ADD COLUMN IF NOT EXISTSquando a coluna já existe no momento da aplicação. Isso acontecia quando a mesma coluna era adicionada duas vezes comIF NOT EXISTSem uma única instrução, ou quando umALTERconcorrente 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) quandoidentity()(ou o resultado de uma subconsulta escalar) envolve um valor que contém umLowCardinalityaninhado e a consulta usaWITH TOTALS/WITH ROLLUP. #110138 (groeneai). - Corrigido um erro
NOT_FOUND_COLUMN_IN_BLOCKao usarGROUP BY ALLsobre uma expressão de tupla junto comORDER BY. #110206 (alexey-milovidov). - Corrigido um erro
NOT_FOUND_COLUMN_IN_BLOCKao executarINSERTem uma tabela que possui uma restriçãoCHECKque referencia uma subcoluna (comox.nullde uma colunaNullableouarr.size0de umArray). #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_byalterava os resultados de consultas comGROUP BY GROUPING SETSeGROUP 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 deGROUPING SETSdo qual ela não é membro) ou para a linha deWITH 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 argumentoJSONcom 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 colunaMapcontinha chaves duplicadas, o resultado demap[key]podia depender de linhas anteriores no mesmo bloco e da configuraçãooptimize_functions_to_subcolumns, de modo que umSELECTe umWHEREsobre 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 cadeiaANDcompara uma coluna com uma constante de valor NULL de um tipo nãoNullable(por exemplo, umVariantcom valor NULL) comuse_variant_default_implementation_for_comparisons = 0. #111292 (groeneai). - Corrigidos resultados incorretos quando uma consulta tem um índice de salto
sete 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__bitWrapperFunce propagavaNULLem 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 TABLEcom o analisador aceitava uma expressãoDEFAULT/MATERIALIZEDde coluna que referencia uma coluna virtual, como_tableou_database. A inserção nessa tabela falhava comNOT_FOUND_COLUMN_IN_BLOCK, e uma colunaMATERIALIZED(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. ColunasALIAS(calculadas na leitura) e colunasEPHEMERAL(entradas de inserção não armazenadas) baseadas em colunas virtuais continuam funcionando. #111776 (groeneai). - Corrigido o erro
UNKNOWN_QUERY_PARAMETERquando uma view parametrizada é chamada com um argumento cujo valor é uma subconsulta do tipoArray,TupleouLowCardinality, 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 ...ehas(const_array, x)). Para uma expressãoVariantcomuse_variant_default_implementation_for_comparisons = 0, a reescrita alterava o tipo do resultado da expressão deUInt8paraNullable(UInt8), o que gerava umLOGICAL_ERRORna 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 comIllegal type ... of argument of function in, porqueINrejeita 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 constanteDateTimecom hora do dia comparada a uma colunaDate. #111924 (groeneai). - Corrigido o problema em que
quantileDeterministic,quantilesDeterministicemedianDeterministicretornavam 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 valorDynamic). 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 nem uma tabela com índicevector_similaritypodia registrar grânulos como não correspondentes a<condition>, fazendo com que uma consulta comumSELECT ... 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_bytedo plano de consulta serializado. Comserialize_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
JOINcuja expressãoONcontém uma conjunção constante, por exemploON 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çõesINNER,LEFT SEMIeRIGHT SEMIretornavam linhas correspondentes quando uma condição nunca verdadeira não deveria retornar nenhuma, eRIGHT ANTInã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. Comenable_analyzer = 0, e emEXPLAIN SYNTAXcom as configurações padrão, chamadas comopv(concat(name, '!')),pv(name, 'a'),pv(name != 'a')epv(tuple(name = 'a'))vinculavam silenciosamente um parâmetro da view a uma expressão não relacionada, em vez de reportarUNKNOWN_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 VIEWouCREATE FUNCTIONcuja definição chamasubstr,midoubyteSliceem uma forma que a gramática desubstringnã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 comSYNTAX_ERRORe, 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 formatosubstring(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 BYem ordem errada e uma exceçãoBAD_TYPE_OF_FIELDquando a chave primária é umArrayouTuplee a consulta aplicaplus,minus,multiply,divideouintDiva 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 contendoPASTE JOINé enviada a outro servidor, por exemplo, quando a tabela à esquerda é uma tabelaDistributedou uma função de tabela*Cluster. O formatador geravaALL 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)ouWITH t(x) AS (SELECT 1), não ficava visível dentro da função de tabelaview: uma referência at.xfalhava comUNKNOWN_IDENTIFIER, embora a mesma construção funcione fora deview. #112690 (groeneai). - Corrige um erro lógico na formatação de consultas quando uma cláusula
ARRAY JOINnão contém expressões. Agora essa cláusula é rejeitada na análise sintática comSYNTAX_ERROR, de forma consistente com umUSINGvazio, em vez de ser aceita e formatada como um texto que não pode ser analisado novamente. #112699 (groeneai). - Corrigido o problema em que
connectionIdlançavaContext has expiredquando 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 ONsem igualdade (non-equi), avaliada durante a junção, contémarrayJoin. Uma junçãohash,parallel_hashougrace_hashagora rejeita essa condição comINVALID_JOIN_ON_EXPRESSION. Quando a expansão depende de apenas um dos lados, mova-a para umARRAY JOINem uma subconsulta antes da junção; uma condição cujo argumento dearrayJoinlê colunas de ambos os lados precisa ser reestruturada. #112889 (groeneai). - Corrigido o problema em que
geohashesInBoxlevava um tempo ilimitado para processar um retângulo de área zero, comogeohashesInBox(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 tantomax_execution_timequantoKILL QUERY. #112976 (groeneai). - Rejeita uma alteração de
SETTINGSmarcada como escrita sem valor quando ela contém um valor diferente detrue, 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çãoBoolcomfalse, enquantosystem.query_logeformatQueryFromJSONexibiam a forma sem valor. #113025 (alexey-milovidov). - Corrigido
UNKNOWN_IDENTIFIERao consultar umaVIEWcujos tipos de coluna declarados diferem dos tipos produzidos por sua consulta interna, por exemploSELECT sum(length(arr)) FROM v, em quevdeclaraarr Array(UInt8)sobre uma colunaString. Com o valor padrãooptimize_functions_to_subcolumns = 1, o otimizador reescrevialength(arr)como uma leitura da subcolunaarr.size0e 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
postgresqle 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çãoCOPYcomeçar a ser executada ainda pode ser descartado. #113150 (groeneai). - Corrigido um
LOGICAL_ERROR(Next task callback is not set for query) quando uma viewSQL SECURITY DEFINERouSQL SECURITY NONEsobre uma função de tabela de cluster (s3Cluster,urlCluster,fileCluster) era lida como consulta secundária, por exemplo por meio deremoteouclusterAllReplicas. 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 expressionquando uma função de tabela da família remote com um argumentoview(...)é usada no lado esquerdo de umJOIN ... USINGcuja chave é um alias da lista doSELECT, comanalyzer_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 filtrasystem.databasespela colunanamecom uma subconsulta dentro deindexHint, por exemploSELECT count() FROM system.databases WHERE indexHint(name IN (SELECT 'foo')). Essa consulta era rejeitada com umLOGICAL_ERRORem 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
Variantignoravamax_execution_timeeKILL QUERY. Chamar uma função com vários argumentosVariantresolvia 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 COLUMNcomCannot specify codec for column type ALIASquando uma mesma instrução transforma uma colunaALIASem física (DEFAULTouMATERIALIZED) e especifica umCODEC. #113853 (groeneai). - Corrigida uma falha do servidor ao fazer junção com uma expressão
ONconstante quando o lado direito contém umARRAY JOIN. A leitura de uma coluna do lado direito replicada de forma lazy usava umColumnReplicatedjá liberado. #113901 (groeneai). - Corrige um vazamento de memória com
optimize_aggregation_in_order = 1quando a sorting key da tabela é um prefixo estrito da chave doGROUP BYe é usada uma função de agregação cujo estado aloca memória no heap, comoquantileDD. A memória do servidor crescia a cada consulta desse tipo até a reinicialização. #114010 (groeneai). - Corrigido o problema em que
isProbablePrimeemUInt128/UInt256ignoravamax_execution_timeeKILL 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áusulaPREWHEREcontém um predicadoIN (subquery)erewrite_in_to_join = 1(oumake_distributed_plan = 1, que o habilita obrigatoriamente) está definido. A mesma consulta escrita comWHEREfuncionava corretamente. #114067 (RohithPariki). - Corrigido um
LOGICAL_ERRORemarrayAutocorrelationquando o argumento é um array não vazio cujo tipo de elemento éNothing, por exemplo,SELECT arrayAutocorrelation([arrayMax([])]). Esse tipo de argumento agora é rejeitado comILLEGAL_COLUMN. O literal de array vazio[]continua retornando[]. #114249 (groeneai). CREATE TABLEeALTER TABLEagora rejeitam codecs com perdas, comoSZ3, em colunas usadas na sorting key. #114531 (groeneai).- Corrigido um loop infinito e não cancelável nas funções
hopewindowIDquando 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 umaWINDOW VIEWem 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 subconsultaINque 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
INSERTem uma tabelaLog,TinyLogouStripeLogque 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 tabelaLogouTinyLogcuja 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 tipoArray(Map(...)), comohas([map('k', 'v')], m), executadas sobre uma tabelaDistributedou 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_NAMEdurante o planejamento. #116152 (groeneai). - Corrigida uma exceção em subconsultas correlacionadas quando colunas externas se tornam
Nullablecomgroup_by_use_nullsem ROLLUP/CUBE. #100365 (alexey-milovidov). max_replication_lag_to_enqueue = 0passa a ser rejeitado em bancos de dadosReplicated. Esse valor tornava trivialmente verdadeira a verificação de dessincronização pós-recuperação e abortava o servidor comLOGICAL_ERRORem builds de depuração e com sanitizador. Agora,0é rejeitado durante a análise comBAD_ARGUMENTS, independentemente da origem (CREATE DATABASE ... SETTINGS, bloco de configuração do servidor<database_replicated>, reaplicação deATTACHe 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_EXISTScom 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çãogeohashesInBoxquando seus argumentos de coordenadas misturavam valores constantes e não constantes, ou quando uma coordenada eraBFloat16. ArgumentosFloat32que misturam valores constantes e não constantes agora funcionam, e argumentosBFloat16são rejeitados com um erro claro. #107063 (groeneai). - Corrigido o cabeçalho de
CSVWithNameseCSVWithNamesAndTypes, que tinha menos colunas que os dados quandooutput_format_csv_serialize_tuple_into_separate_columnsestá habilitado (o padrão). O cabeçalho (e a linha de tipos) agora achata colunasTupleem 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ão1), controla esse comportamento e pode ser definida como0para restaurar o cabeçalho anterior com nome único. #107371 (groeneai). - Corrigido um vazamento de memória no
mongo-c-driverempacotado, que podia ocorrer ao ler do MongoDB (por exemplo, por meio de um dicionário MongoDB ou da função de tabelamongodb) 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 quandopointInPolygoné chamada com um argumento de polígono constante de um tipo encapsulador, comoVariantouDynamic(por exemplo,pointInPolygon((x, y), if(c, [(0, 0), ...], NULL))). #107589 (groeneai). - Corrigidos erros lógicos (
Bad cast) causados pela remoção inconsistente deLowCardinalityaninhado em colunasVarianteDynamic, por exemplo emconcat,formate 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
accurateCastOrNullde umaTuplecujo elemento éDynamic/Variant: umNULLlegítimo na origem era tratado como falha de conversão. Para um elemento de destinoNullable, umNULLna origem agora permanece comoNULLno elemento (assim como ocorre com uma origemTuple(Nullable(...))simples); para um elemento de destino nãoNullable, umNULLna origem agora torna nula a tupla inteira (assim como ocorre na referência semDynamic), 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
mongodbagora aceitaoid_columnspassado como argumento nomeado (por exemplo,oid_columns='_id'), em vez de rejeitá-lo comBAD_ARGUMENTS. #108039 (alexey-milovidov). - Permite consultar um dicionário
range_hashedoucomplex_key_range_hashedque usa um intervalo do tipoDateTime64,Decimalou de ponto flutuante com um argumento correspondente emdictGet/dictHas. Antes, essas consultas falhavam commust be convertible to Int64, e intervalos abertos em faixasDecimal/DateTime64retornavam incorretamente o valor default. #108052 (alexey-milovidov). - Corrige um aborto do servidor (
Logical erroremIColumn::insertFrom) ao converter umArray(Dynamic)ouArray(Variant)paraQBitcomaccurateCastOrNull, 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 campoinitial_addressdeClientInfoagora é validado como umhost:portnumérico antes de ser interpretado, em vez de permitir que uma porta não numérica chegue à funçãogetservbynameda 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/sequenceCountegroupArrayIntersect. 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 comTOO_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 usargroup_by_use_nullscom uma chave de agrupamento constanteLowCardinalityemGROUPING SETS/ROLLUP/CUBE. #108771 (alexey-milovidov). - Corrigido
TYPE_MISMATCHemmapFilter,mapSort,mapReverseSort,mapPartialSortemapConcatquando um valorMapcontém umMapaninhado comLowCardinality, 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 dadoTupleque mistura elementos nomeados e não nomeados (por exemplo,Tuple(a UInt8, UInt16)). #108915 (groeneai). JSONExtractagora respeitacast_string_to_date_time_modeao converter valores JSON do tipo string paraDateTime/DateTime64, de forma consistente comCAST. #109252 (Utkal059).- Corrigido o uso de
INcom uma coluna de array simples como argumento à direita, que retornava silenciosamente um resultado incorreto (sempre falso) ou lançava uma exceção; agorax IN arrse comporta comohas(arr, x). #109416 (alexey-milovidov). - Corrigido um
LOGICAL_ERRORemarrayFoldaplicado a um argumentoArray(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_COLUMNemconvcom a conversão correta de argumentosFixedStringparaString. #109771 (hp77-creator). - Corrigidos resultados incorretos em leituras de funções de tabela com
FINAL/SAMPLEquandoserialize_query_plan = 1e 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/0como valoresBooldentro de tipos contêiner (por exemplo,Array(Bool),Tuple(Bool, ...)). Antes,[1,0]falhava comCANNOT_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 índicetexté construído sobreArray(LowCardinality(Nullable(String)))(incluindo camposNestedarmazenados dessa forma) e um array indexado contém um elementoNULL. ElementosNULLde arrays agora são ignorados durante a construção do índice, assim como já ocorria comArray(Nullable(String)). #110055 (groeneai). - Corrigidos resultados incorretos de
subBitmap,bitmapSubsetInRangeebitmapSubsetLimitpara bitmaps ainda armazenados na representação pequena, incluindo valores de elementosUInt64eInt64acima de2^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 bitmapInt8, o elemento-1é comparado como255, e não como o valor com extensão de sinal4294967295. Isso também corrigebitmapMin,bitmapMax,bitmapContainsebitmapTransformem bitmaps que já ultrapassaram a representação pequena. Consultas que passavam limiares com extensão de sinal precisam ser ajustadas: em um bitmapInt8,bitmapSubsetInRange(bm, 4294967168, 4294967296)passa a serbitmapSubsetInRange(bm, 128, 256). Também foram corrigidos ogroupNumericIndexedVector, que retornava resultados diferentes para colunas de índiceInt8eInt16em relação a tipos de índice mais largos, e onumericIndexedVectorGetValue, que retornava0para í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 embitmapBuild/bitmapToArray. #110072 (RamiDarwiche). - Corrigidos caminhos de overflow com sinal indefinido na aritmética de intervalos em
WITH FILL STEPdo tipo intervalo e nas funções de intervalo de data/horaadd*/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 deWITH FILLdo tipo intervalo com um passoYEARmuito 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_ARGUMENTquando os operandos não tinham um supertipo comum mínimo. Arrays comoArray(Int64)vsArray(UInt64)eArray(Int256)vsArray(UInt256)agora podem ser comparados lexicograficamente com=,!=,<,<=,>,>=,IS DISTINCT FROMeIS NOT DISTINCT FROM. Comparações compatíveis comNULL, comoisDistinctFrom/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 elementosTuple(Nullable(...))aninhados. #110245 (diegomestre2). - Corrigido um overflow de inteiro com sinal (UBSan) ao converter um valor
DateTime64extremo (por exemplo,INT64_MIN) paraTime/Time64em 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 valoresUInt64acima deInt64::max()paraDateTimeeTimeagora 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 paraDatedetoDatee às conversões deUInt64e de inteiros largos ((U)Int128,(U)Int256) paraDateeDate32, que podiam retornar um dia anterior à época em vez de saturar. A conversão de um número paraTimeagora 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 paraTimenão rejeita mais os valores negativos suportados porTime, nem satura silenciosamente os valores que não cabem nele. O cast preciso de um número paraDate32(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 retornaNULL, como já acontecia comDateeDateTime, e as variantesOrDefaultretornam o valor default deDate32para esse tipo de entrada. O cast preciso de um número de ponto flutuante não inteiro paraDate,Date32,DateTimeouTimeagora é rejeitado em vez de ser truncado silenciosamente. Também foi corrigida a documentação da funçãotoDateTime32, que exibia por engano exemplos detoDateTime64e descrevia o intervalo de valores deDateTime64. #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 comoutput_format_orc_dictionary_key_size_thresholdhabilitado. #110492 (tiandiwonder). - Corrigido um erro lógico (
Function node with name '...' is not resolved as ordinary function) que podia ocorrer comoptimize_or_like_chainhabilitado quando uma função de agregação ou de janela aparecia no lado esquerdo de umLIKE/ILIKE/matchdentro de uma cadeia deOR. #110641 (groeneai). - Corrigido um overflow de inteiro com sinal em
toStartOfIntervalao usar uma contagem extrema de intervaloMONTH,WEEKouDAYcom valoresDate/Date32/DateTime64. #110688 (groeneai). - Corrigido o problema em que
readWKTereadWKTPointretornavam coordenadas não inicializadas (versão escalar) ou desatualizadas de uma linha anterior (versão vetorizada) paraPOINT EMPTY.POINT EMPTYagora é rejeitado comCANNOT_PARSE_TEXT, já que umPointdo ClickHouse é umTuple(Float64, Float64)fixo, sem representação vazia. #110692 (groeneai). - Corrigido o problema em que
flipCoordinatesperdia o tipoGeometry: para um argumentoGeometry, o resultado volta a ser do tipoGeometryem vez doVariant(...)subjacente, podendo ser passado diretamente para funções comoareaCartesian. #110694 (groeneai). - Corrigida a serialização WKB não canônica de um polígono vazio:
wkb(POLYGON EMPTY)agora emitenumRings = 0em 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/0na análise deBoolem JSON agora respeitam a configuraçãoallow_special_bool_values. Antes, uma entrada JSON como{"v":1}paraVariant(Bool, UInt32)era lida comoBoolmesmo comallow_special_bool_values_inside_variant = 0, porque os parsers deBoolem JSON ignoravam a configuração eBooltem prioridade de desserialização emVariantmaior que os tipos inteiros. #110835 (groeneai). - Corrigido
throwIf(notLike(col, pattern))(e outros usos dethrowIfsobre uma função), que lançava exceção incondicionalmente quandocoleraLowCardinality. A implementação padrão deLowCardinalityexecutavathrowIfsobre 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 faziathrowIflanç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
-Tupleera usada comRESPECT NULLSe 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 tipoAggregateFunctionserializado 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,MULTIPOINTou o genéricoGEOMETRY) por meio da função de tabelamysqlou dos motores de tabela/banco de dadosMySQL. Essas colunas agora passam a usarNullable(String)como fallback, armazenando o valor tal como o MySQL o retorna (um prefixo SRID de 4 bytes seguido pelo payload WKB).POINTcontinua sendo mapeado paraNullable(Point). #110943 (groeneai). - Corrige a serialização
Nativede wrappersSimpleAggregateFunctionque contêm estados de agregação versionados ao se comunicar com pares de versões mais antigas. #110997 (groeneai). - Corrige o erro
CANNOT_CONVERT_TYPEpara constantes do tipoVariant(incluindoGeometry) 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 é umif/multiIfcom condição constante que mistura um ramo com literalBoole um ramo de comparaçãoUInt8, por exemplo,arrayFilter(p -> multiIf(false, true, p = 'ALL'), ['ALL']). #111245 (groeneai). - Corrigido um overflow de inteiro com sinal em
toStartOfIntervalcom intervalos de subsegundos: para valoresDateTime64situados a menos de um intervalo do limite inferior deInt64, o resultado arredondado dava a volta silenciosamente e virava um valor positivo sem sentido; agora a função lança uma exceçãoDECIMAL_OVERFLOW. #111370 (alexey-milovidov). - Corrigida uma exceção (
CANNOT_CONVERT_TYPEou um erro lógico) em consultas distribuídas que usam o combinador-Tuplecom um modificadorRESPECT NULLS/IGNORE NULLSsob combinadores aninhados, por exemplo,anyRespectNullsStateTuple(...) IGNORE NULLS. #111570 (alexey-milovidov). - Corrige uma tentativa de interpretação de texto de
FixedStringque deixa bytes parcialmente anexados na coluna quando a interpretação falha, o que pode causar o erro lógicoSizes of nested column and null map of Nullable column are not equaldurante a serialização de colunasVariant/Array/Nullableou 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
JSONouDynamic) por meio de uma tabelaBuffer. #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 argumentooriginpróximo ao limite inferior deInt64, 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 como1/0, em vez detrue/false, uma constanteBoolnão literal (por exemplo,CAST(true, 'Nullable(Bool)')) inserida em uma colunaString/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,quantileStateequantilesState(0.9)combinados por umUNIONou produzidos viaarrayReduce. 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,18446744073709551617virava1) em vez de serem rejeitados, e um númeroUInt64acima do máximo deInt64não sobrevivia a uma conversão de ida e volta entre AST e JSON. #112904 (alexey-milovidov). - Corrigida a conversão de uma constante
Boolno lado direito deINpara um lado esquerdoStringcomo'1'/'0'em vez dos valores canônicos'true'/'false'(agora consistente comCASTe com a função de tabelavalues). #113051 (yakov-olkhovskiy). - Corrige a formatação inconsistente da AST de
viewIfPermitted: uma função normalmente escrita como operador (por exemplo,not) no ramoELSEda forma de função de tabela, e a forma de expressãoviewIfPermitted(...)sendo formatada incorretamente comELSE. #113652 (alexey-milovidov). - Corrige comportamento indefinido e resultados incorretos em
avgsobreDate/DateTime/DateTime64/Time/Time64: a média agora é calculada de forma exata no espaço de inteiros, corrigindo tanto o overflow no limite deInt64(UB, resultado incorreto em x86) quanto a perda de precisão deFloat64acima 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,mapContainsValueemapContainsretornavam menos linhas do que o esperado, ou falhavam comTOO_LARGE_STRING_SIZE, quando um índicebloom_filterera consultado com uma constanteFixedString. 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
minemaxem colunasDateTime64retornavam resultados incorretos quando a agregação era compilada via JIT e os dados continham timestamps anteriores a 1970.is_signednão era especializado paraDateTime64eTime64, que derivam deDecimal64; assim, o código gerado comparava as contagens de ticks como inteiros sem sinal, e um timestamp anterior a 1970 vencia emmaxe perdia emmin. #114168 (groeneai). - Corrige o problema em que
arrayExists(x -> x = needle, arr)retornava um resultado incorreto, ou falhava comTOO_LARGE_STRING_SIZE, quando o elemento do array e o needle eram de tipos de string diferentes (por exemplo, um needleStringcomparado a um elementoArray(FixedString(N))). A otimizaçãooptimize_rewrite_array_exists_to_has, habilitada por padrão, reescrevia essa chamada comohas, 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/ILIKEaplicado sobre contêineres Map ou JSON. #114544 (ahmadov). - Corrige comportamento indefinido e resultados incorretos nos limites em
quantileequantilespara valoresDateTime64eDecimallargos. #114919 (alexey-milovidov). - Corrige o problema em que
ifemultiIfretornavam um valor positivo grande em vez de um negativo quando um ramoTimeera combinado comTime64,DateTimeouDateTime64e a expressão era compilada via JIT. #115146 (groeneai). - Corrige o problema em que
timezoneOffset(aliastimeZoneOffset) 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, comoPacific/KiritimatiePacific/Apiaapós cruzarem a linha internacional de data, e para a maioria dos fusos antes de 1970. Isso também corrigeparseDateTime,parseDateTimeOrNull,parseDateTime64,parseDateTimeInJodaSyntax,EXTRACT(TIMEZONE_HOUR / TIMEZONE_MINUTE ...), o%zdeformatDateTime,toUTCTimestampefromUTCTimestamp, que utilizam esse deslocamento. #115332 (groeneai). - Corrigido o erro
Code: 349. Cannot convert NULL value to non-Nullable typequando um predicadohasounotHascontém um elemento de array NULL e a chave primária é do tipoString,Array(String)ouMap(String, String). Também foram corrigidos resultados incorretos quando esse elemento é umDynamicouVariantcontendo 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_nullablenão preservava a nulabilidade quando o tipo de destino eraLowCardinality. Converter um valor que admite NULL paraLowCardinality(T)lançavaCANNOT_INSERT_NULL_IN_ORDINARY_COLUMNem vez de produzirLowCardinality(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
DEFAULTe não está materializada em uma parte (por exemplo, apósALTER TABLE ADD COLUMNou duranteALTER TABLE MATERIALIZE COLUMN): a subcoluna era preenchida com os valores padrão do tipo em vez do resultado da expressãoDEFAULT, e as funções de distância vetorial transpostas (cosineDistanceTransposede outras) aplicadas a essas colunasQBitfalhavam com o erroSIZES_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 subconsultaINdurante a análise da chave primária falhava silenciosamente (por exemplo, por timeout da subconsulta comoverflow_mode = 'break'), fazendo com que o set nunca fosse construído para o pipeline da consulta. #107924 (alexey-milovidov). - Corrigida a falha de um
SELECTcomNOT_FOUND_COLUMN_IN_BLOCKem uma tabela que possui um índice de exclusão de dados do tiposetquando 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). getClientHTTPHeaderagora é 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 comuse_skip_indexes = 0,ignore_data_skipping_indicesou um modo diferente deuse_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 executarSYSTEM STOP VIEWnela, 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 erroSubplan cannot be used to build pipelinee o erro lógicoTrying to extract chunk from ChunkBuffer before all inputs are finishedemIN (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_BLOCKnas funções de distância transpostas sobre colunasQBit(comocosineDistanceTransposed) 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çãooptimize_empty_string_comparisonsreescreve a comparação paranotEmptyapenas no lado da consulta. #112115 (Ergus). - As colunas não são mais removidas quando referenciadas tanto nas condições de filtro
PREWHEREquanto nas deWHERE, mesmo que sejam reescritas como uma coluna virtual de índice de texto. #114460 (ahmadov). - Corrigido o erro lógico
Multi-block postings must be compressedem 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
WHEREcontinha uma expressãoNULLdentro de umNOT, 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, eALTER TABLE ... DELETEcom 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 JOINfull_sorting_mergecomquery_plan_join_shard_by_pk_rangeshabilitado 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 existsquando uma única instruçãoALTER TABLEcombinavaRENAME COLUMNcom outro comando, comoMODIFY SETTING, em uma tabela com índices minmax implícitos (add_minmax_index_for_numeric_columnse similares). Além disso, renomear uma coluna comum não faz mais com que umDROP COLUMNsubsequente falhe comUNKNOWN_IDENTIFIER, nem que umADD COLUMNsubsequente fique sem seu índice implícito. #116063 (groeneai). - Um padrão
LIKE/NOT LIKEsem 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çãoIN/NOT INna chave primária envolve a chave emintDivpor uma constante e a chave é um inteiro sem sinal cujos valores ultrapassam o limite com sinal do tipo de resultado deintDiv(por exemplo,intDiv(uint64_column, -9223372036854775807)). #107586 (groeneai). - Corrigido o retorno de resultado vazio por
numericIndexedVectorPointwiseMultiplyao 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 = 1sobre muitos tokens curtos distintos. #108659 (groeneai). - As expressões
preprocessorepostprocessorde um índice de texto agora podem referenciar colunasALIAS. #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
ILIKEquando o índice é definido sobre uma expressão em vez de uma coluna simples (por exemplo,assumeNotNull(col)com um pré-processadorlower(...)). 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 comvector_search_with_rescoring = 1em 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_similaritycom quantizaçãoi8(antes, esses vetores provocavam comportamento indefinido no usearch e geravam dados inválidos silenciosamente). #111085 (groeneai). - Corrigidas leituras de dados inativos em disks
plain_rewritablecom o page cache habilitado. #111105 (Michicosun). - Corrigidos resultados incorretos de
count()e linhas descartadas quando uma chave ou índice de exclusão minmaxString(ouFixedStringmais estreito) é filtrado por uma comparação com uma constanteFixedStringmais 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_ERRORem vez deINCORRECT_DATA. Agora, o índice de offset é validado no momento da leitura. #114530 (groeneai).
Correções de segurança, acesso, backup e restauração
RESTOREagora executa fsync nos arquivos das partes restauradas quando a tabela de destino temfsync_after_inserthabilitado, 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 oRESTOREretornarRESTOREDpodia 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égioALTER UPDATEalém deALTER DELETE. Um usuário que tenha recebido apenasALTER DELETEagora pode executarDELETE FROM, conforme documentado. #107491 (tiandiwonder). - Corrigido o
CREATE TABLE ... AS SELECTem 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 executarSELECT count()(ou outras consultas triviais) em uma tabela na qual o usuário tem acessoSELECTapenas a uma colunaALIAS. #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_addressestá 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(eSQL 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 comACCESS_DENIED, embora a mesma view funcionasse com o analisador habilitado. #111458 (groeneai). - Corrigido um defeito nas integrações
MySQLem que a substituição de uma credencial TLS de uma coleção nomeada por um valor vazio dessl_ca_pem/ssl_cert_pem/ssl_key_pemera 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 comSQL SECURITY DEFINERouSQL SECURITY NONEcujo corpo contém um JOIN. Em builds de debug e com sanitizers, a consulta era abortada com o erro lógicoJoinStep analyzed without the analyze mode. #115156 (groeneai). - Corrige
RESTORE ... AS <new name>, que deixava a listaREFRESH ... DEPENDS ONde 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_ERRORdurante o backup de um banco de dadosReplicatedque está sendo removido e recriado simultaneamente; esses backups agora falham de forma limpa comCANNOT_GET_REPLICATED_DATABASE_SNAPSHOT. #100651 (alexey-milovidov). GRANT role TO roleaplicado à mesma função agora é rejeitado comBAD_ARGUMENTS, em vez de criar silenciosamente uma entrada autorreferencial emsystem.role_grants. #103315 (zxuhan).- O
BACKUPde um banco de dadosMaterializedPostgreSQLnã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 aoReplacingMergeTreesubjacente), que podem ser restaurados como umReplacingMergeTreeindependente. #107433 (alexey-milovidov). - Permite
EXISTS <dictionary>para um usuário que tem apenas o privilégioSHOW DICTIONARIESsobre o dicionário (antes era necessárioSHOW 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 umRESTOREa 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
constAccessRights::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 formattingemALTER TABLE ... MOVE PART ... TO SHARD '<path>'. O formatador de consultas descartava a palavra-chaveSHARD, de modo que a consulta reformatada não podia ser interpretada novamente, gerando umLOGICAL_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 tabelaDistributeddefinida com um nome de banco de dados remoto vazio é usada em um JOIN comdistributed_product_mode = 'local'. #110677 (groeneai). - Corrigido o retorno de linhas incorretas por
DISTINCTcomLIMIT/OFFSETordenado quando a indicação de limite de parada antecipada do DISTINCT não conseguia delimitar o início do resultado: umLIMITnegativo (retornava o início em vez do final), umLIMIT/OFFSETfracionário (a fração só é resolvida após uma leitura completa) e umOFFSETisolado semLIMIT(o final após o deslocamento era descartado). Por exemplo,SELECT DISTINCT intDiv(x, 100) FROM t ORDER BY intDiv(x, 100) LIMIT -1em 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 umINSERTconcorrente enquanto umALTER RENAME COLUMNestava em andamento em um banco de dadosAtomiccomlazy_load_tables = 1apósDETACH DATABASE/ATTACH DATABASE. #104852 (groeneai). - Corrige a corrupção de nomes de colunas e a exceção
BAD_ARGUMENTScausadas pela configuraçãoinject_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, emCREATE 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 deDatabaseOrdinary::startup_tableeload_tableao desanexar. #106238 (groeneai). - Corrige os motores de tabela e de banco de dados
MaterializedPostgreSQLpara 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_TABLEquando uma consulta com réplicas paralelas seleciona uma colunaALIASde uma tabela enviada como tabela temporária deGLOBAL JOIN,MULTIPLE_EXPRESSIONS_FOR_ALIASquando ambos os lados de umJOINdistribuído declaram uma colunaALIAScom o mesmo nome, eUNKNOWN_IDENTIFIERquando uma tabelaDistributeddeclara uma colunaALIASbaseada em outra colunaALIAS, inclusive como chave deJOIN 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_retriesdefinido como um valor muito grande (próximo ao máximo deInt64). 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 dadosClickHouselocal 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
Hivesem cláusulaWHERE, 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
MATERIALIZEDainda não materializada como tabela externa e a fonte remota era criada sob demanda (fonte adiada). O crash era causado pela desreferência de umLoggernulo dentro deRemoteQueryExecutor::sendExternalTables(). #108547 (groeneai). - Corrigido um erro lógico (
Equal values are not contiguous within the range assumed to be sorted) ao executarDISTINCTsobre uma leituraSTREAM(SELECT DISTINCT ... FROM table STREAM). As otimizações de leitura em ordem não são mais aplicadas a leiturasSTREAM, 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 columne, em compilações debug/com sanitizador, um abort do servidor) quando a chave de sharding de uma tabelaDistributedé uma expressão que o analisador reduz a uma constante, por exemplo,if(1, toInt32(id), toInt32(id) + 1), comoptimize_skip_unused_shards = 1. #108737 (groeneai). - Corrigido um abort do servidor (
LOGICAL_ERROR/ asserção em compilações debug e com sanitizador) quando umINSERT ... SELECTpor meio de uma tabelaAliasé cancelado sem exceção, por exemplo, comtimeout_overflow_mode = 'break'. #108783 (groeneai). - Corrigido um abort do servidor (
LOGICAL_ERROR/ asserção em compilações debug e com sanitizador) quando umINSERT ... SELECTem uma tabelaTimeSeriesé cancelado sem exceção, por exemplo, comtimeout_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 CTEMATERIALIZEDé 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 noWHERE) em uma consulta sobre uma tabelaDistributed. 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_setcolumn in header of MergingAggregatedTransform with grouping sets”, ou “Chunk info was not set for chunk in MergingAggregatedTransform”) que podia ocorrer, sem o analyzer, em umUNION ALL/INTERSECT/EXCEPTem que um ramo usaGROUP BY GROUPING SETScom réplicas paralelas e outro ramo usaFINAL. #109003 (groeneai). - Corrige a falha de
CREATE TABLE ... AS SELECT FROM s3Cluster(...)(e de outras funções de tabela de cluster, comofileCluster/urlCluster) comNOT_FOUND_COLUMN_IN_BLOCKdentro de um banco de dadosReplicated. #109266 (groeneai). - Corrigido um erro (
NOT_FOUND_COLUMN_IN_BLOCK, oustd::bad_function_callem versões mais antigas) ao executarCREATE TABLE ... ON CLUSTER ... AS SELECTcom leitura de uma tabelaDistributedem 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 operadorIN; 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 executarSELECT ... ORDER BY ... WITH FILLem uma tabelaDistributedcom um valor baixo deoptimize_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 quandoquery_plan_merge_expression_into_joinestá habilitado. #110227 (groeneai). - Corrige um raro
Logical error: 'No more packets are available.'gerado em uma consulta distribuída válida comLIMIT, 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 colunaFixedStringretornava0em vez do tamanho fixoNcom réplicas paralelas quando a consulta tinha um filtro seletivo. #110427 (groeneai). - Corrige o erro
NOT_FOUND_COLUMN_IN_BLOCKem consultas com uma subconsulta emFROMquando réplicas paralelas são executadas no modocustom_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 comNot 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 executarEXPLAIN ANALYZEsobre 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 deWHERE ... IN (...)ou de uma CTE) ou oculta por trás de uma view comum ou parametrizada. Agora,EXPLAIN ANALYZErejeita essas consultas comNOT_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 umRIGHT JOINquandoparallel_replicas_min_number_of_rows_per_replicaestá definido e uma coluna da tabela à esquerda é projetada. #111332 (groeneai). - Corrige uma condição de corrida em UDFs executáveis, no mecanismo de tabela
executablee em dicionários executáveis, em que umfcntlsobre um descritor de arquivo já fechado podia corromper um descritor não relacionado de uma consulta concorrente (removendoO_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 — emORDER BY ... WITH FILL ... INTERPOLATEsobre uma tabelaDistributedcom dois ou mais shards, sobreclusterAllReplicasou 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 ... SYNCquando uma consulta sobresystem.replicashavia 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 exemploSELECT count() FROM t1, t2, t3, t4 WHERE (t1.b = t2.b) AND (t3.a = t4.a)comquery_plan_optimize_join_order_limitdefinido como0ou1. #112205 (groeneai). - Corrige o erro lógico
Cannot add step Expression to QueryPlan because it has incompatible header with root step JoinLazyColumnsStepem consultas comFINAL, um filtroPREWHERE, umLIMITpequeno emake_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
toDecimal32ou o fuso horário detoDateTime, 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, eCREATE VIEWeCREATE MATERIALIZED VIEWpersistiam um tipo de coluna incorreto. #112492 (groeneai). - Corrige um erro lógico e um registro de dependência incorreto quando o corpo de uma
VIEWcomum referencia uma tabela ou dicionário por meio de um parâmetro de consulta, como emCREATE 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çãoONcontém uma condição que referencia colunas de ambas as tabelas, por exemploON (t.key = j.key) AND (t.a < j.a). Essa consulta agora é rejeitada com uma exceção clara, em vez de gerarrequired columns: ... but not found any in left tableoustd::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 AFTERenorme. Os atrasos agora são limitados ao maior valor representável, em vez de causarem overflow. #113041 (groeneai). - Corrigido o erro reportado quando um
INSERTassíncrono em uma tabelaDistributedprecisa de um diretório de fila cujo nome excede o limite de 255 bytes do sistema de arquivos (o que pode ocorrer comuse_compact_format_in_distributed_parts_names = 0). Antes, era gerado umLOGICAL_ERRORpara um shard cominternal_replicatione, nos demais casos, umCode: 1001. std::exceptionsem identificação da origem; agora ambos reportamARGUMENT_OUT_OF_BOUND, informando a tabela, o cluster e o limite. #113083 (groeneai). UNDROP TABLEagora pode ser interrompido porKILL QUERYenquanto aguarda que as consultas em execução liberem a tabela removida. #113263 (alexey-milovidov).- Corrigidos um travamento permanente de
DROP TABLEe 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 definedistributed_plan_execute_locallyem sua própria cláusulaSETTINGScommake_distributed_planativo. 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 SELECTcujoSELECTde preenchimento falhava não podia ser encerrado quandodatabase_atomic_wait_for_drop_and_detach_synchronouslyestava habilitado: oDROPinterno de limpeza da tabela temporária aguardava a fila de remoção em segundo plano e ignorava tantoKILL QUERYquantomax_execution_time. #113504 (groeneai). - Corrige resultados incorretos e, em builds com asserções habilitadas, uma falha de asserção em um
JOINcom um dicionário cuja cláusulaONpossui uma condição de não igualdade envolvendo ambas as tabelas, comoON (t.key = d.key) AND (t.a * 10 < d.a), quandojoin_use_nullsestá 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_FUNCTIONou retornava silenciosamente linhas de outra view. AfetaIN,JOINeremote()por meio de uma tabelaDistributed. #113550 (groeneai). - Corrigido o erro
Unsupported JOIN keys of type keys256 in StorageJoinao ler uma tabela com engineJoincuja chave é composta (várias colunas) ou um único valor de 16/32 bytes, comoUUID,Int256ouFixedString(4). Essa tabela podia ser criada, receber gravações e ser usada em junções, mas nunca podia ser lida comSELECT. #113578 (groeneai). - Corrigido o erro lógico
Sending a distributed query with unknown (zero) client versionquando uma tabelaDistributedsem 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_ERRORquando umSELECTusava o modificadorSTREAMem uma tabela nomeada em conjunto com réplicas paralelas no modo de tarefas de leitura. Com uma CTE materializada usada como set deINemPREWHERE, o servidor lançavaReading from materialized CTE ... DelayedPortsProcessor gate is missing in the query plan(um abort do servidor em compilações debug e com sanitizador). Uma tabela comSTREAMagora é rejeitada quando réplicas paralelas são solicitadas: comenable_parallel_replicas = 2, a consulta falha comSUPPORT_IS_DISABLED; com1, ela é executada sem réplicas paralelas, exatamente como já acontece comFINAL. #113754 (groeneai). - Corrigida a complexidade quadrática na análise do argumento de endereço das funções de tabela
remote,mysqle similares: um endereço muito longo (por exemplo, umFixedStringpreenchido 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) enquantodatabase_atomic_wait_for_drop_and_detach_synchronouslyestá 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_logpara uma visão materializada que falha durante a coleta de suas dependências commaterialized_views_ignore_errorshabilitado. Em compilações debug e com sanitizador, isso também abortava o servidor comstd::out_of_rangeem 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_*porCREATE OR REPLACEe a falha deCREATE OR REPLACE VIEWcomNOT_IMPLEMENTEDquandoignore_drop_queries_probabilityestá 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_ERRORao ler uma tabela Delta Lake cujometaData.partitionColumnsreferencia uma coluna que não está declarada emmetaData.schemaString. Esses metadados agora são rejeitados comBAD_ARGUMENTSno leitor delta-kernel e comINCORRECT_DATAno 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_probabilityestá habilitado. ODROPemitido por uma atualização para limpar o destino anterior faz parte da própria atualização, e não é umDROPsolicitado 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 JOINeSEMI RIGHT JOINcom várias condições combinadas comORna seçãoONretornavam algumas linhas da tabela da direita duas vezes e perdiam as correspondências de outras. UmANY LEFT JOINescrito explicitamente também era afetado, pois o planejador pode inverter as tabelas e executá-lo comoANY 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 umJOINacima de uma tabela cuja coluna com índice de texto é usada tanto por um predicado de busca textual emPREWHEREquanto por um emWHERE. #114771 (groeneai). - Corrige o erro
NOT_FOUND_COLUMN_IN_BLOCKem todoINSERTem uma tabela que declaraSTATISTICS(...)em uma colunaALIASouEPHEMERAL, o que tornava essas tabelas read-only. #115231 (groeneai). - Corrige
dictGete 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 CTEMATERIALIZEDé lida dentro de uma subconsultaINsobre uma tabelaDistributed. #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 consultasCREATE 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
MaterializedPostgreSQLinterrompia a replicação de um banco de dados inteiro (comLOGICAL_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 comDETACH/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(eRELOAD DICTIONARY) quando muitos dicionários MySQL definidos em XML compartilhavam um único pool de conexões viashare_connection. Esses pools agora respeitamconnection_pool_sizeeconnection_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 CLUSTERsubsequentes. #108505 (ahaanlimaye). - Corrigida uma possível falha (use-after-free) quando
SYSTEM FLUSH DISTRIBUTEDé executado simultaneamente comDROP TABLEda mesma tabelaDistributed. #108684 (groeneai). - Corrigido um
LOGICAL_ERROR(local_replica_plan_reading_step->getAnalyzedResult() == nullptr) no planejador automático de réplicas paralelas, que podia ocorrer quandoautomatic_parallel_replicas_modeestava habilitado em conjunto comparallel_replicas_min_number_of_rows_per_replicamaior 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 umTRUNCATEnão transacional era executado simultaneamente com uma transação não confirmada que havia inserido dados na mesma tabela. Nesse caso, oTRUNCATEnã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 colunasUUID. 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
MaterializedPostgreSQLque 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
EPHEMERALera reescrito pelasquery_masking_rulesdo servidor. Uma regra que correspondia a um trecho dentro do tipo fazia com queCREATE TABLEarmazenasse 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_droppedsofria wraparound, de modo que oCREATE TABLEera aceito e oDROP TABLEouDROP DATABASEsubsequente falhava comFile name too long. Esse tipo de nome agora é rejeitado comARGUMENT_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 oDROP TABLEnão conseguia remover, e renomear uma tabela para fora desse banco de dados era rejeitado indevidamente. #113019 (groeneai). - Corrige a coluna
viewsemquery_log, que ficava sempre vazia em inserts em uma tabelaAliascujo destino aciona visões materializadas. #113076 (eclbg). - Expressões inválidas de
parallel_replicas_custom_key, comotuple()ou(x, y), agora são rejeitadas comILLEGAL_TYPE_OF_COLUMN_FOR_FILTERem 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 decheck_table_dependenciese 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_MARKERpara 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 umfake_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
WINDOWnomeada. Antes, os parâmetros nesse ponto permaneciam silenciosamente sem substituição, e um parâmetroIdentifiernão definido podia causar a exceçãoLogical error: '!part.empty()'duranteEXPLAIN 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::doSchedulingquando outra thread definia aviewda tarefa comonullptrenquanto o código de escalonamento havia liberado temporariamente seu mutex. #105588 (groeneai). - Corrige o resultado incorreto de uma view definida com
EXCEPTouINTERSECTcujo operando é uma cadeiaUNION, apósDETACH/ATTACHou reinicialização do servidor. O formatador omitia os parênteses em torno dos filhosUNIONdeINTERSECT/EXCEPT, de modo que o SQL armazenado era reanalisado com a precedência invertida. #105935 (groeneai). - Corrigidos resultados incorretos (linhas duplicadas) em
SELECT DISTINCTsobre umGROUP BYcomWITH CUBE,WITH ROLLUPouGROUPING SETSnas mesmas chaves. A otimizaçãoquery_plan_remove_redundant_distinctdeixa de remover oDISTINCTnesses 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, ouWHERE p QUALIFY NULL, em queQUALIFY NULLé mesclado aoWHERE). 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, *) quandocorrelated_subqueries_default_join_kind = 'left'. #107112 (groeneai). - Corrige um
LOGICAL_ERROR(aborto do servidor em builds de debug/sanitizer) quando umJOINusa 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 comumNOT_FOUND_COLUMN_IN_BLOCKem vez de um erro lógico. #108123 (groeneai). - Corrigidas as exceções
LOGICAL_ERROR(Join is supported only for pipelines with one output port) eNOT_IMPLEMENTED(MergeJoinAlgorithm is not implemented for strictness Semi) quandojoin_algorithm = 'full_sorting_merge'era usado em uma junçãoSEMI/ANTI, incluindo junções geradas pela descorrelação de uma subconsulta correlacionadaEXISTS. Ofull_sorting_mergeagora 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 TOTALSde umJOINpodia conter valores default (como0) 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çãoquery_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 dealigned_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 tcomcorrelated_subqueries_default_join_kind = 'right'. #109114 (groeneai). - Corrigido
CREATE USER ... HOST LIKE 'a', 'b'(e o equivalenteALTER USER), que mantinha silenciosamente apenas o primeiro pattern. Agora, todos os patternsHOST LIKEespecificados são armazenados na lista de hosts permitidos do usuário. #109187 (groeneai). - Corrigido um resultado inesperado de
ANY JOINcom uma condiçãoONconstante (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 comjoin_overflow_mode = 'throw'podia ser concluída silenciosamente em vez de gerarSET_SIZE_LIMIT_EXCEEDED. #109488 (m-selmi). - Corrigida a perda silenciosa de dados quando um
INSERT ... VALUESem 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
PREWHEREadiado comoptimize_move_to_prewhere = 1quando oPREWHEREé executado após oFINAL: as condiçõesWHEREnã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 (comallow_experimental_correlated_subqueries = 1). Agora, essas consultas retornam um erroUNSUPPORTED_METHODclaro. #109863 (groeneai). - Corrigido um overflow de inteiro com sinal quando
ORDER BY ... WITH FILLsalta uma lacuna muito grande em uma colunaInt64/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 Chunkquando o alvo de umINTERPOLATEé um alias de uma colunaWITH FILLcom o analisador antigo (enable_analyzer = 0). Essas consultas agora são rejeitadas com um erro claroINVALID_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 comconvert_query_to_cnfouoptimize_and_compare_chain. #110187 (alexey-milovidov). - Uma subconsulta
EXISTScorrelacionada 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 claroNOT_IMPLEMENTED, em vez de um erro internoNOT_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()esum()eram multiplicadas pelo número de duplicatas. Isso afeta o recurso experimentalallow_experimental_correlated_subqueries. #110311 (groeneai). - Corrigido o problema em que
ORDER BY ... WITH FILLnão respeitavamax_execution_timee demorava a ser cancelado ao gerar um intervalo de preenchimento grande (especialmente comINTERPOLATE). #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 umLIMITmenor 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_ordereDISTINCT ... optimize_distinct_in_orderaplicados sobre uma junçãopartial_merge. A otimização de leitura em ordem era propagada através dePartialMergeJoin, 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
INTERSECTouEXCEPT, por exemploWITH 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çãograce_hashquando 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
CREATEcom uma cláusulaCOMMENTpara 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 1nã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ídaWITH TOTALSouextremesé descartada, incluindo agregação externa,INSERT ... SELECT, operações de conjunto eEXPLAIN ANALYZE. #111194 (groeneai). - Corrige
join_algorithm = 'full_sorting_merge', que preenchia as linhas sem correspondência de umLEFT/RIGHT/FULL/ASOFJOINcom um zero bruto em vez do valor padrão do tipo da coluna. Para uma colunaEnum(cujo padrão é seu primeiro elemento, e não0), 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 erroUNKNOWN_ELEMENT_OF_ENUMquando a coluna era selecionada. #111197 (groeneai). - Corrige resultados incorretos de
SummingMergeTree(eCoalescingMergeTree) comFINALquandooptimize_move_to_prewhere_if_final = 1e a cláusulaWHEREé 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 umRIGHT/FULL JOINquando 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 umUNION ALL. #111554 (groeneai). - Corrige uma falha do cliente ao formatar uma consulta
EXECUTE AScuja AST tem um filho substituído (como faz o AST fuzzer).ASTExecuteAsQueryagora detém a posse de seus filhostarget_useresubquery, em vez de manter ponteiros sem posse parachildren. #111725 (groeneai). - Corrige resultados incorretos quando
query_plan_join_swap_tableinverte umANY JOINcomjoin_any_take_last_row = 1: o ClickHouse agora mantém a ordem original dos lados da junção, para queANY JOINcontinue retornando a última linha correspondente. #112458 (vdimir). - Corrige a exceção
Context has expiredquandogetClientHTTPHeaderé usado dentro de uma subconsulta. #112533 (alexey-milovidov). - Corrige resultados incorretos em um
JOINcuja cláusulaONcontém uma condição mista, ou seja, um resíduo de não igualdade entre os dois lados, comoON (t1.key = t2.key) AND (t1.a * 10 < t2.a). Apenas a família hash avalia esse tipo de condição, masfull_sorting_merge,partial_mergee 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
CROSScujoWHEREcompara colunas de duas tabelas por meio de uma expressão não determinística, comorand. Uma consulta desse tipo podia retornar linhas que contradiziam sua própria cláusulaWHERE, porque a reescrita da junção como uma junçãoINNERmovia 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
FixedStringpreenchido 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
intDivsobre 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çãoILLEGAL_DIVISION, como fazem os demais caminhos de execução. Esse estouro silencioso também podia produzir resultados incorretos deORDER BY/DISTINCT, porque a otimização de leitura em ordem trata corretamenteintDivpor uma constante negativa como monotônica, e o valor estourado violava a ordenação resultante. #113048 (alexey-milovidov). - Corrigido o erro
UNKNOWN_IDENTIFIERcomenable_analyzer = 0quando umWHEREfaz referência a uma coluna produzida poruntupledentro de uma subconsulta, por exemploSELECT t.keys FROM (SELECT untuple(arrayJoin(m)) AS t FROM ...) WHERE t.values > 0. A reescrita deenable_optimize_predicate_expressionempurrava esse predicado para dentro da subconsulta como umHAVING, onde o nome ainda não existe. #113760 (groeneai). - Corrigidos resultados incorretos em
JOINcomjoin_algorithm = 'partial_merge'quando o lado direito contém totais: o lado direito podia ficar sem mesclagem, de modo que junçõesLEFTsubstituíam correspondências reais por valores default e junçõesINNER/RIGHTnão retornavam nenhuma linha. No caminho de linhas não unidas deRIGHT/FULL, o mesmo estado desreferenciava um ponteiro nulo, o que derrubava o servidor. #113936 (groeneai). - Corrigidos resultados incorretos em
SELECT DISTINCTcom umLIMITque precisa ler toda a entrada:LIMIT n WITH TIESdescartava linhas empatadas,exact_rows_before_limit = 1informava umrows_before_limit_at_leasttruncado eGROUP BY ... WITH TOTALScalculava 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 fromReadFromMergeTree”) gerado por umSELECT ... FINALcujoPREWHEREusa uma coluna de que oFINALprecisa 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 QUOTAeALTER QUOTA, que descartavam silenciosamente todos os blocosFOR 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
randConstantretornava dois valores diferentes em uma única consulta quando suas chamadas tinham aliases diferentes. Segundo a documentação,randConstantmantém um único valor para toda a consulta, eSELECT randConstant() = randConstant()já retornava1, mas adicionar aliases, como emSELECT 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 arquivoMsgPackouProtobufListcorrompido. O fast path deoptimize_count_from_filescontava as linhas sem exigir que a posição de leitura avançasse, de modo que um arquivoProtobufListde 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_filesemsystem.distribution_queuee a métricaBrokenDistributedFilesToInsertsempre informavam0: ao varrer a fila de async-insert na inicialização,DistributedAsyncInsertDirectoryQueue::initializeFilesFromDiskcontabilizava 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_hashagora 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_timeoute 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 comconnect_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 experimentalmake_distributed_plan = 1usava um valor muito grande dedistributed_plan_default_reader_bucket_countoudistributed_plan_default_shuffle_join_bucket_count. Esses valores agora são rejeitados comINVALID_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 ultrapassavamax_rows_in_distinct/max_bytes_in_distinctera 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 emMEMORY_LIMIT_EXCEEDED. #110075 (skuznetsov-clickhouse). - Corrige o problema em que
optimize_aggregation_in_orderignorava o cancelamento de consultas.AggregatingInOrderTransformagora verifica o cancelamento durante a agregação de um fragmento, de modo que uma consulta interrompida porKILL QUERYou pormax_execution_time(no modo padrãotimeout_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 colunatextdeclarada comoInt32). 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 compiladorprqlcabortava o processo em vez de ser reportado como um erro de consulta. #110316 (groeneai). - Corrige
NOT_FOUND_COLUMN_IN_BLOCKquando uma row policy eadditional_table_filtersreferenciam a mesma coluna, que não é selecionada de outra forma pela consulta. #111099 (groeneai). - Corrigido um travamento em
randChiSquared,randStudentT,randFisherFerandBinomialcom parâmetros extremos. A consulta não podia ser interrompida pormax_execution_timenem porKILL QUERY. Esses parâmetros agora são rejeitados mesmo quandomax_rand_distribution_parameteroumax_rand_distribution_trialsestá definido como 0, emax_rand_distribution_trialsnão pode mais ser elevado acima do seu valor default de 10^9 pararandBinomial. #111909 (alexey-milovidov). - Corrige
connection_pool_max_wait_mspara 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 registrandoNo 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,replaceRegexpOneereplaceRegexpAll, que ignoravammax_execution_timeeKILL 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, comtimeout_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,countSubstringsCaseInsensitiveecountSubstringsCaseInsensitiveUTF8, que ignoravamKILL QUERYemax_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_timeoutsegundos) quando ela termina muito rapidamente no iniciador. #113551 (nickitat). - Corrige
countMatchesecountMatchesCaseInsensitive, que ignoravammax_execution_timeeKILL QUERYao 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_timeter decorrido, falhando com a mensagem contraditóriaTimeout exceeded: elapsed 999.672 ms, maximum: 1000 ms. #114559 (alexey-milovidov). - Corrigida uma leitura fora dos limites em
pointInPolygoncom um polígono constante cuja caixa delimitadora é ilimitada, por exemplo, quando uma coordenada atinge+-DBL_MAX. Esse polígono agora é rejeitado comBAD_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 BOUNDEDretornar menos linhas do que as confirmadas antes de seu início, geralmente nenhuma. #115543 (alexey-milovidov). - Corrige o erro
Unknown identifiergerado durante a otimização do plano de consulta commake_distributed_plan = 1quando a coluna de ordenação de uma consulta com função de janela passa por uma etapaExpressionque não a menciona. #115890 (groeneai). - Corrigido o problema em que
h3kRing,h3HexRing,h3Lineeh3ToChildrenignoravammax_execution_timeeKILL QUERYao expandir um bloco de linhas. #115893 (alexey-milovidov). - Corrigido o erro
NOT_FOUND_COLUMN_IN_BLOCKno leitor nativo Parquet V3 (decorrente de uma regressão anterior) quando umPREWHEREtinha conjunções que compartilhavam uma expressão intermediária comum. #107059 (groeneai). - Corrige um travamento ao gravar Parquet com
output_format_parquet_parallel_encodinghabilitado (o padrão) emax_threadsmaior 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_listpara gravar stack traces de determinados profile events emsystem.trace_log. #113553 (mstetsyuk). - Corrigido o problema em que
intDivOrNull,moduloOrNullepositiveModuloOrNullretornavam0em vez deNULL, eintDivOrNulleintDivOrZerolançavam uma exceção em vez de retornarNULL/0, quando a divisão resulta em uma exceção de ponto flutuante (divisão por zero ouINT_MIN / -1), inclusive para argumentos mistos com e sem sinal. #101976 (yariks5s). - Corrigido
IS DISTINCT FROMpara valoresArrayeMapcomparados comNULL. #103162 (ylw510). - Corrigido
groupConcatquando 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 consultasLIMIT ... WITH TIESexecutadas com o pipeline de leitura em ordem (optimize_read_in_order = 1eread_in_order_use_virtual_row_per_block = 1). #105102 (groeneai). - Corrige
Logical error: 'Pipeline stuck'em consultas que usamenable_sharding_aggregator = 1em conjunto com umUNION ALLemax_streams_for_union_stepmenor que a largura do pipeline.BufferedShardByHashTransformagora 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
removeDirectoryem discos de armazenamento de objetosplain(comos3_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 comCANNOT_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_poolconfiguradas com<lifetime>não detectavam alterações no script subjacente. Antes, apenasSYSTEM RELOAD FUNCTIONSrelia 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 dethreadPoolCallbackRunnerUnsafeda 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
toTime64eCAST(... AS Time64)não restringiam valores fora da faixa ao intervalo válido deTime64nos modos de overflowsaturateeignore, 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,countMatchesesplitByRegexp. 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
hasTokenem índices de texto com tokenizador diferente desplitByNonAlpha. #108066 (rschu1ze). - Corrige o problema em que
toStartOfIntervaledateTruncretornavam 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)retornava10:11:12.001em vez de10:11:12.000. A sobrecarga com origem explícita também era afetada. #108186 (yariks5s). - Corrigidas as funções
replaceRegexpOneereplaceRegexpAllpara 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,replaceRegexpAlletc.), 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/changeSecondaplicadas a um argumentoDateTime64(N), que criavam a coluna de resultado com a escala padrão fixa no código (3) em vez deN. Os valores eram calculados na escalaN, 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 ecorrelated_subqueries_default_join_kind = 'left'. #108554 (groeneai). - Corrigidos bugs de
DateTime64emchangeYear,changeMonth,changeDay,changeHour,changeMinuteechangeSecond: entradas com precisão de nanossegundos (escala 9) não lançam maisDECIMAL_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
LIKEoumatchcom centenas de milhares de wildcards); esses patterns agora falham com um erroCANNOT_COMPILE_REGEXPclaro. #108821 (Algunenano). - Corrige
reinterpret(x, 'Decimal128(scale)')(e destinosDecimal32/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/changeSecondsobreDateTime64(N), que construíam a coluna de resultado com a escala padrão fixa 3 em vez deN, etimeSlotssobreDateTime64, que ignorava a escala do argumento opcionalSizeem seu tipo de retorno declarado. Em ambos os casos, era produzida uma coluna cuja escala física divergia do tipo declarado, o que causava umLOGICAL_ERROR(writeSlice expects same column types) quando o resultado era passado paraarrayPushBack/arrayPushFront/arrayConcat; além disso,timeSlotscom a maior escala emSizeretornava timestamps incorretos. #108994 (groeneai). - Corrige incrementos não monotônicos de ProfileEvents #109180 (azat).
- Corrige proporções de
SAMPLEcom um expoente cuja magnitude causa overflow emInt32(por exemplo,SAMPLE 1e-3000000000), que eram tratadas silenciosamente comoSAMPLE 1. #109197 (Algunenano). - Corrigidos dois bugs no caminho
DateTime64detoUTCTimestamp/fromUTCTimestamp(e de seus aliasesto_utc_timestamp/from_utc_timestamp) e detoTime64. O primeiro era um overflow de inteiro com sinal próximo à fronteira deInt64(agora o cálculo é feito emInt128e 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 quetimezoneOffset()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 usaarrayJoin; 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
accurateCastOrDefaulte a preservação deNULLs de origem codificados porDynamiceVariant. #109946 (Avogar). #114912 (alexey-milovidov). - Corrige
max_bytes_in_distinctemax_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/isZeroOrNullrecebem um argumento cujo tipo é resolvido comoNothing, por exemplo, dentro de expressões comoindexHint(assumeNotNull(materialize(NULL))). #110192 (groeneai). - Corrige a leitura de arquivos em discos
plain_rewritabledepois 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 comUNEXPECTED_END_OF_FILE. #110304 (thevar1able). - Rejeita valores de
vector_search_index_fetch_multiplierabaixo 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 ValuesBlockInputFormatque podia ocorrer ao inserir valores cujas expressões contêm uma conversão numérica, comoinitializeAggregation('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 tipadosreadWKTPoint/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 emusers.xml). O Ed25519 não é aprovado pelo FIPS; agora essas chaves são rejeitadas com um erroLIBSSH_ERRORclaro. #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 paraprecisionplanos 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: paraQBit(BFloat16)com precisão 1, apenas o bit de sinal sobrevive, de modo que todo valor era reconstruído como±0.0e 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ódigosInt8brutos são reconstruídos no centro de sua célula (correspondendo à reconstruçãoLloyd-Maxque o caminho...TransposedQuantizedjá 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.0permanece exatamente zero e a célula não finita é isolada para que±infcontinue exatamente infinito; veja a nota abaixo sobre a célula ambígua deNaN); e, enquanto bits do expoente ainda estão sendo truncados, a borda inferior limitada é mantida, de modo que umaprecisionmenor 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étodossh_keycontavam 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/readWKTpara um ponto vazio com marcação de dimensão, comoPOINT M EMPTY. Essas entradas agora são rejeitadas comCANNOT_PARSE_TEXT, de forma consistente comPOINT EMPTY. #111517 (groeneai). - A criação de estatísticas
minmaxagora emite um aviso em vez de lançar uma exceção. #111785 (hanfei1991). - Mantém
randBinomialutilizável com as probabilidades degeneradas0e1para qualquer número de tentativas. #112021 (alexey-milovidov). - Corrigido o problema em que
system.s3_queue_settingsreportava valores incorretos parabucketing_mode,partitioning_mode,partition_regexepartition_component. #112300 (bharatnc). - Reporta a posição correta de erros em consultas PromQL. #112494 (fallintoplace).
SYSTEM DISABLE FAILPOINTagora rejeita um nome de fail point inexistente, gerandoBAD_ARGUMENTS, comoSYSTEM ENABLE FAILPOINTjá 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
Nestedcuja 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) emreplaceRegexpOne/replaceRegexpAllquando 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_wordnã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
theilsUem 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
Replicatede recebidas pelo protocolo nativo: agora elas são rejeitadas comINCORRECT_DATAem vez deLOGICAL_ERROR(que encerrava o servidor em compilações de depuração e com sanitizadores). #114186 (Avogar). - Corrige literais
Time64e constantes de listasINincorretos, frequentemente com o sinal invertido, produzidos quando a mudança de escala de umDecimal64de escala menor excedia os limites deInt64. Essa conversão agora informaDECIMAL_OVERFLOW, assim como o ramoDateTime64e oCASTexplí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
ReplicatedMergeTreepermanecerem 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). timeSeriesRangeetimeSeriesFromGridgeravam um erroDECIMAL_OVERFLOWindevido 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 tempoDateTime/UInt32, o passo era silenciosamente truncado para seus 32 bits menos significativos. Agora todos os cálculos são feitos emInt64. #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 corrigidoasync_insert_queue_flush_on_shutdownpara que seja feito o flush dos insert enfileirados durante o desligamento do servidor. #114839 (azat). - Corrigida uma exceção
out_of_rangegerada como um erro internoCode: 1001quando um pattern desequenceMatch,sequenceCountousequenceMatchEventscontém o número de evento0, por exemplo,sequenceMatch('(?0)'). Esse pattern agora é rejeitado comBAD_ARGUMENTS. Uma condição temporal contendo apenas um sinal, comosequenceMatch('(?1)(?t>+)(?2)'), era silenciosamente tratada como(?t>0)e agora é rejeitada comSYNTAX_ERROR. #115056 (groeneai). - Corrigida a mensagem de erro de
geoToH3que indicava a posição e o tipo incorretos do argumento quando uma coordenada não eraFloat64. Com a configuração padrãogeotoh3_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
TZestava vazia. #68921 (ardenwick).