spark3的bug

1.[SPARK-39936][SQL] Store schema in properties for Spark Views,spark视图保存到hive metastore时未清空tableschema导致解析失败

Hive DataType解析器主要发生在Hive的元数据存储(Hive Metastore)阶段。当Hive创建表或解析表结构时,Hive会使用DataType解析器来解析表中定义的数据类型。这个解析器会尝试解析和转换表的列、字段和分区的数据类型、长度、约束等信息。它会确保表定义与Hive的数据类型系统相匹配,并正确解析表结构,从而能够正确地进行数据的存储和查询。如果在解析过程中出现格式错误或不受支持的数据类型,解析器会抛出异常并中断解析过程。在这个阶段,Hive DataType解析器负责将用户定义的数据类型转换为Hive支持的数据类型,并确保数据的一致性和正确性。

[SPARK-39936][SQL] 在Spark视图中存储模式属性

这个pull request提出了什么样的改变?

通常我们将tableSchema存储在table属性中,而不是作为实际模式。我们通常这样做是因为它有助于绕过一些Hive-Metastore问题,包括与SparkSQLDataType解析器的解析问题。

然而,问题在于我们没有清空Spark视图的tableSchema(Spark视图本来就与Hive不兼容)。因此,Hive DataType解析器会尝试解析模式并导致错误。解决方法是在将Spark视图保存到Hive Metastore时清空tableSchema。

这修复了以下错误:

-- this works since we use backticks in `date-of-creation`
create table table_with_hyphen (f array<struct<validColumnTypeName:string>>) using parquet;
-- this should work since we use backticks in `date-of-creation` but will break without this bugfix
create or replace view view_with_hyphen as select f from table_with_hyphen;

 

2.[SPARK-40002][SQL] Don't push down limit through window using ntile,将nitle函数应用于limit的结果将会导致错误的结果

[

这个拉取请求提议的更改是更改"LimitPushDownThroughWindow",使其不再支持通过ntile函数将limit下推到窗口。

需要进行这些更改的原因是在无分区窗口中,目前ntile函数应用于limit的结果。这种行为会导致与Spark 3.1.3、Hive 2.3.9和PrestoDB 0.268产生冲突的结果。

举个例子:

假设有以下数据

Assume this data:
```
create table t1 stored as parquet as
select *
from range(101);
```
Also assume this query:
```
select id, ntile(10) over (order by id) as nt
from t1
limit 10;
```
With Spark 3.2.2, Spark 3.3.0, and master, the limit is applied before the ntile function:
```
+---+---+
|id |nt |
+---+---+
|0  |1  |
|1  |2  |
|2  |3  |
|3  |4  |
|4  |5  |
|5  |6  |
|6  |7  |
|7  |8  |
|8  |9  |
|9  |10 |
+---+---+
```
With Spark 3.1.3, and Hive 2.3.9, and Prestodb 0.268, the limit is applied _after_ ntile.

Spark 3.1.3:
```
+---+---+
|id |nt |
+---+---+
|0  |1  |
|1  |1  |
|2  |1  |
|3  |1  |
|4  |1  |
|5  |1  |
|6  |1  |
|7  |1  |
|8  |1  |
|9  |1  |
+---+---+
```
Hive 2.3.9:
```
+-----+-----+
| id  | nt  |
+-----+-----+
| 0   | 1   |
| 1   | 1   |
| 2   | 1   |
| 3   | 1   |
| 4   | 1   |
| 5   | 1   |
| 6   | 1   |
| 7   | 1   |
| 8   | 1   |
| 9   | 1   |
+-----+-----+
10 rows selected (1.72 seconds)
```
Prestodb 0.268:
```
id | nt
----+----
  0 |  1
  1 |  1
  2 |  1
  3 |  1
  4 |  1
  5 |  1
  6 |  1
  7 |  1
  8 |  1
  9 |  1
(10 rows)

```

3. [SPARK-40963][SQL] Set nullable correctly in project created by ExtractGenerator,可能会导致错误的结果以及空指针问题

 

  

### 此拉取请求中提出了哪些更改?

在 `ExtractGenerator` 中创建新投影列表时,考虑到生成器是否为外部生成器,在设置生成器相关的输出属性的可空性时。

### 为什么需要这些更改?

这个拉取请求修复了一个可能导致结果不正确或引发`NullPointerException`的问题。这个问题有点难以重现,除非使用具有内联表的子查询。

例子:
```
select c1, explode(c4) as c5 from (
select c1, array(c3) as c4 from (
select c1, explode_outer(c2) as c3
from values
(1, array(1, 2)),
(2, array(2, 3)),
(3, null)
as data(c1, c2)
)
);

+---+---+
|c1 |c5 |
+---+---+
|1 |1 |
|1 |2 |
|2 |2 |
|2 |3 |
|3 |0 |
+---+---+
```
在最后一行中,`c5` 是0,但应为 `NULL`。

另一个例子:
```
select c1, exists(c4, x -> x is null) as c5 from (
select c1, array(c3) as c4 from (
select c1, explode_outer(c2) as c3
from values
(1, array(1, 2)),
(2, array(2, 3)),
(3, array())
as data(c1, c2)
)
);

+---+-----+
|c1 |c5 |
+---+-----+
|1 |false|
|1 |false|
|2 |false|
|2 |false|
|3 |false|
+---+-----+
```
在最后一行中,`false` 应该为 `true`。

在这两种情况下,在实例化 `CreateArray(c3)` 时,`c3` 的可空性是不正确的,因为由 `ExtractGenerator` 创建的新投影使用来自 `explode_outer(c2)` 的 `generatorOutput` 作为投影列表。`generatorOutput` 没有考虑到 `explode_outer(c2)` 是一个外部爆炸,因此丢失了可空性设置。

`UpdateAttributeNullability` 最终会为引用 `c3` 的属性修复可空性设置,但它不能修复来自第一个示例中的 `explode(c4)` 或来自第二个示例中的 `exists(c4, x -> x is null)` 的 `containsNull` 设置。

此示例将引发 `NullPointerException`:
```
select c1, inline_outer(c4) from (
select c1, array(c3) as c4 from (
select c1, explode_outer(c2) as c3
from values
(1, array(named_struct('a', 1, 'b', 2))),
(2, array(named_struct('a', 3, 'b', 4), named_struct('a', 5, 'b', 6))),
(3, array())
as data(c1, c2)
)
);
22/10/30 17:34:42 ERROR Executor: Exception in task 1.0 in stage 8.0 (TID 14)
java.lang.NullPointerException
at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage1.generate_doConsume_1$(Unknown Source)
at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage1.generate_doConsume_0$(Unknown Source)
at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage1.processNext(Unknown Source)
at org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
at org.apache.spark.sql.execution.WholeStageCodegenExec$$anon$1.hasNext(WholeStageCodegenExec.scala:760)
at org.apache.spark.sql.execution.SparkPlan.$anonfun$getByteArrayRdd$1(SparkPlan.scala:364)
```

### 这个 PR 是否引入了用户界面上的任何更改?

没有。

### 如何测试这个补丁?

 

5.[SPARK-41668][SQL] DECODE function returns wrong results when passed NULL,传NULL后DECODE返回结果有误

 

posted @ 2023-08-15 09:38  平平淡淡以明志  阅读(52)  评论(0编辑  收藏  举报