Reading a Variant column from Parquet files with different shredding layouts null-fills typed_value; every shredded field then reads as NULL, with no error

Aberta
#27,089 10 comentários 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
5/5
Tempo estimado
Mais de uma semana
Facilidade para iniciantes
35/100
Tipo de issue
Bug
Clareza
Claramente especificada
Status de atividade
Ativa
Stack de tecnologia
rust
Domínio
backend, databases

Direção de pesquisa

Start with the linked schema inference and rewrite functions in datafusion/datasource-parquet/src/file_format.rs and datafusion/physical-expr-adapter/src/schema_rewriter.rs, then read #26282 and the Variant shredding specification. Reproduce with the two mixed-layout Parquet cases in the issue and trace how the adapter handles the missing typed_value children. Done means mixed layouts preserve the Variant fields across files, with coverage for both cases.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

Part of #26517.

Is your feature request related to a problem or challenge?

I have a table of Parquet files with one Variant column, event. Each row is a small JSON object like {"service":"api","status":200,"latency_ms":12}. The files were not all written the same way:

  • a.parquet is shredded on service and status. Those two fields are stored as typed columns under typed_value; the rest stays in value.
  • b.parquet is not shredded. The whole object is in value, there is no typed_value.

Both files hold the same 3 rows. Spark reads a table like this fine. Each file also reads fine on its own in DataFusion.

Query (with datafusion-variant registered):

SELECT variant_get(event, 'service', 'VARCHAR') AS service FROM events

What I get:

+---------+
| service |
+---------+
| api     |   <- a.parquet
| api     |
| db      |
|         |   <- b.parquet
|         |
|         |
+---------+

What I expect: api, api, db for both files, so 6 non-null rows. That is what each file returns on its own.

What happens: the merged table schema has typed_value, and b.parquet does not. The schema adapter fills typed_value with NULL for that file. For a plain struct that is right. For Variant it is not: the shredding spec says a NULL typed_value means "this value is not an object", so the reader never looks in value for service. The data is still there, it is just skipped. No error, no warning.

The same thing happens when two files are shredded on different fields. Before #26195 that case failed at open; on branch-56 it null-fills too.

Describe the solution you'd like

Let an extension type decide how a file's layout maps to the table's layout, instead of the default struct null-fill. The Variant version would live in datafusion-variant. Per the discussion below I am starting with a PhysicalExprAdapter there and will report back on what, if anything, core needs.

Additional context

Repro: a 90-line Rust program that writes the two files with arrow-rs shred_variant and runs the query. It is in the edit history of this issue; I will replace it with a SQL-only version once datafusion-contrib/datafusion-variant#145 (COPY ... OPTIONS ('variant.shredding' ...)) lands.

DataFusion branch-56 at 1635ed9, arrow/parquet 60.1, datafusion-variant 642248a.

Linguagem predominante
Rust
Estrelas
9.6k
Forks
2.6k
Merge médio
3d 4h
PRs com merge (30d)
345

Preparar o ambiente

Abrir no Codespaces

Inicia o contêiner de desenvolvimento do projeto no navegador, com a sua própria conta do GitHub.

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de apache/datafusion

Todas as issues de apache/datafusion

Issues semelhantes

Mais issues de Rust

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.