Skip to content

Support unparsing the Value Plan of Array (List) to SQL String #11144

@goldmedal

Description

@goldmedal

Is your feature request related to a problem or challenge?

In unparser/expr.rs, list scalar values haven't been supported yet.

ScalarValue::FixedSizeList(_a) => not_impl_err!("Unsupported scalar: {v:?}"),
ScalarValue::List(_a) => not_impl_err!("Unsupported scalar: {v:?}"),
ScalarValue::LargeList(_a) => not_impl_err!("Unsupported scalar: {v:?}"),

However, I found some problems with supporting it. Currently, array construction is implemented by a ScalarUDF called make_array.

if let Some(udf) = self.context_provider.get_function_meta("make_array") {
Ok(Expr::ScalarFunction(ScalarFunction::new_udf(udf, values)))
} else {
not_impl_err!(
"array_expression featrue is disable, So should implement make_array UDF by yourself"
)
}

This might mean ScalarValue::List is never created from an AST expression node.

If I try to create the logical plan without the default SessionContext, like this:

let sql = r#"select [1,2,3]"#;

println!("SQL: {:?}", sql);
println!("********");
// parse the SQL
let dialect = GenericDialect {}; // or AnsiDialect, or your own dialect ...
let ast = Parser::parse_sql(&dialect, sql).unwrap();
let statement = &ast[0];
println!("AST: {:?}", statement);

// create a logical query plan
let context_provider = MyContextProvider::new();
let sql_to_rel = SqlToRel::new(&context_provider);
let plan = match sql_to_rel.sql_statement_to_plan(statement.clone()) {
    Ok(plan) => plan,
    Err(e) => {
        println!("Error: {:?}", e);
        return;
    }
};
// show the planned SQL
let planned = match plan_to_sql(&plan) {
    Ok(sql) => sql,
    Err(e) => {
        println!("Error: {:?}", e);
        return;
    }
};

println!("unparsed to SQL:\n {}", planned);

I will get the error message:

Error: NotImplemented("array_expression feature is disabled, so you should implement the make_array UDF yourself")

Then, I tried to add make_array_udf in MyContextProvider. I can get the unparsed result like this:

unparsed to SQL:
SELECT make_array(1, 2, 3)

However, I think make_array isn't a common function for standard SQL. It may cause some problems when we try to fully push down the unparsed result to a specific data source.

Describe the solution you'd like

Ideally, we can round-trip the array construction in SQL select [1,2,3] through the following steps:

  1. Transform the AST::Expr::Array to ScalarValue::List (currently, it's the make_array scalar function).
  2. Implement the unparsing of ScalarValue::List.

However, I'm not sure why the array expression was disabled and make_array is used instead. Maybe it is due to some performance issues?

Describe alternatives you've considered

Another approach is to try unparsing the make_array() plan to AST::Expr::Array. It's tricky, but I think it could work.

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions