Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Unparser turns NULL list literals into `[]` and fails on NULL struct/map literals

オープン 初心者向け
#26,316 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
72/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
rust, sql
領域
databases

調査の方向性

Unparser::scalar_to_sql から始めてください(datafusion/sql/src/unparser/expr.rs)。List のアーム(1450〜1454行目付近)は、子の値を null のチェックなしに描画します。Struct、Map、Union のアーム(1579〜1581行目付近)は、null の場合でも not_impl_err! を返します。issue の2つの CASE クエリで再現し、その後 Int32(None) のような型付き null がすでに NULL に unparse されるかを確認してください。ネストした型の NULL リテラルが NULL に unparse され、datafusion-sql の既存の unparser テストがすべて通れば完了です。

索引モデルが issue の本文から書いたものです。

説明

bug help wanted unparser
Describe the bug

The SQL unparser mishandles NULL literals of nested types:

  • A NULL list literal unparses as [], so the generated SQL returns an empty array where the plan returns NULL, with no error.
  • A NULL struct, map, or union literal fails with NotImplemented("Unsupported scalar: ...").

Optimized plans contain these literals whenever type coercion casts a NULL to a nested type and constant folding turns the cast into a literal, e.g. CASE WHEN ... THEN NULL ELSE list_col END or ... UNION ALL SELECT NULL.

The cause is in Unparser::scalar_to_sql. The list arms render the scalar's child values without checking whether the list itself is null (unparser/expr.rs#L1450-L1454), and the Struct/Map/Union arms return not_impl_err! even for nulls (unparser/expr.rs#L1579-L1581). Every other typed null, such as Int32(None) or DurationSecond(None), unparses as NULL.

To Reproduce
use datafusion::error::Result;
use datafusion::prelude::*;
use datafusion::sql::unparser::plan_to_sql;

#[tokio::main]
async fn main() -> Result<()> {
    let ctx = SessionContext::new();
    ctx.sql("CREATE TABLE t AS SELECT 1 AS a, [1, 2] AS l, named_struct('x', 1) AS s")
        .await?;
    for sql in [
        "SELECT CASE WHEN a > 0 THEN NULL ELSE l END AS c FROM t",
        "SELECT CASE WHEN a > 0 THEN NULL ELSE s END AS c FROM t",
    ] {
        let plan = ctx.sql(sql).await?.into_optimized_plan()?;
        println!("{:?}", plan_to_sql(&plan).map(|s| s.to_string()));
    }
    Ok(())
}

Output:

Ok("SELECT CASE WHEN (t.a > 0) THEN [] ELSE t.l END AS c FROM t")
Err(NotImplemented("Unsupported scalar: Struct({x:})"))

Running the first unparsed query returns [] where the original returns NULL. SELECT l FROM t UNION ALL SELECT NULL FROM t similarly unparses to ... UNION ALL SELECT [] AS l FROM t. Map columns fail the same way as struct columns.

Expected behavior

NULL nested-type literals unparse as NULL, like other typed nulls, e.g. CASE WHEN (t.a > 0) THEN NULL ELSE t.l END.

A guard arm at the top of scalar_to_sql is enough:

ScalarValue::List(_)
| ScalarValue::LargeList(_)
| ScalarValue::FixedSizeList(_)
| ScalarValue::ListView(_)
| ScalarValue::LargeListView(_)
| ScalarValue::Struct(_)
| ScalarValue::Map(_)
| ScalarValue::Union(..)
    if v.is_null() =>
{
    Ok(ast::Expr::value(ast::Value::Null))
}

With this arm, the queries above, the UNION ALL case, and the map case all unparse to SQL that returns the same results as the original query, and the existing datafusion-sql tests still pass.

Additional context
  • Non-null struct and map literals, such as a constant-folded named_struct('x', 1), also fail with Unsupported scalar. Rendering those needs dialect-specific syntax, so they are out of scope here.
  • Once #26311 merges, CASE WHEN a > 0 THEN s ELSE NULL END fails the same way. Until then the unparser drops the failing ELSE, which happens to give the same result for ELSE NULL.
  • Line references are pinned to commit 0d79252f61bd.
主要言語
Rust
スター
9.4k
フォーク
2.5k
平均マージ
4日 13時間
マージ済み PR(30日)
353

環境構築

Codespaces で開く

このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

apache/datafusion のほかの issue

apache/datafusion の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。