<villagesql/vsql.h>):
Tipos de Comprimento Fixo
vsql::make_type<kTypeName>(). O nome do tipo
é passado como um parâmetro de template que não é de tipo (NTTP) — um array
static constexpr const char[]. O construtor gera automaticamente nomes de VDF
no formato TYPE::method (por exemplo, "MYTYPE::from_string") a partir desse NTTP,
de modo que nenhuma correspondência manual de strings seja necessária. Passe o objeto de
tipo construído para .type() no construtor da extensão; chamadas .func()
separadas para operações de tipo não são necessárias.
build() falha em tempo de compilação se from_string, to_string ou compare
estiver ausente. Cada método de template verifica a assinatura do pointer de função via
static_assert.
Padrão Intrínseco
Quando uma coluna de tipo personalizadoNOT NULL recebe NULL no modo IGNORE
(por exemplo, INSERT IGNORE ou UPDATE IGNORE), o servidor chama o padrão
intrínseco para produzir um valor alternativo em vez de gerar um erro. O
padrão intrínseco fornece uma representação em string; o servidor a converte
para binário usando a função from_string do tipo.
Se você omitir tanto Para tipos de comprimento fixo, a string padrão deve codificar para exatamente
.intrinsic_default_str() quanto .intrinsic_default_vdf(),
o servidor chama from_string("") como alternativa. Isso acontece quando o tipo
é usado pela primeira vez (na criação da tabela), não em INSTALL EXTENSION. Se a sua
função de encode rejeitar a string vazia (ou codificá-la para o número errado de
bytes), a inicialização do tipo falha com um erro visível no cliente SQL:persisted_length bytes. Defina um padrão explícito para qualquer tipo em que
a string vazia não seja uma entrada válida..intrinsic_default_str()
Para um padrão constante, passe a string diretamente no construtor do tipo (como
mostrado no exemplo de comprimento fixo acima, com .intrinsic_default_str("0")).
Baseado em VDF: .intrinsic_default_vdf() + make_intrinsic_default
Quando o valor padrão depende dos parâmetros do tipo, implemente uma função
de acordo com uma destas assinaturas (disponíveis via <villagesql/vsql.h>):
std::string do valor padrão. Em caso de erro,
escreva uma mensagem em error_msg e retorne qualquer valor (o SDK verifica
error_msg[0] != '\0' para detectar erros). Registre com
make_intrinsic_default<&fn>("vdf_name") (um argumento: o nome da VDF) e
referencie esse nome no construtor do tipo com .intrinsic_default_vdf().
O exemplo de tipos parametrizados abaixo mostra o padrão de registro completo.
Tipos Parametrizados
Os tipos parametrizados precisam dos parâmetros declarados da coluna nos momentos de encode, decode, compare e hash para determinar os tamanhos de alocação e o layout. Defina uma struct de parâmetros com uma função de parse e uma função inversato_strings,
registre ambas no construtor do tipo com
.params<P, &ParseFunc, &ToStringsFunc>(), e use const P& como o primeiro
argumento das suas funções de operação de tipo. O SDK armazena em cache o resultado do parse
por combinação única de parâmetros, de modo que a função de parse é executada no máximo uma vez
por instanciação de tipo. A função to_strings é a inversa de parse:
ela escreve um P tipado de volta na forma canônica de string chave/valor para que
o servidor possa publicar os parâmetros inferidos no mesmo formato que parse consome.
.params<>() no construtor do tipo. Use .int_to_params<&mytype_int_to_params_fn>()
para tratar a sintaxe de inteiro MYTYPE(N) e .resolve_params<&mytype_resolve_params_fn>() para
validar os parâmetros e calcular os tamanhos de armazenamento. Chame .max_persisted_length(N) com um
limite superior do tamanho persistido em bytes em todas as parametrizações válidas; o servidor
usa isso apenas no caminho de inferência de parâmetros de tipo, onde ele ainda não inferiu
os parâmetros e, portanto, não pode consultar resolve_params para dimensionar o buffer de encode.
Para um padrão intrínseco baseado em VDF, use .intrinsic_default_vdf() com o nome da VDF e
registre a VDF separadamente via make_intrinsic_default<&mytype_default>().
TypeEncodeWithParamsFunc<P>,
TypeDecodeWithParamsFunc<P>, TypeCompareWithParamsFunc<P> e
TypeHashWithParamsFunc<P>) juntamente com ParamsToStringsFunc<P>
(void fn(const P&, std::map<std::string,std::string>&)) estão disponíveis via
<villagesql/vsql.h>.
Os métodos de template vsql::make_type detectam o argumento de parâmetros e roteiam
através do cache de parâmetros automaticamente. As funções de encode recebem
vsql::MaybeParams<P> & como primeiro argumento; is_known() é sempre verdadeiro
em tempo de execução, e value() retorna const P&. As variantes de decode, compare e hash
recebem vsql::CustomArgWith<P>, cujo acessador params() retorna
const P&.
Fornecendo parâmetros em SQL. Duas sintaxes chegam a resolve_params:
- Inteiro —
MYTYPE(N). O servidor roteiaNatravés deint_to_paramspara construir o mapa de parâmetros. Requer.int_to_params<>(). - String —
MYTYPE('key=value,...'). O servidor normaliza a string e chamaresolve_paramsdiretamente;int_to_paramsnão é envolvido. Disponível sempre que.resolve_params<>()estiver registrado — sem chamada extra do construtor.
.resolve_params<>() aceita a forma de string e
rejeita MYTYPE(N). SHOW CREATE TABLE preserva qualquer forma que tenha sido escrita.
A string de parâmetros serializada
key=value,... que int_to_params produz
e resolve_params consome é limitada a VEF_MAX_TYPE_PARAMS_STRING_LEN
(1024 bytes). Uma parametrização cuja string canônica exceda esse limite
é rejeitada com um erro definido em vez de ser truncada silenciosamente — mantenha os
nomes e valores de parâmetros combinados de um único tipo dentro de 1024 bytes.Reescrevendo parâmetros e fornecendo padrões
resolve_params tem uma segunda sobrecarga, mutável: ela recebe o mapa de parâmetros por
referência não constante, de modo que o tipo pode reescrevê-lo — normalmente para preencher padrões que o
autor omitiu. Registre-a da mesma forma (.resolve_params<&fn>() aceita
qualquer forma; registre apenas uma):
SHOW CREATE TABLE imprime, portanto a reescrita deve ser idempotente. Uma declaração
simples (MYTYPE, sem comprimento ou parâmetros) agora chama resolve_params com um
mapa vazio em vez de ignorá-la, de modo que um tipo que fornece padrões dá a cada
coluna parâmetros explícitos — o BITFIELD de vsql_bitfield_test resolve uma coluna
simples para max_number_of_bits=4096:
Tipos de Comprimento Variável
Um tipo personalizado de comprimento variável decide seu tamanho persistido por valor, em vez de usar um único footprint fixo. Declare um chamando.variable_length_type()
no construtor do tipo, o que define a flag variable_length do tipo.
Os tipos de comprimento variável também devem chamar .max_persisted_length(N). build() falha
em tempo de compilação se ele for omitido — o servidor precisa do limite superior para alocar
um buffer para o campo de suporte.
.variable_length_type() é monotônico: chamá-lo antes ou depois dos setters do Protocol 3
(max_persisted_length(), params(), int_to_params()) não reduz
a exigência de protocol de volta para abaixo do Protocol 4.
Como todo tipo personalizado, um tipo de comprimento variável deve produzir um
padrão intrínseco utilizável. O padrão é codificado dentro da
capacidade máxima do campo, e qualquer resultado não vazio de 1 a
Caso contrário, o tipo falha ao inicializar na primeira vez que uma coluna
max_persisted_length bytes é aceito. Um tipo cujo encode de string vazia
produz zero bytes (um array ou conjunto de bits vazio, digamos) não tem um padrão
utilizável, portanto declare um explícito que codifique para um valor não vazio:NOT NULL o
referencia, em CREATE TABLE — o mesmo que um tipo de comprimento fixo que não consegue
codificar from_string("").Tipos Personalizados em Stored Procedures
Tipos personalizados de extensão podem ser usados como tipos de parâmetro de stored procedure e em declarações de variáveisDECLARE. O servidor resolve o tipo personalizado no
momento da execução da rotina usando os metadados de tipo da extensão instalada.
Veja Também
- Tipos Personalizados em C++ — introdução em nível de tutorial aos tipos personalizados
- Referência da API C++ — contratos de VDF, tratamento de null e dimensionamento de buffer
- Desenvolvimento em C++ — profundidade de autoria de VDF, tipos de argumento e resultado, agregados, varargs

