> ## 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.

# Funções definidas pelo usuário no Cloud

> Adicione suas próprias funções executáveis em Python no Cloud

export const BetaBadge = ({link, galaxyTrack, galaxyEvent}) => {
  if (link) {
    return <a href={link} target="_blank" rel="noopener noreferrer" className="betaBadge" onClick={galaxyTrack && galaxyEvent ? galaxyOnClick(galaxyEvent) : undefined}>
                <span>Beta</span>
            </a>;
  }
  return <a href="https://clickhouse.com/docs/reference/settings/beta-and-experimental-features#beta-features" className="betaBadge">
            <span>Recurso beta</span>
        </a>;
};

Funções Definidas pelo Usuário (UDF) permitem que os usuários ampliem o comportamento do ClickHouse para além do que é oferecido por mais de mil [funções](/pt-BR/reference/functions/regular-functions/overview) nativas.

No ClickHouse Cloud, há várias maneiras de criar e gerenciar funções definidas pelo usuário:

1. Usando SQL
2. Usando a UI e seu próprio código (beta pública)
3. Usando a [Cloud API](#manage-udfs-with-the-cloud-api) (beta)
4. Usando o [Terraform](#manage-udfs-with-terraform) (alpha)

<div id="sql-udfs">
  ## Funções Definidas pelo Usuário em SQL
</div>

As UDFs em SQL podem ser criadas usando a instrução [`CREATE FUNCTION`](/pt-BR/reference/statements/create/function) a partir de uma expressão lambda.

Neste exemplo, vamos criar uma função definida pelo usuário executável simples, `isBusinessHours`.
A função verificará se um determinado timestamp está dentro do horário comercial e retornará true se estiver; caso contrário, false.

1. Faça login no Cloud Console e abra o SQL Console
2. Escreva a seguinte consulta SQL para criar a função `isBusinessHours`:

```sql theme={null}
CREATE FUNCTION isBusinessHours AS (ts) ->
toDayOfWeek(ts) BETWEEN 1 AND 5
AND toHour(ts) BETWEEN 9 AND 17;
```

3. Execute o comando abaixo para testar sua UDF recém-criada:

```sql theme={null}
SELECT isBusinessHours('2026-03-20 10:00:00'::DateTime), isBusinessHours('2026-03-20 23:00:00'::DateTime);
```

Você deverá receber o seguinte resultado:

```response theme={null}
1   0
```

4. Você pode usar o comando `DROP FUNCTION` para remover a UDF que acabou de criar:

```sql theme={null}
DROP FUNCTION isBusinessHours
```

<Warning>
  **Importante**

  UDFs no ClickHouse Cloud **não herdam configurações no nível do usuário**. Elas são executadas com as configurações padrão do sistema.
</Warning>

Isso significa:

* As configurações no nível da sessão (definidas pela instrução `SET`) não são propagadas para o contexto de execução das UDFs
* As configurações de perfil do usuário não são herdadas pelas UDFs
* As configurações no nível da consulta não se aplicam durante a execução das UDFs

<div id="ui-udfs">
  ## Funções Definidas pelo Usuário criadas via UI
</div>

<BetaBadge />

O ClickHouse Cloud oferece uma interface na UI para criar funções definidas pelo usuário.

Neste exemplo, vamos criar a mesma função definida pelo usuário executável simples, `isBusinessHours`, que verifica se um determinado timestamp está dentro do horário comercial.
Anteriormente, nós a criamos usando SQL, mas desta vez vamos criá-la em Python e configurá-la pela UI.

<Steps>
  <Step title="Crie o arquivo Python" id="create-python-file">
    Crie localmente um novo arquivo `main.py`:

    ```python theme={null}
    cat > main.py << 'EOF'
    import sys
    from datetime import datetime

    for line in sys.stdin:
        ts = datetime.fromisoformat(line.strip())
        result = 1 if (0 <= ts.weekday() <= 4 and 9 <= ts.hour <= 17) else 0
        print(result)
        sys.stdout.flush()
    EOF
    ```

    Se o seu script em Python importar pacotes de terceiros, liste-os em um arquivo `requirements.txt`, e o ClickHouse Cloud os instalará para você. Como alternativa, você pode empacotar as dependências diretamente no ZIP, mas, nesse caso, deverá incluir os pacotes em cache para ambas as arquiteturas de CPU, portanto o `requirements.txt` é mais simples. Por exemplo:

    ```text theme={null}
    requests>=2.28.0
    numpy>=1.23.0
    ```

    <Note>
      O ClickHouse Cloud espera encontrar `main.py` no arquivo zip que você fará upload pela UI na próxima etapa.
      Se o arquivo tiver outro nome, ocorrerá um erro.
    </Note>
  </Step>

  <Step title="Empacote as dependências e os arquivos locais" id="bundle-dependencies">
    Para incluir pacotes de dependência e quaisquer arquivos locais adicionais (como arquivos wheel, arquivos de configuração ou arquivos de dados), coloque-os no mesmo diretório que `main.py` e `requirements.txt`. Ao criar o arquivo ZIP, inclua todos os arquivos:

    ```bash theme={null}
    zip is_business_hours.zip main.py requirements.txt
    ```

    Você pode fazer referência ao diretório base do caminho local incluído no pacote no seu código Python usando `os.path.dirname(os.path.abspath(__file__))`. Isso retorna o caminho absoluto para o diretório em que o `main.py` está localizado dentro do arquivo ZIP, permitindo acessar outros arquivos incluídos no pacote:

    ```python theme={null}
    import os

    # Get the base directory of the bundled files
    base_dir = os.path.dirname(os.path.abspath(__file__))
    config_path = os.path.join(base_dir, 'config.json')
    ```

    Isso é útil quando você precisa:

    * Acessar arquivos de configuração incluídos na sua UDF
    * Carregar pacotes wheel para dependências personalizadas
    * Referenciar scripts adicionais ou arquivos de dados

    Agora compacte o arquivo em um arquivo ZIP:

    ```bash theme={null}
    zip is_business_hours.zip main.py
    ```

    <Warning>
      **Links simbólicos não são permitidos**

      O ClickHouse Cloud rejeita arquivos UDF que contenham links simbólicos. Certifique-se de que seu pacote ZIP contenha apenas arquivos e diretórios comuns — envios com links simbólicos não passarão na validação.
    </Warning>
  </Step>

  <Step title="Criar uma UDF pela UI" id="create-udf-via-ui">
    1. Na página inicial do Cloud Console, clique no nome da sua organização no menu no canto inferior esquerdo.
    2. Selecione **Funções Definidas pelo Usuário** no menu.
    3. Na página de funções definidas pelo usuário, clique em **Set up a UDF**. Um painel de configuração é aberto no lado direito da tela.
    4. Digite um nome para a função. Para este exemplo, use `isBusinessHours`.
    5. Selecione um tipo de função: **Executable pool** ou **Executable**:
       * **Executable pool**: Um pool de processos persistentes é mantido, e um processo é obtido desse pool para leituras.
       * **Executable**: O script é executado em cada consulta.
    6. Para este exemplo, use as configurações padrão. Para ver a lista completa dos parâmetros de configuração, consulte [Funções definidas pelo usuário executáveis](/pt-BR/reference/functions/regular-functions/udf#executable-user-defined-functions).
    7. Clique em **Browse File** para fazer upload do arquivo `.zip` criado no início deste tutorial.
    8. Adicione um novo argumento. Para este exemplo, adicione o argumento `timestamp` com o tipo `DateTime`.
    9. Selecione um tipo de retorno. Para este exemplo, selecione `Bool`.
    10. Clique em **Create UDF**. Uma caixa de diálogo exibe o status atual da compilação.
        * Se houver algum problema, o status muda para **error**.
        * Caso contrário, o status avança de **building** para **provisioning**. Seu serviço precisa estar ativo para concluir o provisioning. Se o serviço estiver ocioso, clique em **Wake Up Service** no painel **UDF details**, ao lado do nome do serviço.
        * Quando a implantação for concluída, o status muda para **deployed**.
  </Step>

  <Step title="Teste sua UDF" id="test-your-udf">
    1. volte à página inicial do SQL Console clicando em **Settings - voltar para a visão do seu serviço** no canto superior esquerdo da página
    2. clique em **SQL Console** no menu à esquerda
    3. escreva a seguinte consulta:

    ```sql theme={null}
    SELECT isBusinessHours('2026-03-20 10:00:00'::DateTime), isBusinessHours('2026-03-20 23:00:00'::DateTime);
    ```

    Você deverá ver o seguinte resultado:

    ```response theme={null}
    true    false
    ```
  </Step>

  <Step title="Criar uma nova versão" id="create-new-version">
    Para alterar o código de uma UDF, crie uma nova versão. O painel **Edit** gerencia apenas a quais serviços uma UDF está atribuída; fazer upload de um arquivo ali não substituirá o código implantado.

    1. Na página inicial do Cloud Console, clique no nome da sua organização no menu no canto inferior esquerdo.
    2. Selecione **Funções Definidas pelo Usuário** no menu.
    3. Clique nos três pontos em **Ações** da UDF `isBusinessHours` e, em seguida, em **Criar nova versão**
    4. Faça upload de um arquivo zip com o código modificado ou altere as configurações e clique em **Criar nova versão**

    Você adicionou com sucesso sua primeira função definida pelo usuário pela UI, confirmou que ela é executada e viu como criar uma nova versão, se necessário.
  </Step>
</Steps>

<div id="manage-udfs-with-the-cloud-api">
  ## Gerencie UDFs com a Cloud API
</div>

<BetaBadge />

Tudo o que está disponível na UI também pode ser acessado programaticamente por meio da [ClickHouse Cloud API](/pt-BR/products/cloud/features/admin-features/api/api-overview).
Os endpoints de UDF permitem automatizar todo o ciclo de vida de uma UDF: fazer upload de arquivos de origem, criar funções e versões, anexá-las a serviços e removê-las.

<Note>
  Estes endpoints estão em beta, e o contrato da API pode mudar.
</Note>

O fluxo de trabalho típico para criar e implantar uma UDF pela API é:

1. [Crie uma URL de upload](/pt-BR/products/cloud/api-reference/udf/udf-upload-session-create) para obter uma URL pré-assinada para upload de `application/zip` e, em seguida, faça upload do seu arquivo ZIP. Cada ID de upload pode ser usado em apenas uma tentativa de criação ou versionamento; solicite uma nova URL de upload ao tentar novamente.
2. [Crie a UDF](/pt-BR/products/cloud/api-reference/udf/udf-create) a partir do arquivo enviado, especificando o nome da função, o runtime, os argumentos e o tipo de retorno.
3. [Anexe a UDF a um serviço](/pt-BR/products/cloud/api-reference/udf/udf-attach). Quando a versão é omitida, a versão pronta mais recente é anexada. O serviço deve estar em execução; serviços inativos podem ser ativados antes.

O conjunto completo de endpoints:

| Endpoint                                                                                        | Descrição                                                                            |
| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| [Criar URL de upload de UDF](/pt-BR/products/cloud/api-reference/udf/udf-upload-session-create) | Cria uma URL pré-assinada para upload de `application/zip` com escopo de organização |
| [Criar UDF](/pt-BR/products/cloud/api-reference/udf/udf-create)                                 | Cria uma nova UDF a partir de um arquivo enviado                                     |
| [Listar UDFs](/pt-BR/products/cloud/api-reference/udf/udf-list)                                 | Retorna a versão mais recente de cada UDF na organização                             |
| [Obter UDF](/pt-BR/products/cloud/api-reference/udf/udf-get)                                    | Retorna a versão mais recente de uma UDF                                             |
| [Excluir UDF](/pt-BR/products/cloud/api-reference/udf/udf-delete)                               | Exclui todas as versões de uma UDF e a desanexa de todos os serviços                 |
| [Criar versão de UDF](/pt-BR/products/cloud/api-reference/udf/udf-version-create)               | Usa um arquivo de origem, atribui uma versão e inicia a compilação da UDF            |
| [Listar versões de UDF](/pt-BR/products/cloud/api-reference/udf/udf-version-list)               | Retorna todas as versões de uma UDF                                                  |
| [Excluir versão de UDF](/pt-BR/products/cloud/api-reference/udf/udf-version-delete)             | Exclui uma versão de UDF que não está anexada a nenhum serviço                       |
| [Anexar UDF ao serviço](/pt-BR/products/cloud/api-reference/udf/udf-attach)                     | Anexa uma versão de UDF a um serviço, substituindo a versão atual quando necessário  |
| [Listar anexos de UDF](/pt-BR/products/cloud/api-reference/udf/udf-attachment-list)             | Retorna os anexos atuais de uma UDF a serviços                                       |
| [Obter anexo de UDF](/pt-BR/products/cloud/api-reference/udf/udf-attachment-get)                | Retorna o anexo atual de uma UDF a um serviço                                        |
| [Desanexar UDF do serviço](/pt-BR/products/cloud/api-reference/udf/udf-detach)                  | Desanexa uma UDF de um serviço                                                       |

Consulte a [referência da API de UDF](/pt-BR/products/cloud/api-reference/udf/udf-create) para ver os schemas de solicitação e resposta.

<div id="manage-udfs-with-terraform">
  ## Gerencie UDFs com o Terraform
</div>

O [provider Terraform oficial do ClickHouse](https://registry.terraform.io/providers/ClickHouse/clickhouse/latest/docs) inclui dois recursos para gerenciar UDFs como infraestrutura como código:

* [`clickhouse_udf`](https://github.com/ClickHouse/terraform-provider-clickhouse/blob/main/docs/resources/udf.md) gerencia a própria função. Ele aceita um arquivo ZIP com o código-fonte da função e publica uma nova versão sempre que o hash do arquivo é alterado, aguardando a conclusão da compilação.
* [`clickhouse_udf_attachment`](https://github.com/ClickHouse/terraform-provider-clickhouse/blob/main/docs/resources/udf_attachment.md) anexa uma versão de UDF a um serviço. Um serviço comporta no máximo uma versão de uma função por vez. Você pode fixar um número de versão específico ou fazer referência a `clickhouse_udf.<name>.version` para atualizar automaticamente os serviços para a versão mais recente.

<Note>
  Esses recursos estão disponíveis na versão 3.24.0 e posteriores do provider. Eles estão em status alpha, e seu comportamento pode mudar em futuras versões do provider.
</Note>

Por exemplo, para implantar com o Terraform a UDF `isBusinessHours` do exemplo anterior:

```terraform theme={null}
resource "clickhouse_udf" "is_business_hours" {
  function_name = "isBusinessHours"
  runtime       = "python3.11"
  type          = "executable_pool"
  return_type   = "Bool"

  arguments = [
    { name = "timestamp", type = "DateTime" },
  ]

  source_archive_path = "${path.module}/is_business_hours.zip"
  source_archive_hash = filebase64sha256("${path.module}/is_business_hours.zip")
}

resource "clickhouse_udf_attachment" "production" {
  function_name = clickhouse_udf.is_business_hours.function_name
  service_id    = var.service_id
  version       = clickhouse_udf.is_business_hours.version
}
```

A anexação só é concluída para versões prontas e pode levar vários minutos; serviços inativos são ativados automaticamente. A exclusão de um recurso `clickhouse_udf` remove todas as versões da função e a desanexa de todos os serviços.
