You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I think you can select with something like my_struct_col['foo'] which returns the 'foo' field.
However now re-reading this ticket, I think it would be possible to create a user defined function like COLUMN by Implemening return_type_from_exprs to
🤔
I think you can select with something like my_struct_col['foo'] which returns the 'foo' field.
However now re-reading this ticket, I think it would be possible to create a user defined function like COLUMN by Implemening return_type_from_exprs to 🤔
What I was trying to say is that looking at that UDF isn't clear for me how the other fields are dropped. It seems that Datafusion performs an intersection between the field names returned by the return type and the ones returned by array_struct ?
I think you can select with something like my_struct_col['foo'] which returns the 'foo' field.
However now re-reading this ticket, I think it would be possible to create a user defined function like COLUMN by Implemening return_type_from_exprs to 🤔
What I was trying to say is that looking at that UDF isn't clear for me how the other fields are dropped. It seems that Datafusion performs an intersection between the field names returned by the return type and the ones returned by array_struct ?
@edmondop
By default the column name is named c0, c1 ... which defined in array_struct, so in return_type we also find the associated column with name c0, c1 ...
how the other fields are dropped
I don't think we drop any field in struct.
One of the example can be
statement ok
create table t(a1 int, a2 float) as values(1, 1.2), (2, 2.4);
query IR
select a1, a2 from t;
----
1 1.2
2 2.4
// make this works
query IR
select columns(a1, a2) from t;
----
1 1.2
2 2.4
I want to create a udf that can select multiple functions at once, such as a COLUMNS() function.
select COLUMNS('number\d+') from my_table.
looking at the struct UDF, it seems that it only receives the columns that are passed to function invocation and doesn't have access to other columns, i.e. in the struct udf, all columns are returned as a struct, which suggests that the engine only pass a subset of the available columns
However, in the case of COLUMNS('number\d+'), you need to have all the columns, and only return few of them from the function. In my understanding neither udf nor udaf or udwf from what I have seen. We would need maybe a fourth type of udf something like udgf which is invoked on all the columns of a logical plan?
However, in the case of COLUMNS('number\d+'), you need to have all the columns, and only return few of them from the function
I agree, we can't get all the columns by the current design of function, it is quite challenging than I thought 🤔. We expect to build up a projection plan given the syntax columns(..). The function mentioned here is similar to unnest, it is more like a table function. Therefore, I think we need a user-defined table function that we can define the returned Expr given the function we parsed in the parser.
The difference behaviour in parser (datafusion/sql) between these.
Activity
jayzhan211 commentedon Apr 19, 2024
It looks good to me, and we can gradually deprecate single column in the long-term
edmondop commentedon Apr 20, 2024
@universalmind303 are you already working on this?
universalmind303 commentedon Apr 21, 2024
no, feel free to go ahead and work on it if you'd like.
edmondop commentedon Apr 22, 2024
This would require also modifying the protobuf definitions, are we ok with it?
alamb commentedon Apr 23, 2024
How about returning
DataType::StructorDataType::ListorDataType::FixedSizeList?edmondop commentedon Apr 23, 2024
My current wip has a struct since it supports different data types and field names, can a List work as well?
alamb commentedon Apr 24, 2024
No, you are right, a List can't really support multiple different types
edmondop commentedon Apr 24, 2024
@universalmind303 I think it would be interesting to test it, do you have an example / have you written the UDF?
alamb commentedon Apr 24, 2024
I wonder if
struct(col1, col2)ornamed_struct('a', col1, 'b', col2)would work for your usecase 🤔edmondop commentedon Apr 25, 2024
that works, but isn't this unrelated to this change? I suppose it was working before too...
edmondop commentedon Apr 25, 2024
@alamb by the way, how does the
structudf works? I am not sure I understand how this select only a subset of the fields, does Datafusion drop from the resulting dataset the fields that are not in thereturn_type? https://github.com/apache/datafusion/blob/main/datafusion/functions/src/core/struct.rs#L97alamb commentedon Apr 25, 2024
I think https://datafusion.apache.org/user-guide/sql/scalar_functions.html#struct has some pretty good examples
edmondop commentedon Apr 25, 2024
Apologies I wasn't precise in my question. The code of the struct udf doesn't explicitly drop fields but returns all of them.
How does the selection happens ?
alamb commentedon Apr 25, 2024
I think you can select with something like
my_struct_col['foo']which returns the 'foo' field.However now re-reading this ticket, I think it would be possible to create a user defined function like
COLUMNby Implemeningreturn_type_from_exprsto🤔
edmondop commentedon Apr 27, 2024
What I was trying to say is that looking at that UDF isn't clear for me how the other fields are dropped. It seems that Datafusion performs an intersection between the field names returned by the return type and the ones returned by array_struct ?
universalmind303 commentedon Apr 29, 2024
FWIW, #10102 seems related as multi selection could be implemented via
structandunnest.jayzhan211 commentedon May 8, 2024
@edmondop
By default the column name is named c0, c1 ... which defined in
array_struct, so inreturn_typewe also find the associated column with name c0, c1 ...I don't think we drop any field in struct.
One of the example can be
edmondop commentedon May 16, 2024
I want to create a udf that can select multiple functions at once, such as a COLUMNS() function.
looking at the struct UDF, it seems that it only receives the columns that are passed to function invocation and doesn't have access to other columns, i.e. in the
structudf, all columns are returned as a struct, which suggests that the engine only pass a subset of the available columnsHowever, in the case of COLUMNS('number\d+'), you need to have all the columns, and only return few of them from the function. In my understanding neither
udfnorudaforudwffrom what I have seen. We would need maybe a fourth type of udf something likeudgfwhich is invoked on all the columns of a logical plan?jayzhan211 commentedon May 16, 2024
I agree, we can't get all the columns by the current design of function, it is quite challenging than I thought 🤔. We expect to build up a projection plan given the syntax
columns(..). The function mentioned here is similar tounnest, it is more like atablefunction. Therefore, I think we need a user-defined table function that we can define the returnedExprgiven the function we parsed in the parser.The difference behaviour in parser (datafusion/sql) between these.
Expr::ScalarFunction/Expr::AggregateFunction/Expr::WindowFunctionrespectivelyExpr::UnnestColumns(regex): returnsExpr::Columns(Vec<Column>)ExprTo make the mentioned function possible, we don;t even need to introduce
Expr::Columns, but returnsVec<Expr>forsql_to_expr.datafusion/datafusion/sql/src/select.rs
Lines 449 to 457 in 7535d93
edmondop commentedon May 16, 2024
@jayzhan211 that function already returns a
Vec<Expr>, or am I missing something? Do we still need to have udtf?jayzhan211 commentedon May 17, 2024
sql_to_exprreturnsResult<Expr>, we can extend it toResult<Vec<Expr>>. Which function are you mentioning?jayzhan211 commentedon May 19, 2024
I didn't find equivalent behavior in postgres. I'm not sure should we support this kind of
returns subset of columns based on column name matching