> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-trino-dialect.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Especificação do protocolo TCP nativo do ClickHouse: estruturação de pacotes, ciclo de vida da conexão, negociação de versão e o corpo de cada mensagem

# Protocolo Nativo

O protocolo nativo é o protocolo binário orientado à conexão com que clientes e servidores ClickHouse se comunicam via TCP. Ele transporta consultas SQL, dados de resultado, payloads de `INSERT`, telemetria de execução e sinais de erro. É o protocolo usado pelo cliente de linha de comando, pelo driver nativo em C++ e pela maioria dos drivers nativos de terceiros.

Esta página aborda o protocolo em si: estruturação de pacotes, a máquina de estados da conexão, negociação de versão e o corpo de todas as mensagens que não sejam `Block`. Os bytes dentro dos pacotes da família `Data` (o `Block`, suas colunas e as codificações por tipo) são um assunto à parte, documentado na especificação de [Formato Nativo](/pt-BR/reference/interfaces/specs/NativeFormat).

<Info>
  **Especificação complementar**

  Esta página faz par com a especificação complementar de [Formato Nativo](/pt-BR/reference/interfaces/specs/NativeFormat) e é publicada junto com ela. As duas especificações dividem o trabalho de forma clara: esta página cobre a camada de pacotes e transporte; a especificação de Formato Nativo cobre os bytes dentro dos pacotes da família `Data`.
</Info>

Algumas propriedades se mantêm ao longo de toda a especificação. O protocolo é binário e posicional: não há tags de campo, exceto dentro de `BlockInfo`, portanto um único byte fora do lugar dessincroniza tudo o que vem a seguir. Ele é com estado, e cada conexão TCP processa uma consulta por vez — não há multiplexação. Inteiros de largura fixa são codificados em little-endian.

<div id="overview">
  ## Visão geral
</div>

| Propriedade       | Valor                                                                                            |
| ----------------- | ------------------------------------------------------------------------------------------------ |
| Transporte        | TCP, opcionalmente protegido por TLS                                                             |
| Ordem dos bytes   | little-endian para inteiros de largura fixa                                                      |
| Codificação       | Binária e posicional (sem tags de campo, exceto em `BlockInfo`)                                  |
| Modelo de conexão | Com estado, uma consulta por vez, sem multiplexação                                              |
| Versionamento     | Negociado no handshake; recursos individuais condicionados à versão                              |
| Formato de dados  | O [Formato Nativo](/pt-BR/reference/interfaces/specs/NativeFormat) para todos os dados tabulares |

Cada mensagem no wire começa com um código de tipo de pacote `VarUInt`, seguido de um corpo cuja estrutura depende desse código e da versão negociada do protocolo.

Uma conexão passa por três fases — um handshake único, depois qualquer número de trocas `Ping` ou `Query` e, por fim, o encerramento:

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant C as Client
    participant S as Server

    C->>S: TCP connect

    rect rgb(220, 235, 255)
        Note over C,S: Handshake
        C->>S: ClientHello (name, version, db, user, password)
        S->>C: ServerHello (server_name, version, [timezone, display_name, ...])
        Note over C,S: negotiated_version = min(client, server)
        opt negotiated_version ≥ 54458
            C->>S: Addendum (quota_key)
        end
    end

    rect rgb(220, 245, 225)
        Note over C,S: Query phase
        C->>S: Query packet (ClientInfo, settings, params, SQL)
        C->>S: External-table Data packets (0 or more)
        C->>S: Empty Data marker — the "go" signal
        loop until EndOfStream or Exception
            S->>C: Data / Progress / Log / ProfileInfo / Totals / ...
        end
        S->>C: EndOfStream
    end
```

O protocolo TCP nativo sempre transporta dados tabulares no formato Native, independentemente de qualquer cláusula `FORMAT` no SQL. Reformatar para `RowBinary`, `CSV`, `JSON` e assim por diante é tarefa do cliente, feita depois que ele decodifica os blocos Native. (A interface HTTP segue um caminho de código diferente e *de fato* respeita a cláusula `FORMAT`; HTTP está fora do escopo aqui.)

<div id="security">
  ## Segurança
</div>

<div id="transport-security">
  ### Segurança de transporte (TLS)
</div>

O TLS opera na camada de transporte, abaixo do protocolo. Quando está habilitado, todo o tráfego TCP é criptografado, e as mensagens do protocolo permanecem idênticas byte a byte, com ou sem TLS.

<div id="authentication">
  ### Autenticação
</div>

A autenticação ocorre durante o handshake, na mensagem [`ClientHello`](#clienthello). Os campos `user` e `password` são transmitidos como strings em texto simples, portanto a criptografia na camada de transporte (TLS) é a responsável por proteger as credenciais em trânsito.

A autenticação SSH por challenge-response está disponível a partir da versão 54466 do protocolo — consulte [autenticação SSH por challenge-response](#ssh-authentication).

<div id="inter-server-secret">
  ### Segredo entre servidores
</div>

Na execução distribuída de consultas, os servidores se autenticam entre si ao comprovar que conhecem um segredo compartilhado — sem expor o segredo no wire. Cada consulta carrega um `auth_hash` SHA-256 de 32 bytes no campo 4 de [`Query`](#query), calculado a partir de um salt, um nonce, do segredo configurado e da consulta; o servidor receptor o recalcula e o compara. Isso é controlado pelo recurso `INTERSERVER_SECRET` (v54441). Clientes externos sempre enviam uma string vazia aqui. Consulte [Autenticação entre servidores](#inter-server-authentication).

<div id="versioning-and-feature-gates">
  ## Versionamento e feature gates
</div>

<div id="version-negotiation">
  ### Negociação de versão
</div>

Tanto o cliente quanto o servidor declaram a versão máxima do protocolo compatível durante o handshake. A **versão negociada** é a menor das duas:

```text theme={null}
negotiated_version = min(client_version, server_version)
```

Cada mensagem após isso usa a versão negociada para determinar quais campos estão presentes no wire.

<div id="feature-gates">
  ### Feature gates
</div>

Uma funcionalidade é identificada pela versão do protocolo que a introduziu e fica **ativa** quando a versão negociada é maior ou igual a esse número.

<Warning>
  Quando uma funcionalidade está ativa, seus campos **devem** estar presentes no wire. O protocolo é estritamente posicional, portanto, omitir um campo sujeito a feature gate corrompe o fluxo de bytes de todos os campos seguintes.
</Warning>

<div id="feature-table">
  ### Tabela de funcionalidades
</div>

| Funcionalidade                             | Versão | Afeta                            | Impacto no wire                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------------------------------ | ------ | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| BLOCK\_INFO                                | all    | Block                            | Adiciona o prefixo BlockInfo (`is_overflows`, `bucket_number`) a cada Block.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| CLIENT\_INFO                               | 54032  | Query                            | Adiciona o bloco ClientInfo ao corpo de Query.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| TIMEZONE                                   | 54058  | ServerHello                      | Adiciona o campo `timezone` a ServerHello.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| QUOTA\_KEY\_IN\_CLIENT\_INFO               | 54060  | ClientInfo                       | Adiciona o campo `quota_key` a ClientInfo.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| DISPLAY\_NAME                              | 54372  | ServerHello                      | Adiciona o campo `display_name` a ServerHello.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| VERSION\_PATCH                             | 54401  | ServerHello, ClientInfo          | Adiciona o campo `version_patch` a ambos.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| SERVER\_LOGS                               | 54406  | Log                              | O servidor emite pacotes Log quando `send_logs_level` está definido.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| COLUMN\_DEFAULTS\_METADATA                 | 54410  | TableColumns                     | O servidor pode enviar o pacote [`TableColumns`](#tablecolumns) (tipo 11) com metadados de valores padrão das colunas antes do bloco de schema de INSERT/entrada. Enviado somente quando a versão negociada ≥ 54410 **e** `input_format_defaults_for_omitted_fields` estiver habilitado. Abaixo dessa versão, o pacote nunca é enviado; os clientes não devem aguardar por ele.                                                                                                                                                                                                                                                                                                                                                                                                         |
| WRITE\_CLIENT\_INFO                        | 54420  | Progress                         | Adiciona `wrote_rows` e `wrote_bytes` a Progress. (Apesar do nome, isso **não** controla o bloco ClientInfo — isso é feito por `CLIENT_INFO` (v54032).)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| SETTINGS\_SERIALIZED\_AS\_STRINGS          | 54429  | Query (settings encoding)        | Altera **como** a lista de settings, sempre presente, é codificada; **não** controla se as settings são enviadas. v54429+ grava cada setting como `(name, flags, value-as-string)`; peers mais antigos gravam `(name, type-specific-binary-value)` sem flags. Veja [Setting](#setting).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| INTERSERVER\_SECRET                        | 54441  | Query                            | Adiciona o campo `auth_hash` entre servidores a Query — um SHA-256 com salt sobre o secret do cluster, não o secret bruto. Clientes externos enviam uma string vazia. Veja [Autenticação entre servidores](#inter-server-authentication).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| OPEN\_TELEMETRY                            | 54442  | ClientInfo                       | Adiciona o contexto de rastreamento do OpenTelemetry a ClientInfo.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| DISTRIBUTED\_DEPTH                         | 54448  | ClientInfo                       | Adiciona o campo `distributed_depth` a ClientInfo.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| INITIAL\_QUERY\_START\_TIME                | 54449  | ClientInfo                       | Adiciona o campo `initial_time` (Int64, largura fixa).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| PROFILE\_EVENTS                            | 54451  | ProfileEvents                    | O servidor emite pacotes ProfileEvents durante a execução da consulta.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| PARALLEL\_REPLICAS                         | 54453  | ClientInfo                       | Adiciona campos de coordination de réplicas paralelas a ClientInfo.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| CUSTOM\_SERIALIZATION                      | 54454  | Block (Column)                   | Adiciona o byte `has_custom_serialization` após a string de tipo de cada coluna.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ADDENDUM                                   | 54458  | Handshake                        | O cliente envia um addendum (`quota_key`) após a troca de handshake.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| PARAMETERS                                 | 54459  | Query                            | Adiciona a lista de parâmetros ao corpo de Query.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| SERVER\_QUERY\_TIME\_IN\_PROGRESS          | 54460  | Progress                         | Adiciona o campo `elapsed_ns` a Progress.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| PASSWORD\_COMPLEXITY\_RULES                | 54461  | ServerHello                      | Adiciona a ServerHello uma lista de Patterns regex da política de senha e mensagens legíveis por humanos.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| INTERSERVER\_SECRET\_V2                    | 54462  | ServerHello                      | Adiciona um nonce `UInt64` de 8 bytes a ServerHello. Usado para assinatura de consultas entre servidores; clientes externos o decodificam e o ignoram.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| TOTAL\_BYTES\_IN\_PROGRESS                 | 54463  | Progress                         | Adiciona o campo `total_bytes_to_read` (VarUInt) a Progress, entre `total_rows` e `wrote_rows`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| TIMEZONE\_UPDATES                          | 54464  | TimezoneUpdate                   | Adiciona o pacote de servidor `TimezoneUpdate` (tipo 17). Corpo: um único `String` que carrega a session timezone. Enviado somente pelo inicializador da table function `input`, logo após o bloco de schema de entrada, para que o cliente faça parse das linhas que envia com a `session_timezone` do servidor. Veja [TimezoneUpdate](#timezoneupdate).                                                                                                                                                                                                                                                                                                                                                                                                                               |
| SPARSE\_SERIALIZATION                      | 54465  | Block (Column)                   | O servidor pode definir `has_custom_serialization = 1` e emitir uma coluna codificada de forma esparsa. Formato wire: kind de 1 byte (0x01 = SPARSE), seguido por um fluxo de offsets VarUInt terminado por EOG, depois os valores não padrão codificados densamente no tipo interno. Veja [kind\_stack and sparse encoding](/pt-BR/reference/interfaces/specs/NativeFormat#kind-stack-and-sparse-encoding).                                                                                                                                                                                                                                                                                                                                                                            |
| SSH\_AUTHENTICATION                        | 54466  | Auth flow                        | Adiciona autenticação SSH por desafio-resposta. Opt-in: o cliente envia um `user` no formato `" SSH KEY AUTHENTICATION " + <real_user>` com senha vazia para acioná-la. Veja [Autenticação SSH por desafio-resposta](#ssh-authentication).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| TABLE\_READ\_ONLY\_CHECK                   | 54467  | TablesStatusResponse             | Adiciona um flag `is_readonly` à linha de cada tabela em TablesStatusResponse. Clientes externos que não emitem `TablesStatusRequest` não veem nenhuma mudança no wire.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| SYSTEM\_KEYWORDS\_TABLE                    | 54468  | system tables                    | O servidor popula `system.keywords` para que o `clickhouse-client` canônico possa autocompletar palavras-chave. Não há mudança no wire do protocolo nativo.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ROWS\_BEFORE\_AGGREGATION                  | 54469  | ProfileInfo                      | Adiciona `applied_aggregation` (Bool) e `rows_before_aggregation` (VarUInt) a ProfileInfo, nessa ordem, no final.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| CHUNKED\_PROTOCOL                          | 54470  | Connection framing               | O enquadramento em fragmentos por pacote envolve cada packet body. Negociado em Addendum. ServerHello carrega a preferência do servidor para cada direção; Addendum carrega a escolha final do cliente. Veja [chunked framing](#chunked-framing).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| VERSIONED\_PARALLEL\_REPLICAS\_PROTOCOL    | 54471  | ServerHello, Addendum            | Ambos os lados trocam um `VarUInt` com a versão do protocolo de coordenação de réplicas paralelas. O campo de ServerHello fica **imediatamente após `protocol_version`** (antes de `timezone`). O campo de Addendum é anexado após as strings do protocolo em blocos. Valor atual: `8` (`DBMS_PARALLEL_REPLICAS_PROTOCOL_VERSION`). A versão `8` adiciona [`MergeTreeAllRangesAnnouncementResponse`](#mergetreeallrangesannouncementresponse) (pacote de cliente `14`): quando a versão negociada de réplicas paralelas é `≥ 8`, o iniciador responde a cada announcement de seguidor em modo não `Default` com a lista autoritativa de parts para aquele stream, e o seguidor espera por ela antes de emitir solicitações de leitura. Abaixo de `8`, o announcement é fire-and-forget. |
| INTERSERVER\_EXTERNALLY\_GRANTED\_ROLES    | 54472  | Query                            | Adiciona um campo `String external_roles` ao corpo de Query, entre o terminador de settings e o hash do segredo interserver. Clientes externos enviam uma lista de roles vazia (um único byte `0x00`, ou seja, VarUInt 0 dentro de um envelope String).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| V2\_DYNAMIC\_AND\_JSON\_SERIALIZATION      | 54473  | Column body                      | O servidor pode emitir serialização V2 para os tipos de coluna `Dynamic` e `JSON` — isso determina qual versão de `state_prefix` eles usam. Veja [tipos versionados](/pt-BR/reference/interfaces/specs/NativeFormat#versioned-types).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| SERVER\_SETTINGS                           | 54474  | ServerHello                      | O servidor transmite seus settings fora do padrão como uma lista no final de ServerHello, após `nonce`. Formato: triplas `(key, flags, value)` terminadas por uma key vazia — igual à lista de settings do pacote Query.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| QUERY\_AND\_LINE\_NUMBERS                  | 54475  | ClientInfo                       | Adiciona `script_query_number` (VarUInt) e `script_line_number` (VarUInt) ao final de ClientInfo. Usado pelo clickhouse-client para atribuir erros em scripts com várias instruções; clientes externos enviam `0, 0`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| JWT\_IN\_INTERSERVER                       | 54476  | ClientInfo                       | Adiciona um UInt8 indicando a presença de JWT + um `String jwt` opcional ao final de ClientInfo. Clientes externos (sem JWT) enviam o byte `0x00`. (Escrito como `DBMS_MIN_REVISON_WITH_JWT_IN_INTERSERVER` em C++ — observe o erro de digitação no nome da constante.)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| QUERY\_PLAN\_SERIALIZATION                 | 54477  | ServerHello, QueryPlan packet    | ServerHello anexa `VarUInt query_plan_serialization_version` após os server settings. Também introduz `ClientPacket::QueryPlan` (código `13`) para entrega entre servidores de planos de consulta pré-construídos — clientes externos nunca enviam.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| PARALLEL\_BLOCK\_MARSHALLING               | 54478  | Block (Column)                   | O servidor pode encapsular colunas em `ColumnBLOB` (comprimido inline) para processamento paralelo. Isso é controlado por a consulta ter compressão habilitada AND `rows > 1`; caso contrário, aplica-se o formato wire normal da coluna. Clientes que nunca habilitam compressão em pacotes Query de saída não veem alteração no wire.                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| VERSIONED\_CLUSTER\_FUNCTION\_PROTOCOL     | 54479  | ServerHello                      | Adiciona `VarUInt cluster_function_protocol_version` ao final de ServerHello. Usado para funções de tabela `*Cluster` (`s3Cluster`, etc.). Valor atual: `8` (`DBMS_CLUSTER_PROCESSING_PROTOCOL_VERSION`); a versão `7` é reservada para um recurso de repositório privado (compactação Iceberg), e `8` adiciona um `read_source_index` opcional à carga útil da tarefa de leitura de cluster entre servidores (o corpo de `ReadTaskResponse`, que continua não especificado aqui — veja abaixo). Clientes externos decodificam e ignoram.                                                                                                                                                                                                                                               |
| OUT\_OF\_ORDER\_BUCKETS\_IN\_AGGREGATION   | 54480  | BlockInfo                        | Adiciona o campo 3 (`out_of_order_buckets: Vec<Int32>`) ao fluxo com tags de campo de BlockInfo. Decodificado como `[VarUInt count][Int32]*count`. Clientes externos não emitem isso por conta própria; o decodificador lê qualquer lista não vazia que o servidor enviar.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| COMPRESSED\_LOGS\_PROFILE\_EVENTS\_COLUMNS | 54481  | Log, ProfileEvents, TableColumns | O servidor pode encapsular os corpos dos pacotes [`Log`](#log), [`ProfileEvents`](#profileevents) e [`TableColumns`](#tablecolumns) no [frame de compressão](/pt-BR/reference/interfaces/specs/NativeFormat#compression-frame). Nesta versão, os corpos dos três trafegam pelo mesmo caminho de saída opcionalmente comprimido, que se torna um frame de compressão real apenas quando a consulta tem `compression = true`. Clientes que nunca habilitam compressão em pacotes Query de saída não veem alteração no wire.                                                                                                                                                                                                                                                               |
| REPLICATED\_SERIALIZATION                  | 54482  | Block (Column)                   | O servidor pode emitir colunas com kind\_stack `0x04 = REPLICATED` — uma forma compacta no estilo Dicionário para valores repetidos — veja [kind\_stack e codificação esparsa](/pt-BR/reference/interfaces/specs/NativeFormat#kind-stack-and-sparse-encoding). Abaixo desta versão, o gravador expandia essas colunas antes de enviá-las. A decodificação é feita por busca de índice (`elements[indexes[i]]` por linha); há suporte a tipos folha e a tipos internos `Nullable`/`Array`/`Tuple`/`Map`/`Nested`/`LowCardinality`.                                                                                                                                                                                                                                                       |
| NULLABLE\_SPARSE\_SERIALIZATION            | 54483  | Block (Column)                   | Combina serialização esparsa com `Nullable(T)`. Abaixo desta versão, o gravador expandia o formato esparso para colunas Nullable antes do envio; em v54483+, os dados no wire ficam em formato esparso sobre Nullable. Veja [kind\_stack e codificação esparsa](/pt-BR/reference/interfaces/specs/NativeFormat#kind-stack-and-sparse-encoding).                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| PROGRESS\_IN\_ASYNC\_INSERT                | 54484  | Progress (INSERT)                | Em um INSERT **assíncrono** (`async_insert = 1`), assim que o insert é descarregado, o servidor envia um pacote extra [`Progress`](#progress) e, em seguida, os `ProfileEvents` do insert, antes de `EndOfStream`. Isso é controlado pela versão *negociada* ≥ 54484; abaixo disso, o servidor omite esse Progress final. O formato wire de Progress não muda — apenas a emissão é nova. Na prática, o incremento carrega o tempo decorrido; os contadores de linhas gravadas são reportados pelos ProfileEvents correspondentes. Um cliente que já consome Progress intercalado não precisa de mudança de formato, apenas tolerar mais um pacote.                                                                                                                                      |
| CLIENT\_AGENT\_IN\_CLIENT\_INFO            | 54485  | ClientInfo                       | Adiciona um `String` `client_agent` ao final de ClientInfo. O cliente canônico detecta automaticamente um identificador de agent a partir do ambiente (por exemplo, `claude-code`, `cursor`, `gemini-cli` ou o valor da variável `AGENT`); um cliente externo sem nada detectado envia uma string vazia. Obrigatório quando a versão negociada for ≥ 54485 — omiti-lo dessincroniza o restante do pacote Query.                                                                                                                                                                                                                                                                                                                                                                         |
| INTERNAL\_QUERY\_FLAG                      | 54486  | ClientInfo                       | Adiciona um `UInt8` `is_internal` ao final de ClientInfo. `1` para uma consulta interna do servidor (não emitida pelo usuário), propagada para consultas remotas para que suas linhas em `system.query_log` sejam rotuladas como internas; clientes externos enviam `0`. Obrigatório quando a versão negociada for ≥ 54486 — omiti-lo dessincroniza o restante do pacote Query.                                                                                                                                                                                                                                                                                                                                                                                                         |
| INTERSERVER\_CURRENT\_ROLES                | 54488  | ClientInfo                       | Adiciona uma lista opcional de String `current_roles` ao final de ClientInfo (`[UInt8 present]` e, se `1`, `[VarUInt count][String]*count`) e, para consultas entre servidores, estende o `auth_hash` para abranger a lista serializada. Carrega os nomes das roles ativas (habilitadas) do iniciador para que um nó secundário aplique as políticas de linha da mesma forma, em vez de recorrer às roles padrão do usuário. Preenchida somente para consultas entre servidores e apenas quando `push_external_roles_in_interserver_queries = 1`; clientes externos enviam `0` (ausente). Obrigatório quando a versão negociada for ≥ 54488 — omitir o byte de presença dessincroniza o restante do pacote Query.                                                                       |
| HTTP\_HANDLER\_IN\_CLIENT\_INFO            | 54490  | ClientInfo                       | Adiciona `http_handler_name` e `http_request_url` (ambos `String`) ao ramo **HTTP** de ClientInfo, imediatamente após `http_referer`. Eles carregam o nome do handler HTTP definido em SQL correspondente e a URL da solicitação, para que `currentHandler`/`currentRequestURL` e as colunas `http_handler_name`/`http_request_url` de `system.query_log` permaneçam preenchidas em shards remotos para consultas distribuídas do handler. Gravados somente quando `query_interface = HTTP` (strings vazias para uma consulta HTTP sem handler); obrigatório quando a versão negociada for ≥ 54490 — omiti-los dessincroniza o restante do pacote Query.                                                                                                                                |
| QUANTILE\_DETERMINISTIC\_SKIP\_DEGREE      | 54491  | Block (Column)                   | Eleva a versão de estado de `AggregateFunction(quantileDeterministic, ...)` (e das grafias `quantiles`/`median`) de `0` para `1`, o que anexa um `UInt8 skip_degree` ao final de cada estado serializado. Apenas a carga útil de estado dessa função agregada é alterada; o enquadramento da coluna permanece intacto, e todas as outras funções agregadas mantêm sua própria versão. Abaixo desta revisão, o gravador emite estados da versão `0`, portanto um peer mais antigo não é afetado.                                                                                                                                                                                                                                                                                         |

<div id="packet-envelope">
  ## Encapsulamento do pacote
</div>

Toda mensagem no wire tem a mesma estrutura externa, em ambas as direções:

```text theme={null}
[VarUInt: packet_type_code]    always encoded as VarUInt
[message body]                 format depends on packet_type_code
```

As tabelas completas dos tipos de pacote estão na [referência de tipos de pacote](#packet-type-reference).

O tipo de pacote é um `VarUInt`, não um byte de largura fixa. Para valores abaixo de 128, um `VarUInt` produz o mesmo único byte, mas as implementações devem usar a codificação `VarUInt` para permanecer compatíveis caso tipos de pacote futuros cheguem a 128 ou mais.

A [referência de mensagens](#message-reference) documenta apenas o **corpo** de cada pacote — os bytes após o código do tipo de pacote. A numeração dos campos começa em 1, com o primeiro campo do corpo.

<div id="chunked-framing">
  ### Enquadramento em fragmentos (v54470+)
</div>

Quando o recurso `CHUNKED_PROTOCOL` é **negociado** (consulte [o handshake](#handshake-phase)), cada pacote no wire é envolvido por um enquadramento em fragmentos. Esse encapsulamento é **por direção**: cliente→servidor e servidor→cliente são negociados separadamente e podem acabar em modos diferentes (em fragmentos versus sem enquadramento).

Layout no wire de cada pacote:

```text theme={null}
<chunk>...   one or more chunks; their payloads concatenated form the whole packet
[u32 LE = 0] zero-size terminator marking end of packet
```

Layout wire por fragmento:

```text theme={null}
[u32 LE: chunk_size]   chunk_size in [1, UINT32_MAX]
[chunk_size bytes]     packet bytes (see note below)
```

O tipo de pacote `VarUInt` está **dentro** do fluxo em fragmentos: ele é o primeiro byte do payload do pacote (o primeiro byte do primeiro fragmento), não um byte separado enviado antes do framing. O payload em fragmentos de cada pacote é o `[VarUInt packet_type_code][message body]` completo do [envelope do pacote](#packet-envelope). Um cliente que deixa o tipo de pacote fora do fluxo em fragmentos faz com que a outra ponta leia esse byte de tipo como o primeiro byte do tamanho do fragmento `u32`, dessincronizando a conexão.

Um único pacote pode ser dividido em vários fragmentos se o buffer do gravador encher no meio do pacote; uma divisão pode ocorrer em qualquer ponto, inclusive dentro do `VarUInt` do tipo de pacote. O leitor concatena os payloads dos fragmentos e trata o zero final de 4 bytes como um limite de pacote transparente — ele o consome, mas não o expõe ao que estiver lendo os corpos dos pacotes.

Pacotes sem corpo ainda são encapsulados: um pacote de um único byte, como `Ping` ou `Pong`, torna-se `[u32 size = 1][0x04][u32 0]` assim que o envio em fragmentos é negociado. Qualquer descrição de "byte único no wire" em outro ponto desta página se refere à forma anterior ao envio em fragmentos.

**Negociação.** ServerHello e Addendum carregam, cada um, dois campos `String`, um por direção, com valores de `{"chunked", "notchunked", "chunked_optional", "notchunked_optional"}`:

* `chunked` / `notchunked` são estritos: esse lado exige exatamente esse modo.
* As variantes `_optional` são flexíveis: aceitam qualquer modo que o outro lado escolher.

O valor acordado para cada direção é calculado em pares:

| Preferência do servidor   | Preferência do cliente    | Acordado                                             |
| ------------------------- | ------------------------- | ---------------------------------------------------- |
| `*_optional`              | qualquer valor            | seguir o CLIENT (seu `starts_with("chunked")`)       |
| qualquer valor            | `*_optional`              | seguir o SERVER                                      |
| `chunked` estrito         | `chunked` estrito         | `chunked`                                            |
| `notchunked` estrito      | `notchunked` estrito      | `notchunked`                                         |
| incompatibilidade estrita | incompatibilidade estrita | **erro de protocolo** — a conexão DEVE ser encerrada |

No lado do cliente, a preferência de ENVIO do cliente é negociada com a preferência de RECEBIMENTO do servidor, e vice-versa.

**Temporização.** As strings de negociação trafegam no wire sem framing: ClientHello → ServerHello (preferências do servidor) → Addendum (valores negociados do cliente). A mudança de framing se aplica a cada byte enviado *depois* que o Addendum é descarregado do buffer. O próprio Addendum, o ClientHello e o ServerHello nunca usam framing.

<div id="connection-lifecycle">
  ## Ciclo de vida da conexão
</div>

A qualquer momento, uma conexão está em exatamente um de quatro estados: `HANDSHAKE`, `READY`, `READING_RESPONSE` ou encerrada. Como o protocolo não oferece multiplexação, um cliente que envia uma nova solicitação antes de consumir totalmente a resposta anterior intercala bytes no wire e corrompe o fluxo.

<div id="states">
  ### Estados
</div>

```mermaid theme={null}
stateDiagram-v2
    [*] --> HANDSHAKE: TCP connect

    HANDSHAKE --> READY: handshake ok
    READY --> READING_RESPONSE: send Query
    READING_RESPONSE --> READY: EndOfStream / Exception
    READY --> READY: Ping / Pong

    HANDSHAKE --> Terminated: handshake error
    READING_RESPONSE --> Terminated: protocol violation / I/O error
    READY --> Terminated: close
    Terminated --> [*]
```

O fluxo principal segue em linha reta — `HANDSHAKE → READY → READING_RESPONSE → READY` — com o loop de `Ping`/`Pong` e todas as transições de falha convergindo para o único sink `Terminated`.

| Estado             | Descrição                                                                                                                                                                                                                                   |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HANDSHAKE`        | Estado inicial após a abertura da conexão TCP. Somente mensagens de [handshake](#handshake-phase) são válidas. Faz a transição para `READY` em caso de sucesso ou é encerrado em caso de falha.                                             |
| `READY`            | Ocioso. O cliente pode enviar [Ping](#ping-phase), [consulta](#query-phase) ou fechar a conexão. A conexão pode permanecer em `READY` indefinidamente (sujeita a `idle_connection_timeout`, veja [limites de conexão](#connection-limits)). |
| `READING_RESPONSE` | É acessado quando o cliente envia uma consulta. O cliente deve consumir completamente o fluxo de resposta do servidor antes de retornar a `READY`. O único pacote cliente→servidor permitido aqui é Cancel (não especificado nesta página). |
| Terminated         | Não pode mais ser usado. O cliente deve abrir uma nova conexão TCP e reiniciar o handshake.                                                                                                                                                 |

<div id="handshake-phase">
  ### Fase de handshake
</div>

Autentica e negocia a versão do protocolo. Ocorre exatamente uma vez por conexão, antes de qualquer outra coisa.

A conexão TCP acabou de ser aberta e nenhuma mensagem foi trocada. O fluxo:

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant C as Client
    participant S as Server

    C->>S: ClientHello
    alt success
        S->>C: ServerHello
    else error
        S->>C: Exception — connection terminates
    end
    Note over C,S: negotiated_version = min(client, server)
    opt negotiated_version ≥ 54458
        C->>S: Addendum
    end
```

1. O cliente envia [`ClientHello`](#clienthello) com a versão máxima de protocolo compatível.

2. O cliente lê a resposta e a encaminha de acordo com o tipo de pacote:

   | Tipo de pacote  | Ação                                                                                                                           |
   | --------------- | ------------------------------------------------------------------------------------------------------------------------------ |
   | `Hello` (0)     | Decodifica [`ServerHello`](#serverhello). Calcula `negotiated_version = min(client_ver, server_ver)`. Prossiga para o passo 3. |
   | `Exception` (2) | Decodifica [`Exception`](#exception). Retorna como erro e encerra a conexão.                                                   |
   | qualquer outro  | Violação de protocolo. Encerra a conexão.                                                                                      |

3. Se `negotiated_version ≥ 54458` (o recurso `ADDENDUM`), o cliente envia um [`Addendum`](#addendum). Essa decisão se baseia na versão **negociada**, não na versão declarada pelo cliente.

Em caso de sucesso, a conexão passa para `READY`; em caso de erro, ela é encerrada.

<div id="ping-phase">
  ### Fase de Ping
</div>

Uma verificação de liveness em nível de aplicação, independente do keepalive do TCP. Uma troca de Ping/Pong bem-sucedida confirma que a conexão TCP está ativa em ambas as direções e que o servidor está respondendo. O Ping é sem estado e não está correlacionado a nenhuma consulta, portanto vários Pings sequenciais são independentes.

Partindo de `READY`, o fluxo é:

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant C as Client
    participant S as Server

    C->>S: Ping (0x04)
    alt responsive
        S->>C: Pong (0x04)
    else error
        S->>C: Exception
    end
```

1. O cliente envia [`Ping`](#ping).
2. O cliente lê a resposta:

   | Tipo de pacote  | Ação                                                       |
   | --------------- | ---------------------------------------------------------- |
   | `Pong` (4)      | Disponibilidade confirmada. Retorne para `READY`.          |
   | `Exception` (2) | Decodifique [`Exception`](#exception) e retorne como erro. |
   | qualquer outro  | Violação de protocolo.                                     |

<div id="query-phase">
  ### Fase da consulta
</div>

O cliente envia uma instrução SQL; o servidor retorna, em fluxo contínuo, os blocos de resultados e a telemetria de execução. A resposta é uma sequência de pacotes terminada por exatamente um `EndOfStream` ou `Exception`.

Partindo de `READY`, o fluxo é:

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant C as Client
    participant S as Server

    C->>S: Query message
    C->>S: External-table Data packets (0 or more)
    C->>S: Empty Data marker — end-of-client-data (required)
    S->>C: Data — header block (N cols, 0 rows)
    loop until EndOfStream or Exception
        S->>C: Progress / Log (interleaved)
        S->>C: Data — result block (N cols, M rows)
        S->>C: Totals / Extremes (aggregation queries)
        S->>C: ProfileInfo / ProfileEvents (profiling)
    end
    S->>C: Data — empty block (boundary marker)
    S->>C: Progress — final updates
    S->>C: EndOfStream — authoritative end of query
```

Em caso de erro em qualquer ponto, o servidor envia uma `Exception` em vez de `EndOfStream`, o que encerra a consulta.

1. O cliente envia [`Query`](#query) com um `query_id` exclusivo (normalmente um UUID).
2. O cliente envia quaisquer tabelas externas e, em seguida, o marcador `Data` vazio. O pacote `Data` vazio tem `table_name = ""`, `num_columns = 0`, `num_rows = 0`. O servidor não começa a executar a consulta até receber esse marcador.
3. O cliente passa para `READING_RESPONSE` e faz flush do buffer de escrita.
4. O cliente lê os pacotes de resposta em loop, despachando por tipo:

   | Tipo de pacote       | Ação                                                                                                                                                                                                   |
   | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
   | `Data` (1)           | Decodifique o bloco. O primeiro `Data` é o cabeçalho do esquema; os seguintes são blocos de resultado (acumule-os); um bloco vazio é um marcador de limite. `num_rows == 0` **não** é fim de consulta. |
   | `Progress` (3)       | Métricas de execução. Cada pacote é um **incremento** em relação ao anterior — acumule localmente.                                                                                                     |
   | `EndOfStream` (5)    | Consulta concluída. Saia do loop e retorne para `READY`.                                                                                                                                               |
   | `ProfileInfo` (6)    | Dados de profiling pós-execução.                                                                                                                                                                       |
   | `Totals` (7)         | Bloco de totais da agregação (mesmo wire format de `Data`).                                                                                                                                            |
   | `Extremes` (8)       | Bloco de valores mínimo/máximo (mesmo wire format de `Data`).                                                                                                                                          |
   | `Log` (10)           | Linha de log do servidor.                                                                                                                                                                              |
   | `TableColumns` (11)  | Metadados de valores padrão de coluna.                                                                                                                                                                 |
   | `ProfileEvents` (14) | Counters de desempenho.                                                                                                                                                                                |
   | `Exception` (2)      | Decodifique e retorne como erro. Saia do loop e retorne para `READY`.                                                                                                                                  |
   | qualquer outro       | Inesperado durante a fase da consulta. Encerre a conexão.                                                                                                                                              |

Em `EndOfStream` ou em uma `Exception` tratada, a conexão retorna para `READY`. Uma violação de protocolo ou erro de E/S a encerra.

<Note>
  O caso `num_rows == 0` costuma confundir novas implementações. Um bloco com zero linhas é um marcador de limite ou um cabeçalho de esquema, não um sinal de fim de stream. Somente `EndOfStream` ou `Exception` encerra a resposta.
</Note>

<div id="insert-phase">
  ### Fase INSERT
</div>

A fase INSERT é a [fase de consulta](#query-phase) com duas trocas adicionais. O cliente envia uma instrução `INSERT`; o servidor responde com um **bloco de esquema** que descreve a tabela de destino; o cliente transmite pacotes Data com as linhas e, em seguida, o marcador Data vazio; o servidor finaliza com `EndOfStream` ou `Exception`.

Partindo de `READY`, o SQL é um `INSERT` no formato `INSERT INTO <table> [(<cols>)] VALUES` — sem um literal `VALUES (...)` embutido, já que os dados das linhas fluem por meio de pacotes Data. O fluxo:

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant C as Client
    participant S as Server

    C->>S: Query packet (INSERT body)
    C->>S: External-table Data packets (0 or more)
    Note over C,S: No empty Data marker here —<br/>it would end the row stream before it starts
    opt metadata before schema
        S->>C: TableColumns / Progress / ...
    end
    S->>C: Data packet — schema block (columns, 0 rows)
    Note over C,S: Schema block is the contract:<br/>rows sent next must match these column shapes
    loop one or more blocks
        C->>S: Data packet (rows N)
    end
    C->>S: Data packet — empty block (0 rows), end-of-input terminator
    loop until EndOfStream or Exception
        S->>C: Progress / ProfileInfo / Log / ProfileEvents
    end
    opt async_insert = 1 and negotiated_version ≥ 54484
        S->>C: trailing Progress, then insert ProfileEvents
    end
    S->>C: EndOfStream
```

1. O cliente envia [`Query`](#query) com `body` definido como o SQL de INSERT.
2. O cliente envia quaisquer tabelas externas (raro em INSERT). Diferentemente da [fase de consulta](#query-phase), ele **não** envia aqui um marcador Data vazio. O pacote `Query` de `INSERT` é enviado com dados pendentes, portanto o bloco vazio de fim de dados é adiado para a etapa 5; enviá-lo antes do bloco de esquema faria o servidor interpretá-lo como o fim do stream de linhas, concluir o INSERT sem linhas e então analisar o primeiro pacote de linha real como um pacote avulso de nível superior.
3. O cliente drena os pacotes de metadados (TableColumns, Progress, ProfileInfo, Log, ProfileEvents) até ler o pacote Data de esquema — um Block com 0 linhas, mas com a estrutura completa das colunas (nomes e tipos). O bloco de esquema é o contrato: as linhas que o cliente envia em seguida devem corresponder a essas estruturas de coluna.
4. O cliente envia bloco(s) de dados. Para cada bloco, ele grava `VarUInt(ClientPacket::Data = 2)`, depois `String("")` para o nome vazio da tabela externa, e então o Block. Os tipos das colunas devem corresponder, por posição, às colunas do bloco de esquema.
5. O cliente envia o terminador de fim de entrada: um pacote Data com um Block vazio (0 colunas, 0 linhas).
6. O cliente drena o stream de resposta até `EndOfStream` (sucesso) ou `Exception` (falha).

**INSERT assíncrono (v54484+).** Quando a consulta inclui `async_insert = 1`, o servidor enfileira as linhas e faz o flush delas como parte de um batch. Na versão negociada ≥ 54484 (`PROGRESS_IN_ASYNC_INSERT`), assim que o flush é concluído, o servidor emite um pacote extra de [`Progress`](#progress), imediatamente seguido pelos `ProfileEvents` do insert e então por `EndOfStream`. Abaixo de 54484, o servidor omite esse Progress final. O pacote é um `Progress` comum; como o servidor redefine o pipeline da consulta antes de incorporar as contagens de escrita, na prática o incremento carrega apenas o tempo decorrido, e as estatísticas de linhas e bytes gravados chegam ao cliente por meio dos `ProfileEvents` correspondentes. Um cliente que já drena pacotes `Progress` intercalados na etapa 6 só precisa aceitar mais um pacote.

A conexão retorna para `READY` em `EndOfStream` ou em uma `Exception` tratada. Violações de protocolo e erros de E/S a encerram.

<div id="message-reference">
  ## Referência de mensagens
</div>

Os campos estão listados na ordem em que aparecem no wire. A coluna `Type` usa:

* `VarUInt` — inteiro sem sinal de comprimento variável (consulte [VarUInt](/pt-BR/reference/interfaces/specs/NativeFormat#varuint)).
* `String` — bytes com prefixo VarUInt (consulte [String](/pt-BR/reference/interfaces/specs/NativeFormat#string)).
* `UInt8`, `Int32` e assim por diante — inteiros little-endian de largura fixa.
* `Bool` — um único byte, `0x00` ou `0x01`.

A coluna `Role` indica quem usa cada campo:

* **client** — definido por clientes externos.
* **inter-server** — relevante apenas para a comunicação entre servidores; clientes externos gravam um valor padrão.
* **universal** — usado por ambos.

Estas tabelas documentam apenas o corpo de cada pacote, após o código do tipo de pacote.

<div id="clienthello">
  ### ClientHello (tipo de pacote 0)
</div>

Cliente → servidor. A primeira mensagem após o estabelecimento da conexão TCP.

| # | Campo             | Tipo    | Função    | Descrição                                                     |
| - | ----------------- | ------- | --------- | ------------------------------------------------------------- |
| 1 | client\_name      | String  | universal | Identificador do cliente (por exemplo, `"clickhouse-client"`) |
| 2 | version\_major    | VarUInt | universal | Versão principal do cliente                                   |
| 3 | version\_minor    | VarUInt | universal | Versão secundária do cliente                                  |
| 4 | protocol\_version | VarUInt | universal | Versão máxima do protocolo compatível com o cliente           |
| 5 | database          | String  | universal | nome do banco de dados padrão                                 |
| 6 | user              | String  | universal | Nome de usuário para autenticação                             |
| 7 | password          | String  | universal | Senha (em texto simples)                                      |

<div id="serverhello">
  ### ServerHello (tipo de pacote 0)
</div>

Servidor → Cliente. A resposta a ClientHello em caso de autenticação bem-sucedida.

| #  | Field                                 | Type       | Role         | Condition                                        | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| -- | ------------------------------------- | ---------- | ------------ | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1  | server\_name                          | String     | universal    | sempre                                           | Identificador do servidor                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| 2  | version\_major                        | VarUInt    | universal    | sempre                                           | Versão principal do servidor                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| 3  | version\_minor                        | VarUInt    | universal    | sempre                                           | Versão secundária do servidor                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| 4  | protocol\_version                     | VarUInt    | universal    | sempre                                           | Versão do protocolo do servidor                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| 4a | parallel\_replicas\_protocol\_version | VarUInt    | universal    | VERSIONED\_PARALLEL\_REPLICAS\_PROTOCOL (v54471) | Versão do protocolo de coordination de réplicas paralelas do servidor. **Posição no wire: imediatamente após `protocol_version`**, antes de `timezone`. Atual: `8`.                                                                                                                                                                                                                                                                                                               |
| 5  | timezone                              | String     | universal    | TIMEZONE (v54058)                                | Fuso horário do servidor (por exemplo, `"UTC"`)                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| 6  | display\_name                         | String     | universal    | DISPLAY\_NAME (v54372)                           | Nome legível por humanos do servidor                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| 7  | version\_patch                        | VarUInt    | universal    | VERSION\_PATCH (v54401)                          | Versão de patch do servidor                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| 8  | proto\_send\_chunked\_srv             | String     | universal    | CHUNKED\_PROTOCOL (v54470)                       | Fragmentação de saída preferida do servidor. Um de `"chunked"`, `"notchunked"`, `"chunked_optional"`, `"notchunked_optional"`. Consulte [enquadramento por fragmentos](#chunked-framing). **Fica ANTES de `password_complexity_rules` no wire, embora seu gate de versão seja mais alto.**                                                                                                                                                                                        |
| 9  | proto\_recv\_chunked\_srv             | String     | universal    | CHUNKED\_PROTOCOL (v54470)                       | Fragmentação de entrada preferida do servidor. Mesmo conjunto de valores do campo 8.                                                                                                                                                                                                                                                                                                                                                                                              |
| 10 | password\_complexity\_rules           | Rule\[]    | universal    | PASSWORD\_COMPLEXITY\_RULES (v54461)             | Política de senhas do servidor. `VarUInt count` seguido de `count × Rule`. Veja abaixo.                                                                                                                                                                                                                                                                                                                                                                                           |
| 11 | nonce                                 | UInt64     | inter-server | INTERSERVER\_SECRET\_V2 (v54462)                 | Nonce aleatório LE de 8 bytes. O esquema de assinatura de consultas inter-server do servidor o utiliza. Clientes externos DEVEM decodificá-lo (para manter o fluxo alinhado) e DEVERIAM ignorar o valor.                                                                                                                                                                                                                                                                          |
| 12 | server\_settings                      | Setting\[] | universal    | SERVER\_SETTINGS (v54474)                        | Broadcast das configurações não padrão do servidor. Formato: zero ou mais triplas `(String key, VarUInt flags, String value)`, terminadas por uma chave vazia. Igual à [lista de configuração do pacote Query](#setting).                                                                                                                                                                                                                                                         |
| 13 | query\_plan\_serialization\_version   | VarUInt    | universal    | QUERY\_PLAN\_SERIALIZATION (v54477)              | Versão de serialização do plano de consulta compatível com o servidor. Clientes externos decodificam e ignoram.                                                                                                                                                                                                                                                                                                                                                                   |
| 14 | cluster\_function\_protocol\_version  | VarUInt    | universal    | VERSIONED\_CLUSTER\_FUNCTION\_PROTOCOL (v54479)  | Versão do protocolo da table function `*Cluster` do servidor. Atual: `8`. O valor controla campos aditivos no payload inter-server da tarefa de leitura do cluster (o corpo `ReadTaskResponse`, que de outra forma não é especificado); a versão `7` é reservada para um recurso de repositório privado (compaction do Iceberg), e `8` adiciona um `read_source_index` opcional. Clientes externos não participam de leituras de cluster — eles decodificam e ignoram este campo. |

**Rule** — um elemento de `password_complexity_rules`:

| # | Field   | Type   | Description                                                                |
| - | ------- | ------ | -------------------------------------------------------------------------- |
| 1 | pattern | String | Expressão regular à qual uma senha compatível deve corresponder.           |
| 2 | message | String | Explicação legível por humanos exibida quando uma senha falha nesta regra. |

A lista reflete a configuração da política de senhas do operador do servidor e é puramente consultiva — o servidor não aplica essas regras durante o handshake. Um cliente que exponha funcionalidade de alteração/definição de senha pode usar as regras para sinalizar erros antes de fazer o round-trip de uma senha incompatível até o servidor.

<Note>
  Para limitar o uso de recursos diante de um servidor hostil ou mal configurado, limite o `count` decodificado a 256 entradas e cada String `pattern` e `message` a 4096 bytes. Um `count` de `0` (sem pares subsequentes) é o caso comum para servidores sem política de senhas configurada.
</Note>

<div id="addendum">
  ### Adendo (sem tipo de pacote)
</div>

Cliente → Servidor, condicionado a `ADDENDUM` (v54458). Enviado imediatamente após a conclusão da troca de handshake. Não é um tipo de pacote distinto — os campos vão pelo wire em bruto, sem prefixo de byte de tipo de pacote.

| # | Campo                                 | Tipo    | Função    | Condição                                         | Descrição                                                                                                                                                                                                                                                                               |
| - | ------------------------------------- | ------- | --------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | quota\_key                            | String  | universal | sempre                                           | Chave de quota de recurso para quotas com chave do lado do servidor. Clientes que não usam quota com chave enviam uma string vazia.                                                                                                                                                     |
| 2 | proto\_send\_chunked                  | String  | universal | CHUNKED\_PROTOCOL (v54470)                       | Fragmentação de saída negociada pelo cliente: `"chunked"` ou `"notchunked"`. Calculada com base em `proto_recv_chunked_srv` de ServerHello.                                                                                                                                             |
| 3 | proto\_recv\_chunked                  | String  | universal | CHUNKED\_PROTOCOL (v54470)                       | Fragmentação de entrada negociada pelo cliente. Calculada com base em `proto_send_chunked_srv`.                                                                                                                                                                                         |
| 4 | parallel\_replicas\_protocol\_version | VarUInt | universal | VERSIONED\_PARALLEL\_REPLICAS\_PROTOCOL (v54471) | Versão do protocolo de coordination de réplicas paralelas compatível com o cliente. Clientes externos que não participam de consultas distribuídas AINDA ASSIM DEVEM enviar uma versão válida (atualmente `8`) para que a verificação de compatibilidade do servidor seja bem-sucedida. |

A mudança para o enquadramento chunked se aplica *depois* que este Adendo é enviado — o próprio Adendo não tem enquadramento.

<div id="ping">
  ### Ping (tipo de pacote 4)
</div>

Cliente → servidor. Sem corpo — o pacote é um único byte `0x04` antes do enquadramento por fragmentos; quando o uso de fragmentos é negociado, o byte passa a ser o payload de um byte de um fragmento (consulte [enquadramento por fragmentos](#chunked-framing)).

<div id="pong">
  ### Pong (tipo de pacote 4)
</div>

Servidor → cliente. Sem corpo — o pacote é um único byte `0x04` antes do enquadramento por fragmentos; quando a fragmentação é negociada, o byte se torna o payload de um byte de um fragmento (consulte [enquadramento por fragmentos](#chunked-framing)).

<div id="exception">
  ### Exception (tipo de pacote 2)
</div>

Servidor → Cliente. Enviado quando o servidor encontra um erro durante qualquer fase.

| # | Campo                  | Tipo   | Papel     | Descrição                                                                   |
| - | ---------------------- | ------ | --------- | --------------------------------------------------------------------------- |
| 1 | code                   | Int32  | universal | Código de erro                                                              |
| 2 | name                   | String | universal | Classe da Exception (por exemplo, `"DB::Exception"`)                        |
| 3 | message                | String | universal | Mensagem de erro legível para humanos                                       |
| 4 | stack\_trace           | String | universal | Stack trace no servidor                                                     |
| 5 | has\_nested (obsoleto) | Bool   | universal | Byte de compatibilidade obsoleto. Sempre gravado como `false` pelo servidor |

<div id="query">
  ### Consulta (tipo de pacote 1)
</div>

Cliente → servidor.

| #  | Campo           | Type         | Função       | Condição                                         | Descrição                                                                                                                                                                                                                                                                                                                                                         |
| -- | --------------- | ------------ | ------------ | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1  | query\_id       | String       | universal    | sempre                                           | Identificador único da consulta (UUID)                                                                                                                                                                                                                                                                                                                            |
| 2  | client\_info    | ClientInfo   | universal    | CLIENT\_INFO (v54032)                            | Veja [ClientInfo](#clientinfo)                                                                                                                                                                                                                                                                                                                                    |
| 3  | settings        | Setting\[]   | universal    | sempre                                           | Veja [Setting](#setting). **Sempre presente** (terminado por uma chave vazia); apenas a *codificação* de cada configuração depende da versão — veja a observação sobre codificação em [Setting](#setting). Um cliente não deve omitir este campo para versões negociadas abaixo de `54429`.                                                                       |
| 3a | external\_roles | String       | universal    | INTERSERVER\_EXTERNALLY\_GRANTED\_ROLES (v54472) | Lista serializada de nomes de roles concedidos externamente. Lista vazia = byte `0x00` (VarUInt 0) encapsulado em um envelope String (`[VarUInt 1][0x00]` no wire). Clientes externos sempre enviam uma lista vazia.                                                                                                                                              |
| 4  | auth\_hash      | String       | inter-server | INTERSERVER\_SECRET (v54441)                     | Hash de autenticação entre servidores — **não** o segredo bruto do cluster. Veja [Autenticação entre servidores](#inter-server-authentication) abaixo. Clientes externos (e qualquer `InitialQuery`) enviam uma string vazia.                                                                                                                                     |
| 5  | stage           | VarUInt      | universal    | sempre                                           | Estágio de processamento da consulta. `0` = FetchColumns, `1` = WithMergeableState, `2` = Complete, `3` = WithMergeableStateAfterAggregation, `4` = WithMergeableStateAfterAggregationAndLimit, `7` = QueryPlan. Os valores `3`/`4` aparecem em consultas distribuídas; `7` acompanha um plano de consulta serializado. Clientes externos normalmente enviam `2`. |
| 6  | compression     | VarUInt      | universal    | sempre                                           | 0 = desativado, 1 = ativado                                                                                                                                                                                                                                                                                                                                       |
| 7  | query\_body     | String       | universal    | sempre                                           | Texto SQL                                                                                                                                                                                                                                                                                                                                                         |
| 8  | parameters      | Parameter\[] | client       | PARAMETERS (v54459)                              | Veja [Parameter](#parameter). Terminado por chave vazia.                                                                                                                                                                                                                                                                                                          |

<div id="clientinfo">
  ### ClientInfo (embutido em consulta)
</div>

Cliente → servidor, embutido no corpo da consulta (campo 2). Condicionado a `CLIENT_INFO` (v54032). (Alguns campos dentro de ClientInfo são condicionados a versões posteriores, como indicado abaixo em cada campo.)

| #  | Campo                          | Tipo                       | Papel        | Condição                                         | Descrição                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| -- | ------------------------------ | -------------------------- | ------------ | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1  | query\_kind                    | UInt8                      | universal    | sempre                                           | 0 = NoQuery, 1 = InitialQuery, 2 = SecondaryQuery. Clientes externos enviam `1`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| 2  | initial\_user                  | String                     | universal    | sempre                                           | Usuário que iniciou a consulta                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| 3  | initial\_query\_id             | String                     | universal    | sempre                                           | ID original da consulta                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| 4  | initial\_address               | String                     | universal    | sempre                                           | Endereço do socket do cliente de origem. O servidor nunca resolve este valor (sem resolução de hostname nem busca de nome de serviço). Para uma `SECONDARY_QUERY` (em que o valor é mantido e usado, por exemplo, em `system.query_log` e na autenticação inter-server), a gramática aceita é IPv4 `a.b.c.d:port` ou IPv6 entre colchetes `[addr]:port`, com o host sendo um IP literal e a porta sendo um número decimal em `0..65535`; outros formatos (por exemplo, `localhost:9000`, `host:http`, `:9000` ou um caminho de socket UNIX como `/tmp/ch.sock`) são rejeitados com `INCORRECT_DATA`. Para uma `INITIAL_QUERY`, o servidor substitui este campo pelo endereço real do peer, portanto qualquer valor é aceito (um valor que não seja um `ip:port` simples é substituído pelo `default` `0.0.0.0:0`). Clientes externos devem enviar seu próprio `ip:port`. |
| 5  | initial\_time                  | Int64                      | client       | INITIAL\_QUERY\_START\_TIME (v54449)             | Horário de início da consulta (microssegundos). Largura fixa de 8 bytes, não VarUInt                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| 6  | query\_interface               | UInt8                      | universal    | sempre                                           | 1 = TCP, 2 = HTTP                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| 7  | os\_user                       | String                     | client       | se interface = TCP                               | Nome de usuário do sistema operacional                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| 8  | client\_hostname               | String                     | client       | se interface = TCP                               | Nome do host da máquina cliente                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| 9  | client\_name                   | String                     | client       | se interface = TCP                               | Nome da aplicação cliente                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| 10 | version\_major                 | VarUInt                    | universal    | se interface = TCP                               | Versão principal do cliente                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| 11 | version\_minor                 | VarUInt                    | universal    | se interface = TCP                               | Versão secundária do cliente                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| 12 | protocol\_version              | VarUInt                    | universal    | se interface = TCP                               | A própria versão do protocolo TCP do cliente de origem (`DBMS_TCP_PROTOCOL_VERSION`), **não** a versão negociada. A revisão do peer apenas decide quais campos estão presentes; este valor é a versão compilada no iniciador, portanto, em um cliente mais novo se comunicando com um servidor mais antigo, ele pode ser maior que a revisão negociada/do servidor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| 13 | quota\_key                     | String                     | universal    | QUOTA\_KEY\_IN\_CLIENT\_INFO (v54060)            | Chave de cota de recursos para cotas com chave no lado do servidor. Clientes que não usam uma cota com chave enviam uma string vazia.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| 14 | distributed\_depth             | VarUInt                    | inter-server | DISTRIBUTED\_DEPTH (v54448)                      | Profundidade de aninhamento da consulta distribuída. Clientes externos enviam `0`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| 15 | version\_patch                 | VarUInt                    | universal    | VERSION\_PATCH (v54401), somente TCP             | Versão de patch do cliente                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| 16 | open\_telemetry                | (abaixo)                   | client       | OPEN\_TELEMETRY (v54442)                         | contexto de rastreamento. Clientes sem rastreamento enviam `0`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| 17 | collaborate\_with\_initiator   | VarUInt                    | inter-server | PARALLEL\_REPLICAS (v54453)                      | Bool como VarUInt. Clientes externos enviam `0`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| 18 | count\_participating\_replicas | VarUInt                    | inter-server | PARALLEL\_REPLICAS (v54453)                      | Clientes externos enviam `0`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| 19 | number\_of\_current\_replica   | VarUInt                    | inter-server | PARALLEL\_REPLICAS (v54453)                      | Clientes externos enviam `0`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| 20 | script\_query\_number          | VarUInt                    | client       | QUERY\_AND\_LINE\_NUMBERS (v54475)               | Posição da instrução, com índice iniciado em 1, em um script com múltiplas instruções. Clientes externos enviam `0`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| 21 | script\_line\_number           | VarUInt                    | client       | QUERY\_AND\_LINE\_NUMBERS (v54475)               | Número da linha, com índice iniciado em 1, dentro do script de origem. Clientes externos enviam `0`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| 22 | jwt\_present                   | UInt8                      | inter-server | JWT\_IN\_INTERSERVER (v54476)                    | `0` = sem JWT; `1` = JWT em seguida. Clientes externos sem autenticação JWT enviam `0`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| 23 | jwt                            | String                     | inter-server | JWT\_IN\_INTERSERVER (v54476), se jwt\_present=1 | Bearer token JWT, presente somente quando o campo 22 = `1`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| 24 | client\_agent                  | String                     | client       | CLIENT\_AGENT\_IN\_CLIENT\_INFO (v54485)         | Campo final. Identificador da ferramenta/agente cliente, detectado automaticamente a partir do ambiente (por exemplo, `claude-code`, `cursor`, `gemini-cli` ou a variável de ambiente `AGENT`). Clientes externos sem agente detectado enviam uma string vazia. Presente no caminho normal de Query quando a versão negociada é ≥ 54485 (enviado em todas as interfaces, não apenas TCP).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| 25 | is\_internal                   | UInt8                      | client       | INTERNAL\_QUERY\_FLAG (v54486)                   | Campo final. `1` para uma consulta interna do servidor (não iniciada por usuário), propagada para consultas remotas para marcá-las como internas em `system.query_log`; ortogonal a `query_kind` (campo 1). Clientes externos enviam `0`. Presente quando a versão negociada é ≥ 54486 (enviado em todas as interfaces, não apenas TCP).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| 26 | funções\_atuais                | UInt8 \[+ lista de String] | inter-server | INTERSERVER\_CURRENT\_ROLES (v54488)             | Campo final. `[UInt8 present]`, seguido, quando `present = 1`, de uma lista `[VarUInt count][String]*count` com os nomes das funções ativas (habilitadas) do iniciador. Permite que um nó secundário restrinja as políticas de linha às funções do iniciador em vez das funções padrão do usuário. Preenchido somente para consultas inter-server e apenas quando `push_external_roles_in_interserver_queries = 1`; caso contrário, e para clientes externos, `present = 0`. O byte de presença é obrigatório quando a versão negociada é ≥ 54488 (enviado em todas as interfaces, não apenas TCP). Para consultas inter-server, a lista serializada também é incorporada ao `auth_hash` (consulte [Autenticação inter-server](#inter-server-authentication)).                                                                                                           |

<Info>
  **Layout dependente da interface (campos 7–12)**

  Os campos 7–12 acima correspondem ao ramo **TCP**. Quando `query_interface` (campo 6) **não** é TCP, esses campos são *substituídos* por um layout de wire diferente — não se trata apenas de omissões opcionais, portanto um decodificador deve seguir o ramo com base no campo 6.

  * `query_interface = 2` (**HTTP**): nesse caso, são gravadas as informações da requisição HTTP encaminhada pelo servidor — `http_method` (`UInt8`), `http_user_agent` (`String`), depois `forwarded_for` (`String`, condicionado a `X_FORWARDED_FOR_IN_CLIENT_INFO` v54443), `http_referer` (`String`, condicionado a `REFERER_IN_CLIENT_INFO` v54447) e, por fim, `http_handler_name` (`String`) e `http_request_url` (`String`) (ambos condicionados a `HTTP_HANDLER_IN_CLIENT_INFO` v54490, nessa ordem). Os campos `os_user`/`client_hostname`/`client_name`/`version_*`/`protocol_version` não estão presentes. Os dois últimos contêm o nome correspondente do handler HTTP definido em SQL e a URL da requisição, para que sejam preservados nos shards remotos (vazios para uma consulta HTTP sem handler).
  * Qualquer outra interface: nenhum dos campos TCP (7–12) nem dos campos HTTP é gravado; o fluxo segue diretamente para `quota_key`.

  Após esse ramo, o layout volta a convergir: `quota_key` (campo 13) e `distributed_depth` (campo 14) vêm em seguida para todas as interfaces, e `version_patch` (campo 15) é gravado apenas para TCP.

  Esse ramo importa principalmente para o tráfego entre servidores, quando o servidor de origem encaminha uma consulta que chegou originalmente por HTTP. Um decodificador que sempre ler os campos TCP interpretará esses pacotes de forma incorreta — tratando `http_method` ou `http_user_agent` como `quota_key`.
</Info>

Codificação OpenTelemetry (campo 16):

```text theme={null}
[UInt8: has_trace]              0 = no trace data follows, 1 = trace data follows
If has_trace == 1:
  [16 bytes: trace_id]          byte-swapped per-8-bytes
  [8 bytes:  span_id]           byte-swapped
  [String:   trace_state]       W3C trace state
  [UInt8:    trace_flags]       W3C trace flags
```

<div id="inter-server-authentication">
  ### Autenticação entre servidores
</div>

O campo 4 da consulta (`auth_hash`) **não** é o segredo compartilhado do cluster no wire. Enviar o segredo puro faria a autenticação falhar e ainda o exporia. Em vez disso, um servidor atuando como cliente interservidor prova que conhece o segredo com um hash SHA-256 com salt:

1. **Entre no modo interservidor.** O servidor que está se conectando sinaliza isso em `ClientHello`: o campo `user` é o marcador interservidor e `password` fica vazio. Em seguida, ele acrescenta mais duas strings — o nome do cluster e um `salt` de 32 bytes recém-gerado (`encodeSHA256` de um valor aleatório) — imediatamente após os campos `user`/`password`, como parte do mesmo pacote `ClientHello`. O servidor lê essas duas strings **antes** de enviar `ServerHello`, então o cliente precisa escrevê-las logo de saída; esperar primeiro por `ServerHello` causa deadlock, porque o servidor fica bloqueado tentando lê-las.
2. **Obtenha o nonce.** `ServerHello` traz um nonce `UInt64` de 8 bytes quando `INTERSERVER_SECRET_V2` (v54462) é negociado.
3. **Calcule o hash.** Para cada pacote de consulta que não seja `InitialQuery`, o cliente escreve `encodeSHA256(salt + nonce + cluster_secret + query + query_id + initial_user + external_roles + current_roles)` no campo 4 — um digest de 32 bytes. (`nonce` usa sua forma de string decimal, presente somente quando negociado ≥ v54462; `external_roles` é acrescentado somente quando `INTERSERVER_EXTERNALLY_GRANTED_ROLES` (v54472) é negociado; `current_roles` é a lista serializada de nomes de roles — `[VarUInt count][String]*count`, sem o byte de presença — acrescentada somente quando `INTERSERVER_CURRENT_ROLES` (v54488) é negociado e a lista está presente.) Para um `InitialQuery`, ou quando nenhum segredo de cluster está configurado, o cliente escreve uma string vazia.
4. **Verifique.** O servidor lê o campo 4 com um limite de 32 bytes e recompõe a mesma concatenação usando sua própria cópia do segredo do cluster; a conexão é rejeitada se os digests forem diferentes.

Clientes externos (não interservidor) nunca entram nesse modo e sempre enviam `auth_hash` vazio.

<div id="setting">
  ### SETTING
</div>

Codificada em linha na lista de configurações do corpo de consulta (o pacote [consulta](#query), campo 3). A lista **está sempre presente**, independentemente da versão negociada, e é terminada por uma SETTING com `key` vazia — um único `VarUInt 0`, sem `flags` nem `value` em seguida. Apenas a codificação de cada configuração depende da versão negociada, condicionada por `SETTINGS_SERIALIZED_AS_STRINGS` (v54429).

**v54429+ (`STRINGS_WITH_FLAGS`)** — cada configuração é a tripla mostrada aqui:

| # | Campo | Tipo    | Função    | Descrição                                   |
| - | ----- | ------- | --------- | ------------------------------------------- |
| 1 | key   | String  | universal | Nome da configuração. Vazio = fim da lista. |
| 2 | flags | VarUInt | universal | Flags de bits de metadados; veja abaixo.    |
| 3 | value | String  | universal | Valor da configuração como string           |

Os campos 2 e 3 ficam ausentes quando `key` está vazia.

**Pré-54429 (`BINARY`)** — cada configuração é `[String key][type-specific binary value]`: o campo `flags` **não** é gravado, e o valor é codificado na forma binária nativa da configuração (por exemplo, um inteiro de largura fixa ou uma string com prefixo de comprimento), em vez de como uma string decimal/textual. A lista continua sendo terminada por uma `key` vazia. Um cliente que tenha como alvo uma versão negociada inferior a `54429` deve ler e gravar essa forma binária, não a tripla acima. (As configurações personalizadas definidas pelo usuário são a exceção: elas sempre incluem `flags` e um valor em string, em ambas as codificações.)

O campo `flags` agrupa:

* `0x01` — **Important**: a configuração afeta os resultados da consulta e não deve ser ignorada silenciosamente por pares mais antigos.
* `0x02` — **Custom**: uma custom setting definida pelo usuário.
* `0x0c` — um campo de **tier de 2 bits**, não uma flag independente: `0x00` = Production, `0x04` = Obsolete, `0x08` = Experimental, `0x0c` = Beta. Leia os 2 bits completos (`flags & 0x0c`) — um teste ingênuo com `flags & 0x04` classificaria Beta (`0x0c`) incorretamente como Obsolete.
* `0x80` — **HotReload** (recarregamento de config sem reinicialização; definido no enum de flags, encontrado principalmente em configurações de coordination).

<div id="parameter">
  ### Parâmetro
</div>

Parâmetros de consulta, para consultas parametrizadas como `SELECT {x:UInt64}`. Codificados exatamente como uma [SETTING](#setting), com o sinalizador `Custom` (`0x02`) ativado, e encerrados da mesma forma, por uma chave vazia.

| # | Campo | Tipo    | Função  | Descrição                                                             |
| - | ----- | ------- | ------- | --------------------------------------------------------------------- |
| 1 | key   | String  | cliente | Nome do parâmetro. Vazio = fim da lista.                              |
| 2 | flags | VarUInt | cliente | Sempre `0x02` (Custom)                                                |
| 3 | value | String  | cliente | Valor do parâmetro como string. Veja a observação abaixo sobre aspas. |

<Note>
  O valor do parâmetro é a representação SQL do valor, não um literal bruto. Parâmetros do tipo string devem ser passados já entre aspas simples (por exemplo, o valor de `{name:String}` é `'Alice'`, não `Alice`); caso contrário, o analisador de valores do servidor os rejeitará.
</Note>

<div id="data">
  ### Data (tipo de pacote 1 servidor→cliente, tipo de pacote 2 cliente→servidor)
</div>

Em ambas as direções. Transporta blocos de resultado, dados de INSERT, tabelas externas e marcadores de fim dos dados.

O formato wire é simétrico — em ambas as direções, há um prefixo `table_name` antes do Block. Apenas o byte do tipo de pacote difere.

```text theme={null}
[VarUInt: packet_type]     1 (server→client) or 2 (client→server)
[String:  table_name]      External table name; empty in most cases
[Block]                    See the Native Format spec for the Block layout
```

| Campo          | Tipo   | Função    | Descrição                                                                                                                                                                                                                                                                    |
| -------------- | ------ | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| table\_name    | String | universal | Nome da tabela externa. Vazio (`""`) é o caso mais comum — para a tabela principal, os resultados da consulta e o fluxo de linhas de INSERT. `table_name` vazio, por si só, **não** é o marcador de fim de dados (pacotes normais de linhas de INSERT também carregam `""`). |
| Corpo do bloco | —      | —         | Consulte [Block & column structure](/pt-BR/reference/interfaces/specs/NativeFormat#block-and-column-structure).                                                                                                                                                              |

O **marcador de fim de dados** é um pacote cujo Block está vazio — `0` colunas e `0` linhas — independentemente de `table_name`. O servidor trata um pacote `Data` do cliente como terminador apenas quando o bloco decodificado está vazio (`block.empty()`); um pacote com `table_name = ""` e um bloco não vazio é um pacote comum de linhas, não um terminador. Portanto, um fluxo de linhas de INSERT é uma sequência de blocos `Data` não vazios, seguida por um bloco `Data` vazio que o encerra.

As variantes de bloco e seus significados estão documentados em [Block variants](/pt-BR/reference/interfaces/specs/NativeFormat#block-variants).

<div id="progress">
  ### Progress (tipo de pacote 3)
</div>

Servidor → cliente. Enviado periodicamente durante a execução da consulta. Todos os campos são VarUInt, e cada pacote traz **incrementos desde o pacote `Progress` anterior**, não totais acumulados. Antes de enviar, o servidor lê seus contadores, reinicia-os atomicamente para zero e calcula `elapsed_ns` como o delta de tempo desde o último envio. Portanto, um cliente **deve acumular** os pacotes sucessivos localmente para obter totais correntes — tratar um pacote como um valor absoluto faz a exibição do progresso retroceder ou subestimar a contagem quando mais de um pacote chega.

| # | Field        | Type    | Role      | Condition                                  | Description                                                                                                   |
| - | ------------ | ------- | --------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| 1 | rows         | VarUInt | universal | always                                     | Linhas lidas desde o pacote anterior (adicione ao total corrente)                                             |
| 2 | bytes        | VarUInt | universal | always                                     | Bytes lidos desde o pacote anterior (adicione ao total corrente)                                              |
| 3 | total\_rows  | VarUInt | universal | always                                     | Incremento no total estimado de linhas a serem lidas; acumule (pode ser 0 em um determinado pacote)           |
| 4 | total\_bytes | VarUInt | universal | TOTAL\_BYTES\_IN\_PROGRESS (v54463)        | Incremento no total estimado de bytes a serem lidos; acumule. Fica ENTRE `total_rows` e `wrote_rows` no wire. |
| 5 | wrote\_rows  | VarUInt | universal | WRITE\_CLIENT\_INFO (v54420)               | Linhas gravadas desde o pacote anterior (para INSERT); acumule                                                |
| 6 | wrote\_bytes | VarUInt | universal | WRITE\_CLIENT\_INFO (v54420)               | Bytes gravados desde o pacote anterior (para INSERT); acumule                                                 |
| 7 | elapsed\_ns  | VarUInt | universal | SERVER\_QUERY\_TIME\_IN\_PROGRESS (v54460) | Nanosegundos decorridos desde o pacote anterior (um delta, não o tempo total da consulta); acumule            |

<div id="profileinfo">
  ### ProfileInfo (tipo de pacote 6)
</div>

Servidor → cliente. Enviado uma vez por consulta, próximo ao fim da execução.

| # | Campo                     | Tipo    | Função    | Condição                           | Descrição                                                                                                                                                                                                                                                                     |
| - | ------------------------- | ------- | --------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | rows                      | VarUInt | universal | sempre                             | Total de linhas processadas                                                                                                                                                                                                                                                   |
| 2 | blocks                    | VarUInt | universal | sempre                             | Total de blocos processados                                                                                                                                                                                                                                                   |
| 3 | bytes                     | VarUInt | universal | sempre                             | Total de bytes processados                                                                                                                                                                                                                                                    |
| 4 | applied\_limit            | Bool    | universal | sempre                             | Indica se uma cláusula LIMIT foi aplicada                                                                                                                                                                                                                                     |
| 5 | rows\_before\_limit       | VarUInt | universal | sempre                             | Número de linhas antes de LIMIT                                                                                                                                                                                                                                               |
| 6 | *obsolete*                | Bool    | universal | sempre                             | Byte de compatibilidade obsoleto. O servidor sempre escreve `true` aqui, e o cliente o lê e descarta; **não** é um indicador de que "`rows_before_limit` foi calculado". O estado de limite relevante é o campo 4 (`applied_limit`) em conjunto com o campo 5. Leia e ignore. |
| 7 | applied\_aggregation      | Bool    | universal | ROWS\_BEFORE\_AGGREGATION (v54469) | Indica se GROUP BY foi aplicado                                                                                                                                                                                                                                               |
| 8 | rows\_before\_aggregation | VarUInt | universal | ROWS\_BEFORE\_AGGREGATION (v54469) | Número de linhas antes da agregação                                                                                                                                                                                                                                           |

<div id="totals">
  ### Totais (tipo de pacote 7)
</div>

Servidor → Cliente. Enviado para consultas com `WITH TOTALS`. O formato wire é idêntico a [Data](#data): uma string `table_name` (sempre vazia), seguida por um Block. Apenas o byte do tipo de pacote difere.

```text theme={null}
[VarUInt: 7]                packet type
[String:  table_name]       always empty
[Block]                     see the Native Format spec
```

<div id="extremes">
  ### Extremes (tipo de pacote 8)
</div>

Servidor → Client. Enviado quando a configuração `extremes` está ativada. O formato wire é idêntico a [Data](#data). O bloco tem exatamente 2 linhas: a linha 0 contém o mínimo de cada coluna, e a linha 1 contém o máximo.

```text theme={null}
[VarUInt: 8]                packet type
[String:  table_name]       always empty
[Block]                     num_rows = 2
```

<div id="log">
  ### Log (tipo de pacote 10)
</div>

Servidor → cliente. Enviado quando a consulta tem uma fila de logs ativa (a configuração `send_logs_level`; consulte [streaming de logs](#log-streaming)).

Mesmo formato de envelope e corpo que [Data](#data). O bloco tem `num_columns = 8` fixo e um esquema predefinido. Cada linha de log corresponde a uma linha nas 8 colunas, e um único pacote Log pode carregar muitas linhas.

```text theme={null}
[VarUInt: 10]               packet type
[String:  table_name]       always empty
[Block]                     num_columns = 8, num_rows = number of log lines
```

As 8 colunas, nesta ordem exata:

| # | Nome                      | Tipo     | Descrição                                                           |
| - | ------------------------- | -------- | ------------------------------------------------------------------- |
| 1 | event\_time               | DateTime | Timestamp do evento (segundos desde a epoch)                        |
| 2 | event\_time\_microseconds | UInt32   | Componente de microssegundos                                        |
| 3 | host\_name                | String   | Hostname do servidor que emite o log                                |
| 4 | query\_id                 | String   | ID da consulta à qual o log pertence                                |
| 5 | thread\_id                | UInt64   | ID da thread do SO                                                  |
| 6 | priority                  | Int8     | Nível de log (prioridade do Poco: 1 = Fatal, … 8 = Trace, 9 = Test) |
| 7 | source                    | String   | Nome do logger                                                      |
| 8 | text                      | String   | Texto da mensagem de log                                            |

<div id="profileevents">
  ### ProfileEvents (tipo de pacote 14)
</div>

Servidor → cliente. Carrega contadores de desempenho por consulta.

Mesmo formato de envelope e de corpo de [Data](#data). O bloco tem `num_columns = 6` fixo e um esquema predefinido. Cada evento corresponde a uma linha.

```text theme={null}
[VarUInt: 14]               packet type
[String:  table_name]       always empty
[Block]                     num_columns = 6, num_rows = number of events
```

As 6 colunas:

| # | Nome          | Tipo     | Descrição                                                                                             |
| - | ------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| 1 | host\_name    | String   | Hostname do servidor                                                                                  |
| 2 | current\_time | DateTime | Timestamp do evento                                                                                   |
| 3 | thread\_id    | UInt64   | ID da thread                                                                                          |
| 4 | type          | Enum8    | Tipo de evento: 1 = Incremento (contador), 2 = Gauge. O armazenamento subjacente é um byte com sinal. |
| 5 | name          | String   | Nome do evento (por exemplo, `"Query"`, `"NetworkReceiveBytes"`)                                      |
| 6 | value         | Int64    | Valor do contador ou medição do gauge                                                                 |

<Note>
  O tipo de elemento da coluna `value` não é fixo de um pacote para outro — servidores mais antigos emitem `UInt64`, e os mais novos, `Int64`. Leia a string de tipo da coluna no cabeçalho do bloco, em vez de presumir um tamanho fixo.
</Note>

<div id="tablecolumns">
  ### TableColumns (tipo de pacote 11)
</div>

Servidor → Cliente, condicionado por `COLUMN_DEFAULTS_METADATA` (v54410). O servidor o envia antes do bloco de esquema do INSERT para carregar os metadados de valores padrão das colunas, mas apenas quando a versão negociada é ≥ 54410 **e** a configuração `input_format_defaults_for_omitted_fields` está habilitada. Abaixo de 54410, o pacote nunca é enviado, portanto um cliente mais antigo **não** deve esperar por ele — o bloco de esquema `Data` vem diretamente. Um cliente v54410+ deve estar preparado para qualquer uma das ordens: um `TableColumns` opcional, seguido pelo bloco de esquema.

| # | Field                | Type   | Role      | Description                                                                                                                   |
| - | -------------------- | ------ | --------- | ----------------------------------------------------------------------------------------------------------------------------- |
| 1 | external\_table      | String | universal | Nome da tabela externa. Vazio = tabela principal.                                                                             |
| 2 | columns\_description | String | universal | Definições textuais das colunas, por exemplo, `"id Int32, name String DEFAULT ''"`. Texto livre — interprete como uma string. |

<Info>
  **Corpo comprimido a partir da v54481**

  Na versão negociada ≥ 54481 (`COMPRESSED_LOGS_PROFILE_EVENTS_COLUMNS`), o servidor grava **ambos** os campos pelo mesmo caminho de saída opcionalmente comprimido; portanto, quando a consulta tem `compression = true`, todo o corpo de `TableColumns` (`external_table` + `columns_description`) fica dentro do [frame de compressão](/pt-BR/reference/interfaces/specs/NativeFormat#compression-frame), e o cliente o lê pelo fluxo descomprimido correspondente. Quando a consulta não tem compressão, o corpo vai pela wire sem compressão, exatamente como a tabela acima mostra. Isso é importante para respostas de esquema de `INSERT`: um cliente que altere o tratamento de compressão para `Log` e `ProfileEvents`, mas não para `TableColumns`, lerá a resposta incorretamente quando a compressão da consulta estiver habilitada.
</Info>

<div id="timezoneupdate">
  ### TimezoneUpdate (tipo de pacote 17)
</div>

Servidor → cliente, condicionado a `TIMEZONE_UPDATES` (v54464). Enviado em exatamente um lugar: no inicializador da table function `input` (uma consulta no formato `INSERT INTO <table> SELECT ... FROM input('<structure>')`, que transmite linhas do cliente). Logo após o servidor enviar o bloco `Data` do esquema de entrada (veja a [fase de INSERT](#insert-phase)), ele emite `TimezoneUpdate` com o `session_timezone` atual do contexto da consulta, para que o cliente analise as linhas que está prestes a enviar com o mesmo fuso horário. O servidor **não** emite esse pacote para alterações arbitrárias de `SET session_timezone` no meio da consulta, nem para informar ao cliente como formatar blocos de resultado posteriores.

| # | Field    | Type   | Role      | Description                                                                     |
| - | -------- | ------ | --------- | ------------------------------------------------------------------------------- |
| 1 | timezone | String | universal | O novo fuso horário padrão da sessão (por exemplo, `"UTC"`, `"Europe/Berlin"`). |

O pacote chega uma vez, imediatamente após o bloco de esquema de entrada e antes de o cliente começar a enviar blocos de linhas. Um decodificador que ignora `TimezoneUpdate` AINDA DEVE consumir a `String` final para manter o wire alinhado.

<div id="ssh-authentication">
  ### Autenticação SSH por desafio-resposta (tipos de pacote 11, 12, 18)
</div>

Condicionada a `SSH_AUTHENTICATION` (v54466) e habilitada apenas por ativação explícita. Uma conexão entra no fluxo SSH quando `ClientHello` envia `user = " SSH KEY AUTHENTICATION " + <real_user>` (com os espaços iniciais e finais) e `password = ""`. O servidor lê o prefixo, remove-o para recuperar o usuário real e passa para o modo desafio-resposta.

| Packet               | Code | Direction       | Body                                                                                                    |
| -------------------- | ---- | --------------- | ------------------------------------------------------------------------------------------------------- |
| SSHChallengeRequest  | 11   | Client → Server | (sem corpo)                                                                                             |
| SSHChallenge         | 18   | Server → Client | `String challenge` — bytes aleatórios; um dos componentes da string que é assinada (veja abaixo)        |
| SSHChallengeResponse | 12   | Client → Server | `String signature` — assinatura SSH sobre a concatenação definida abaixo, **não** sobre o desafio bruto |

O fluxo é executado no lugar da autenticação por senha, e a troca de desafio-resposta acontece **antes** de `ServerHello` — o servidor adia sua resposta `Hello` até que a autenticação seja concluída com sucesso:

1. O cliente envia `ClientHello` com o prefixo marcador SSH e uma senha vazia.

2. O cliente envia `SSHChallengeRequest` (pacote 11). O servidor **ainda não** enviou `ServerHello` — ele primeiro processa a autenticação e fica aguardando esse pacote.

3. O servidor responde com `SSHChallenge` trazendo bytes aleatórios (pacote 18).

4. O cliente monta a string a ser assinada e assina **essa string**, não o desafio bruto, depois envia `SSHChallengeResponse` (pacote 12) com a assinatura. A mensagem assinada é a concatenação byte a byte, sem separadores, de quatro partes nesta ordem exata:

   ```text theme={null}
   to_sign = decimal(protocol_version) + default_database + user + challenge
   ```

   | Part                        | Source                                                                                                                                                                                                                                                                |
   | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | `decimal(protocol_version)` | A versão do protocolo do cliente como uma **string ASCII decimal** (por exemplo, `"54466"`) — o número da versão como string, não como `VarUInt` nem como inteiro de largura fixa. O servidor valida usando a mesma versão do protocolo que recebeu em `ClientHello`. |
   | `default_database`          | O campo `database` de `ClientHello` (string vazia se não houver).                                                                                                                                                                                                     |
   | `user`                      | O nome do usuário real **com o prefixo marcador `" SSH KEY AUTHENTICATION "` removido** — o mesmo nome que o servidor recupera após remover o prefixo.                                                                                                                |
   | `challenge`                 | Os bytes brutos de `challenge` do pacote `SSHChallenge`.                                                                                                                                                                                                              |

5. O servidor verifica a assinatura usando a chave pública registrada do usuário, reconstruindo a mesma string `decimal(protocol_version) + default_database + user + challenge`. Em caso de sucesso, ele envia `ServerHello` — a mesma resposta do fluxo por senha — e o handshake continua normalmente (Addendum etc.); em caso de falha, retorna uma `Exception` e encerra a conexão. Um cliente que assinar apenas os bytes brutos de `challenge` falhará na autenticação.

```mermaid theme={null}
sequenceDiagram
    autonumber
    participant C as Client
    participant S as Server

    C->>S: ClientHello (SSH marker user, empty password)
    C->>S: SSHChallengeRequest (11)
    Note over C,S: Server has NOT sent ServerHello yet —<br/>it authenticates first and blocks here
    S->>C: SSHChallenge (18) — random bytes to sign
    C->>S: SSHChallengeResponse (12) — signature over version+db+user+challenge
    alt signature verifies
        S->>C: ServerHello — handshake continues normally
    else verification fails
        S->>C: Exception — connection terminates
    end
```

<Note>
  Isso é o inverso do handshake de senha, em que `ServerHello` vem imediatamente após `ClientHello`. Na autenticação SSH, `ServerHello` fica retido até que a assinatura seja verificada, de modo que o mecanismo de desafio-resposta do SSH é intercalado ao handshake antes que qualquer `ServerHello` apareça.
</Note>

Clientes externos que não usam autenticação SSH nunca veem os pacotes 11, 12 ou 18 — eles não aparecem no wire, a menos que o usuário opte explicitamente por isso por meio do prefixo do nome de usuário.

<div id="mergetreeallrangesannouncementresponse">
  ### MergeTreeAllRangesAnnouncementResponse (tipo de pacote 14)
</div>

Cliente → Servidor, somente entre servidores. Condicionado a `parallel_replicas_protocol_version ≥ 8` (consulte [VERSIONED\_PARALLEL\_REPLICAS\_PROTOCOL](#feature-table)). Clientes externos nunca enviam este pacote.

Quando a versão negociada de réplicas paralelas é `≥ 8`, o ciclo de solicitação/resposta do iniciador para um [`MergeTreeAllRangesAnnouncement`](#packet-type-reference) de um seguidor (tipo de pacote `15`, direção servidor→cliente) muda:

1. Um seguidor abre seu pipeline de leitura e envia `MergeTreeAllRangesAnnouncement` ao iniciador.
2. **Somente quando o `mode` do anúncio não é `Default`** (`WithOrder = 1` ou `ReverseOrder = 2`, ambos usados para leituras paralelas em ordem), o iniciador responde com `MergeTreeAllRangesAnnouncementResponse`. Para `mode = Default = 0`, o iniciador permanece em silêncio e o seguidor não espera — o modo `Default` distribui intervalos a cada `MergeTreeReadTaskRequest` e nunca precisa da lista prévia de partes.
3. O seguidor bloqueia aguardando a resposta (quando ela é esperada) antes de emitir sua primeira [`MergeTreeReadTaskRequest`](#packet-type-reference) (pacote do servidor `16` — enviado do seguidor para o iniciador; o iniciador responde com `MergeTreeReadTaskResponse`, pacote do cliente `10`), usando a lista de partes retornada para filtrar a construção das origens exatamente para as partes que pertencem ao seu stream `#split_i`.

Abaixo da versão `8`, o anúncio é fire-and-forget independentemente do modo, e o seguidor constrói origens sobre todas as partes conhecidas localmente (o comportamento legado).

<div id="mergetreeallrangesannouncementresponse-body">
  #### Corpo
</div>

| # | Campo      | Tipo                                                          | Descrição                                                                                                                                                                                                                                                                                                                                                                                                                                |
| - | ---------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | version    | Int64 (little-endian)                                         | A versão do protocolo de réplicas paralelas do remetente. É igual a `DBMS_PARALLEL_REPLICAS_PROTOCOL_VERSION` (atualmente `8`) quando a revisão TCP do destinatário é `≥ DBMS_MIN_REVISION_WITH_VERSIONED_PARALLEL_REPLICAS_PROTOCOL` (`54471`); caso contrário, usa `DBMS_MIN_SUPPORTED_PARALLEL_REPLICAS_PROTOCOL_VERSION` (`3`). O receptor rejeita qualquer valor abaixo de `DBMS_MIN_SUPPORTED_PARALLEL_REPLICAS_PROTOCOL_VERSION`. |
| 2 | parts      | [RangesInDataPartsDescription](#rangesindatapartsdescription) | Conjunto autoritativo de partes que o coordenador registrou para o stream do anúncio. Uma lista vazia significa que o stream não existe no coordenador (por exemplo, o seguidor anunciou mais splits do que o iniciador criou); o pool do seguidor para esse stream se considera finalizado imediatamente.                                                                                                                               |
| 3 | stream\_id | String                                                        | Repete o `stream_id` do anúncio ao qual esta resposta se refere (nome da tabela mais o sufixo `#split_i` quando a topologia de split está em uso).                                                                                                                                                                                                                                                                                       |

<div id="rangesindatapartsdescription">
  #### Corpo de RangesInDataPartsDescription
</div>

| # | Campo | Tipo                                                                               | Descrição                                                                                                              |
| - | ----- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| 1 | count | VarUInt                                                                            | Número de descritores de partes a seguir. O decodificador rejeita como malformados valores acima de `100'000'000'000`. |
| 2 | parts | [RangesInDataPartDescription](#rangesindatapartdescription) repetido `count` vezes | Os descritores, na ordem de registro do coordenador.                                                                   |

<div id="rangesindatapartdescription">
  #### corpo de RangesInDataPartDescription
</div>

| # | Campo                 | Tipo                                    | Gate                                                                 | Descrição                                                                                                                                                                    |
| - | --------------------- | --------------------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | info                  | [MergeTreePartInfo](#mergetreepartinfo) | universal                                                            | Identidade da parte (partição, intervalo de blocos, nível, mutação).                                                                                                         |
| 2 | ranges                | [MarkRanges](#markranges)               | universal                                                            | Intervalos de marcas dentro de `info` que este stream pode atender. Uma lista vazia significa que a parte está registrada, mas no momento não tem nenhum trabalho atribuído. |
| 3 | rows                  | VarUInt                                 | universal                                                            | Total de linhas cobertas por `ranges`.                                                                                                                                       |
| 4 | projection\_name      | String                                  | `DBMS_PARALLEL_REPLICAS_MIN_VERSION_WITH_PROJECTION` (PR v5)         | Vazio para linhas da parte primária; caso contrário, o nome da projeção.                                                                                                     |
| 5 | min\_marks\_per\_task | VarUInt                                 | `DBMS_PARALLEL_REPLICAS_MIN_VERSION_WITH_MIN_MARKS_PER_TASK` (PR v6) | Limite inferior de marcas que o pool do seguidor deve agrupar em uma única tarefa de leitura para esta parte.                                                                |

<div id="mergetreepartinfo">
  #### Corpo de MergeTreePartInfo
</div>

| # | Campo                   | Tipo                   | Descrição                                                                                                                                                    |
| - | ----------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1 | version                 | Int64 (little-endian)  | Sempre `DBMS_MERGE_TREE_PART_INFO_VERSION` (`1`). O decodificador rejeita qualquer outro valor.                                                              |
| 2 | partition\_id           | String                 | Identificador da partição (por exemplo, `"all"` para tabelas não particionadas, ou o valor convertido em string da expressão de tupla da chave de partição). |
| 3 | min\_block              | Int64 (little-endian)  | Primeiro número de bloco no intervalo de blocos da parte.                                                                                                    |
| 4 | max\_block              | Int64 (little-endian)  | Último número de bloco no intervalo de blocos da parte (inclusive).                                                                                          |
| 5 | level                   | UInt32 (little-endian) | Nível de merge.                                                                                                                                              |
| 6 | mutation                | Int64 (little-endian)  | Versão da mutation que produziu esta parte (`0` para uma parte sem mutation).                                                                                |
| 7 | use\_legacy\_max\_level | Bool (texto)           | Codificado como um único byte ASCII (`'1'` ou `'0'`) — indicador de compatibilidade histórica para o formato do nome da parte.                               |

<div id="markranges">
  #### Corpo de MarkRanges
</div>

| # | Campo  | Tipo                                                                         | Descrição                                                                                                     |
| - | ------ | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| 1 | size   | UInt64 (little-endian)                                                       | Número de pares de intervalos de marcas a seguir. Observação: largura fixa em little-endian, **não** VarUInt. |
| 2 | ranges | `size` repetições de `(UInt64 begin, UInt64 end)`, cada uma em little-endian | Intervalos de marcas semiabertos `[begin, end)`.                                                              |

<div id="packet-type-reference">
  ## Referência de tipos de pacote
</div>

<div id="client-to-server">
  ### Cliente → Servidor
</div>

| Código | Nome                                   | Formato do corpo                                                                  | Descrição                                                                                                                                                                                                                                                                             |
| ------ | -------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 0      | Hello                                  | [ClientHello](#clienthello)                                                       | Início do handshake                                                                                                                                                                                                                                                                   |
| 1      | consulta                               | [consulta](#query)                                                                | Solicitação de execução de consulta                                                                                                                                                                                                                                                   |
| 2      | Data                                   | [Data](#data)                                                                     | Bloco de dados (dados de INSERT, tabelas externas, marcador de fim dos dados)                                                                                                                                                                                                         |
| 3      | Cancel                                 | (sem corpo)                                                                       | Cancelar consulta em execução                                                                                                                                                                                                                                                         |
| 4      | Ping                                   | [Ping](#ping)                                                                     | Verificação de disponibilidade                                                                                                                                                                                                                                                        |
| 5      | TablesStatusRequest                    | não especificado                                                                  | Verificação de status das tabelas                                                                                                                                                                                                                                                     |
| 6      | KeepAlive                              | não especificado                                                                  | Manutenção da conexão ativa                                                                                                                                                                                                                                                           |
| 7      | Scalar                                 | não especificado                                                                  | Bloco de dados escalar                                                                                                                                                                                                                                                                |
| 8      | IgnoredPartUUIDs                       | não especificado                                                                  | Partes a serem excluídas da consulta                                                                                                                                                                                                                                                  |
| 9      | ReadTaskResponse                       | não especificado                                                                  | Resposta de leitura do cluster S3                                                                                                                                                                                                                                                     |
| 10     | MergeTreeReadTaskResponse              | não especificado                                                                  | Resposta da tarefa de leitura paralela                                                                                                                                                                                                                                                |
| 11     | SSHChallengeRequest                    | [autenticação SSH](#ssh-authentication)                                           | Solicitação de desafio de autenticação SSH                                                                                                                                                                                                                                            |
| 12     | SSHChallengeResponse                   | [autenticação SSH](#ssh-authentication)                                           | Resposta ao desafio de autenticação SSH                                                                                                                                                                                                                                               |
| 13     | QueryPlan                              | não especificado                                                                  | Plano de consulta                                                                                                                                                                                                                                                                     |
| 14     | MergeTreeAllRangesAnnouncementResponse | [MergeTreeAllRangesAnnouncementResponse](#mergetreeallrangesannouncementresponse) | Resposta do iniciador ao [`MergeTreeAllRangesAnnouncement`](#packet-type-reference) de um seguidor (condicionado a `parallel_replicas_protocol_version ≥ 8` — veja [VERSIONED\_PARALLEL\_REPLICAS\_PROTOCOL](#feature-table)). Somente inter-server — clientes externos nunca enviam. |

<div id="server-to-client">
  ### Servidor → Cliente
</div>

| Código | Nome                           | Formato do corpo                        | Descrição                                   |
| ------ | ------------------------------ | --------------------------------------- | ------------------------------------------- |
| 0      | Hello                          | [ServerHello](#serverhello)             | Resposta do handshake                       |
| 1      | Data                           | [Data](#data)                           | Bloco de dados do resultado                 |
| 2      | Exception                      | [Exception](#exception)                 | Erro                                        |
| 3      | Progress                       | [Progress](#progress)                   | Progresso da execução da consulta           |
| 4      | Pong                           | [Pong](#pong)                           | Resposta de liveness                        |
| 5      | EndOfStream                    | (sem corpo)                             | Consulta concluída                          |
| 6      | ProfileInfo                    | [ProfileInfo](#profileinfo)             | Dados de profiling após a execução          |
| 7      | Totals                         | [Totals](#totals)                       | Linha de GROUP BY WITH TOTALS               |
| 8      | Extremes                       | [Extremes](#extremes)                   | Valores mínimos/máximos (bloco de 2 linhas) |
| 9      | TablesStatusResponse           | não especificado                        | Resposta de status da tabela                |
| 10     | Log                            | [Log](#log)                             | Linhas de log da execução da consulta       |
| 11     | TableColumns                   | [TableColumns](#tablecolumns)           | Descrições de colunas para valores padrão   |
| 12     | PartUUIDs                      | não especificado                        | IDs únicos de partes                        |
| 13     | ReadTaskRequest                | não especificado                        | Solicitação de tarefa de leitura do cluster |
| 14     | ProfileEvents                  | [ProfileEvents](#profileevents)         | Contadores de desempenho                    |
| 15     | MergeTreeAllRangesAnnouncement | não especificado                        | Inicialização da leitura paralela           |
| 16     | MergeTreeReadTaskRequest       | não especificado                        | Atribuição de tarefa de leitura paralela    |
| 17     | TimezoneUpdate                 | [TimezoneUpdate](#timezoneupdate)       | Atualização do fuso horário do servidor     |
| 18     | SSHChallenge                   | [autenticação SSH](#ssh-authentication) | Desafio de autenticação SSH                 |

<div id="configuration">
  ## Configuração
</div>

Esta seção aborda os parâmetros ajustáveis que definem as conexões via protocolo nativo:

* [Configurações da camada de transporte](#transport-layer-settings) — opções de socket TCP e timeouts, que afetam o comportamento da própria conexão TCP.
* [Configurações da camada de aplicação](#application-layer-settings) — ajustes por consulta incluídos na [lista de configurações do pacote consulta](#setting), que afetam o que o servidor envia no wire ou como isso é estruturado.
* [Configurações fora do escopo](#settings-out-of-scope) — configurações frequentemente confundidas com configurações de protocolo, mas que na verdade controlam a execução de SQL ou o armazenamento.

Os valores padrão abaixo refletem um lançamento recente do servidor; podem variar entre versões e implantações.

<div id="transport-layer-settings">
  ### Configurações da camada de transporte
</div>

<div id="socket-options">
  #### Opções de socket
</div>

| Opção                     | Padrão                                     | Lado        | Descrição                                                                                                                                                |
| ------------------------- | ------------------------------------------ | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TCP_NODELAY`             | ativado                                    | ambos       | Algoritmo de Nagle desativado. Pacotes pequenos são enviados imediatamente.                                                                              |
| `SO_KEEPALIVE`            | ativado (cliente), padrão do SO (servidor) | assimétrico | Sondagens de keepalive TCP no nível do kernel. O cliente ativa isso explicitamente quando `tcp_keep_alive_timeout > 0`. O servidor herda o padrão do SO. |
| `SO_RCVBUF` / `SO_SNDBUF` | padrões do SO                              | —           | Tamanhos de buffer do socket. Não são ajustados pelo protocolo.                                                                                          |

<div id="timeouts">
  #### Timeouts
</div>

| Setting                                   | Default | Unit          | Side   | Description                                                                          |
| ----------------------------------------- | ------- | ------------- | ------ | ------------------------------------------------------------------------------------ |
| `connect_timeout`                         | 10      | segundos      | client | Tempo limite para estabelecer a conexão TCP inicial.                                 |
| `handshake_timeout_ms`                    | 10000   | milissegundos | client | Tempo limite para receber o ServerHello durante o handshake.                         |
| `send_timeout`                            | 300     | segundos      | both   | Se nenhum byte puder ser enviado dentro deste intervalo, a conexão gera uma exceção. |
| `receive_timeout`                         | 300     | segundos      | both   | Se nenhum byte puder ser lido dentro deste intervalo, a conexão gera uma exceção.    |
| `tcp_keep_alive_timeout`                  | 290     | segundos      | client | Tempo de inatividade antes de o SO enviar a primeira sondagem de keepalive do TCP.   |
| `receive_data_timeout_ms`                 | 2000    | milissegundos | client | Tempo limite para receber o primeiro pacote Data de uma réplica.                     |
| `connect_timeout_with_failover_ms`        | 1000    | milissegundos | client | Tempo limite de conexão por tentativa ao percorrer as réplicas.                      |
| `connect_timeout_with_failover_secure_ms` | 1000    | milissegundos | client | Tempo limite de conexão por tentativa ao percorrer as réplicas por TLS.              |
| `hedged_connection_timeout_ms`            | 50      | milissegundos | client | Tempo limite de conexão por tentativa para requisições hedged.                       |
| `poll_interval`                           | 10      | segundos      | server | Granularidade do loop do servidor para verificar conexões ociosas e desligamento.    |

Os timeouts se encadeiam assim:

```text theme={null}
tcp_keep_alive_timeout (290s)
      < receive_timeout (300s)
      < idle_connection_timeout (3600s)
      < tcp_close_connection_after_queries_seconds (0 = unlimited by default)
```

O keepalive do SO dispara primeiro e pode detectar peers mortos de forma transparente, no nível do kernel. O timeout de recebimento da aplicação é a próxima linha de defesa. O timeout de inatividade é o último recurso, que encerra conexões sem uso há muito tempo.

<div id="connection-limits">
  #### Limites de conexão
</div>

| Configuração                                 | Padrão        | Unidade    | Lado     | Descrição                                                                |
| -------------------------------------------- | ------------- | ---------- | -------- | ------------------------------------------------------------------------ |
| `max_connections`                            | 4096          | quantidade | servidor | Número máximo de conexões TCP simultâneas.                               |
| `idle_connection_timeout`                    | 3600          | segundos   | servidor | Tempo máximo que uma conexão ociosa pode permanecer aberta.              |
| `tcp_close_connection_after_queries_num`     | 0 (ilimitado) | quantidade | servidor | Número máximo de consultas por conexão antes de um encerramento forçado. |
| `tcp_close_connection_after_queries_seconds` | 0 (ilimitado) | segundos   | servidor | Ciclo de vida total máximo da conexão, independentemente da atividade.   |

Uma conexão que executa consultas regularmente pode permanecer ativa indefinidamente. Apenas conexões ociosas são encerradas após uma hora, e não há um ciclo de vida máximo padrão.

<div id="application-layer-settings">
  ### Configurações da camada de aplicação
</div>

Essas configurações são transmitidas com cada consulta na [lista de configurações do pacote de consulta](#setting). Elas alteram o que o servidor envia no wire ou como os dados são delimitados.

<div id="compression-settings">
  #### Compressão
</div>

| Configuração                     | Padrão  | Unidade | Descrição                                                                                                                                       |
| -------------------------------- | ------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `network_compression_method`     | `"LZ4"` | string  | Codec de compressão usado quando o sinalizador `compression` do pacote consulta está definido. Valores: `"LZ4"`, `"LZ4HC"`, `"ZSTD"`, `"NONE"`. |
| `network_zstd_compression_level` | 1       | 1–15    | Nível de ZSTD quando `network_compression_method == "ZSTD"`.                                                                                    |

O sinalizador `compression` no [pacote consulta](#query) (campo 6) ativa e desativa a compressão; essas configurações definem qual codec é usado quando ele está ativado.

<div id="log-streaming">
  #### Streaming de logs
</div>

| Configuração              | Padrão    | Unidade | Descrição                                                                                                                   |
| ------------------------- | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
| `send_logs_level`         | `"fatal"` | string  | Nível mínimo de log. Valores: `"none"`, `"fatal"`, `"error"`, `"warning"`, `"information"`, `"debug"`, `"trace"`, `"test"`. |
| `send_logs_source_regexp` | `""`      | string  | Filtro Regex para a origem do logger. Vazio = todas as origens são aceitas.                                                 |

Configurar `send_logs_level` com qualquer valor diferente de `"none"` faz com que o servidor emita pacotes de [Log](#log) durante a execução da consulta.

<div id="progress-reporting">
  #### Relatório de Progress
</div>

| Configuração        | Padrão | Unidade        | Descrição                                                      |
| ------------------- | ------ | -------------- | -------------------------------------------------------------- |
| `interactive_delay` | 100000 | microssegundos | Intervalo mínimo esperado entre pacotes Progress consecutivos. |

Este é um mínimo esperado, não um máximo rígido: o servidor pode enviar pacotes Progress com menos frequência quando a consulta não estiver gerando trabalho com rapidez suficiente.

<div id="result-envelope">
  #### Envelope do resultado
</div>

| Configuração           | Padrão        | Unidade               | Descrição                                                                                                           |
| ---------------------- | ------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `extremes`             | false         | bool                  | Quando definido como true, o servidor envia um pacote [Extremes](#extremes) com valores mínimos/máximos por coluna. |
| `max_result_rows`      | 0 (ilimitado) | contagem              | Limite de linhas transmitidas. O comportamento é controlado por `result_overflow_mode`.                             |
| `max_result_bytes`     | 0 (ilimitado) | bytes não comprimidos | Limite do volume de bytes não comprimidos. O comportamento é controlado por `result_overflow_mode`.                 |
| `result_overflow_mode` | `"throw"`     | string                | `"throw"` encerra o fluxo com Exception; `"break"` envia resultados parciais seguidos por EndOfStream.              |

<div id="async-insert">
  #### INSERT assíncrono
</div>

| Configuração                    | Padrão | Unidade  | Descrição                                                                                                                                       |
| ------------------------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `async_insert`                  | true   | bool     | Quando true, os dados de INSERT são enfileirados no servidor e agrupados em lote.                                                               |
| `wait_for_async_insert`         | true   | bool     | Quando true (com `async_insert` ativado), o servidor mantém a resposta em espera até que os dados enfileirados sejam gravados no armazenamento. |
| `wait_for_async_insert_timeout` | 120    | segundos | Tempo máximo que o servidor espera por uma gravação no armazenamento antes de retornar.                                                         |

<div id="distributed-tracing">
  #### Rastreamento distribuído
</div>

| Configuração                            | Padrão | Unidade           | Descrição                                                                                     |
| --------------------------------------- | ------ | ----------------- | --------------------------------------------------------------------------------------------- |
| `opentelemetry_start_trace_probability` | 0.0    | probabilidade 0–1 | Probabilidade, no servidor, de associar o contexto do OpenTelemetry à telemetria de resposta. |

<div id="settings-out-of-scope">
  ### Configurações fora do escopo
</div>

Às vezes, essas configurações são confundidas com configurações no nível do protocolo, mas controlam a execução de SQL, o armazenamento ou o uso de CPU, e não o comportamento na wire. Uma implementação de protocolo não precisa tratá-las de forma especial.

* `max_threads` — paralelismo na execução da consulta.
* `max_memory_usage` — limite de memória por consulta.
* `max_block_size`, `preferred_block_size_bytes` — dimensionamento interno de blocos durante o processamento da consulta; os blocos wire são independentes dessas configurações.
* `compile_expressions` — compilação JIT; afeta apenas a CPU.
* `async_insert_max_data_size` — buffer da fila no servidor.
* Todas as configurações `input_format_*` e `output_format_*`, **exceto** a família `input_format_native_*` / `output_format_native_*` — as não-`native` selecionam ou ajustam outros formatos (por exemplo, via HTTP) e não alteram os blocos `Data` do protocolo nativo.

As configurações `*_native_*` são a exceção: elas alteram os bytes dentro dos blocos `Data` do native TCP, portanto uma implementação de protocolo deve levá-las em conta. `output_format_native_encode_types_in_binary_format` muda o campo `type` da coluna de uma string textual para uma codificação binária de tipo, `output_format_native_write_json_as_string` emite colunas `JSON` como `String`, e `output_format_native_use_flattened_dynamic_and_json_serialization` seleciona o layout FLATTENED de `Dynamic`/`JSON`. Como elas afetam o body do bloco, e não o envelope do pacote, elas são especificadas na especificação [Native Format](/pt-BR/reference/interfaces/specs/NativeFormat) — consulte [layout wire da coluna](/pt-BR/reference/interfaces/specs/NativeFormat#column-wire-layout) e [tipos versionados](/pt-BR/reference/interfaces/specs/NativeFormat#versioned-types).

<div id="glossary">
  ## Glossário
</div>

**Cancel** — um pacote iniciado pelo cliente (tipo 3) que aborta uma consulta em execução. Não é detalhado nesta página.

**Marcador de fim dos dados do cliente** — um pacote Data vazio (0 colunas, 0 linhas) que o cliente envia para encerrar um fluxo de entrada. Sua posição varia conforme o tipo de consulta:

* **Consulta normal (`SELECT`, etc.):** enviado após o pacote consulta e quaisquer pacotes Data de tabelas externas para sinalizar "não há mais dados externos". O servidor então inicia a execução.
* **`INSERT`:** o cliente **não** envia um marcador antes do esquema. O servidor envia primeiro o bloco de esquema, o cliente transmite seus blocos Data de linhas e só então envia o pacote Data vazio para encerrar o fluxo de linhas. Enviar um marcador vazio antes do bloco de esquema seria interpretado como um fim imediato das linhas, e os dados seriam perdidos.

**Recurso** — uma mudança no formato wire introduzida em uma versão específica do protocolo. Fica ativo quando a versão negociada é igual ou superior à versão do recurso. Veja [versionamento e feature gates](#versioning-and-feature-gates).

**Entre servidores** — um rótulo de função para um campo que só faz sentido em consultas distribuídas de servidor para servidor. Clientes externos gravam um valor padrão (geralmente string vazia, 0 ou false).

**Versão negociada** — `min(client_version, server_version)`, calculada durante o handshake. Determina quais recursos ficam ativos durante o ciclo de vida da conexão.

**Pacote** — uma mensagem wire: um código de tipo de pacote VarUInt seguido por um body cujo formato depende do tipo. Veja [envelope do pacote](#packet-envelope).

**Código de tipo de pacote** — o VarUInt inicial de um pacote que identifica seu formato. Os valores de 0 a 18 estão atribuídos no momento. Veja a [referência de tipos de pacote](#packet-type-reference).

**Fluxo de resposta** — a sequência de pacotes que o servidor emite durante uma consulta. Seu comprimento é indefinido e ele é encerrado por exatamente um `EndOfStream` (sucesso) ou `Exception` (falha). Veja a [fase da consulta](#query-phase).

**Bloco de esquema** — o bloco de cabeçalho (um Block com colunas, mas 0 linhas) que o servidor envia durante a fase de INSERT para informar os formatos de coluna esperados antes de o cliente enviar os dados.

**Lista de configurações** — uma sequência de tuplas `(key, flags, value)` no body de consulta, terminada por uma chave vazia. Carrega a configuração por consulta na camada de aplicação. Veja [SETTING](#setting).

**Estágio** — um campo VarUInt no pacote [consulta](#query) (campo 5) que controla até onde o servidor executa a consulta. Clientes externos normalmente enviam `2` (Complete); consultas distribuídas e planos de consulta serializados usam os valores mais altos. Veja o campo 5 de [consulta](#query) para o conjunto completo de valores wire.

**Terminador** — um pacote que encerra um fluxo. A resposta de consulta termina em `EndOfStream` (sucesso) ou `Exception` (falha). O fluxo de entrada do cliente termina no marcador Data vazio.
