Pular para o conteúdo principal

Conversões de tipo

O cliente busca ser o mais flexível possível quanto à aceitação de tipos de variáveis tanto para inserção quanto para o marshaling de respostas. Na maioria dos casos, existe um tipo equivalente em Golang para um tipo de coluna do ClickHouse, por exemplo, UInt64 para uint64. Esses mapeamentos lógicos devem ser sempre suportados. Você pode querer usar tipos de variáveis que possam ser inseridos em colunas ou usados para receber uma resposta, desde que a conversão da variável ou dos dados recebidos ocorra primeiro. O cliente busca suportar essas conversões de forma transparente, para que os usuários não precisem converter seus dados previamente para que correspondam exatamente aos tipos antes da inserção, além de oferecer marshaling flexível no momento da consulta. Essa conversão transparente não permite perda de precisão. Por exemplo, um uint32 não pode ser usado para receber dados de uma coluna UInt64. Por outro lado, uma string pode ser inserida em um campo datetime64, desde que atenda aos requisitos de formato. As conversões de tipo atualmente suportadas para tipos primitivos estão descritas aqui. Esse trabalho está em andamento e pode ser dividido entre inserção (Append/AppendRow) e leitura (via Scan). Se você precisar de suporte para uma conversão específica, abra uma issue. A interface padrão database/sql deve oferecer suporte aos mesmos tipos que a ClickHouse API. Há algumas exceções, principalmente para tipos complexos, documentadas nas seções abaixo. Assim como a ClickHouse API, o cliente busca ser o mais flexível possível quanto à aceitação de tipos de variáveis tanto para inserção quanto para o marshaling de respostas.

Tipos complexos

Date/DateTime

O cliente Go do ClickHouse oferece suporte aos tipos de data/data e hora Date, Date32, DateTime e DateTime64. Datas podem ser inseridas como string no formato 2006-01-02 ou usando os tipos nativos do Go time.Time{} ou sql.NullTime. DateTime também oferece suporte a esses tipos, mas exige que as strings sejam passadas no formato 2006-01-02 15:04:05, com um deslocamento de fuso horário opcional, por exemplo 2006-01-02 15:04:05 +08:00. time.Time{} e sql.NullTime também têm suporte na leitura, assim como qualquer implementação da interface sql.Scanner. O tratamento das informações de fuso horário depende do tipo do ClickHouse e de o valor estar sendo inserido ou lido:
  • DateTime/DateTime64
    • No momento do insert, o valor é enviado ao ClickHouse no formato de timestamp Unix. Se nenhum fuso horário for informado, o cliente assumirá o fuso horário local do cliente. time.Time{} ou sql.NullTime serão convertidos para epoch de acordo com isso.
    • No momento do select, o fuso horário da coluna será usado, se estiver definido, ao retornar um valor time.Time. Caso contrário, será usado o fuso horário do servidor.
  • Date/Date32
    • No momento do insert, o fuso horário de qualquer data é considerado ao converter a data para um timestamp Unix; ou seja, ele será ajustado pelo fuso horário antes de ser armazenado como data, já que os tipos Date não têm localidade no ClickHouse. Se isso não for especificado em um valor de string, será usado o fuso horário local.
    • No momento do select, as datas lidas em instâncias time.Time{} ou sql.NullTime{} serão retornadas sem informações de fuso horário.

Tipos Time/Time64

Os tipos de coluna Time e Time64 armazenam valores de hora do dia sem um componente de data. Ambos são mapeados para time.Duration do Go.
  • Time armazena a hora com precisão de segundos.
  • Time64(precision) oferece suporte à precisão de subsegundos (como DateTime64), em que a precisão vai de 0 a 9.

Array

Arrays devem ser inseridos como slices. As regras de tipagem dos elementos são as mesmas do tipo primitivo, ou seja, os elementos serão convertidos quando possível. Um ponteiro para um slice deve ser fornecido no momento do Scan.
Exemplo completo

Map

Maps devem ser inseridos como maps em Go, com chaves e valores em conformidade com as regras de tipo definidas anteriormente.
Exemplo completo
Ao usar a API database/sql, os valores de Map exigem tipagem estrita — você não pode usar interface{} como tipo de valor. Por exemplo, não é possível passar um map[string]interface{} para um campo Map(String,String); em vez disso, é preciso usar um map[string]string. Já uma variável interface{} será sempre compatível e pode ser usada para estruturas mais complexas.Exemplo completo

Tuplas

As tuplas representam um grupo de colunas de tamanho arbitrário. As colunas podem ser explicitamente nomeadas ou ter apenas um tipo especificado, por exemplo.
Entre essas abordagens, as tuplas nomeadas oferecem maior flexibilidade. Embora as tuplas sem nome precisem ser inseridas e lidas por meio de slices, as tuplas nomeadas também são compatíveis com maps.
Exemplo completo Observação: slices tipados e maps são compatíveis, desde que as subcolunas na tupla nomeada sejam todas do mesmo tipo.

Nested

Um campo Nested é equivalente a um Array de Tuples nomeadas. O uso depende de o usuário ter definido flatten_nested como 1 ou 0. Ao definir flatten_nested como 0, as colunas Nested permanecem como um único array de tuplas. Isso permite usar slices de maps para inserção e recuperação, além de níveis arbitrários de aninhamento. A chave do map deve ser igual ao nome da coluna, como mostrado no exemplo abaixo. Observação: como os maps representam uma tupla, eles devem ser do tipo map[string]interface{}. No momento, os valores não são fortemente tipados.
Exemplo completo - flatten_tested=0 Se o valor padrão 1 for usado para flatten_nested, as colunas aninhadas serão achatadas em arrays separados. Isso exige o uso de slices aninhados para inserção e recuperação. Embora níveis arbitrários de aninhamento possam funcionar, isso não é oficialmente suportado.
Exemplo completo - flatten_nested=1 Observação: as colunas Nested devem ter as mesmas dimensões. Por exemplo, no exemplo acima, Col_2_2 e Col_2_1 devem ter o mesmo número de elementos. Devido a uma interface mais direta e ao suporte oficial a aninhamento, recomendamos flatten_nested=0.

Tipos Geo

O cliente é compatível com os tipos Geo Point, Ring, LineString, Polygon, MultiPolygon e MultiLineString. Esses tipos são representados em Go usando o pacote github.com/paulmach/orb.
Exemplo completo

UUID

O tipo UUID é compatível com o pacote github.com/google/uuid. Você também pode enviar e serializar um UUID como string ou qualquer tipo que implemente sql.Scanner ou Stringify.
Exemplo completo

Decimal

Como o Go não tem um tipo Decimal nativo, recomendamos usar o pacote de terceiros github.com/shopspring/decimal para trabalhar com tipos Decimal de forma nativa sem modificar suas consultas originais.
Você pode se sentir tentado a usar Float no lugar para evitar dependências de terceiros. No entanto, saiba que os tipos Float no ClickHouse não são recomendados quando valores precisos são necessários.Se ainda assim você optar por usar o tipo Float nativo do Go no lado do cliente, deverá converter explicitamente Decimal em Float usando a função toFloat64() ou suas variantes em suas consultas no ClickHouse. Saiba que essa conversão pode resultar em perda de precisão.
Exemplo completo

Nullable

O valor Nil em Go representa um NULL no ClickHouse. Isso pode ser usado se um campo for declarado como Nullable. No momento do insert, Nil pode ser passado tanto para a versão normal quanto para a versão Nullable de uma coluna. No primeiro caso, o valor padrão do tipo será persistido, por exemplo, uma string vazia para string. Já na versão Nullable, um valor NULL será armazenado no ClickHouse. No momento da leitura, o usuário deve passar um ponteiro para um tipo que aceite nil, por exemplo, *string, para representar o valor nil de um campo Nullable. No exemplo abaixo, col1, que é um Nullable(String), recebe, portanto, um **string. Isso permite representar nil.
Exemplo completo O cliente também oferece suporte aos tipos sql.Null*, por exemplo, sql.NullInt64. Eles são compatíveis com os tipos equivalentes no ClickHouse.

Inteiros grandes

Tipos numéricos com mais de 64 bits são representados com o pacote nativo big do Go.
Exemplo completo

BFloat16

BFloat16 é um tipo de ponto flutuante brain de 16 bits usado em cargas de trabalho de machine learning. Em Go, os valores BFloat16 são inseridos e lidos como float32. As variantes Nullable usam sql.NullFloat64.
Exemplo completo

QBit

QBit é um tipo de coluna experimental para armazenar embeddings vetoriais em formato bit-sliced, otimizado para busca por similaridade vetorial. Requer que a configuração allow_experimental_qbit_type esteja habilitada. Em Go, uma coluna QBit(Float32, N) é inserida e lida como []float32, em que N é a dimensão do vetor.
Exemplo completo
Última modificação em 10 de junho de 2026