> ## Documentation Index
> Fetch the complete documentation index at: https://villagesql.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Arquitetura de Extensões

> Como o sistema de extensões do VillageSQL funciona internamente

Entender a arquitetura de extensões do VillageSQL ajuda a depurar problemas e otimizar o desempenho ao criar extensões.

A jornada do autor de extensões é direta: você escreve funções em C++ ou Rust
usando o SDK correspondente, compila-as em uma biblioteca compartilhada e empacota essa biblioteca
junto com um manifesto em um arquivo `.veb`. Quando você executa `INSTALL EXTENSION`, o VillageSQL
carrega sua biblioteca, chama seu código de registro e disponibiliza suas funções
imediatamente como SQL, chamáveis a partir de qualquer consulta como se estivessem integradas ao
servidor. Nenhuma reinicialização do servidor é necessária. O restante desta página explica como cada
etapa desse processo funciona.

## Terminologia

* **VEB** (VillageSQL Extension Bundle) - O formato de arquivo `.veb`, um arquivo tar contendo manifesto, biblioteca e metadados
* **VEF** (VillageSQL Extension Framework) - Os SDKs de C++ e Rust para criação de extensões
* **VDF** (VillageSQL Defined Function) - Funções registradas por meio do VEF, via `VEF_GENERATE_ENTRY_POINTS()` em C++ ou a macro `extension!` em Rust

***

## Busca de Funções VDF

As VDFs oferecem suporte a chamadas de função qualificadas e não qualificadas:

```sql theme={null}
-- Unqualified lookup
SELECT complex_abs(impedance) FROM signals;

-- Qualified lookup
SELECT vsql_complex.complex_abs(impedance) FROM signals;
```

**Ordem de resolução:**

1. Funções do sistema (integradas ao MySQL)
2. UDFs (funções tradicionais definidas pelo usuário do MySQL via `CREATE FUNCTION ... SONAME`)
3. VDFs (funções de extensão) - somente se existir exatamente uma função com esse nome
4. Funções armazenadas (criadas com `CREATE FUNCTION`)

Se mais de uma extensão registrar uma função com o mesmo nome, a chamada não qualificada é ambígua e o nome totalmente qualificado (`extension_name.function_name()`) deve ser usado.

> [!NOTE]
>
> **Alterado na versão 0.0.8-dev.** Um nome de tipo personalizado que mais de uma extensão instalada fornece é rejeitado em `CREATE TABLE` e `ALTER TABLE ADD COLUMN` quando não está qualificado. O erro nomeia as extensões: `Ambiguous type 'TESTTYPE' - provided by multiple extensions: test_type_a, test_type_b. Use qualified name (extension.type).`

***

## Formato de Arquivo VEB

As extensões do VillageSQL são distribuídas como arquivos `.veb` (VillageSQL Extension Bundle) - arquivos tar contendo:

```
extension_name.veb (tar archive)
├── manifest.json       # Extension metadata (required)
└── lib/
    └── extension_name.so    # Compiled shared library (required, named after the extension)
```

### Esquema do manifest.json

```json theme={null}
{
  "name": "extension_name",
  "version": "1.0.0",
  "description": "Brief description",
  "author": "Your Name",
  "license": "GPL-2.0"
}
```

* **name:** Deve corresponder ao nome da extensão usado em SQL (lowercase\_with\_underscores)
* **version:** Versão semântica (MAJOR.MINOR.PATCH)
* **description, author, license:** Metadados opcionais

## Ciclo de Vida da Extensão

### Fluxo de Instalação

```
INSTALL EXTENSION name
    ↓
1. Validate .veb exists in veb_dir
    ↓
2. Parse and validate manifest.json
    ↓
3. Calculate SHA256 hash of .veb
    ↓
4. Expand to {datadir}/.veb_expansion_cache/{name}/{sha256}/
    ↓
5. Load .so library (dlopen with RTLD_LOCAL)
    ↓
6. Call vef_register() entry point
    ↓
7. Register VDFs and custom types
    ↓
8. Persist registration and update cache
    ↓
Success
```

**Reversão:** Se qualquer etapa falhar, a extensão não é registrada e a `.so` é descarregada. Os arquivos expandidos permanecem em `.veb_expansion_cache` até a próxima reinicialização do servidor.

> [!NOTE]
>
> **Alterado na versão 0.0.8-dev.** Um arquivo `.veb` truncado é rejeitado na instalação, e o servidor remove imediatamente os seus arquivos parcialmente expandidos.

**Isolamento de Símbolos:** As extensões são carregadas com a flag `RTLD_LOCAL`, garantindo que os símbolos de uma extensão não entrem em conflito com os símbolos de outras extensões. Isso evita colisões de nomes quando várias extensões usam nomes de biblioteca ou nomes de função comuns.

> [!NOTE]
>
> A variável de sistema `veb_dir` aponta para o diretório onde os arquivos de extensão `.veb` são armazenados.

### Fluxo de Desinstalação

```
UNINSTALL EXTENSION name
    ↓
1. Check for column dependencies
    ↓
2. Drop registered VDFs
    ↓
3. Drop custom types
    ↓
4. Remove extension registration and update cache
    ↓
5. Call vef_unregister() cleanup hook
    ↓
6. Unload .so library (dlclose)
    ↓
7. Keep .veb_expansion_cache directory (for reinstall)
    ↓
Success
```

**Prevenção de dependências:** Não é possível desinstalar se colunas de tabelas usarem os tipos personalizados da extensão.

***

## Estrutura do Diretório de Expansão

O VillageSQL expande arquivos .veb no diretório de dados do MySQL para oferecer suporte a várias versões:

```
datadir/
└── .veb_expansion_cache/
    └── extension_name/
        ├── abc123.../              # SHA256 of v1.0.0 .veb
        │   ├── manifest.json
        │   └── lib/extension_name.so
        └── def456.../              # SHA256 of v2.0.0 .veb
            ├── manifest.json
            └── lib/extension_name.so
```

**Por que diretórios SHA256?**

* Testar novas versões sem sobrescrever
* Habilitar reversão
* Evitar "mesma versão, código diferente"

**Limpeza:** Na inicialização do servidor, o diretório `.veb_expansion_cache` de uma extensão que não está instalada é removido. Os diretórios SHA256 mais antigos de uma extensão instalada permanecem.

***

## Camada de Cache do Victionary

O VictionaryClient mantém caches em memória dos metadados do sistema para buscas O(log n).

### Operações de Cache

| Operação | Bloqueio | Desempenho |
| - | - | - |
| Leitura (resolver tipo) | Bloqueio de leitura | Busca em mapa O(log n) |
| Escrita (instalar extensão) | Bloqueio de escrita | Inserção O(log n) + E/S de disco |
| Inicialização do servidor | N/A | Varredura completa da tabela para a memória |

**Invalidação de cache:** Automática durante operações DDL (INSTALL/UNINSTALL EXTENSION).

**Sobrecarga de memória:** cada entrada confirmada é um nó `std::map<std::string, std::shared_ptr<EntryType>>` mais o payload do descritor — nenhum valor fixo por entrada é registrado no código-fonte.

***

## Sistema de Tipos Personalizados

### Resolução de Tipo

```cpp theme={null}
CREATE TABLE t (col COMPLEX)
    ↓
1. Parser encounters COMPLEX
    ↓
2. PT_custom_type::create()
    ↓
3. ResolveTypeDescriptor(extension_name, type_name)
    ↓
4. VictionaryClient::type_descriptors().get_prefix_committed() → O(log n)
    ↓
5. Find TypeDescriptor in cache
    ↓
6. AcquireOrCreateTypeContext(descriptor, parameters, mem_root)
    ↓
7. Create Field with implementation_type
```

### Tipos de Implementação

Os tipos personalizados são mapeados para tipos de armazenamento do MySQL:

| Tipo Personalizado | Implementação MySQL | Bytes |
| - | - | - |
| COMPLEX | MYSQL\_TYPE\_VARCHAR | 16 |
| UUID | MYSQL\_TYPE\_VARCHAR | 16 |
| INET | MYSQL\_TYPE\_VARCHAR | 19 |

***

## Comportamento de Concorrência e Transações

### Modelo de Segurança de Threads

As funções de extensão são chamadas em um modelo de execução por linha:

* **Execução isolada por linha:** Cada chamada de função recebe seu próprio buffer de resultado (thread-safe por design)
* **Ganchos Prerun/Postrun:** Configuração/limpeza por instrução, chamados uma vez para cada lugar em que a função aparece em uma instrução SQL
* **Sem isolamento garantido:** Várias conexões podem chamar suas funções simultaneamente
* **Prática recomendada:** Evite estado global; use parâmetros de função e valores de retorno

> [!WARNING]
>
> O VillageSQL não garante isolamento de threads para funções de extensão. Se você usar variáveis globais ou estado compartilhado, proteja-os com mutexes ou bloqueios.

### Comportamento de Transações

As funções de extensão devem seguir estas práticas recomendadas:

* Projete funções para serem sem estado quando possível
* Evite efeitos colaterais persistentes (escritas em arquivo, chamadas a APIs externas) nas funções
* Se usar estado prerun/postrun, trate a limpeza adequadamente

***

## Considerações de Desempenho

**Otimização:** Use ganchos prerun para armazenar em cache configurações caras por instrução em vez de repetir o trabalho por linha.

### Desempenho de Tipos Personalizados

```sql theme={null}
-- Slow: VDF call per row
SELECT * FROM signals WHERE complex_abs(impedance) > 100;

-- Fast: Computed column with index
ALTER TABLE signals
ADD COLUMN impedance_magnitude DOUBLE AS (complex_abs(impedance)) STORED,
ADD INDEX(impedance_magnitude);

SELECT * FROM signals WHERE impedance_magnitude > 100;
```

***

## Segurança e Depuração

### Modelo de Segurança

**Modelo de confiança:** As extensões são executadas com privilégios completos do servidor.

* Sem sandbox ou sistema de permissões
* As extensões podem ler qualquer arquivo, acessar a rede, executar código
* **Implicações de confiança:** Instale apenas extensões de fontes confiáveis

**Segurança de instalação:** `INSTALL EXTENSION` e `UNINSTALL EXTENSION` exigem o privilégio `EXTENSION_ADMIN` (ou `SUPER`), imposto pelo sistema comum de concessões do MySQL.

> [accordion] Depurando Extensões
>
> **Habilitar log detalhado:**
>
> ```bash theme={null}
> mysqld --log-error-verbosity=3
> ```
>
> **Depuração com GDB:**
>
> ```bash theme={null}
> # Linux
> gdb -p $(pidof mysqld)
> (gdb) break vef_register
> (gdb) continue
>
> # macOS
> lldb -p $(pgrep -x mysqld)
> (lldb) breakpoint set -n vef_register
> (lldb) continue
> ```
>
> **Verificar dependências:**
>
> ```bash theme={null}
> # Linux
> ldd /path/to/extension.so
>
> # macOS
> otool -L /path/to/extension.so
> ```
>
> **Erros comuns:**
>
> * **Undefined symbol:** Verifique as dependências da biblioteca com `ldd` (Linux) ou `otool -L` (macOS)
> * **Cannot open shared object:** Verifique se as dependências da biblioteca estão presentes e vinculadas corretamente
> * **Crash on VDF call:** Verifique o tratamento de pointers NULL

***

## Próximos Passos

> [card] [Criar Extensão](https://villagesql.com/docs/pt-BR/extensions/build/create.md)
>
> Crie sua primeira extensão

> [card] [Referência do Sistema](https://villagesql.com/docs/pt-BR/8.4/stable/reference.md)
>
> Tabelas e visões do sistema

> [card] [Exemplos](https://villagesql.com/docs/pt-BR/sdk/cpp/examples.md)
>
> Estude a implementação do vsql\_complex

> [card] [Gerenciando Extensões](https://villagesql.com/docs/pt-BR/extensions/managing.md)
>
> Monitore e solucione problemas


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.