DataFusion 48.0.0
升级指南
DataFusion 48.0.0
Expr::Literal 现在带有可选元数据
Expr::Literal 变体现在包含可选元数据,从而能够传递 Arrow 字段元数据,以支持扩展类型及其他用途。
这意味着类似下面这样的代码
match expr {
...
Expr::Literal(scalar) => ...
...
}应更新为:
match expr {
...
Expr::Literal(scalar, _metadata) => ...
...
}同样,构造 Expr::Literal 也需要元数据。lit 函数没有变化,仍然返回一个不带元数据的 Expr::Literal。
Expr::WindowFunction 现在被 Box 包装
Expr::WindowFunction 现在是 Box<WindowFunction>,而不再是直接的 WindowFunction。做出这一改动是为了减小 Expr 的大小,并提升查询规划时的性能(详见 devlive-community/knowforge#16207 的讨论)。
这是一个破坏性变更,因此如果你直接对 Expr::WindowFunction 进行模式匹配,就需要更新代码。例如,如果你有这样的代码:
match expr {
Expr::WindowFunction(WindowFunction {
params:
WindowFunctionParams {
partition_by,
order_by,
..
}
}) => {
// Use partition_by and order_by as needed
}
_ => {
// other expr
}
}你需要将其改为:
match expr {
Expr::WindowFunction(window_fun) => {
let WindowFunction {
fun,
params: WindowFunctionParams {
args,
partition_by,
..
},
} = window_fun.as_ref();
// Use partition_by and order_by as needed
}
_ => {
// other expr
}
}SQL 的 VARCHAR 类型现在在 Arrow 中表示为 Utf8View
SQL VARCHAR 类型的映射已从 Utf8 更改为 Utf8View,这提升了许多字符串操作的性能。你可以在 DataFusion 关于德式字符串的博客文章 中了解更多关于 Utf8View 的内容。
这意味着,当你创建一个包含 VARCHAR 列的表时,它现在会使用 Utf8View 作为底层数据类型。例如:
> CREATE TABLE my_table (my_column VARCHAR);
0 row(s) fetched.
Elapsed 0.001 seconds.
> DESCRIBE my_table;
+-------------+-----------+-------------+
| column_name | data_type | is_nullable |
+-------------+-----------+-------------+
| my_column | Utf8View | YES |
+-------------+-----------+-------------+
1 row(s) fetched.
Elapsed 0.000 seconds.通过修改 datafusion.sql_parser.map_varchar_to_utf8view 配置项,可以恢复使用 Utf8 的旧行为。例如:
> set datafusion.sql_parser.map_varchar_to_utf8view = false;
0 row(s) fetched.
Elapsed 0.001 seconds.
> CREATE TABLE my_table (my_column VARCHAR);
0 row(s) fetched.
Elapsed 0.014 seconds.
> DESCRIBE my_table;
+-------------+-----------+-------------+
| column_name | data_type | is_nullable |
+-------------+-----------+-------------+
| my_column | Utf8 | YES |
+-------------+-----------+-------------+
1 row(s) fetched.
Elapsed 0.004 seconds.ListingOptions 的 collect_stat 默认值由 true 变更为 false
此变更使其与 SessionConfig 的默认值保持一致。大多数用户不会受到这一变更的影响,但如果你直接使用 ListingOptions,并且依赖 collect_stat 默认值为 true,则需要在代码中显式将其设置为 true。
ListingOptions::new(Arc::new(ParquetFormat::default()))
.with_collect_stat(true)
// other options为用户自定义函数处理 FieldRef 而非 DataType
为了支持元数据处理和扩展类型,用户自定义函数现在改为使用以 FieldRef(而非 DataType 和可空性)作为参数的 trait。这样可以为这两个参数提供统一的接口,并且还能访问元数据字段,元数据字段可用于扩展类型。
要升级实现了 ScalarUDFImpl 的结构体,如果你实现了 return_type_from_args,则需要改为实现 return_field_from_args。如果你的函数不需要处理元数据,这只是一次简单的改动——将输出数据重新包装为 FieldRef。你在字段上指定的名称并不重要,规划阶段会将其覆盖。ReturnInfo 已被移除,因此你需要删除所有对它的引用。
ScalarFunctionArgs 现在包含一个名为 arg_fields 的字段。你可以在调用期间使用它来访问与列值相关联的元数据。
要升级用户自定义聚合函数,现在有一个 return_field 函数,它允许你同时指定函数的元数据和可空性。如果你不需要处理元数据,则无需实现该函数。
聚合函数最大的变化在于累加器参数。AccumulatorArgs 和 StateFieldsArgs 现在都包含 FieldRef 而不是 DataType。
要升级窗口函数,ExpressionArgs 现在包含输入字段而非输入数据类型。设置这些字段时,字段的名称并不重要,因为规划阶段会将其覆盖。你只需要将现有的数据类型包装为字段,并根据使用场景设置可空性即可。
物理表达式返回 Field
为了支持用户自定义函数处理元数据的这些变更,PhysicalExpr trait 现在必须根据输入 schema 指定返回 Field。要升级实现了 PhysicalExpr 的结构体,你需要实现 return_field 函数。physical-expr crate 中提供了大量示例。
FileFormat::supports_filters_pushdown 被 FileSource::try_pushdown_filters 取代
为了支持更通用的过滤下推,FileFormat::supports_filters_pushdown 被 FileSource::try_pushdown_filters 取代。如果你实现了使用自定义 FileSource 的自定义 FileFormat,则需要实现 FileSource::try_pushdown_filters。可参考 ParquetSource::try_pushdown_filters 了解实现示例。
FileFormat::supports_filters_pushdown 已被移除。
移除 ParquetExec、AvroExec、CsvExec、JsonExec
ParquetExec、AvroExec、CsvExec 和 JsonExec 在 DataFusion 46 中已被弃用,并在 DataFusion 48 中被移除。这比 API 弃用指南中描述的常规流程要早,因为所有测试都已经覆盖了新的 DataSourceExec,而不是这些旧的结构。随着我们对 DataSource 的不断演进,这些旧结构开始出现"陈旧腐化"的迹象(已经不能正常工作,但由于缺乏测试覆盖而无人察觉)。
在 FileOpener trait 中新增 PartitionedFile 参数
这是正确修复同时涉及分区列和文件列的过滤条件下推(例如 day = username['dob'])所必需的。
如果你实现了自定义的 FileOpener,则需要添加 PartitionedFile 参数,但不要求以任何方式使用它。
评论
登录后参与评论
KnowForge