mirror of
https://github.com/apache/impala.git
synced 2026-01-20 12:01:06 -05:00
The bug: In one specific code path in inline-view planning where the inline-view plan is simply an EmptySetNode, the final output exprs of the query still referred to the non-materialized inline-view slots because the inline-view's smap was not set on the EmptySetNode, so the final output exprs were not substituted. The following conditions / sequence of actions triggered this bug: - A query statement that has an inline view on a select stmt without a FROM clause - During planning, a conjunct is migrated into that inline view (e.g. from the WHERE-clause of an enclosing query block) - After migration the conjunct becomes constant end evaluates to false - The inline view plan becomes an EmptySetNode - The bug: The output smap of that EmptySetNode was not set Change-Id: Ieaad6e4e9675fb52fbbfc843f9fa25b48b34406d Reviewed-on: http://gerrit.cloudera.org:8080/657 Reviewed-by: Alex Behm <alex.behm@cloudera.com> Tested-by: Internal Jenkins
385 lines
10 KiB
Plaintext
385 lines
10 KiB
Plaintext
# Constant conjunct in WHERE clause turns query block into an empty-set node.
|
|
select t1.id, t2.id
|
|
from functional.alltypestiny t1
|
|
left outer join functional.alltypes t2
|
|
on t1.id = t2.id
|
|
where false
|
|
---- PLAN
|
|
00:EMPTYSET
|
|
====
|
|
# HBase scan turns into empty-set node due to a constant conjunct.
|
|
select * from functional_hbase.alltypessmall where false
|
|
---- PLAN
|
|
00:EMPTYSET
|
|
====
|
|
# Data source scan turns into empty-set node due to a constant conjunct.
|
|
select *
|
|
from functional.alltypes_datasource a
|
|
inner join functional.alltypestiny b
|
|
on a.id = b.id
|
|
where length("a") > 7
|
|
---- PLAN
|
|
00:EMPTYSET
|
|
====
|
|
# Constant conjunct in ON clause turns query block into an empty-set node.
|
|
select *
|
|
from functional.alltypestiny t1
|
|
inner join functional.alltypes t2
|
|
on (t1.id = t2.id and (false or false))
|
|
---- PLAN
|
|
00:EMPTYSET
|
|
====
|
|
# Constant conjunct in WHERE clause turns query block into an aggregation
|
|
# fed by an empty-set node.
|
|
select count(int_col), avg(double_col), count(*)
|
|
from functional.alltypes
|
|
where null
|
|
---- PLAN
|
|
01:AGGREGATE [FINALIZE]
|
|
| output: count(int_col), avg(double_col), count(*)
|
|
|
|
|
00:EMPTYSET
|
|
====
|
|
# Constant conjunct in ON clause turns query block into an aggregation
|
|
# fed by an empty-sed node.
|
|
select count(*)
|
|
from functional.alltypestiny t1
|
|
inner join functional.alltypes t2
|
|
on (t1.id = t2.id and (false or false))
|
|
---- PLAN
|
|
01:AGGREGATE [FINALIZE]
|
|
| output: count(*)
|
|
|
|
|
00:EMPTYSET
|
|
====
|
|
# Constant conjunct in HAVING clause turns query block into an empty-set node,
|
|
# regardless of aggregation.
|
|
select t1.int_col, count(*)
|
|
from functional.alltypestiny t1
|
|
left outer join functional.alltypes t2
|
|
on t1.id = t2.id
|
|
group by t1.int_col
|
|
having ifnull(null, false)
|
|
---- PLAN
|
|
00:EMPTYSET
|
|
====
|
|
# Constant conjunct causes empty-set inline view.
|
|
select e.id, f.id
|
|
from functional.alltypessmall f
|
|
inner join
|
|
(select t1.id
|
|
from functional.alltypestiny t1
|
|
left outer join functional.alltypes t2
|
|
on t1.id = t2.id
|
|
where 1 + 3 > 10) e
|
|
on e.id = f.id
|
|
---- PLAN
|
|
02:HASH JOIN [INNER JOIN]
|
|
| hash predicates: f.id = t1.id
|
|
|
|
|
|--01:EMPTYSET
|
|
|
|
|
00:SCAN HDFS [functional.alltypessmall f]
|
|
partitions=4/4 files=4 size=6.32KB
|
|
====
|
|
# Constant conjunct causes union operand to be dropped.
|
|
select * from functional.alltypessmall
|
|
union all
|
|
select * from functional.alltypes where "abc" = "cde"
|
|
union all
|
|
select * from functional.alltypestiny
|
|
---- PLAN
|
|
00:UNION
|
|
|
|
|
|--02:SCAN HDFS [functional.alltypestiny]
|
|
| partitions=4/4 files=4 size=460B
|
|
|
|
|
01:SCAN HDFS [functional.alltypessmall]
|
|
partitions=4/4 files=4 size=6.32KB
|
|
====
|
|
# Constant conjunct turns union into an empty-set node.
|
|
select *
|
|
from functional.alltypes a
|
|
full outer join
|
|
(select * from
|
|
(select * from functional.alltypestiny
|
|
union all
|
|
select * from functional.alltypessmall) t1
|
|
where null) t2
|
|
on a.id = t2.id
|
|
---- PLAN
|
|
02:HASH JOIN [FULL OUTER JOIN]
|
|
| hash predicates: a.id = id
|
|
|
|
|
|--01:EMPTYSET
|
|
|
|
|
00:SCAN HDFS [functional.alltypes a]
|
|
partitions=24/24 files=24 size=478.45KB
|
|
====
|
|
# Constant conjunct in the ON-clause of an outer join is
|
|
# assigned to the join.
|
|
select *
|
|
from functional.alltypessmall a
|
|
left outer join functional.alltypestiny b
|
|
on (a.id = b.id and 1 + 1 > 10)
|
|
---- PLAN
|
|
02:HASH JOIN [LEFT OUTER JOIN]
|
|
| hash predicates: a.id = b.id
|
|
| other join predicates: 1 + 1 > 10
|
|
|
|
|
|--01:SCAN HDFS [functional.alltypestiny b]
|
|
| partitions=4/4 files=4 size=460B
|
|
|
|
|
00:SCAN HDFS [functional.alltypessmall a]
|
|
partitions=4/4 files=4 size=6.32KB
|
|
====
|
|
# Constant conjunct in the ON-clause of an outer join is
|
|
# assigned to the join.
|
|
select *
|
|
from functional.alltypessmall a
|
|
right outer join functional.alltypestiny b
|
|
on (a.id = b.id and !true)
|
|
---- PLAN
|
|
02:HASH JOIN [RIGHT OUTER JOIN]
|
|
| hash predicates: a.id = b.id
|
|
| other join predicates: NOT TRUE
|
|
|
|
|
|--01:SCAN HDFS [functional.alltypestiny b]
|
|
| partitions=4/4 files=4 size=460B
|
|
|
|
|
00:SCAN HDFS [functional.alltypessmall a]
|
|
partitions=4/4 files=4 size=6.32KB
|
|
====
|
|
# Constant conjunct in the ON-clause of an outer join is
|
|
# assigned to the join.
|
|
select *
|
|
from functional.alltypessmall a
|
|
full outer join functional.alltypestiny b
|
|
on (a.id = b.id and null = "abc")
|
|
---- PLAN
|
|
02:HASH JOIN [FULL OUTER JOIN]
|
|
| hash predicates: a.id = b.id
|
|
| other join predicates: NULL = 'abc'
|
|
|
|
|
|--01:SCAN HDFS [functional.alltypestiny b]
|
|
| partitions=4/4 files=4 size=460B
|
|
|
|
|
00:SCAN HDFS [functional.alltypessmall a]
|
|
partitions=4/4 files=4 size=6.32KB
|
|
====
|
|
# Limit 0 turns query block into an empty-set node.
|
|
select t1.id, t2.id
|
|
from functional.alltypestiny t1
|
|
left outer join functional.alltypes t2
|
|
on t1.id = t2.id
|
|
limit 0
|
|
---- PLAN
|
|
00:EMPTYSET
|
|
====
|
|
# Limit 0 turns query block into an empty-set node.
|
|
select count(int_col), avg(double_col), count(*)
|
|
from functional.alltypes
|
|
limit 0
|
|
---- PLAN
|
|
00:EMPTYSET
|
|
====
|
|
# Limit 0 causes empty-set inline view.
|
|
select e.id, f.id
|
|
from functional.alltypessmall f
|
|
inner join
|
|
(select t1.id
|
|
from functional.alltypestiny t1
|
|
left outer join functional.alltypes t2
|
|
on t1.id = t2.id
|
|
limit 0) e
|
|
on e.id = f.id
|
|
---- PLAN
|
|
02:HASH JOIN [INNER JOIN]
|
|
| hash predicates: f.id = t1.id
|
|
|
|
|
|--01:EMPTYSET
|
|
|
|
|
00:SCAN HDFS [functional.alltypessmall f]
|
|
partitions=4/4 files=4 size=6.32KB
|
|
====
|
|
# Limit 0 causes union operand to be dropped.
|
|
select * from functional.alltypessmall
|
|
union all
|
|
select * from functional.alltypes limit 0
|
|
union all
|
|
select * from functional.alltypestiny
|
|
---- PLAN
|
|
00:UNION
|
|
|
|
|
|--02:SCAN HDFS [functional.alltypestiny]
|
|
| partitions=4/4 files=4 size=460B
|
|
|
|
|
01:SCAN HDFS [functional.alltypessmall]
|
|
partitions=4/4 files=4 size=6.32KB
|
|
====
|
|
# Limit 0 causes empty-set union.
|
|
select * from functional.alltypessmall
|
|
union all
|
|
select * from functional.alltypes where "abc" = "cde"
|
|
union all
|
|
(select * from functional.alltypestiny)
|
|
limit 0
|
|
---- PLAN
|
|
00:EMPTYSET
|
|
====
|
|
# Inline view with a constant select stmt that is guaranteed to be empty.
|
|
select count(w1.c1)
|
|
from
|
|
(select 1 as c1 from functional.alltypessmall)
|
|
w1 where w1.c1 is null
|
|
union all
|
|
select int_col from functional.alltypesagg
|
|
---- PLAN
|
|
00:UNION
|
|
|
|
|
|--03:SCAN HDFS [functional.alltypesagg]
|
|
| partitions=11/11 files=11 size=814.73KB
|
|
|
|
|
02:AGGREGATE [FINALIZE]
|
|
| output: count(1)
|
|
|
|
|
01:EMPTYSET
|
|
====
|
|
# IMPALA-1234: Analytic with constant empty result set failed precondition check in FE
|
|
select MIN(int_col) OVER () FROM functional.alltypes limit 0
|
|
---- PLAN
|
|
00:EMPTYSET
|
|
====
|
|
# IMPALA-1860: INSERT/CTAS should evaluate and apply constant predicates.
|
|
insert into functional.alltypes partition(year, month)
|
|
select * from functional.alltypes where 1 = 0
|
|
---- PLAN
|
|
WRITE TO HDFS [functional.alltypes, OVERWRITE=false, PARTITION-KEYS=(functional.alltypes.year,functional.alltypes.month)]
|
|
| partitions=24
|
|
|
|
|
00:EMPTYSET
|
|
====
|
|
# IMPALA-1860: INSERT/CTAS should evaluate and apply constant predicates.
|
|
with t as (select * from functional.alltypes where coalesce(NULL) > 10)
|
|
insert into functional.alltypes partition(year, month)
|
|
select * from t
|
|
---- PLAN
|
|
WRITE TO HDFS [functional.alltypes, OVERWRITE=false, PARTITION-KEYS=(functional.alltypes.year,functional.alltypes.month)]
|
|
| partitions=24
|
|
|
|
|
00:EMPTYSET
|
|
====
|
|
# IMPALA-1860: INSERT/CTAS should evaluate and apply constant predicates.
|
|
create table test_1860 as
|
|
select * from (select 1 from functional.alltypes limit 0) v
|
|
---- PLAN
|
|
WRITE TO HDFS [default.test_1860, OVERWRITE=false]
|
|
| partitions=1
|
|
|
|
|
00:EMPTYSET
|
|
====
|
|
# IMPALA-1960: Exprs in the aggregation that reference slots from an inline view when
|
|
# the select stmt has an empty select-project-join portion.
|
|
select sum(T.id), count(T.int_col)
|
|
from
|
|
(select id, int_col, bigint_col from functional.alltypestiny) T
|
|
where false
|
|
---- PLAN
|
|
01:AGGREGATE [FINALIZE]
|
|
| output: sum(id), count(int_col)
|
|
|
|
|
00:EMPTYSET
|
|
====
|
|
# IMPALA-1960: Exprs in the aggregation that reference slots from an inline view when
|
|
# the select stmt has an empty select-project-join portion.
|
|
select sum(T1.id + T2.int_col)
|
|
from
|
|
(select id, bigint_col from functional.alltypestiny) T1 inner join
|
|
(select id, int_col from functional.alltypestiny) T2 on (T1.id = T2.id)
|
|
where T1.bigint_col < 10 and 1 > 1
|
|
---- PLAN
|
|
01:AGGREGATE [FINALIZE]
|
|
| output: sum(id + int_col)
|
|
|
|
|
00:EMPTYSET
|
|
====
|
|
# IMPALA-1960: Exprs in the aggregation that reference slots from an inline view when
|
|
# the select stmt has an empty select-project-join portion.
|
|
select count(distinct T1.int_col)
|
|
from
|
|
(select id, int_col from functional.alltypestiny) T1 inner join
|
|
functional.alltypessmall T2 on T1.id = T2.id
|
|
where T2.bigint_col < 10 and false
|
|
---- PLAN
|
|
02:AGGREGATE [FINALIZE]
|
|
| output: count(T1.int_col)
|
|
|
|
|
01:AGGREGATE
|
|
| group by: int_col
|
|
|
|
|
00:EMPTYSET
|
|
====
|
|
# IMPALA-2088: Test empty union operands with analytic functions.
|
|
# TODO: Simplify the plan of unions with empty operands using an empty set node.
|
|
# TODO: Simplify the plan of unions with only a single non-empty operand to not
|
|
# use a union node (this is tricky because a union materializes a new tuple).
|
|
select lead(-496, 81) over (order by t1.double_col desc, t1.id asc)
|
|
from functional.alltypestiny t1 where 5 = 6
|
|
union
|
|
select 794.67
|
|
from functional.alltypes t1 where 5 = 6
|
|
union all
|
|
select coalesce(10.4, int_col)
|
|
from functional.alltypes where false
|
|
---- PLAN
|
|
02:UNION
|
|
|
|
|
01:AGGREGATE [FINALIZE]
|
|
| group by: lead(-496, 81, NULL) OVER(...)
|
|
|
|
|
00:UNION
|
|
====
|
|
# IMPALA-2088: Test empty union operands with analytic functions.
|
|
select lead(-496, 81) over (order by t1.double_col desc, t1.id asc)
|
|
from functional.alltypestiny t1 where 5 = 6
|
|
union
|
|
select 794.67
|
|
from functional.alltypes t1 where 5 = 6
|
|
union all
|
|
select coalesce(10.4, int_col)
|
|
from functional.alltypes where false
|
|
union all
|
|
select 1
|
|
union all select bigint_col
|
|
from functional.alltypestiny
|
|
---- PLAN
|
|
02:UNION
|
|
| constant-operands=1
|
|
|
|
|
|--01:AGGREGATE [FINALIZE]
|
|
| | group by: lead(-496, 81, NULL) OVER(...)
|
|
| |
|
|
| 00:UNION
|
|
|
|
|
03:SCAN HDFS [functional.alltypestiny]
|
|
partitions=4/4 files=4 size=460B
|
|
====
|
|
# IMPALA-2216: Make sure the final output exprs are substituted, even
|
|
# if the resulting plan is an EmptySetNode.
|
|
select * from (select 10 as i, 2 as j, '2013' as s) as t
|
|
where t.i < 10
|
|
---- PLAN
|
|
00:EMPTYSET
|
|
====
|
|
# IMPALA-2216: Make sure the final output exprs are substituted, even
|
|
# if the table sink is fed by an EmptySetNode.
|
|
insert into functional.alltypes (id) partition(year,month)
|
|
select * from (select 10 as i, 2 as j, 2013 as s) as t
|
|
where t.i < 10
|
|
---- PLAN
|
|
WRITE TO HDFS [functional.alltypes, OVERWRITE=false, PARTITION-KEYS=(2,2013)]
|
|
| partitions=1
|
|
|
|
|
00:EMPTYSET
|
|
====
|