On this page
Problem
当前,Hive 不支持 SELECT 语句中的子查询,例如,以下查询将不会在 Hive 上运行:
SELECT customer.customer_num,
(SELECT SUM(ship_charge)
FROM orders
WHERE customer.customer_num = orders.customer_num
) AS total_ship_chg
FROM customer
最近,为扩展对子查询(HIVE-15456)的支持,已经完成了许多工作。但是这项工作主要针对扩展 WHERE 和 HAVING 子句中的子查询支持。我们计划 continue 在 HIVE-15456 中完成工作,以支持选择列表中的子查询(请参见HIVE-16091)。
Assumptions
我们计划通过以下假设和限制来限制范围。
- 子查询只能是 SELECT 中的顶级表达式。也就是说,暂时将不支持复杂表达式,聚合,UDF 等中的子查询。例如,以下查询将不会在 Hive 上运行:
Not Supported
-- subquery in non-simple expression
SELECT 1 + (SELECT SUM(ship_charge) FROM orders), customer.customer_num FROM customer
-- subquery in CASE
SELECT CASE WHEN (select count(*) from store_sales
where ss_quantity between 1 and 20) > 409437
THEN (select avg(ss_ext_list_price)
from store_sales
where ss_quantity between 1 and 20)
ELSE (select avg(ss_net_paid_inc_tax)
from store_sales
where ss_quantity between 1 and 20) end bucket1
FROM reason
WHERE r_reason_sk = 1
- 标量子查询最多只能返回一行。 Hive 将在运行时检查这种情况,如果不满意,则会抛出错误。例如,以下查询无效:
Not Supported
SELECT customer.customer_num,
(SELECT ship_charge
FROM orders
WHERE customer.customer_num = orders.customer_num
) AS total_ship_chg
FROM customer
- 标量子查询只能有一列。 Hive 将在编译过程中检查这种情况并抛出错误。例如,以下查询无效:
Not Supported
SELECT customer.customer_num,
(SELECT ship_charge, customer_num
FROM orders LIMIT 1
) AS total_ship_chg
FROM customer
- 仅在过滤器(即 WHERE 或 HAVING 子句)中允许使用相关变量。例如,以下查询无效:
Not Supported
SELECT customer.customer_num,
(SELECT customer.customer_num
FROM orders
WHERE customer.customer_num = orders.customer_num
) AS total_ship_chg
FROM customer
- 不允许使用 DISTINCT 的子查询。由于 DISTINCT<expression>将被评估为 GROUP BY<expression>,因此暂时不允许使用 DISTINCT 的子查询。
Design
给定以上假设,可以在 SELECT 中使用以下类型的子查询。
- 标量子查询,例如:
SELECT customer.customer_num,
(SELECT SUM(ship_charge)
FROM orders
WHERE customer.customer_num = orders.customer_num
) AS total_ship_chg
FROM customer
- IN 子查询,例如:
SELECT p_size IN (
SELECT MAX(p_size) FROM part)
FROM part
- EXISTS 子查询,例如:
SELECT EXISTS(SELECT p_size FROM part)
FROM part
以上所有查询都可以是 相关 或 不相关 。
其设计将类似于HIVE-15456中完成的工作。
genLogicalPlan 将遍历选择列表以执行以下操作:
如果子查询不是顶级表达式,则引发错误。
- 否则,通过使用 RexSubquery 代表子查询来生成适当的计划。
然后将应用 HiveSubqueryRemoveRule 删除 RexSubquery 节点,并将查询重写为联接。
然后,将使用 HiveRelDecorrelator :: decorrelateQuery 对相关查询进行解相关。
HIVE-16091介绍了支持 SELECT 中的子查询的初步工作。