PT EN
Voltar ao site

DATTAX — Referência da Linguagem

Escrever a mesma análise três vezes — uma em SQL, outra em Cypher, outra na linguagem do índice de busca — é retrabalho que não gera valor. DATTAX é a linguagem declarativa do DATTA para consultar, transformar e materializar dados em qualquer fonte cadastrada (PostgreSQL, Neo4j, Iceberg, Kafka e dezenas de outras): você escreve uma sintaxe única e a plataforma traduz para o dialeto do destino. Esta página é a referência completa da linguagem; para uma introdução guiada, comece pelo guia da linguagem.

Versão 1.4.0 (2026-05). Versionamento semântico — bump menor adiciona funções/features backward-compat; bump maior pode quebrar scripts antigos.

Estrutura de um script

dattax
LET windowDays = 30;
DEFINE DATASET vendas
  FROM JDBC "postgres-vendas"
  SELECT cliente_id, valor, data
  WHERE data >= NOW() - DAYS(windowDays);

EVALUATE
  vendas
  | GROUP BY cliente_id
  | AGG total = SUM(valor), pedidos = COUNT(*);

Instruções de topo:

  • LET nome = expr; — variável local imutável.
  • DEFINE DATASET nome FROM <source> ... — declara um dataset reutilizável.
  • DATASET nome = <pipeline>; — nomeia um pipeline inteiro (com os |>) para reaproveitar em EVALUATE ou MATERIALIZE.
  • EVALUATE expr — query final; devolve as linhas ao chamador (gráfico, materialização).
  • MATERIALIZE nome FROM <source> ... — persiste o resultado em um destino (Iceberg, Neo4j, cache da plataforma).

Camada semântica universal (USL)

Você pode referenciar entidades pelo nome de negócio definido na ontologia (ex: Contribuinte) em vez do nome físico da tabela ou do índice. Antes de interpretar o script, a plataforma substitui textualmente os tokens conceituais pelas referências físicas resolvidas:

TokenResolve paraExemplo
${entity:<Nome>}dataset físico da entidade${entity:Contribuinte}TB_RF_01
${entity:<ontologyId>.<Nome>}idem, com ontologia explícita${entity:cnpj.Empresa} → dataset físico da ontologia cnpj
${conn:<Nome>}conexão resolvida da entidade${conn:Contribuinte} → id da conexão

Formato do token: ${(entity|conn):(<ontologyId>.)?<Nome>}.

Como a resolução acontece. A plataforma consulta o catálogo de ontologia e recebe a referência da entidade — o dataset físico mais a conexão (ou o espaço de nomes) correspondente. O resultado fica em cache de duas camadas (memória local + cache distribuído da plataforma) sob a chave datta:dattax:catalog:ontology:<ontologyId>:<entity>, com TTL de 30 minutos (datta.dattax.cache.ontology-ttl-minutes) — scripts que repetem as mesmas entidades não pagam o custo da resolução de novo.

Comportamento seguro:

  • Token não resolvido é preservado textualmente (com aviso no registro de execução) — o script falha de forma informativa, em vez de gerar SQL/Cypher incorreto em silêncio.
  • Com a ontologia desabilitada, o pré-processamento não faz nada: o script segue exatamente como você escreveu.

Fontes (FROM <source>)

TokenTipoConector
GRAPH "name"Neo4jDriver nativo (Cypher + algoritmos de grafo)
INDEX "name"OpenSearchCliente REST nativo
ELASTIC "name"ElasticsearchCliente REST nativo
JDBC "name"Qualquer banco JDBC catalogado38 drivers homologados no catálogo oficial
TRINO "name"TrinoFederação SQL via trino-jdbc
ICEBERG "table"Apache Icebergiceberg-java + REST catalog
FILE "path"CSV/Parquet/JSON localParser nativo
CASSANDRA "name"Cassandra/ScyllaDBDriver Java DataStax (paginação assíncrona)
MONGO "name"MongoDBDriver MongoDB (aggregation pipeline)
BIGQUERY "name"Google BigQuerygoogle-cloud-bigquery + Storage Read API
`STREAM "topic" KAFKA \PULSAR \CDC \

Toda fonte é referenciada pelo nome da conexão cadastrada em SistemaConexões — endereços e credenciais nunca aparecem no script.

Transformações

O pipe | encadeia transformações sobre o dataset:

TransformaçãoSintaxeEquivalente SQL/DAX
Filter`\FILTER expr`
Project`\SELECT cols...`
Mutate`\MUTATE col = expr`
Join`\JOIN [INNER\
Group`\GROUP BY cols... SUMMARIZE name=fn(col)`
Sort`\ORDER BY col [DESC]`
Limit`\LIMIT n`
Window`\WINDOW TUMBLING("5m")`
Union`\UNION [ALL\

Há mais de 50 transformações adicionais definidas na gramática da linguagem — as mais usadas no dia a dia estão no guia da linguagem.

Tipos de JOIN (1.2.0+)

TipoComportamentoCaso de uso típico
INNER (default)Apenas linhas com correspondência em ambos os lados.Cruzar vendas com clientes (ambos obrigatórios).
LEFTMantém todas as linhas da esquerda; sem match → as colunas da direita ficam NULL.Listar clientes com (ou sem) último pedido.
RIGHTInverso de LEFT.Listar metas com (ou sem) vendedor.
FULLUnião dos LEFT + RIGHT.Reconciliação de duas fontes.
CROSSProduto cartesiano (ignora ON).Grade calendário × cliente.
ANTILinhas da esquerda sem correspondência na direita. Esquema do resultado = esquema da esquerda (não traz colunas da direita).Clientes sem pedido; produtos não vendidos; registros órfãos.
dattax
EVALUATE clientes
  |> JOIN ANTI pedidos ON id = cliente_id ;
-- Retorna clientes que nunca compraram.

Operadores de filtro (1.2.0+)

Além de =, !=, <, >, <=, >=, AND, OR e NOT, a linguagem aceita os operadores SQL-like abaixo, com precedência entre aritmética e comparação (i.e. x + 1 IS NULL é interpretado como (x + 1) IS NULL):

OperadorSintaxeSemântica
Nulocol IS NULL / col IS NOT NULLIgual a SQL — só verdadeiro se a célula for NULL.
Intervalocol BETWEEN a AND b / col NOT BETWEEN a AND bInclusivo nos dois extremos. NULL em qualquer lado → NULL (3-valued logic).
Listacol IN ("a", "b", "c") / col NOT IN (...)Comparação solta (1 casa com "1").
TextoCONTAINS(col, "x"), NOT_CONTAINS(col, "x"), STARTS_WITH(col, "x"), ENDS_WITH(col, "x")Funções, não operadores.

Exemplo (§5.7 da especificação funcional):

dattax
EVALUATE FROM JDBC "warehouse"
    "SELECT * FROM vendas"
  |> FILTER status IN ("concluido", "pago")
       AND valor BETWEEN 100 AND 5000
       AND cancelado_em IS NULL
       AND cliente_id IS NOT NULL
       AND NOT_CONTAINS(observacao, "teste") ;

UNION — validação de schema

UNION emite um aviso não-fatal (UNION_SCHEMA_MISMATCH) quando os dois lados têm conjuntos de colunas diferentes. A execução continua: as colunas faltantes são preenchidas com NULL na linha alvo. A execução termina com o status "concluído com alertas" — o contador de avisos do evento final vem maior que zero.

Data Quality — |> DATA_QUALITY (1.3.0+)

Atende §5.14 da especificação funcional. Executa verificações declarativas sobre o dataset corrente e emite avisos não-fatais para cada violação. Cada aviso tem um código fixo que a interface usa para cor e ícone.

CheckSintaxeCódigo de aviso
Coluna sem nulosCHECK NOT NULL colDQ_NULLS_FOUND
Chave únicaCHECK UNIQUE col1, col2DQ_DUPLICATES_FOUND
IntervaloCHECK RANGE col BETWEEN 0 AND 100DQ_RANGE_VIOLATION
Não vazioCHECK NOT EMPTYDQ_EMPTY_DATASET
Cardinalidade exataCHECK EXPECTED ROWS 1000DQ_EXPECTED_ROWS_MISMATCH
Cardinalidade em faixaCHECK EXPECTED ROWS BETWEEN 100 AND 5000DQ_EXPECTED_ROWS_OUT_OF_RANGE
Schema esperadoCHECK EXPECTED COLUMNS id, nome, valorDQ_MISSING_COLUMNS
% nulos máximoCHECK PCT_NULL col < 5DQ_PCT_NULL_EXCEEDED
Predicado customCHECK CUSTOM "msg" predicateDQ_CUSTOM_VIOLATION
dattax
EVALUATE FROM JDBC "warehouse" "SELECT * FROM vendas"
  |> DATA_QUALITY
       CHECK NOT NULL cliente_id,
       CHECK UNIQUE pedido_id,
       CHECK RANGE valor BETWEEN 0 AND 1000000,
       CHECK PCT_NULL desconto < 10,
       CHECK EXPECTED ROWS BETWEEN 100 AND 5000000,
       CHECK CUSTOM "data futura" data_venda <= NOW()
  |> SELECT * ;

DQ é observação — não filtra. Para descartar linhas inválidas, combine com FILTER. O dataset passa para a próxima etapa intocado.

Estados granulares de execução — 1.3.0+

Atende §5.16 da especificação. Cada execução reporta progresso em tempo real na tela, estágio a estágio:

EstágioQuandoO que você vê
dattaxInício da execuçãoExecução iniciada
connectingResolvendo a conexão com a fonteNome da fonte sendo conectada
extractingLendo da fonteContagem de registros lidos
transformingAplicando transformações"Etapa N/M: FILTER" e similares
materializePersistindoProgresso da gravação

Ao final, o evento de conclusão carrega o número de avisos acumulados: se for maior que zero, a execução aparece como "concluído com alertas" — você sabe que terminou e sabe que vale conferir os avisos.

Modos de persistência — MATERIALIZE ... MODE ... PARTITION BY ... (1.3.0+)

Atende §5.15. Sintaxe:

dattax
MATERIALIZE vendas_consolidadas AS ICEBERG TABLE "gold.vendas"
  MODE INCREMENTAL
  PARTITION BY ano, mes
  WATERMARK data_venda ;

Modos suportados (cada destino mapeia para a semântica nativa do motor):

ModoSemântica
OVERWRITESubstitui todos os dados existentes.
APPENDAcrescenta novos registros sem tocar nos antigos.
UPDATEAtualiza registros existentes (requer chave).
INCREMENTALAPPEND + UPDATE baseado em WATERMARK <col>.
HISTORICALMantém histórico por data de processamento.
VERSIONEDCria nova versão do dataset (snapshot).

PARTITION BY é repassado aos destinos que suportam particionamento (Iceberg, Parquet/Delta). Destinos sem suporte (índice OpenSearch simples, label Neo4j) emitem o aviso MATERIALIZE_PARTITION_IGNORED e seguem com o padrão.

MATERIALIZE ... AS NEO4J — banco de destino obrigatório

A persistência em Neo4j nunca adivinha o banco de destino. Abrir uma sessão de escrita amarrada a um banco "default" silencioso é receita para dado no lugar errado: o destino tem de ser uma decisão explícita.

Sintaxe explícita

A cláusula DATABASE é obrigatória, seguida do label e da chave de merge — todos obrigatórios:

antlr
materializeNeo4j : 'NEO4J' 'DATABASE' STRING 'LABEL' IDENT 'KEY' IDENT ;

Na prática, o script informa o banco como literal de string, o label como identificador e a propriedade-chave usada no MERGE:

dattax
MATERIALIZE grafo_partes AS NEO4J
  DATABASE "processotributario"
  LABEL Parte
  KEY documento
  MODE UPDATE ;

Omitir DATABASE é erro de sintaxe — o script é rejeitado antes de qualquer execução, porque a cláusula não é opcional na gramática.

Validação em tempo de execução (banco vazio)

Mesmo que o valor chegue vazio (nulo ou em branco) durante a execução, a gravação é rejeitada antes de abrir qualquer sessão no grafo, com esta mensagem exata:

text
Banco de destino da materializacao Neo4j e obrigatorio — nunca adivinhado.

Não há fallback para "neo4j" nem para nenhum outro nome. O label (validado contra o padrão [A-Za-z_][A-Za-z0-9_]*) e a chave de merge são conferidos na mesma etapa, antes da gravação.

MATERIALIZE ... AS AUTO — a plataforma escolhe o motor

Quando você escreve MATERIALIZE <ds> AS AUTO, a plataforma pontua os motores disponíveis (Iceberg, Neo4j, OpenSearch) e escolhe o mais adequado ao formato do resultado. Se o Neo4j vencer, o resultado é depositado no banco de sistema padrão do grafo ("neo4j"). Isso não é fallback silencioso: uma materialização AUTO é um artefato derivado pela própria plataforma, sem contexto de domínio escolhido por você, então o destino padrão é uma escolha deliberada e documentada — distinta dos uploads, que sempre carregam um contexto de destino explícito. Para um destino específico, use a forma explícita com DATABASE.

FormaQuem decide o bancoOrigem do valor
AS NEO4J DATABASE "<db>" LABEL <l> KEY <k>VocêCláusula DATABASE da gramática (obrigatória).
AS AUTO (motor resolvido = Neo4j)A plataformaBanco de sistema padrão do grafo — escolha deliberada, não fallback.
(banco vazio em runtime)Rejeitado com a mensagem em português acima.

Standard Library (F11+)

Funções chamáveis em qualquer expressão — cerca de 40 na versão 1.1.0, organizadas em 4 categorias. O editor DATTAX oferece autocomplete com todas elas.

Math (category: math)

FunçãoAssinatura
SUM(values)number[] -> number
AVG(values)number[] -> number
COUNT(values)any[] -> number
COUNT_DISTINCT(values)any[] -> number
MIN(values)comparable[] -> any
MAX(values)comparable[] -> any
MEDIAN(values)number[] -> number
ROUND(value, decimals?)number -> number
FLOOR(value) / CEIL(value)number -> number
ABS(value)number -> number
POWER(base, exp)(number, number) -> number
SQRT(value)number -> number

String (category: string)

FunçãoAssinatura
CONCAT(parts...)any... -> string
UPPER(value) / LOWER(value)string -> string
LENGTH(value)string -> number
SUBSTRING(value, start, length?)string -> string
TRIM(value)string -> string
REPLACE(value, target, replacement)string -> string
REGEX_EXTRACT(value, pattern, group?)string -> string
SPLIT(value, sep, index?)`string -> string[]\
STARTS_WITH(value, prefix) / ENDS_WITH(value, suffix)string -> boolean

Date (category: date)

Aceita string ISO-8601, instante, data ou epoch millis. Fuso padrão America/Sao_Paulo.

FunçãoAssinatura
NOW()-> instant
TODAY()-> date
DATE_PARSE(value, pattern?)string -> instant
DATE_FORMAT(value, pattern)(date, string) -> string
DATE_ADD(value, amount, unit)`unit: SECOND\
DATE_DIFF(start, end, unit)`unit: SECOND\
YEAR / MONTH / DAY / QUARTER / WEEK_OF_YEAR / DAY_OF_WEEKdate -> number

Time Intelligence (category: time-intelligence, 1.1.0+)

Funções sobre séries temporais. Recebem (rows, dateColumn, valueColumn, refDate?) e operam em janela determinada pela função.

FunçãoJanela
YTD(rows, date, value, ref?)01/jan ano atual → ref
MTD(rows, date, value, ref?)1º dia mês atual → ref
QTD(rows, date, value, ref?)1º dia trimestre atual → ref
SAMEPERIODLASTYEAR(rows, date, value, ref?)01/jan ano-1 → ref-1ano
GROWTH_PCT(current, previous)(current - previous) / previous * 100
ROLLING_AVG(rows, date, value, windowDays, ref?)últimos N dias até ref

Medidas tipo YoY e Q vs Q-1 saem prontas, sem você reescrever a query — o mesmo conforto que se espera do Power BI ou do Tableau. Para o mapa completo de equivalências com DAX, veja DATTAX × DAX.

Exemplo prático — pipeline completo com qualidade e materialização

Cenário: consolidar as vendas válidas do warehouse numa tabela gold do Iceberg, com checagens de qualidade no meio do caminho.

  1. Abra o editor DATTAX.
  2. Confirme que a conexão warehouse existe em SistemaConexões.
  3. Cole e execute o script — ele declara o dataset consolidado e, em seguida, materializa esse dataset na tabela gold:
dattax
DATASET vendas_mensais =
  FROM JDBC "warehouse" "SELECT * FROM vendas"
  |> FILTER status IN ("concluido", "pago") AND cancelado_em IS NULL
  |> DATA_QUALITY
       CHECK NOT NULL cliente_id,
       CHECK UNIQUE pedido_id,
       CHECK PCT_NULL desconto < 10
  |> MUTATE ano = YEAR(data_venda), mes = MONTH(data_venda)
  |> GROUP BY ano, mes SUMMARIZE total = SUM(valor), pedidos = COUNT(*),
       ultima_venda = MAX(data_venda) ;

MATERIALIZE vendas_mensais AS ICEBERG TABLE "gold.vendas_mensais"
  MODE INCREMENTAL
  PARTITION BY ano, mes
  WATERMARK ultima_venda ;
  1. Acompanhe os estágios (connectingextractingtransformingmaterialize) em tempo real. Se alguma checagem de qualidade falhar, a execução termina como "concluído com alertas" — os avisos ficam listados, mas a tabela é gravada.

Versionamento e compatibilidade

  • A versão corrente da biblioteca padrão é 1.1.0, e a plataforma carrega apenas as funções cuja versão de introdução seja menor ou igual a ela.
  • Scripts antigos em produção continuam executando após upgrades — funções novas entram por bump menor, sem quebrar o que já existe.
  • Funções descontinuadas geram avisos na execução, mas seguem disponíveis até o próximo bump maior. Você tem tempo de migrar no seu ritmo.
  • Uma função nova é adicionada declarando um método estático anotado no pacote da biblioteca padrão — o catálogo a descobre sozinho na inicialização, sem editar a gramática (funções entram pelo funcCall genérico que já existe).

Evolução da linguagem

  • 1.3.0ANTI JOIN; operadores SQL-like (IS NULL, BETWEEN, IN, NOT_CONTAINS, ENDS_WITH); UNION com validação de schema; avisos não-fatais e "concluído com alertas"; estados granulares de execução (connecting/extracting/transforming/persisting); transformação DATA_QUALITY com 9 tipos de checks (§5.14); modos de persistência (MODE, PARTITION BY, WATERMARK, §5.15); Excel (.xlsx) como fonte de arquivo (§5.3); pausa, retries e fuso configurável no agendador (§5.17); mascaramento de PII no designer (§5.19); duplicação de etapa (§5.6); cards do canvas com schema visível + desfazer/refazer.
  • 1.4.0 (atual) — editor com syntax highlight e autocomplete de toda a biblioteca padrão e dos comandos principais (EVALUATE / FROM JDBC / FILTER / JOIN / GROUP BY / DATA_QUALITY / MATERIALIZE), alimentado pelo catálogo da biblioteca padrão que a plataforma publica (ver referência de API); quoting correto por dialeto ao empurrar consultas para a fonte (MySQL ` backticks , MSSQL [brackets], BigQuery backticks , Oracle/PostgreSQL "double quotes"); monitoramento de pastas com padrões glob (/data/incoming/.csv, /data//.parquet); métricas de execução (fontes acessadas, avisos, estágio do erro, registros descartados) persistidas no Neo4j e visíveis no monitor de pipelines; ciclo de vida completo do pipeline (pausar, retomar, arquivar, ativar — também disponível pela **referência de API**); templates de notificação por email/webhook com variáveis ({{pipelineName}}, {{status}}`); conversão do pipeline visual em script DATTAX, fechando o loop entre o canvas e a linguagem.
  • Ainda em aberto para 1.4.0CALCULATE(expr, modifiers...) e contextos de filtro formalizados (RowContext vs FilterContext, equivalente DAX); visualizador de plano de consulta; diálogo visual de configuração de JOIN/aresta no designer; cardinalidade automática 1:1 / 1:N / N:1 / N:N.
  • 2.0.0 (planejado) — pushdown completo de filtros (§5.7 — WHERE traduzido para o dialeto da fonte); modos de gravação totalmente implementados em todos os destinos (não só na gramática); interface de execução de produção; novas famílias de fonte (GraphQL, SaaS, cloud storage, ODBC); tipagem estática opcional; otimizador de consultas com eliminação de subexpressões comuns.