You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2015/12/13 23:01:27 UTC
[1/7] calcite git commit: [CALCITE-1022] Rename ".oq" Quidem files to
".iq"
Repository: calcite
Updated Branches:
refs/heads/master 84b55ef58 -> 5197a7147
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/sort.oq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/sort.oq b/core/src/test/resources/sql/sort.oq
deleted file mode 100644
index be30ac4..0000000
--- a/core/src/test/resources/sql/sort.oq
+++ /dev/null
@@ -1,179 +0,0 @@
-# sort.oq - Sorting and collation
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to you under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-!use foodmart
-!set outputformat mysql
-
-# The ArrayTable "days" is sorted by "day", so plan must not contain sort
-select * from "days" order by "day";
-!verify
-EnumerableTableScan(table=[[foodmart2, days]])
-!plan
-
-# The ArrayTable "days" is sorted by "day", so the plan does not sort, only applies limit
-select * from "days" order by "day" limit 2;
-+-----+----------+
-| day | week_day |
-+-----+----------+
-| 1 | Sunday |
-| 2 | Monday |
-+-----+----------+
-(2 rows)
-
-!ok
-EnumerableLimit(fetch=[2])
- EnumerableTableScan(table=[[foodmart2, days]])
-!plan
-
-# The ArrayTable "days" is sorted by "day", so the plan must not contain Sort
-select * from "days" where "day" between 2 and 4 order by "day";
-+-----+-----------+
-| day | week_day |
-+-----+-----------+
-| 2 | Monday |
-| 3 | Tuesday |
-| 4 | Wednesday |
-+-----+-----------+
-(3 rows)
-
-!ok
-EnumerableCalc(expr#0..1=[{inputs}], expr#2=[2], expr#3=[>=($t0, $t2)], expr#4=[4], expr#5=[<=($t0, $t4)], expr#6=[AND($t3, $t5)], proj#0..1=[{exprs}], $condition=[$t6])
- EnumerableTableScan(table=[[foodmart2, days]])
-!plan
-
-# [CALCITE-970] Default collation of NULL values
-# Nulls high, i.e. first if DESC
-select "store_id", "grocery_sqft" from "store"
-where "store_id" < 3
-order by 2 DESC;
-+----------+--------------+
-| store_id | grocery_sqft |
-+----------+--------------+
-| 0 | |
-| 2 | 22271 |
-| 1 | 17475 |
-+----------+--------------+
-(3 rows)
-
-!ok
-
-# Nulls high, i.e. first if DESC, composite sort
-select "store_id", "grocery_sqft" from "store"
-where "store_id" < 3
-order by "florist", 2 DESC;
-+----------+--------------+
-| store_id | grocery_sqft |
-+----------+--------------+
-| 0 | |
-| 2 | 22271 |
-| 1 | 17475 |
-+----------+--------------+
-(3 rows)
-
-!ok
-
-# Nulls high, i.e. last if ASC
-select "store_id", "grocery_sqft" from "store"
-where "store_id" < 3
-order by 2;
-+----------+--------------+
-| store_id | grocery_sqft |
-+----------+--------------+
-| 1 | 17475 |
-| 2 | 22271 |
-| 0 | |
-+----------+--------------+
-(3 rows)
-
-!ok
-
-# [CALCITE-969] Composite EnumerableSort with DESC wrongly sorts NULL values low
-# Nulls high, i.e. last if ASC, composite sort
-select "store_id", "grocery_sqft" from "store"
-where "store_id" < 3
-order by "florist", 2;
-+----------+--------------+
-| store_id | grocery_sqft |
-+----------+--------------+
-| 1 | 17475 |
-| 2 | 22271 |
-| 0 | |
-+----------+--------------+
-(3 rows)
-
-!ok
-
-!use post
-
-# [CALCITE-603] WITH ... ORDER BY cannot find table
-with e as (select "empid" as empid from "hr"."emps" where "empid" < 120)
-select * from e as e1, e as e2 order by e1.empid + e2.empid, e1.empid;
-+-------+--------+
-| EMPID | EMPID0 |
-+-------+--------+
-| 100 | 100 |
-| 100 | 110 |
-| 110 | 100 |
-| 110 | 110 |
-+-------+--------+
-(4 rows)
-
-!ok
-
-# WITH ... LIMIT
-with e as (select "empid" as empid from "hr"."emps" where "empid" < 200)
-select * from e where empid > 100 limit 5;
-+-------+
-| EMPID |
-+-------+
-| 150 |
-| 110 |
-+-------+
-(2 rows)
-
-!ok
-
-# [CALCITE-634] Allow ORDER BY aggregate function in SELECT DISTINCT, provided
-# that it occurs in SELECT clause
-select distinct "deptno", count(*) as c
-from "hr"."emps"
-group by "deptno"
-order by count(*) desc;
-+--------+---+
-| deptno | C |
-+--------+---+
-| 10 | 3 |
-| 20 | 1 |
-+--------+---+
-(2 rows)
-
-!ok
-
-select distinct count("empid") as c
-from "hr"."emps"
-group by "empid"
-order by 1;
-+---+
-| C |
-+---+
-| 1 |
-+---+
-(1 row)
-
-!ok
-
-# End sort.oq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/subquery.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/subquery.iq b/core/src/test/resources/sql/subquery.iq
new file mode 100644
index 0000000..b69b669
--- /dev/null
+++ b/core/src/test/resources/sql/subquery.iq
@@ -0,0 +1,278 @@
+# subquery.iq - Queries involving IN and EXISTS sub-queries
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+!use post
+!set outputformat psql
+
+# [CALCITE-373]
+# the following should return no rows, because the IN list has a null.
+# for details on this: see HIVE-784, Dayal's paper from VLDB-87
+with
+t1(x) as (select * from (values 1,2, case when 1 = 1 then null else 3 end)),
+t2(x) as (select * from (values 1,case when 1 = 1 then null else 3 end))
+select *
+from t1
+where t1.x not in (select t2.x from t2);
+ X
+---
+(0 rows)
+
+!ok
+EnumerableCalc(expr#0..5=[{inputs}], expr#6=[0], expr#7=[=($t1, $t6)], expr#8=[false], expr#9=[IS NOT NULL($t5)], expr#10=[true], expr#11=[IS NULL($t3)], expr#12=[null], expr#13=[<($t2, $t1)], expr#14=[CASE($t7, $t8, $t9, $t10, $t11, $t12, $t13, $t12, $t8)], expr#15=[NOT($t14)], X=[$t0], $condition=[$t15])
+ EnumerableJoin(condition=[=($3, $4)], joinType=[left])
+ EnumerableCalc(expr#0..2=[{inputs}], $f0=[$t2], $f1=[$t0], $f2=[$t1], $f3=[$t2])
+ EnumerableJoin(condition=[true], joinType=[inner])
+ EnumerableAggregate(group=[{}], agg#0=[COUNT()], agg#1=[COUNT($0)])
+ EnumerableUnion(all=[true])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=[1], EXPR$0=[$t1])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=[1], expr#2=[=($t1, $t1)], expr#3=[null], expr#4=[3], expr#5=[CASE($t2, $t3, $t4)], EXPR$0=[$t5])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableUnion(all=[true])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=[1], EXPR$0=[$t1])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=[2], EXPR$0=[$t1])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=[1], expr#2=[=($t1, $t1)], expr#3=[null], expr#4=[3], expr#5=[CASE($t2, $t3, $t4)], EXPR$0=[$t5])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableAggregate(group=[{0}], agg#0=[MIN($1)])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=[true], proj#0..1=[{exprs}])
+ EnumerableUnion(all=[true])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=[1], EXPR$0=[$t1])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=[1], expr#2=[=($t1, $t1)], expr#3=[null], expr#4=[3], expr#5=[CASE($t2, $t3, $t4)], EXPR$0=[$t5])
+ EnumerableValues(tuples=[[{ 0 }]])
+!plan
+
+# Use of case is to get around issue with directly specifying null in values
+# list. Postgres gives 0 rows.
+with
+t1(x) as (select * from (values (1),(2),(case when 1 = 1 then null else 3 end)) as t1),
+t2(x) as (select * from (values (1),(case when 1 = 1 then null else 3 end)) as t2)
+select *
+from t1
+where t1.x not in (select t2.x from t2);
+
+ X
+---
+(0 rows)
+
+!ok
+
+# RHS has a mixture of NULL and NOT NULL keys
+select * from dept where deptno not in (select deptno from emp);
+ DEPTNO | DNAME
+--------+-------
+(0 rows)
+
+!ok
+select deptno, deptno in (select deptno from emp) from dept;
+ DEPTNO | EXPR$1
+--------+--------
+ 10 | true
+ 20 | true
+ 30 | true
+ 40 | null
+(4 rows)
+
+!ok
+select deptno, deptno not in (select deptno from emp) from dept;
+ DEPTNO | EXPR$1
+--------+--------
+ 10 | false
+ 20 | false
+ 30 | false
+ 40 | null
+(4 rows)
+
+!ok
+
+# RHS has only NULL keys
+select * from dept where deptno not in (select deptno from emp where deptno is null);
+ DEPTNO | DNAME
+--------+-------
+(0 rows)
+
+!ok
+select deptno, deptno in (select deptno from emp where deptno is null) from dept;
+ DEPTNO | EXPR$1
+--------+--------
+ 10 | null
+ 20 | null
+ 30 | null
+ 40 | null
+(4 rows)
+
+!ok
+select deptno, deptno not in (select deptno from emp where deptno is null) from dept;
+ DEPTNO | EXPR$1
+--------+--------
+ 10 | null
+ 20 | null
+ 30 | null
+ 40 | null
+(4 rows)
+
+!ok
+
+# RHS has only NOT NULL keys
+select * from dept where deptno not in (select deptno from emp where deptno is not null);
+ DEPTNO | DNAME
+--------+-------------
+ 40 | Empty
+(1 row)
+
+!ok
+select deptno, deptno in (select deptno from emp where deptno is not null) from dept;
+ DEPTNO | EXPR$1
+--------+--------
+ 10 | true
+ 20 | true
+ 30 | true
+ 40 | false
+(4 rows)
+
+!ok
+select deptno, deptno not in (select deptno from emp where deptno is not null) from dept;
+ DEPTNO | EXPR$1
+--------+--------
+ 10 | false
+ 20 | false
+ 30 | false
+ 40 | true
+(4 rows)
+
+!ok
+
+# RHS has no rows
+# Even 'NULL NOT IN ...' is TRUE.
+select * from dept where deptno not in (select deptno from emp where false);
+ DEPTNO | DNAME
+--------+-------------
+ 10 | Sales
+ 20 | Marketing
+ 30 | Engineering
+ 40 | Empty
+(4 rows)
+
+!ok
+select deptno, deptno in (select deptno from emp where false) from dept;
+ DEPTNO | EXPR$1
+--------+--------
+ 10 | false
+ 20 | false
+ 30 | false
+ 40 | false
+(4 rows)
+
+!ok
+select deptno, deptno not in (select deptno from emp where false) from dept;
+ DEPTNO | EXPR$1
+--------+--------
+ 10 | true
+ 20 | true
+ 30 | true
+ 40 | true
+(4 rows)
+
+!ok
+
+# Multiple IN, connected by OR
+select * from dept
+where deptno in (select deptno from emp where gender = 'F')
+or deptno in (select deptno from emp where gender = 'M');
+ DEPTNO | DNAME
+--------+-------------
+ 30 | Engineering
+ 10 | Sales
+ 20 | Marketing
+(3 rows)
+
+!ok
+
+# Mix IN and EXISTS
+select * from dept
+where deptno in (select deptno from emp where gender = 'F')
+or exists (select 99, 101 from emp where gender = 'X');
+ DEPTNO | DNAME
+--------+-------------
+ 30 | Engineering
+ 10 | Sales
+(2 rows)
+
+!ok
+
+# Composite key
+select * from dept
+where (deptno, deptno) in (select deptno * 2 - deptno, deptno from emp where gender = 'F');
+
+# Composite key, part literal
+select * from emp
+where (gender, deptno) in (select gender, 10 from emp where gender = 'F');
+ ENAME | DEPTNO | GENDER
+-------+--------+--------
+ Jane | 10 | F
+(1 row)
+
+!ok
+
+!use scott
+
+# [CALCITE-694] Scan HAVING clause for sub-queries and IN-lists
+SELECT count(*) AS c
+FROM "scott".emp
+GROUP BY emp.deptno
+HAVING sum(case when emp.empno in (7369, 7839, 7902) then emp.sal else 0 end)
+ BETWEEN 5000.0 AND 10000.0;
+ C
+---
+ 3
+(1 row)
+
+!ok
+
+# [CALCITE-716] Scalar sub-query and aggregate function in SELECT or HAVING
+# clause gives AssertionError
+SELECT emp.deptno
+FROM "scott".emp
+GROUP BY emp.deptno
+HAVING max(emp.empno) > (SELECT min(emp.empno) FROM "scott".emp);
+ DEPTNO
+--------
+ 10
+ 20
+ 30
+(3 rows)
+
+!ok
+
+# [CALCITE-716] Scalar sub-query and aggregate function in SELECT or HAVING
+# clause gives AssertionError
+SELECT emp.deptno,
+ max(emp.empno) > (SELECT min(emp.empno) FROM "scott".emp) as bbbb
+FROM "scott".emp
+GROUP BY emp.deptno;
+ DEPTNO | BBBB
+--------+------
+ 10 | true
+ 20 | true
+ 30 | true
+(3 rows)
+
+!ok
+
+# End subquery.iq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/subquery.oq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/subquery.oq b/core/src/test/resources/sql/subquery.oq
deleted file mode 100644
index 9db95d3..0000000
--- a/core/src/test/resources/sql/subquery.oq
+++ /dev/null
@@ -1,278 +0,0 @@
-# subquery.oq - Queries involving IN and EXISTS sub-queries
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to you under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-!use post
-!set outputformat psql
-
-# [CALCITE-373]
-# the following should return no rows, because the IN list has a null.
-# for details on this: see HIVE-784, Dayal's paper from VLDB-87
-with
-t1(x) as (select * from (values 1,2, case when 1 = 1 then null else 3 end)),
-t2(x) as (select * from (values 1,case when 1 = 1 then null else 3 end))
-select *
-from t1
-where t1.x not in (select t2.x from t2);
- X
----
-(0 rows)
-
-!ok
-EnumerableCalc(expr#0..5=[{inputs}], expr#6=[0], expr#7=[=($t1, $t6)], expr#8=[false], expr#9=[IS NOT NULL($t5)], expr#10=[true], expr#11=[IS NULL($t3)], expr#12=[null], expr#13=[<($t2, $t1)], expr#14=[CASE($t7, $t8, $t9, $t10, $t11, $t12, $t13, $t12, $t8)], expr#15=[NOT($t14)], X=[$t0], $condition=[$t15])
- EnumerableJoin(condition=[=($3, $4)], joinType=[left])
- EnumerableCalc(expr#0..2=[{inputs}], $f0=[$t2], $f1=[$t0], $f2=[$t1], $f3=[$t2])
- EnumerableJoin(condition=[true], joinType=[inner])
- EnumerableAggregate(group=[{}], agg#0=[COUNT()], agg#1=[COUNT($0)])
- EnumerableUnion(all=[true])
- EnumerableCalc(expr#0=[{inputs}], expr#1=[1], EXPR$0=[$t1])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=[1], expr#2=[=($t1, $t1)], expr#3=[null], expr#4=[3], expr#5=[CASE($t2, $t3, $t4)], EXPR$0=[$t5])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableUnion(all=[true])
- EnumerableCalc(expr#0=[{inputs}], expr#1=[1], EXPR$0=[$t1])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=[2], EXPR$0=[$t1])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=[1], expr#2=[=($t1, $t1)], expr#3=[null], expr#4=[3], expr#5=[CASE($t2, $t3, $t4)], EXPR$0=[$t5])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableAggregate(group=[{0}], agg#0=[MIN($1)])
- EnumerableCalc(expr#0=[{inputs}], expr#1=[true], proj#0..1=[{exprs}])
- EnumerableUnion(all=[true])
- EnumerableCalc(expr#0=[{inputs}], expr#1=[1], EXPR$0=[$t1])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=[1], expr#2=[=($t1, $t1)], expr#3=[null], expr#4=[3], expr#5=[CASE($t2, $t3, $t4)], EXPR$0=[$t5])
- EnumerableValues(tuples=[[{ 0 }]])
-!plan
-
-# Use of case is to get around issue with directly specifying null in values
-# list. Postgres gives 0 rows.
-with
-t1(x) as (select * from (values (1),(2),(case when 1 = 1 then null else 3 end)) as t1),
-t2(x) as (select * from (values (1),(case when 1 = 1 then null else 3 end)) as t2)
-select *
-from t1
-where t1.x not in (select t2.x from t2);
-
- X
----
-(0 rows)
-
-!ok
-
-# RHS has a mixture of NULL and NOT NULL keys
-select * from dept where deptno not in (select deptno from emp);
- DEPTNO | DNAME
---------+-------
-(0 rows)
-
-!ok
-select deptno, deptno in (select deptno from emp) from dept;
- DEPTNO | EXPR$1
---------+--------
- 10 | true
- 20 | true
- 30 | true
- 40 | null
-(4 rows)
-
-!ok
-select deptno, deptno not in (select deptno from emp) from dept;
- DEPTNO | EXPR$1
---------+--------
- 10 | false
- 20 | false
- 30 | false
- 40 | null
-(4 rows)
-
-!ok
-
-# RHS has only NULL keys
-select * from dept where deptno not in (select deptno from emp where deptno is null);
- DEPTNO | DNAME
---------+-------
-(0 rows)
-
-!ok
-select deptno, deptno in (select deptno from emp where deptno is null) from dept;
- DEPTNO | EXPR$1
---------+--------
- 10 | null
- 20 | null
- 30 | null
- 40 | null
-(4 rows)
-
-!ok
-select deptno, deptno not in (select deptno from emp where deptno is null) from dept;
- DEPTNO | EXPR$1
---------+--------
- 10 | null
- 20 | null
- 30 | null
- 40 | null
-(4 rows)
-
-!ok
-
-# RHS has only NOT NULL keys
-select * from dept where deptno not in (select deptno from emp where deptno is not null);
- DEPTNO | DNAME
---------+-------------
- 40 | Empty
-(1 row)
-
-!ok
-select deptno, deptno in (select deptno from emp where deptno is not null) from dept;
- DEPTNO | EXPR$1
---------+--------
- 10 | true
- 20 | true
- 30 | true
- 40 | false
-(4 rows)
-
-!ok
-select deptno, deptno not in (select deptno from emp where deptno is not null) from dept;
- DEPTNO | EXPR$1
---------+--------
- 10 | false
- 20 | false
- 30 | false
- 40 | true
-(4 rows)
-
-!ok
-
-# RHS has no rows
-# Even 'NULL NOT IN ...' is TRUE.
-select * from dept where deptno not in (select deptno from emp where false);
- DEPTNO | DNAME
---------+-------------
- 10 | Sales
- 20 | Marketing
- 30 | Engineering
- 40 | Empty
-(4 rows)
-
-!ok
-select deptno, deptno in (select deptno from emp where false) from dept;
- DEPTNO | EXPR$1
---------+--------
- 10 | false
- 20 | false
- 30 | false
- 40 | false
-(4 rows)
-
-!ok
-select deptno, deptno not in (select deptno from emp where false) from dept;
- DEPTNO | EXPR$1
---------+--------
- 10 | true
- 20 | true
- 30 | true
- 40 | true
-(4 rows)
-
-!ok
-
-# Multiple IN, connected by OR
-select * from dept
-where deptno in (select deptno from emp where gender = 'F')
-or deptno in (select deptno from emp where gender = 'M');
- DEPTNO | DNAME
---------+-------------
- 30 | Engineering
- 10 | Sales
- 20 | Marketing
-(3 rows)
-
-!ok
-
-# Mix IN and EXISTS
-select * from dept
-where deptno in (select deptno from emp where gender = 'F')
-or exists (select 99, 101 from emp where gender = 'X');
- DEPTNO | DNAME
---------+-------------
- 30 | Engineering
- 10 | Sales
-(2 rows)
-
-!ok
-
-# Composite key
-select * from dept
-where (deptno, deptno) in (select deptno * 2 - deptno, deptno from emp where gender = 'F');
-
-# Composite key, part literal
-select * from emp
-where (gender, deptno) in (select gender, 10 from emp where gender = 'F');
- ENAME | DEPTNO | GENDER
--------+--------+--------
- Jane | 10 | F
-(1 row)
-
-!ok
-
-!use scott
-
-# [CALCITE-694] Scan HAVING clause for sub-queries and IN-lists
-SELECT count(*) AS c
-FROM "scott".emp
-GROUP BY emp.deptno
-HAVING sum(case when emp.empno in (7369, 7839, 7902) then emp.sal else 0 end)
- BETWEEN 5000.0 AND 10000.0;
- C
----
- 3
-(1 row)
-
-!ok
-
-# [CALCITE-716] Scalar sub-query and aggregate function in SELECT or HAVING
-# clause gives AssertionError
-SELECT emp.deptno
-FROM "scott".emp
-GROUP BY emp.deptno
-HAVING max(emp.empno) > (SELECT min(emp.empno) FROM "scott".emp);
- DEPTNO
---------
- 10
- 20
- 30
-(3 rows)
-
-!ok
-
-# [CALCITE-716] Scalar sub-query and aggregate function in SELECT or HAVING
-# clause gives AssertionError
-SELECT emp.deptno,
- max(emp.empno) > (SELECT min(emp.empno) FROM "scott".emp) as bbbb
-FROM "scott".emp
-GROUP BY emp.deptno;
- DEPTNO | BBBB
---------+------
- 10 | true
- 20 | true
- 30 | true
-(3 rows)
-
-!ok
-
-# End subquery.oq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/winagg.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/winagg.iq b/core/src/test/resources/sql/winagg.iq
new file mode 100644
index 0000000..f7c6f54
--- /dev/null
+++ b/core/src/test/resources/sql/winagg.iq
@@ -0,0 +1,323 @@
+# winagg.iq - Unit tests for windowed aggregation, verified on Postgres
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+!use post
+!set outputformat psql
+
+# Multiple window functions sharing a single window
+select count(*) over(partition by gender order by ename) as count1,
+ count(*) over(partition by deptno order by ename) as count2,
+ sum(deptno) over(partition by gender order by ename) as sum1,
+ sum(deptno) over(partition by deptno order by ename) as sum2
+from emp
+order by sum1, sum2;
+ COUNT1 | COUNT2 | SUM1 | SUM2
+--------+--------+------+------
+ 1 | 1 | 30 | 30
+ 1 | 1 | 50 | 50
+ 2 | 1 | 60 | 10
+ 3 | 1 | 80 | 20
+ 2 | 2 | 80 | 100
+ 3 | 1 | 140 | 60
+ 4 | 2 | 150 | 20
+ 5 | 2 | 180 | 60
+ 6 | 1 | 180 |
+(9 rows)
+
+!ok
+
+!if (false) {
+select *, first_value(deptno) over () from emp;
+ ename | deptno | gender | first_value
+-------+--------+--------+-------------
+ Jane | 10 | F | 10
+ Bob | 10 | M | 10
+ Eric | 20 | M | 10
+ Susan | 30 | F | 10
+ Alice | 30 | F | 10
+ Adam | 50 | M | 10
+ Eve | 50 | F | 10
+ Grace | 60 | F | 10
+(8 rows)
+
+!ok
+!}
+!if (false) {
+select *, first_value(ename) over () from emp;
+ ename | deptno | gender | first_value
+-------+--------+--------+-------------
+ Jane | 10 | F | Jane
+ Bob | 10 | M | Jane
+ Eric | 20 | M | Jane
+ Susan | 30 | F | Jane
+ Alice | 30 | F | Jane
+ Adam | 50 | M | Jane
+ Eve | 50 | F | Jane
+ Grace | 60 | F | Jane
+(8 rows)
+
+!ok
+!}
+!if (false) {
+select *, first_value(ename) over (partition by deptno) from emp;
+ ename | deptno | gender | first_value
+-------+--------+--------+-------------
+ Jane | 10 | F | Jane
+ Bob | 10 | M | Jane
+ Eric | 20 | M | Eric
+ Susan | 30 | F | Susan
+ Alice | 30 | F | Susan
+ Adam | 50 | M | Adam
+ Eve | 50 | F | Adam
+ Grace | 60 | F | Grace
+(8 rows)
+
+!ok
+!}
+!if (false) {
+select *, first_value(ename) over (partition by deptno range current row) from emp;
+ ename | deptno | gender | first_value
+-------+--------+--------+-------------
+ Jane | 10 | F | Jane
+ Bob | 10 | M | Jane
+ Eric | 20 | M | Eric
+ Susan | 30 | F | Susan
+ Alice | 30 | F | Susan
+ Adam | 50 | M | Adam
+ Eve | 50 | F | Adam
+ Grace | 60 | F | Grace
+(8 rows)
+
+!ok
+!}
+!if (false) {
+select *, first_value(ename) over (partition by deptno range unbounded preceding) from emp;
+ ename | deptno | gender | first_value
+-------+--------+--------+-------------
+ Jane | 10 | F | Jane
+ Bob | 10 | M | Jane
+ Eric | 20 | M | Eric
+ Susan | 30 | F | Susan
+ Alice | 30 | F | Susan
+ Adam | 50 | M | Adam
+ Eve | 50 | F | Adam
+ Grace | 60 | F | Grace
+(8 rows)
+
+!ok
+!}
+!if (false) {
+select *, first_value(ename) over (partition by deptno order by gender range unbounded preceding) from emp;
+ ename | deptno | gender | first_value
+-------+--------+--------+-------------
+ Jane | 10 | F | Jane
+ Bob | 10 | M | Jane
+ Eric | 20 | M | Eric
+ Alice | 30 | F | Alice
+ Susan | 30 | F | Alice
+ Eve | 50 | F | Eve
+ Adam | 50 | M | Eve
+ Grace | 60 | F | Grace
+(8 rows)
+
+!ok
+!}
+# Calcite does not yet generate tied ranks
+!if (false) {
+select *, count(*) over (order by deptno) as c from emp;
+ ENAME | DEPTNO | GENDER | C
+-------+--------+--------+---
+ Jane | 10 | F | 2
+ Bob | 10 | M | 2
+ Eric | 20 | M | 3
+ Susan | 30 | F | 5
+ Alice | 30 | F | 5
+ Adam | 50 | M | 7
+ Eve | 50 | F | 7
+ Grace | 60 | F | 8
+(8 rows)
+
+!ok
+!}
+select *, rank() over (order by deptno) as c from emp;
+ ENAME | DEPTNO | GENDER | C
+-------+--------+--------+---
+ Jane | 10 | F | 1
+ Bob | 10 | M | 1
+ Eric | 20 | M | 3
+ Susan | 30 | F | 4
+ Alice | 30 | F | 4
+ Adam | 50 | M | 6
+ Eve | 50 | F | 6
+ Grace | 60 | F | 8
+ Wilma | | F | 9
+(9 rows)
+
+!ok
+
+# Calcite does not yet generate tied ranks
+select *, dense_rank() over (order by deptno) as c from emp;
+ ENAME | DEPTNO | GENDER | C
+-------+--------+--------+---
+ Jane | 10 | F | 1
+ Bob | 10 | M | 1
+ Eric | 20 | M | 2
+ Susan | 30 | F | 3
+ Alice | 30 | F | 3
+ Adam | 50 | M | 4
+ Eve | 50 | F | 4
+ Grace | 60 | F | 5
+ Wilma | | F | 6
+(9 rows)
+
+!ok
+
+# [CALCITE-806] ROW_NUMBER should emit distinct values
+#
+# We only run this test under JDK 1.8 because the results are
+# non-deterministic and are different (but still correct) on
+# JDK 1.7 and other platforms.
+!if (jdk18) {
+select *,
+ row_number() over (order by deptno) as r1,
+ row_number() over (partition by deptno order by gender desc) as r2,
+ row_number() over (partition by deptno order by gender) as r3,
+ row_number() over (partition by gender) as r4,
+ row_number() over () as r
+from emp;
+ ENAME | DEPTNO | GENDER | R1 | R2 | R3 | R4 | R
+-------+--------+--------+----+----+----+----+---
+ Wilma | | F | 9 | 1 | 1 | 1 | 1
+ Eve | 50 | F | 7 | 2 | 1 | 2 | 2
+ Jane | 10 | F | 1 | 2 | 1 | 3 | 3
+ Grace | 60 | F | 8 | 1 | 1 | 4 | 4
+ Susan | 30 | F | 4 | 1 | 1 | 5 | 5
+ Alice | 30 | F | 5 | 2 | 2 | 6 | 6
+ Adam | 50 | M | 6 | 1 | 2 | 1 | 7
+ Eric | 20 | M | 3 | 1 | 1 | 2 | 8
+ Bob | 10 | M | 2 | 1 | 2 | 3 | 9
+(9 rows)
+
+!ok
+!}
+
+# As above, ROW_NUMBER without explicit ORDER BY
+select deptno,
+ ename,
+ row_number() over (partition by deptno) as r
+from emp
+where gender = 'F';
+ DEPTNO | ENAME | R
+--------+-------+---
+ 10 | Jane | 1
+ 30 | Alice | 2
+ 30 | Susan | 1
+ 50 | Eve | 1
+ 60 | Grace | 1
+ | Wilma | 1
+(6 rows)
+
+!ok
+
+!if (false) {
+select *, count(*) over (order by deptno), first_value(ename) over (order by deptno rows 2 following) from emp;
+ ERROR: frame starting from following row cannot end with current row
+ LINE 1: ...o), first_value(ename) over (order by deptno rows 2 followin...
+!ok
+!}
+
+# Without ORDER BY
+select *, count(*) over (partition by deptno) as c from emp;
+ ENAME | DEPTNO | GENDER | C
+-------+--------+--------+---
+ Adam | 50 | M | 2
+ Alice | 30 | F | 2
+ Bob | 10 | M | 2
+ Eric | 20 | M | 1
+ Eve | 50 | F | 2
+ Grace | 60 | F | 1
+ Jane | 10 | F | 2
+ Susan | 30 | F | 2
+ Wilma | | F | 1
+(9 rows)
+
+!ok
+
+# No ORDER BY, windows defined in WINDOW clause.
+select deptno, gender, min(gender) over w1 as a, min(gender) over w2 as d
+from emp
+window w1 as (),
+ w2 as (partition by deptno);
+ DEPTNO | GENDER | A | D
+--------+--------+---+---
+ 10 | F | F | F
+ 10 | M | F | F
+ 20 | M | F | M
+ 30 | F | F | F
+ 30 | F | F | F
+ 50 | F | F | F
+ 50 | M | F | F
+ 60 | F | F | F
+ | F | F | F
+(9 rows)
+
+!ok
+
+# Composite COUNT.
+select deptno, gender, count(gender, deptno) over w1 as a
+from emp
+window w1 as ();
+ DEPTNO | GENDER | A
+--------+--------+---
+ 10 | F | 8
+ 10 | M | 8
+ 20 | M | 8
+ 30 | F | 8
+ 30 | F | 8
+ 50 | F | 8
+ 50 | M | 8
+ 60 | F | 8
+ | F | 8
+(9 rows)
+
+!ok
+
+# Window Aggregate and group-by.
+!set outputformat mysql
+select min(deptno) as x, rank() over (order by ename) as y,
+ max(ename) over (partition by deptno) as z
+from emp
+group by deptno, ename;
+
++----+---+-------+
+| X | Y | Z |
++----+---+-------+
+| | 9 | Wilma |
+| 50 | 1 | Eve |
+| 50 | 5 | Eve |
+| 20 | 4 | Eric |
+| 10 | 3 | Jane |
+| 10 | 7 | Jane |
+| 60 | 6 | Grace |
+| 30 | 2 | Susan |
+| 30 | 8 | Susan |
++----+---+-------+
+(9 rows)
+
+!ok
+
+# End winagg.iq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/winagg.oq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/winagg.oq b/core/src/test/resources/sql/winagg.oq
deleted file mode 100644
index 44bc186..0000000
--- a/core/src/test/resources/sql/winagg.oq
+++ /dev/null
@@ -1,323 +0,0 @@
-# winagg.oq - Unit tests for windowed aggregation, verified on Postgres
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to you under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-!use post
-!set outputformat psql
-
-# Multiple window functions sharing a single window
-select count(*) over(partition by gender order by ename) as count1,
- count(*) over(partition by deptno order by ename) as count2,
- sum(deptno) over(partition by gender order by ename) as sum1,
- sum(deptno) over(partition by deptno order by ename) as sum2
-from emp
-order by sum1, sum2;
- COUNT1 | COUNT2 | SUM1 | SUM2
---------+--------+------+------
- 1 | 1 | 30 | 30
- 1 | 1 | 50 | 50
- 2 | 1 | 60 | 10
- 3 | 1 | 80 | 20
- 2 | 2 | 80 | 100
- 3 | 1 | 140 | 60
- 4 | 2 | 150 | 20
- 5 | 2 | 180 | 60
- 6 | 1 | 180 |
-(9 rows)
-
-!ok
-
-!if (false) {
-select *, first_value(deptno) over () from emp;
- ename | deptno | gender | first_value
--------+--------+--------+-------------
- Jane | 10 | F | 10
- Bob | 10 | M | 10
- Eric | 20 | M | 10
- Susan | 30 | F | 10
- Alice | 30 | F | 10
- Adam | 50 | M | 10
- Eve | 50 | F | 10
- Grace | 60 | F | 10
-(8 rows)
-
-!ok
-!}
-!if (false) {
-select *, first_value(ename) over () from emp;
- ename | deptno | gender | first_value
--------+--------+--------+-------------
- Jane | 10 | F | Jane
- Bob | 10 | M | Jane
- Eric | 20 | M | Jane
- Susan | 30 | F | Jane
- Alice | 30 | F | Jane
- Adam | 50 | M | Jane
- Eve | 50 | F | Jane
- Grace | 60 | F | Jane
-(8 rows)
-
-!ok
-!}
-!if (false) {
-select *, first_value(ename) over (partition by deptno) from emp;
- ename | deptno | gender | first_value
--------+--------+--------+-------------
- Jane | 10 | F | Jane
- Bob | 10 | M | Jane
- Eric | 20 | M | Eric
- Susan | 30 | F | Susan
- Alice | 30 | F | Susan
- Adam | 50 | M | Adam
- Eve | 50 | F | Adam
- Grace | 60 | F | Grace
-(8 rows)
-
-!ok
-!}
-!if (false) {
-select *, first_value(ename) over (partition by deptno range current row) from emp;
- ename | deptno | gender | first_value
--------+--------+--------+-------------
- Jane | 10 | F | Jane
- Bob | 10 | M | Jane
- Eric | 20 | M | Eric
- Susan | 30 | F | Susan
- Alice | 30 | F | Susan
- Adam | 50 | M | Adam
- Eve | 50 | F | Adam
- Grace | 60 | F | Grace
-(8 rows)
-
-!ok
-!}
-!if (false) {
-select *, first_value(ename) over (partition by deptno range unbounded preceding) from emp;
- ename | deptno | gender | first_value
--------+--------+--------+-------------
- Jane | 10 | F | Jane
- Bob | 10 | M | Jane
- Eric | 20 | M | Eric
- Susan | 30 | F | Susan
- Alice | 30 | F | Susan
- Adam | 50 | M | Adam
- Eve | 50 | F | Adam
- Grace | 60 | F | Grace
-(8 rows)
-
-!ok
-!}
-!if (false) {
-select *, first_value(ename) over (partition by deptno order by gender range unbounded preceding) from emp;
- ename | deptno | gender | first_value
--------+--------+--------+-------------
- Jane | 10 | F | Jane
- Bob | 10 | M | Jane
- Eric | 20 | M | Eric
- Alice | 30 | F | Alice
- Susan | 30 | F | Alice
- Eve | 50 | F | Eve
- Adam | 50 | M | Eve
- Grace | 60 | F | Grace
-(8 rows)
-
-!ok
-!}
-# Calcite does not yet generate tied ranks
-!if (false) {
-select *, count(*) over (order by deptno) as c from emp;
- ENAME | DEPTNO | GENDER | C
--------+--------+--------+---
- Jane | 10 | F | 2
- Bob | 10 | M | 2
- Eric | 20 | M | 3
- Susan | 30 | F | 5
- Alice | 30 | F | 5
- Adam | 50 | M | 7
- Eve | 50 | F | 7
- Grace | 60 | F | 8
-(8 rows)
-
-!ok
-!}
-select *, rank() over (order by deptno) as c from emp;
- ENAME | DEPTNO | GENDER | C
--------+--------+--------+---
- Jane | 10 | F | 1
- Bob | 10 | M | 1
- Eric | 20 | M | 3
- Susan | 30 | F | 4
- Alice | 30 | F | 4
- Adam | 50 | M | 6
- Eve | 50 | F | 6
- Grace | 60 | F | 8
- Wilma | | F | 9
-(9 rows)
-
-!ok
-
-# Calcite does not yet generate tied ranks
-select *, dense_rank() over (order by deptno) as c from emp;
- ENAME | DEPTNO | GENDER | C
--------+--------+--------+---
- Jane | 10 | F | 1
- Bob | 10 | M | 1
- Eric | 20 | M | 2
- Susan | 30 | F | 3
- Alice | 30 | F | 3
- Adam | 50 | M | 4
- Eve | 50 | F | 4
- Grace | 60 | F | 5
- Wilma | | F | 6
-(9 rows)
-
-!ok
-
-# [CALCITE-806] ROW_NUMBER should emit distinct values
-#
-# We only run this test under JDK 1.8 because the results are
-# non-deterministic and are different (but still correct) on
-# JDK 1.7 and other platforms.
-!if (jdk18) {
-select *,
- row_number() over (order by deptno) as r1,
- row_number() over (partition by deptno order by gender desc) as r2,
- row_number() over (partition by deptno order by gender) as r3,
- row_number() over (partition by gender) as r4,
- row_number() over () as r
-from emp;
- ENAME | DEPTNO | GENDER | R1 | R2 | R3 | R4 | R
--------+--------+--------+----+----+----+----+---
- Wilma | | F | 9 | 1 | 1 | 1 | 1
- Eve | 50 | F | 7 | 2 | 1 | 2 | 2
- Jane | 10 | F | 1 | 2 | 1 | 3 | 3
- Grace | 60 | F | 8 | 1 | 1 | 4 | 4
- Susan | 30 | F | 4 | 1 | 1 | 5 | 5
- Alice | 30 | F | 5 | 2 | 2 | 6 | 6
- Adam | 50 | M | 6 | 1 | 2 | 1 | 7
- Eric | 20 | M | 3 | 1 | 1 | 2 | 8
- Bob | 10 | M | 2 | 1 | 2 | 3 | 9
-(9 rows)
-
-!ok
-!}
-
-# As above, ROW_NUMBER without explicit ORDER BY
-select deptno,
- ename,
- row_number() over (partition by deptno) as r
-from emp
-where gender = 'F';
- DEPTNO | ENAME | R
---------+-------+---
- 10 | Jane | 1
- 30 | Alice | 2
- 30 | Susan | 1
- 50 | Eve | 1
- 60 | Grace | 1
- | Wilma | 1
-(6 rows)
-
-!ok
-
-!if (false) {
-select *, count(*) over (order by deptno), first_value(ename) over (order by deptno rows 2 following) from emp;
- ERROR: frame starting from following row cannot end with current row
- LINE 1: ...o), first_value(ename) over (order by deptno rows 2 followin...
-!ok
-!}
-
-# Without ORDER BY
-select *, count(*) over (partition by deptno) as c from emp;
- ENAME | DEPTNO | GENDER | C
--------+--------+--------+---
- Adam | 50 | M | 2
- Alice | 30 | F | 2
- Bob | 10 | M | 2
- Eric | 20 | M | 1
- Eve | 50 | F | 2
- Grace | 60 | F | 1
- Jane | 10 | F | 2
- Susan | 30 | F | 2
- Wilma | | F | 1
-(9 rows)
-
-!ok
-
-# No ORDER BY, windows defined in WINDOW clause.
-select deptno, gender, min(gender) over w1 as a, min(gender) over w2 as d
-from emp
-window w1 as (),
- w2 as (partition by deptno);
- DEPTNO | GENDER | A | D
---------+--------+---+---
- 10 | F | F | F
- 10 | M | F | F
- 20 | M | F | M
- 30 | F | F | F
- 30 | F | F | F
- 50 | F | F | F
- 50 | M | F | F
- 60 | F | F | F
- | F | F | F
-(9 rows)
-
-!ok
-
-# Composite COUNT.
-select deptno, gender, count(gender, deptno) over w1 as a
-from emp
-window w1 as ();
- DEPTNO | GENDER | A
---------+--------+---
- 10 | F | 8
- 10 | M | 8
- 20 | M | 8
- 30 | F | 8
- 30 | F | 8
- 50 | F | 8
- 50 | M | 8
- 60 | F | 8
- | F | 8
-(9 rows)
-
-!ok
-
-# Window Aggregate and group-by.
-!set outputformat mysql
-select min(deptno) as x, rank() over (order by ename) as y,
- max(ename) over (partition by deptno) as z
-from emp
-group by deptno, ename;
-
-+----+---+-------+
-| X | Y | Z |
-+----+---+-------+
-| | 9 | Wilma |
-| 50 | 1 | Eve |
-| 50 | 5 | Eve |
-| 20 | 4 | Eric |
-| 10 | 3 | Jane |
-| 10 | 7 | Jane |
-| 60 | 6 | Grace |
-| 30 | 2 | Susan |
-| 30 | 8 | Susan |
-+----+---+-------+
-(9 rows)
-
-!ok
-
-# End winagg.oq
[4/7] calcite git commit: [CALCITE-1022] Rename ".oq" Quidem files to
".iq"
Posted by jh...@apache.org.
[CALCITE-1022] Rename ".oq" Quidem files to ".iq"
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/8c2bc8f1
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/8c2bc8f1
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/8c2bc8f1
Branch: refs/heads/master
Commit: 8c2bc8f16b7b26fed7a53aa06f940341dea18219
Parents: 84b55ef
Author: Julian Hyde <jh...@apache.org>
Authored: Sat Dec 12 10:35:22 2015 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Sat Dec 12 13:41:05 2015 -0800
----------------------------------------------------------------------
.../calcite/sql/fun/SqlGroupIdFunction.java | 2 +-
.../calcite/sql/fun/SqlGroupingFunction.java | 2 +-
.../calcite/sql/fun/SqlGroupingIdFunction.java | 2 +-
.../java/org/apache/calcite/test/JdbcTest.java | 33 +-
core/src/test/resources/sql/agg.iq | 1347 ++++++++++++++++++
core/src/test/resources/sql/agg.oq | 1347 ------------------
core/src/test/resources/sql/conditions.iq | 261 ++++
core/src/test/resources/sql/conditions.oq | 259 ----
core/src/test/resources/sql/dummy.iq | 23 +
core/src/test/resources/sql/dummy.oq | 23 -
core/src/test/resources/sql/join.iq | 288 ++++
core/src/test/resources/sql/join.oq | 288 ----
core/src/test/resources/sql/misc.iq | 1111 +++++++++++++++
core/src/test/resources/sql/misc.oq | 1111 ---------------
core/src/test/resources/sql/outer.iq | 349 +++++
core/src/test/resources/sql/outer.oq | 349 -----
core/src/test/resources/sql/scalar.iq | 216 +++
core/src/test/resources/sql/scalar.oq | 216 ---
core/src/test/resources/sql/sequence.iq | 79 +
core/src/test/resources/sql/sequence.oq | 79 -
core/src/test/resources/sql/sort.iq | 179 +++
core/src/test/resources/sql/sort.oq | 179 ---
core/src/test/resources/sql/subquery.iq | 278 ++++
core/src/test/resources/sql/subquery.oq | 278 ----
core/src/test/resources/sql/winagg.iq | 323 +++++
core/src/test/resources/sql/winagg.oq | 323 -----
26 files changed, 4474 insertions(+), 4471 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupIdFunction.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupIdFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupIdFunction.java
index f72a159..7b61703 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupIdFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupIdFunction.java
@@ -27,7 +27,7 @@ import org.apache.calcite.sql.type.ReturnTypes;
* <p>This function is not defined in the SQL standard; our implementation is
* consistent with Oracle.
*
- * <p>Some examples are in {@code agg.oq}.
+ * <p>Some examples are in {@code agg.iq}.
*/
class SqlGroupIdFunction extends SqlAbstractGroupFunction {
public SqlGroupIdFunction() {
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupingFunction.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupingFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupingFunction.java
index c3dae08..16e75e0 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupingFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupingFunction.java
@@ -26,7 +26,7 @@ import org.apache.calcite.sql.type.ReturnTypes;
*
* <p>This function is defined in the SQL standard.
*
- * <p>Some examples are in {@code agg.oq}.
+ * <p>Some examples are in {@code agg.iq}.
*/
class SqlGroupingFunction extends SqlAbstractGroupFunction {
public SqlGroupingFunction() {
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupingIdFunction.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupingIdFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupingIdFunction.java
index 6470db4..a4276b4 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupingIdFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlGroupingIdFunction.java
@@ -27,7 +27,7 @@ import org.apache.calcite.sql.type.ReturnTypes;
* <p>This function is not defined in the SQL standard; our implementation is
* consistent with Oracle.
*
- * <p>Some examples are in {@code agg.oq}.
+ * <p>Some examples are in {@code agg.iq}.
*/
class SqlGroupingIdFunction extends SqlAbstractGroupFunction {
public SqlGroupingIdFunction() {
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/java/org/apache/calcite/test/JdbcTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index 391729d..9d2597f 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -3058,7 +3058,8 @@ public class JdbcTest {
.query("select \"store_id\", \"grocery_sqft\" from \"store\"\n"
+ "where \"store_id\" < 10\n"
+ "order by 1 fetch first 5 rows only")
- .explainContains("PLAN=EnumerableCalc(expr#0..23=[{inputs}], store_id=[$t0], grocery_sqft=[$t16])\n"
+ .explainContains(""
+ + "PLAN=EnumerableCalc(expr#0..23=[{inputs}], store_id=[$t0], grocery_sqft=[$t16])\n"
+ " EnumerableLimit(fetch=[5])\n"
+ " EnumerableCalc(expr#0..23=[{inputs}], expr#24=[10], expr#25=[<($t0, $t24)], proj#0..23=[{exprs}], $condition=[$t25])\n"
+ " EnumerableTableScan(table=[[foodmart2, store]])\n")
@@ -4307,7 +4308,7 @@ public class JdbcTest {
/** Tests CALCITE-980: different flavors of boolean logic */
@Test public void testBooleansInWhere() throws Exception {
- checkRun("sql/conditions.oq");
+ checkRun("sql/conditions.iq");
}
/** Tests CALCITE-980: different flavors of boolean logic */
@@ -4613,25 +4614,25 @@ public class JdbcTest {
/** Runs the dummy script, which is checked in empty but which you may
* use as scratch space during development. */
- // Do not add '@Ignore'; just remember not to commit changes to dummy.oq
+ // Do not add '@Ignore'; just remember not to commit changes to dummy.iq
@Test public void testRunDummy() throws Exception {
- checkRun("sql/dummy.oq");
+ checkRun("sql/dummy.iq");
}
@Test public void testRunAgg() throws Exception {
- checkRun("sql/agg.oq");
+ checkRun("sql/agg.iq");
}
@Test public void testRunJoin() throws Exception {
- checkRun("sql/join.oq");
+ checkRun("sql/join.iq");
}
@Test public void testRunOuter() throws Exception {
- checkRun("sql/outer.oq");
+ checkRun("sql/outer.iq");
}
@Test public void testRunWinAgg() throws Exception {
- checkRun("sql/winagg.oq");
+ checkRun("sql/winagg.iq");
}
@Test public void testRunMisc() throws Exception {
@@ -4641,35 +4642,35 @@ public class JdbcTest {
// Oracle as the JDBC data source.
return;
}
- checkRun("sql/misc.oq");
+ checkRun("sql/misc.iq");
}
@Test public void testRunSequence() throws Exception {
- checkRun("sql/sequence.oq");
+ checkRun("sql/sequence.iq");
}
@Test public void testRunSort() throws Exception {
- checkRun("sql/sort.oq");
+ checkRun("sql/sort.iq");
}
@Test public void testRunScalar() throws Exception {
- checkRun("sql/scalar.oq");
+ checkRun("sql/scalar.iq");
}
@Test public void testRunSubquery() throws Exception {
- checkRun("sql/subquery.oq");
+ checkRun("sql/subquery.iq");
}
private void checkRun(String path) throws Exception {
final File inFile;
final File outFile;
if (path.startsWith("/")) {
- // e.g. path = "/tmp/foo.oq"
+ // e.g. path = "/tmp/foo.iq"
inFile = new File(path);
outFile = new File(path + ".out");
} else {
- // e.g. path = "sql/outer.oq"
- // inUrl = "file:/home/fred/calcite/core/target/test-classes/sql/outer.oq"
+ // e.g. path = "sql/outer.iq"
+ // inUrl = "file:/home/fred/calcite/core/target/test-classes/sql/outer.iq"
final URL inUrl = JdbcTest.class.getResource("/" + path);
String x = inUrl.getFile();
assert x.endsWith(path);
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/agg.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/agg.iq b/core/src/test/resources/sql/agg.iq
new file mode 100644
index 0000000..8e5770e
--- /dev/null
+++ b/core/src/test/resources/sql/agg.iq
@@ -0,0 +1,1347 @@
+# agg.iq - Aggregate functions
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+!use post
+!set outputformat mysql
+
+# count(*) returns number of rows in table
+select count(ename) as c from emp;
++---+
+| C |
++---+
+| 9 |
++---+
+(1 row)
+
+!ok
+
+# count of not-nullable column same as count(*)
+select count(ename) as c from emp;
++---+
+| C |
++---+
+| 9 |
++---+
+(1 row)
+
+!ok
+
+# count of nullable column
+select count(deptno) as c from emp;
++---+
+| C |
++---+
+| 8 |
++---+
+(1 row)
+
+!ok
+
+# composite count
+select count(deptno, ename, 1, deptno) as c from emp;
++---+
+| C |
++---+
+| 8 |
++---+
+(1 row)
+
+!ok
+
+select city, gender as c from emps;
++---------------+---+
+| CITY | C |
++---------------+---+
+| Vancouver | F |
+| San Francisco | M |
+| | |
+| Vancouver | M |
+| | F |
++---------------+---+
+(5 rows)
+
+!ok
+
+# SELECT DISTINCT includes fully and partially null rows
+select distinct city, gender from emps;
++---------------+--------+
+| CITY | GENDER |
++---------------+--------+
+| | |
+| Vancouver | M |
+| | F |
+| San Francisco | M |
+| Vancouver | F |
++---------------+--------+
+(5 rows)
+
+!ok
+
+# COUNT excludes fully or partially null rows
+select count(city, gender) as c from emps;
++---+
+| C |
++---+
+| 3 |
++---+
+(1 row)
+
+!ok
+
+# COUNT-DISTINCT excludes fully or partially null rows
+select count(distinct city, gender) as c from emps;
++---+
+| C |
++---+
+| 3 |
++---+
+(1 row)
+
+!ok
+
+select distinct mod(deptno, 20) as m, gender as c from emps;
++----+---+
+| M | C |
++----+---+
+| 0 | F |
+| 10 | |
+| 0 | M |
++----+---+
+(3 rows)
+
+!ok
+
+# Partially null row (10, NULL) is excluded from count.
+select count(distinct mod(deptno, 20), gender) as c from emps;
++---+
+| C |
++---+
+| 2 |
++---+
+(1 row)
+
+!ok
+
+select count(mod(deptno, 20), gender) as c from emps;
++---+
+| C |
++---+
+| 4 |
++---+
+(1 row)
+
+!ok
+
+# Nulls in GROUP BY
+select x = 1 as x1, count(*) as c
+from (values 0, 1, 2, cast(null as integer)) as t(x)
+group by x = 1;
+X1 BOOLEAN(1)
+C BIGINT(19) NOT NULL
+!type
++-------+---+
+| X1 | C |
++-------+---+
+| false | 2 |
+| true | 1 |
+| | 1 |
++-------+---+
+(3 rows)
+
+!ok
+
+# Basic GROUPING SETS
+select deptno, count(*) as c from emps group by grouping sets ((), (deptno));
++--------+---+
+| DEPTNO | C |
++--------+---+
+| 10 | 1 |
+| 20 | 2 |
+| 40 | 2 |
+| | 5 |
++--------+---+
+(4 rows)
+
+!ok
+
+# GROUPING SETS on expression
+select deptno + 1, count(*) as c from emps group by grouping sets ((), (deptno + 1));
++--------+---+
+| EXPR$0 | C |
++--------+---+
+| 11 | 1 |
+| 21 | 2 |
+| 41 | 2 |
+| | 5 |
++--------+---+
+(4 rows)
+
+!ok
+
+# CUBE
+select deptno + 1, count(*) as c from emp group by cube(deptno, gender);
++--------+---+
+| EXPR$0 | C |
++--------+---+
+| 11 | 1 |
+| 11 | 1 |
+| 11 | 2 |
+| 21 | 1 |
+| 21 | 1 |
+| 31 | 2 |
+| 31 | 2 |
+| 51 | 1 |
+| 51 | 1 |
+| 51 | 2 |
+| 61 | 1 |
+| 61 | 1 |
+| | 1 |
+| | 1 |
+| | 3 |
+| | 6 |
+| | 9 |
++--------+---+
+(17 rows)
+
+!ok
+
+# ROLLUP on 1 column
+select deptno + 1, count(*) as c
+from emp
+group by rollup(deptno);
++--------+---+
+| EXPR$0 | C |
++--------+---+
+| 11 | 2 |
+| 21 | 1 |
+| 31 | 2 |
+| 51 | 2 |
+| 61 | 1 |
+| | 1 |
+| | 9 |
++--------+---+
+(7 rows)
+
+!ok
+
+# ROLLUP on 2 columns; project columns in different order
+select gender, deptno + 1, count(*) as c
+from emp
+group by rollup(deptno, gender);
++--------+--------+---+
+| GENDER | EXPR$1 | C |
++--------+--------+---+
+| M | 21 | 1 |
+| F | 11 | 1 |
+| F | 31 | 2 |
+| F | 51 | 1 |
+| F | 61 | 1 |
+| F | | 1 |
+| M | 11 | 1 |
+| M | 51 | 1 |
+| | 11 | 2 |
+| | 21 | 1 |
+| | 31 | 2 |
+| | 51 | 2 |
+| | 61 | 1 |
+| | | 1 |
+| | | 9 |
++--------+--------+---+
+(15 rows)
+
+!ok
+
+# ROLLUP on column with nulls
+# Note the two rows with NULL key (one represents ALL)
+select gender, count(*) as c
+from emp
+group by rollup(gender);
++--------+---+
+| GENDER | C |
++--------+---+
+| F | 6 |
+| M | 3 |
+| | 9 |
++--------+---+
+(3 rows)
+
+!ok
+
+# ROLLUP plus ORDER BY
+select gender, count(*) as c
+from emp
+group by rollup(gender)
+order by c desc;
++--------+---+
+| GENDER | C |
++--------+---+
+| | 9 |
+| F | 6 |
+| M | 3 |
++--------+---+
+(3 rows)
+
+!ok
+
+# ROLLUP cartesian product
+select deptno, count(*) as c
+from emp
+group by rollup(deptno), rollup(gender);
++--------+---+
+| DEPTNO | C |
++--------+---+
+| 10 | 1 |
+| 10 | 1 |
+| 20 | 1 |
+| 20 | 1 |
+| | 1 |
+| 10 | 2 |
+| 30 | 2 |
+| 30 | 2 |
+| 50 | 1 |
+| 50 | 1 |
+| 50 | 2 |
+| 60 | 1 |
+| 60 | 1 |
+| | 1 |
+| | 3 |
+| | 6 |
+| | 9 |
++--------+---+
+(17 rows)
+
+!ok
+
+# ROLLUP cartesian product of with tuple with expression
+select deptno / 2 + 1 as half1, count(*) as c
+from emp
+group by rollup(deptno / 2, gender), rollup(substring(ename FROM 1 FOR 1));
++-------+---+
+| HALF1 | C |
++-------+---+
+| 11 | 1 |
+| 11 | 1 |
+| 11 | 1 |
+| 11 | 1 |
+| 16 | 1 |
+| 16 | 1 |
+| 16 | 1 |
+| 16 | 1 |
+| 16 | 2 |
+| 16 | 2 |
+| 26 | 1 |
+| 26 | 1 |
+| 26 | 1 |
+| 26 | 1 |
+| 26 | 1 |
+| 26 | 1 |
+| 26 | 2 |
+| 31 | 1 |
+| 31 | 1 |
+| 31 | 1 |
+| 31 | 1 |
+| 6 | 1 |
+| 6 | 1 |
+| 6 | 1 |
+| 6 | 1 |
+| 6 | 1 |
+| 6 | 1 |
+| 6 | 2 |
+| | 1 |
+| | 1 |
+| | 1 |
+| | 1 |
+| | 1 |
+| | 1 |
+| | 1 |
+| | 1 |
+| | 1 |
+| | 2 |
+| | 2 |
+| | 9 |
++-------+---+
+(40 rows)
+
+!ok
+
+# ROLLUP with HAVING
+select deptno + 1 as d1, count(*) as c
+from emp
+group by rollup(deptno)
+having count(*) > 3;
++----+---+
+| D1 | C |
++----+---+
+| | 9 |
++----+---+
+(1 row)
+
+!ok
+
+# CUBE and DISTINCT
+select distinct count(*) from emp group by cube(deptno, gender);
++--------+
+| EXPR$0 |
++--------+
+| 1 |
+| 2 |
+| 3 |
+| 6 |
+| 9 |
++--------+
+(5 rows)
+
+!ok
+
+# CUBE and JOIN
+select e.deptno, e.gender, min(e.ename) as min_name
+from emp as e join dept as d using (deptno)
+group by cube(e.deptno, d.deptno, e.gender)
+having count(*) > 2 or gender = 'M' and e.deptno = 10;
++--------+--------+----------+
+| DEPTNO | GENDER | MIN_NAME |
++--------+--------+----------+
+| 10 | M | Bob |
+| 10 | M | Bob |
+| | F | Alice |
+| | | Alice |
++--------+--------+----------+
+(4 rows)
+
+!ok
+
+# GROUPING in SELECT clause of GROUP BY query
+select count(*) as c, grouping(deptno) as g
+from emp
+group by deptno;
++---+---+
+| C | G |
++---+---+
+| 1 | 1 |
+| 1 | 1 |
+| 1 | 1 |
+| 2 | 1 |
+| 2 | 1 |
+| 2 | 1 |
++---+---+
+(6 rows)
+
+!ok
+
+# GROUPING, GROUP_ID, GROUPING_ID in SELECT clause of GROUP BY query
+select count(*) as c,
+ grouping(deptno) as g,
+ group_id() as gid,
+ grouping_id(deptno) as gd,
+ grouping_id(gender) as gg,
+ grouping_id(gender, deptno) as ggd,
+ grouping_id(gender, deptno) as gdg
+from emp
+group by deptno, gender;
++---+---+-----+----+----+-----+-----+
+| C | G | GID | GD | GG | GGD | GDG |
++---+---+-----+----+----+-----+-----+
+| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
+| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
+| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
+| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
+| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
+| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
+| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
+| 2 | 1 | 3 | 1 | 1 | 3 | 3 |
++---+---+-----+----+----+-----+-----+
+(8 rows)
+
+!ok
+
+# GROUPING in ORDER BY clause
+select count(*) as c
+from emp
+group by deptno
+order by grouping(deptno);
++---+
+| C |
++---+
+| 1 |
+| 2 |
+| 1 |
+| 2 |
+| 1 |
+| 2 |
++---+
+(6 rows)
+
+!ok
+
+# Duplicate argument to GROUPING_ID.
+select deptno, gender, grouping_id(deptno, gender, deptno), count(*) as c
+from emp
+where deptno = 10
+group by rollup(gender, deptno);
++--------+--------+--------+---+
+| DEPTNO | GENDER | EXPR$2 | C |
++--------+--------+--------+---+
+| 10 | F | 0 | 1 |
+| 10 | M | 0 | 1 |
+| | F | 5 | 1 |
+| | M | 5 | 1 |
+| | | 7 | 2 |
++--------+--------+--------+---+
+(5 rows)
+
+!ok
+
+# GROUPING in SELECT clause of ROLLUP query
+select count(*) as c, deptno, grouping(deptno) as g
+from emp
+group by rollup(deptno);
++---+--------+---+
+| C | DEPTNO | G |
++---+--------+---+
+| 1 | 20 | 0 |
+| 1 | 60 | 0 |
+| 1 | | 0 |
+| 2 | 10 | 0 |
+| 2 | 30 | 0 |
+| 2 | 50 | 0 |
+| 9 | | 1 |
++---+--------+---+
+(7 rows)
+
+!ok
+
+# GROUPING, GROUPING_ID and GROUP_ID
+select deptno, gender, grouping(deptno) gd, grouping(gender) gg,
+ grouping_id(deptno, gender) dg, grouping_id(gender, deptno) gd,
+ group_id() gid, count(*) c
+from emp group by cube(deptno, gender);
++--------+--------+----+----+----+----+-----+---+
+| DEPTNO | GENDER | GD | GG | DG | GD | GID | C |
++--------+--------+----+----+----+----+-----+---+
+| 10 | F | 0 | 0 | 0 | 0 | 0 | 1 |
+| 10 | M | 0 | 0 | 0 | 0 | 0 | 1 |
+| 10 | | 0 | 1 | 1 | 2 | 1 | 2 |
+| 20 | M | 0 | 0 | 0 | 0 | 0 | 1 |
+| 20 | | 0 | 1 | 1 | 2 | 1 | 1 |
+| 30 | F | 0 | 0 | 0 | 0 | 0 | 2 |
+| 30 | | 0 | 1 | 1 | 2 | 1 | 2 |
+| 50 | F | 0 | 0 | 0 | 0 | 0 | 1 |
+| 50 | M | 0 | 0 | 0 | 0 | 0 | 1 |
+| 50 | | 0 | 1 | 1 | 2 | 1 | 2 |
+| 60 | F | 0 | 0 | 0 | 0 | 0 | 1 |
+| 60 | | 0 | 1 | 1 | 2 | 1 | 1 |
+| | F | 0 | 0 | 0 | 0 | 0 | 1 |
+| | F | 1 | 0 | 2 | 1 | 2 | 6 |
+| | M | 1 | 0 | 2 | 1 | 2 | 3 |
+| | | 0 | 1 | 1 | 2 | 1 | 1 |
+| | | 1 | 1 | 3 | 3 | 3 | 9 |
++--------+--------+----+----+----+----+-----+---+
+(17 rows)
+
+!ok
+
+!use scott
+
+# [KYLIN-751] Max on negative double values is not working
+# [CALCITE-735] Primitive.DOUBLE.min should be large and negative
+select max(v) as x, min(v) as n
+from (values cast(-86.4 as double), cast(-100 as double)) as t(v);
++-------+--------+
+| X | N |
++-------+--------+
+| -86.4 | -100.0 |
++-------+--------+
+(1 row)
+
+!ok
+
+select max(v) as x, min(v) as n
+from (values cast(-86.4 as double), cast(-100 as double), cast(2 as double)) as t(v);
++-----+--------+
+| X | N |
++-----+--------+
+| 2.0 | -100.0 |
++-----+--------+
+(1 row)
+
+!ok
+
+select max(v) as x, min(v) as n
+from (values cast(-86.4 as float), cast(-100 as float)) as t(v);
++-------+--------+
+| X | N |
++-------+--------+
+| -86.4 | -100.0 |
++-------+--------+
+(1 row)
+
+!ok
+
+# COLLECT
+select deptno, collect(empno) as empnos
+from "scott".emp
+group by deptno;
++--------+--------------------------------------+
+| DEPTNO | EMPNOS |
++--------+--------------------------------------+
+| 10 | [7782, 7839, 7934] |
+| 20 | [7369, 7566, 7788, 7876, 7902] |
+| 30 | [7499, 7521, 7654, 7698, 7844, 7900] |
++--------+--------------------------------------+
+(3 rows)
+
+!ok
+
+# COLLECT DISTINCT
+# Disabled in JDK 1.7 because order of values is different
+!if (jdk18) {
+select deptno, collect(distinct job) as jobs
+from "scott".emp
+group by deptno;
++--------+-----------------------------+
+| DEPTNO | JOBS |
++--------+-----------------------------+
+| 10 | [MANAGER, CLERK, PRESIDENT] |
+| 20 | [CLERK, ANALYST, MANAGER] |
+| 30 | [SALESMAN, MANAGER, CLERK] |
++--------+-----------------------------+
+(3 rows)
+
+!ok
+!}
+
+# COLLECT ... FILTER
+select deptno, collect(empno) filter (where empno < 7550) as empnos
+from "scott".emp
+group by deptno;
++--------+--------------+
+| DEPTNO | EMPNOS |
++--------+--------------+
+| 10 | [] |
+| 20 | [7369] |
+| 30 | [7499, 7521] |
++--------+--------------+
+(3 rows)
+
+!ok
+
+# Aggregate FILTER
+select deptno,
+ sum(sal) filter (where job = 'CLERK') c_sal,
+ sum(sal) filter (where job = 'CLERK' and deptno > 10) c10_sal,
+ max(sal) filter (where job = 'CLERK') as max_c,
+ min(sal) filter (where job = 'CLERK') as min_c,
+ max(sal) filter (where job = 'CLERK')
+ - min(sal) filter (where job = 'CLERK') as range_c,
+ max(sal) filter (where job = 'SALESMAN')
+ - min(sal) filter (where job = 'SALESMAN') as range_m
+from "scott".emp
+group by deptno;
++--------+---------+---------+---------+---------+---------+---------+
+| DEPTNO | C_SAL | C10_SAL | MAX_C | MIN_C | RANGE_C | RANGE_M |
++--------+---------+---------+---------+---------+---------+---------+
+| 10 | 1300.00 | | 1300.00 | 1300.00 | 0.00 | |
+| 20 | 1900.00 | 1900.00 | 1100.00 | 800.00 | 300.00 | |
+| 30 | 950.00 | 950.00 | 950.00 | 950.00 | 0.00 | 350.00 |
++--------+---------+---------+---------+---------+---------+---------+
+(3 rows)
+
+!ok
+
+# Aggregate FILTER on condition in GROUP BY
+select deptno,
+ sum(sal) filter (where deptno = 10) sal_10
+from "scott".emp
+group by deptno;
+DEPTNO TINYINT(3)
+SAL_10 DECIMAL(7, 2)
+!type
++--------+---------+
+| DEPTNO | SAL_10 |
++--------+---------+
+| 10 | 8750.00 |
+| 20 | |
+| 30 | |
++--------+---------+
+(3 rows)
+
+!ok
+
+# Aggregate FILTER with HAVING
+select deptno
+from "scott".emp
+group by deptno
+having sum(sal) filter (where job = 'CLERK') > 1000;
++--------+
+| DEPTNO |
++--------+
+| 10 |
+| 20 |
++--------+
+(2 rows)
+
+!ok
+
+# Aggregate FILTER with ORDER BY
+select deptno
+from "scott".emp
+group by deptno
+order by sum(sal) filter (where job = 'CLERK');
++--------+
+| DEPTNO |
++--------+
+| 30 |
+| 10 |
+| 20 |
++--------+
+(3 rows)
+
+!ok
+
+# Aggregate FILTER with JOIN
+select dept.deptno,
+ sum(sal) filter (where 1 < 2) as s,
+ sum(sal) as s1,
+ count(*) filter (where emp.ename < dept.dname) as c
+from "scott".emp
+join "scott".dept using (deptno)
+group by dept.deptno;
++--------+----------+----------+---+
+| DEPTNO | S | S1 | C |
++--------+----------+----------+---+
+| 10 | 8750.00 | 8750.00 | 0 |
+| 20 | 10875.00 | 10875.00 | 3 |
+| 30 | 9400.00 | 9400.00 | 4 |
++--------+----------+----------+---+
+(3 rows)
+
+!ok
+
+# Aggregate FILTER with DISTINCT
+select deptno,
+ count(distinct job) as cdj
+from "scott".emp
+group by deptno;
++--------+-----+
+| DEPTNO | CDJ |
++--------+-----+
+| 10 | 3 |
+| 20 | 3 |
+| 30 | 3 |
++--------+-----+
+(3 rows)
+
+!ok
+
+select deptno,
+ count(distinct job) filter (where job <> 'SALESMAN') as cdj
+from "scott".emp
+group by deptno;
++--------+-----+
+| DEPTNO | CDJ |
++--------+-----+
+| 10 | 3 |
+| 20 | 3 |
+| 30 | 2 |
++--------+-----+
+(3 rows)
+
+!ok
+
+# Multiple distinct count
+select deptno,
+ count(distinct job) as j, count(distinct mgr) as m
+from "scott".emp
+group by deptno;
++--------+---+---+
+| DEPTNO | J | M |
++--------+---+---+
+| 10 | 3 | 2 |
+| 20 | 3 | 4 |
+| 30 | 3 | 2 |
++--------+---+---+
+(3 rows)
+
+!ok
+
+# Multiple distinct count and non-distinct aggregates
+select deptno,
+ count(distinct job) as dj,
+ count(job) as j,
+ count(distinct mgr) as m,
+ sum(sal) as s
+from "scott".emp
+group by deptno;
++--------+----+---+---+----------+
+| DEPTNO | DJ | J | M | S |
++--------+----+---+---+----------+
+| 10 | 3 | 3 | 2 | 8750.00 |
+| 20 | 3 | 5 | 4 | 10875.00 |
+| 30 | 3 | 6 | 2 | 9400.00 |
++--------+----+---+---+----------+
+(3 rows)
+
+!ok
+
+# Multiple distinct count and non-distinct aggregates, no GROUP BY
+select count(distinct job) as dj,
+ count(job) as j,
+ count(distinct mgr) as m,
+ sum(sal) as s
+from "scott".emp;
++----+----+---+----------+
+| DJ | J | M | S |
++----+----+---+----------+
+| 5 | 14 | 6 | 29025.00 |
++----+----+---+----------+
+(1 row)
+
+!ok
+
+# [CALCITE-280] BigDecimal underflow
+# Previously threw "java.lang.ArithmeticException: Non-terminating decimal
+# expansion; no exact representable decimal result"
+select avg(comm) as a, count(comm) as c from "scott".emp where empno < 7844;
++-------------------+---+
+| A | C |
++-------------------+---+
+| 733.3333333333333 | 3 |
++-------------------+---+
+(1 row)
+
+!ok
+
+# [CALCITE-846] Push aggregate with FILTER through UNION ALL
+select deptno, count(*) filter (where job = 'CLERK') as cf, count(*) as c
+from (
+ select * from "scott".emp where deptno < 20
+ union all
+ select * from "scott".emp where deptno > 20)
+group by deptno;
++--------+----+---+
+| DEPTNO | CF | C |
++--------+----+---+
+| 10 | 1 | 3 |
+| 30 | 1 | 6 |
++--------+----+---+
+(2 rows)
+
+!ok
+EnumerableAggregate(group=[{0}], CF=[COUNT() FILTER $1], C=[COUNT()])
+ EnumerableCalc(expr#0..1=[{inputs}], expr#2=['CLERK'], expr#3=[=($t0, $t2)], DEPTNO=[$t1], $f1=[$t3])
+ EnumerableUnion(all=[true])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[20], expr#9=[<($t7, $t8)], JOB=[$t2], DEPTNO=[$t7], $condition=[$t9])
+ EnumerableTableScan(table=[[scott, EMP]])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[20], expr#9=[>($t7, $t8)], JOB=[$t2], DEPTNO=[$t7], $condition=[$t9])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# [CALCITE-751] Aggregate join transpose
+select count(*)
+from "scott".emp join "scott".dept using (deptno);
++--------+
+| EXPR$0 |
++--------+
+| 14 |
++--------+
+(1 row)
+
+!ok
+EnumerableAggregate(group=[{}], EXPR$0=[COUNT()])
+ EnumerableJoin(condition=[=($0, $2)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Push sum: splits into sum * count
+select sum(sal)
+from "scott".emp join "scott".dept using (deptno);
++----------+
+| EXPR$0 |
++----------+
+| 29025.00 |
++----------+
+(1 row)
+
+!ok
+EnumerableAggregate(group=[{}], EXPR$0=[SUM($2)])
+ EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Push sum; no aggregate needed after join
+select sum(sal)
+from "scott".emp join "scott".dept using (deptno)
+group by emp.deptno, dept.deptno;
++----------+
+| EXPR$0 |
++----------+
+| 10875.00 |
+| 8750.00 |
+| 9400.00 |
++----------+
+(3 rows)
+
+!ok
+EnumerableCalc(expr#0..2=[{inputs}], EXPR$0=[$t2])
+ EnumerableAggregate(group=[{0, 3}], EXPR$0=[SUM($2)])
+ EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Push sum; group by only one of the join keys
+select sum(sal)
+from "scott".emp join "scott".dept using (deptno)
+group by emp.deptno;
++----------+
+| EXPR$0 |
++----------+
+| 10875.00 |
+| 8750.00 |
+| 9400.00 |
++----------+
+(3 rows)
+
+!ok
+EnumerableCalc(expr#0..1=[{inputs}], EXPR$0=[$t1])
+ EnumerableAggregate(group=[{3}], EXPR$0=[SUM($2)])
+ EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Push min; Join-Aggregate is optimized to SemiJoin
+select min(sal)
+from "scott".emp join "scott".dept using (deptno)
+group by emp.deptno;
++---------+
+| EXPR$0 |
++---------+
+| 1300.00 |
+| 800.00 |
+| 950.00 |
++---------+
+(3 rows)
+
+!ok
+EnumerableCalc(expr#0..1=[{inputs}], EXPR$0=[$t1])
+ EnumerableAggregate(group=[{3}], EXPR$0=[MIN($2)])
+ EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Push sum and count
+select count(*) as c, sum(sal) as s
+from "scott".emp join "scott".dept using (deptno);
++----+----------+
+| C | S |
++----+----------+
+| 14 | 29025.00 |
++----+----------+
+(1 row)
+
+!ok
+EnumerableAggregate(group=[{}], C=[COUNT()], S=[SUM($2)])
+ EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Push sum and count, group by join key
+select count(*) as c, sum(sal) as s
+from "scott".emp join "scott".dept using (deptno) group by emp.deptno;
++---+----------+
+| C | S |
++---+----------+
+| 3 | 8750.00 |
+| 5 | 10875.00 |
+| 6 | 9400.00 |
++---+----------+
+(3 rows)
+
+!ok
+# No aggregate on top, because output of join is unique
+EnumerableCalc(expr#0..2=[{inputs}], C=[$t1], S=[$t2])
+ EnumerableAggregate(group=[{3}], C=[COUNT()], S=[SUM($2)])
+ EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Push sum and count, group by join key plus another column
+select count(*) as c, sum(sal) as s
+from "scott".emp join "scott".dept using (deptno) group by emp.job, dept.deptno;
++---+---------+
+| C | S |
++---+---------+
+| 1 | 1300.00 |
+| 1 | 2450.00 |
+| 1 | 2850.00 |
+| 1 | 2975.00 |
+| 1 | 5000.00 |
+| 1 | 950.00 |
+| 2 | 1900.00 |
+| 2 | 6000.00 |
+| 4 | 5600.00 |
++---+---------+
+(9 rows)
+
+!ok
+EnumerableCalc(expr#0..3=[{inputs}], C=[$t2], S=[$t3])
+ EnumerableAggregate(group=[{0, 2}], C=[COUNT()], S=[SUM($3)])
+ EnumerableJoin(condition=[=($0, $4)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], JOB=[$t2], SAL=[$t5], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Push sum and count, group by non-join column
+select count(*) as c, sum(sal) as s
+from "scott".emp join "scott".dept using (deptno) group by emp.job;
++---+---------+
+| C | S |
++---+---------+
+| 1 | 5000.00 |
+| 2 | 6000.00 |
+| 3 | 8275.00 |
+| 4 | 4150.00 |
+| 4 | 5600.00 |
++---+---------+
+(5 rows)
+
+!ok
+EnumerableCalc(expr#0..2=[{inputs}], C=[$t1], S=[$t2])
+ EnumerableAggregate(group=[{2}], C=[COUNT()], S=[SUM($3)])
+ EnumerableJoin(condition=[=($0, $4)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], JOB=[$t2], SAL=[$t5], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Push count and sum, group by superset of join key
+select count(*) as c, sum(sal) as s
+from "scott".emp join "scott".dept using (deptno) group by emp.job, dept.deptno;
++---+---------+
+| C | S |
++---+---------+
+| 1 | 5000.00 |
+| 2 | 6000.00 |
+| 4 | 5600.00 |
+| 1 | 1300.00 |
+| 1 | 2450.00 |
+| 1 | 2850.00 |
+| 1 | 2975.00 |
+| 1 | 950.00 |
+| 2 | 1900.00 |
++---+---------+
+(9 rows)
+
+!ok
+EnumerableCalc(expr#0..3=[{inputs}], C=[$t2], S=[$t3])
+ EnumerableAggregate(group=[{0, 2}], C=[COUNT()], S=[SUM($3)])
+ EnumerableJoin(condition=[=($0, $4)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], JOB=[$t2], SAL=[$t5], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Push count and sum, group by a column being aggregated
+select count(*) as c, sum(sal) as s
+from "scott".emp join "scott".dept using (deptno) group by emp.sal;
++---+---------+
+| C | S |
++---+---------+
+| 1 | 5000.00 |
+| 2 | 6000.00 |
+| 1 | 1100.00 |
+| 1 | 1300.00 |
+| 1 | 1500.00 |
+| 1 | 1600.00 |
+| 1 | 2450.00 |
+| 1 | 2850.00 |
+| 1 | 2975.00 |
+| 1 | 800.00 |
+| 1 | 950.00 |
+| 2 | 2500.00 |
++---+---------+
+(12 rows)
+
+!ok
+EnumerableCalc(expr#0..2=[{inputs}], C=[$t1], S=[$t2])
+ EnumerableAggregate(group=[{2}], C=[COUNT()], S=[SUM($2)])
+ EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# Push sum, self-join, returning one row with a null value
+select sum(e.sal) as s
+from "scott".emp e join "scott".emp m on e.mgr = e.empno;
++---+
+| S |
++---+
+| |
++---+
+(1 row)
+
+!ok
+
+# Push sum, self-join
+select sum(e.sal) as s
+from "scott".emp e join "scott".emp m on e.mgr = m.empno;
++----------+
+| S |
++----------+
+| 24025.00 |
++----------+
+(1 row)
+
+!ok
+
+# Push sum, self-join, cartesian product over nullable and non-nullable columns
+select sum(e.sal) as ss, count(e.sal) as cs, count(e.mgr) as cm
+from "scott".emp e
+join "scott".emp m on e.deptno = m.deptno
+group by e.deptno, m.deptno;
++----------+----+----+
+| SS | CS | CM |
++----------+----+----+
+| 26250.00 | 9 | 6 |
+| 54375.00 | 25 | 25 |
+| 56400.00 | 36 | 36 |
++----------+----+----+
+(3 rows)
+
+!ok
+
+# Push sum, self-join, aggregate by column on "many" side
+select sum(e.sal) as s
+from "scott".emp e join "scott".emp m on e.mgr = m.empno
+group by m.empno;
++---------+
+| S |
++---------+
+| 1100.00 |
+| 1300.00 |
+| 6000.00 |
+| 6550.00 |
+| 800.00 |
+| 8275.00 |
++---------+
+(6 rows)
+
+!ok
+
+# Push sum, self-join, aggregate by column on "one" side.
+# Note inflated totals due to cartesian product.
+select sum(m.sal) as s
+from "scott".emp e join "scott".emp m on e.mgr = m.empno
+group by m.empno;
++----------+
+| S |
++----------+
+| 14250.00 |
+| 15000.00 |
+| 2450.00 |
+| 3000.00 |
+| 3000.00 |
+| 5950.00 |
++----------+
+(6 rows)
+
+!ok
+
+# Collation of LogicalAggregate ([CALCITE-783] and [CALCITE-822])
+select sum(x) as sum_cnt,
+ count(distinct y) as cnt_dist
+from
+ (
+ select
+ count(*) as x,
+ t1.job as y,
+ t1.deptno as z
+ from
+ "scott".emp t1
+ group by t1.job, t1.deptno
+ order by t1.job, t1.deptno
+) sq(x,y,z)
+group by z
+order by sum_cnt;
+
++---------+----------+
+| SUM_CNT | CNT_DIST |
++---------+----------+
+| 3 | 3 |
+| 5 | 3 |
+| 6 | 3 |
++---------+----------+
+(3 rows)
+
+!ok
+
+# [CALCITE-938] Aggregate row count
+select empno, d.deptno
+from "scott".emp
+join (select distinct deptno from "scott".dept) d
+using (deptno);
++-------+--------+
+| EMPNO | DEPTNO |
++-------+--------+
+| 7369 | 20 |
+| 7499 | 30 |
+| 7521 | 30 |
+| 7566 | 20 |
+| 7654 | 30 |
+| 7698 | 30 |
+| 7782 | 10 |
+| 7788 | 20 |
+| 7839 | 10 |
+| 7844 | 30 |
+| 7876 | 20 |
+| 7900 | 30 |
+| 7902 | 20 |
+| 7934 | 10 |
++-------+--------+
+(14 rows)
+
+!ok
+EnumerableCalc(expr#0..2=[{inputs}], EMPNO=[$t1], DEPTNO=[$t0])
+ EnumerableJoin(condition=[=($0, $2)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# [CALCITE-729] IndexOutOfBoundsException in ROLLUP query on JDBC data source
+!use jdbc_scott
+select deptno, job, count(*) as c
+from jdbc_scott.emp
+group by rollup (deptno, job)
+order by 1, 2;
++--------+-----------+----+
+| DEPTNO | JOB | C |
++--------+-----------+----+
+| 10 | CLERK | 1 |
+| 10 | MANAGER | 1 |
+| 10 | PRESIDENT | 1 |
+| 10 | | 3 |
+| 20 | ANALYST | 2 |
+| 20 | CLERK | 2 |
+| 20 | MANAGER | 1 |
+| 20 | | 5 |
+| 30 | CLERK | 1 |
+| 30 | MANAGER | 1 |
+| 30 | SALESMAN | 4 |
+| 30 | | 6 |
+| | | 14 |
++--------+-----------+----+
+(13 rows)
+
+!ok
+
+# [CALCITE-799] Incorrect result for "HAVING count(*) > 1"
+select d.deptno, min(e.empid) as empid
+from (values (100, 'Bill', 1),
+ (200, 'Eric', 1),
+ (150, 'Sebastian', 3)) as e(empid, name, deptno)
+join (values (1, 'LeaderShip'),
+ (2, 'TestGroup'),
+ (3, 'Development')) as d(deptno, name)
+on e.deptno = d.deptno
+group by d.deptno
+having count(*) > 1;
++--------+-------+
+| DEPTNO | EMPID |
++--------+-------+
+| 1 | 100 |
++--------+-------+
+(1 row)
+
+!ok
+
+# Same, using USING (combining [CALCITE-799] and [CALCITE-801])
+select d.deptno, min(e.empid) as empid
+from (values (100, 'Bill', 1),
+ (200, 'Eric', 1),
+ (150, 'Sebastian', 3)) as e(empid, name, deptno)
+join (values (1, 'LeaderShip'),
+ (2, 'TestGroup'),
+ (3, 'Development')) as d(deptno, name)
+using (deptno)
+group by d.deptno
+having count(*) > 1;
++--------+-------+
+| DEPTNO | EMPID |
++--------+-------+
+| 1 | 100 |
++--------+-------+
+(1 row)
+
+!ok
+
+# [CALCITE-886] System functions in the GROUP BY clause
+# Calls to system functions do not have "()", which may confuse the validator.
+select CURRENT_USER as CUSER
+from jdbc_scott.emp
+group by CURRENT_USER;
++-------+
+| CUSER |
++-------+
+| SCOTT |
++-------+
+(1 row)
+
+!ok
+
+# [CALCITE-886] System functions in the GROUP BY clause
+# System function inside a GROUPING SETS.
+select CURRENT_USER as CUSER
+from jdbc_scott.emp
+group by grouping sets(CURRENT_USER);
++-------+
+| CUSER |
++-------+
+| SCOTT |
++-------+
+(1 row)
+
+!ok
+
+# End agg.iq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/agg.oq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/agg.oq b/core/src/test/resources/sql/agg.oq
deleted file mode 100644
index 2dea732..0000000
--- a/core/src/test/resources/sql/agg.oq
+++ /dev/null
@@ -1,1347 +0,0 @@
-# agg.oq - Aggregate functions
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to you under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-!use post
-!set outputformat mysql
-
-# count(*) returns number of rows in table
-select count(ename) as c from emp;
-+---+
-| C |
-+---+
-| 9 |
-+---+
-(1 row)
-
-!ok
-
-# count of not-nullable column same as count(*)
-select count(ename) as c from emp;
-+---+
-| C |
-+---+
-| 9 |
-+---+
-(1 row)
-
-!ok
-
-# count of nullable column
-select count(deptno) as c from emp;
-+---+
-| C |
-+---+
-| 8 |
-+---+
-(1 row)
-
-!ok
-
-# composite count
-select count(deptno, ename, 1, deptno) as c from emp;
-+---+
-| C |
-+---+
-| 8 |
-+---+
-(1 row)
-
-!ok
-
-select city, gender as c from emps;
-+---------------+---+
-| CITY | C |
-+---------------+---+
-| Vancouver | F |
-| San Francisco | M |
-| | |
-| Vancouver | M |
-| | F |
-+---------------+---+
-(5 rows)
-
-!ok
-
-# SELECT DISTINCT includes fully and partially null rows
-select distinct city, gender from emps;
-+---------------+--------+
-| CITY | GENDER |
-+---------------+--------+
-| | |
-| Vancouver | M |
-| | F |
-| San Francisco | M |
-| Vancouver | F |
-+---------------+--------+
-(5 rows)
-
-!ok
-
-# COUNT excludes fully or partially null rows
-select count(city, gender) as c from emps;
-+---+
-| C |
-+---+
-| 3 |
-+---+
-(1 row)
-
-!ok
-
-# COUNT-DISTINCT excludes fully or partially null rows
-select count(distinct city, gender) as c from emps;
-+---+
-| C |
-+---+
-| 3 |
-+---+
-(1 row)
-
-!ok
-
-select distinct mod(deptno, 20) as m, gender as c from emps;
-+----+---+
-| M | C |
-+----+---+
-| 0 | F |
-| 10 | |
-| 0 | M |
-+----+---+
-(3 rows)
-
-!ok
-
-# Partially null row (10, NULL) is excluded from count.
-select count(distinct mod(deptno, 20), gender) as c from emps;
-+---+
-| C |
-+---+
-| 2 |
-+---+
-(1 row)
-
-!ok
-
-select count(mod(deptno, 20), gender) as c from emps;
-+---+
-| C |
-+---+
-| 4 |
-+---+
-(1 row)
-
-!ok
-
-# Nulls in GROUP BY
-select x = 1 as x1, count(*) as c
-from (values 0, 1, 2, cast(null as integer)) as t(x)
-group by x = 1;
-X1 BOOLEAN(1)
-C BIGINT(19) NOT NULL
-!type
-+-------+---+
-| X1 | C |
-+-------+---+
-| false | 2 |
-| true | 1 |
-| | 1 |
-+-------+---+
-(3 rows)
-
-!ok
-
-# Basic GROUPING SETS
-select deptno, count(*) as c from emps group by grouping sets ((), (deptno));
-+--------+---+
-| DEPTNO | C |
-+--------+---+
-| 10 | 1 |
-| 20 | 2 |
-| 40 | 2 |
-| | 5 |
-+--------+---+
-(4 rows)
-
-!ok
-
-# GROUPING SETS on expression
-select deptno + 1, count(*) as c from emps group by grouping sets ((), (deptno + 1));
-+--------+---+
-| EXPR$0 | C |
-+--------+---+
-| 11 | 1 |
-| 21 | 2 |
-| 41 | 2 |
-| | 5 |
-+--------+---+
-(4 rows)
-
-!ok
-
-# CUBE
-select deptno + 1, count(*) as c from emp group by cube(deptno, gender);
-+--------+---+
-| EXPR$0 | C |
-+--------+---+
-| 11 | 1 |
-| 11 | 1 |
-| 11 | 2 |
-| 21 | 1 |
-| 21 | 1 |
-| 31 | 2 |
-| 31 | 2 |
-| 51 | 1 |
-| 51 | 1 |
-| 51 | 2 |
-| 61 | 1 |
-| 61 | 1 |
-| | 1 |
-| | 1 |
-| | 3 |
-| | 6 |
-| | 9 |
-+--------+---+
-(17 rows)
-
-!ok
-
-# ROLLUP on 1 column
-select deptno + 1, count(*) as c
-from emp
-group by rollup(deptno);
-+--------+---+
-| EXPR$0 | C |
-+--------+---+
-| 11 | 2 |
-| 21 | 1 |
-| 31 | 2 |
-| 51 | 2 |
-| 61 | 1 |
-| | 1 |
-| | 9 |
-+--------+---+
-(7 rows)
-
-!ok
-
-# ROLLUP on 2 columns; project columns in different order
-select gender, deptno + 1, count(*) as c
-from emp
-group by rollup(deptno, gender);
-+--------+--------+---+
-| GENDER | EXPR$1 | C |
-+--------+--------+---+
-| M | 21 | 1 |
-| F | 11 | 1 |
-| F | 31 | 2 |
-| F | 51 | 1 |
-| F | 61 | 1 |
-| F | | 1 |
-| M | 11 | 1 |
-| M | 51 | 1 |
-| | 11 | 2 |
-| | 21 | 1 |
-| | 31 | 2 |
-| | 51 | 2 |
-| | 61 | 1 |
-| | | 1 |
-| | | 9 |
-+--------+--------+---+
-(15 rows)
-
-!ok
-
-# ROLLUP on column with nulls
-# Note the two rows with NULL key (one represents ALL)
-select gender, count(*) as c
-from emp
-group by rollup(gender);
-+--------+---+
-| GENDER | C |
-+--------+---+
-| F | 6 |
-| M | 3 |
-| | 9 |
-+--------+---+
-(3 rows)
-
-!ok
-
-# ROLLUP plus ORDER BY
-select gender, count(*) as c
-from emp
-group by rollup(gender)
-order by c desc;
-+--------+---+
-| GENDER | C |
-+--------+---+
-| | 9 |
-| F | 6 |
-| M | 3 |
-+--------+---+
-(3 rows)
-
-!ok
-
-# ROLLUP cartesian product
-select deptno, count(*) as c
-from emp
-group by rollup(deptno), rollup(gender);
-+--------+---+
-| DEPTNO | C |
-+--------+---+
-| 10 | 1 |
-| 10 | 1 |
-| 20 | 1 |
-| 20 | 1 |
-| | 1 |
-| 10 | 2 |
-| 30 | 2 |
-| 30 | 2 |
-| 50 | 1 |
-| 50 | 1 |
-| 50 | 2 |
-| 60 | 1 |
-| 60 | 1 |
-| | 1 |
-| | 3 |
-| | 6 |
-| | 9 |
-+--------+---+
-(17 rows)
-
-!ok
-
-# ROLLUP cartesian product of with tuple with expression
-select deptno / 2 + 1 as half1, count(*) as c
-from emp
-group by rollup(deptno / 2, gender), rollup(substring(ename FROM 1 FOR 1));
-+-------+---+
-| HALF1 | C |
-+-------+---+
-| 11 | 1 |
-| 11 | 1 |
-| 11 | 1 |
-| 11 | 1 |
-| 16 | 1 |
-| 16 | 1 |
-| 16 | 1 |
-| 16 | 1 |
-| 16 | 2 |
-| 16 | 2 |
-| 26 | 1 |
-| 26 | 1 |
-| 26 | 1 |
-| 26 | 1 |
-| 26 | 1 |
-| 26 | 1 |
-| 26 | 2 |
-| 31 | 1 |
-| 31 | 1 |
-| 31 | 1 |
-| 31 | 1 |
-| 6 | 1 |
-| 6 | 1 |
-| 6 | 1 |
-| 6 | 1 |
-| 6 | 1 |
-| 6 | 1 |
-| 6 | 2 |
-| | 1 |
-| | 1 |
-| | 1 |
-| | 1 |
-| | 1 |
-| | 1 |
-| | 1 |
-| | 1 |
-| | 1 |
-| | 2 |
-| | 2 |
-| | 9 |
-+-------+---+
-(40 rows)
-
-!ok
-
-# ROLLUP with HAVING
-select deptno + 1 as d1, count(*) as c
-from emp
-group by rollup(deptno)
-having count(*) > 3;
-+----+---+
-| D1 | C |
-+----+---+
-| | 9 |
-+----+---+
-(1 row)
-
-!ok
-
-# CUBE and DISTINCT
-select distinct count(*) from emp group by cube(deptno, gender);
-+--------+
-| EXPR$0 |
-+--------+
-| 1 |
-| 2 |
-| 3 |
-| 6 |
-| 9 |
-+--------+
-(5 rows)
-
-!ok
-
-# CUBE and JOIN
-select e.deptno, e.gender, min(e.ename) as min_name
-from emp as e join dept as d using (deptno)
-group by cube(e.deptno, d.deptno, e.gender)
-having count(*) > 2 or gender = 'M' and e.deptno = 10;
-+--------+--------+----------+
-| DEPTNO | GENDER | MIN_NAME |
-+--------+--------+----------+
-| 10 | M | Bob |
-| 10 | M | Bob |
-| | F | Alice |
-| | | Alice |
-+--------+--------+----------+
-(4 rows)
-
-!ok
-
-# GROUPING in SELECT clause of GROUP BY query
-select count(*) as c, grouping(deptno) as g
-from emp
-group by deptno;
-+---+---+
-| C | G |
-+---+---+
-| 1 | 1 |
-| 1 | 1 |
-| 1 | 1 |
-| 2 | 1 |
-| 2 | 1 |
-| 2 | 1 |
-+---+---+
-(6 rows)
-
-!ok
-
-# GROUPING, GROUP_ID, GROUPING_ID in SELECT clause of GROUP BY query
-select count(*) as c,
- grouping(deptno) as g,
- group_id() as gid,
- grouping_id(deptno) as gd,
- grouping_id(gender) as gg,
- grouping_id(gender, deptno) as ggd,
- grouping_id(gender, deptno) as gdg
-from emp
-group by deptno, gender;
-+---+---+-----+----+----+-----+-----+
-| C | G | GID | GD | GG | GGD | GDG |
-+---+---+-----+----+----+-----+-----+
-| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
-| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
-| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
-| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
-| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
-| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
-| 1 | 1 | 3 | 1 | 1 | 3 | 3 |
-| 2 | 1 | 3 | 1 | 1 | 3 | 3 |
-+---+---+-----+----+----+-----+-----+
-(8 rows)
-
-!ok
-
-# GROUPING in ORDER BY clause
-select count(*) as c
-from emp
-group by deptno
-order by grouping(deptno);
-+---+
-| C |
-+---+
-| 1 |
-| 2 |
-| 1 |
-| 2 |
-| 1 |
-| 2 |
-+---+
-(6 rows)
-
-!ok
-
-# Duplicate argument to GROUPING_ID.
-select deptno, gender, grouping_id(deptno, gender, deptno), count(*) as c
-from emp
-where deptno = 10
-group by rollup(gender, deptno);
-+--------+--------+--------+---+
-| DEPTNO | GENDER | EXPR$2 | C |
-+--------+--------+--------+---+
-| 10 | F | 0 | 1 |
-| 10 | M | 0 | 1 |
-| | F | 5 | 1 |
-| | M | 5 | 1 |
-| | | 7 | 2 |
-+--------+--------+--------+---+
-(5 rows)
-
-!ok
-
-# GROUPING in SELECT clause of ROLLUP query
-select count(*) as c, deptno, grouping(deptno) as g
-from emp
-group by rollup(deptno);
-+---+--------+---+
-| C | DEPTNO | G |
-+---+--------+---+
-| 1 | 20 | 0 |
-| 1 | 60 | 0 |
-| 1 | | 0 |
-| 2 | 10 | 0 |
-| 2 | 30 | 0 |
-| 2 | 50 | 0 |
-| 9 | | 1 |
-+---+--------+---+
-(7 rows)
-
-!ok
-
-# GROUPING, GROUPING_ID and GROUP_ID
-select deptno, gender, grouping(deptno) gd, grouping(gender) gg,
- grouping_id(deptno, gender) dg, grouping_id(gender, deptno) gd,
- group_id() gid, count(*) c
-from emp group by cube(deptno, gender);
-+--------+--------+----+----+----+----+-----+---+
-| DEPTNO | GENDER | GD | GG | DG | GD | GID | C |
-+--------+--------+----+----+----+----+-----+---+
-| 10 | F | 0 | 0 | 0 | 0 | 0 | 1 |
-| 10 | M | 0 | 0 | 0 | 0 | 0 | 1 |
-| 10 | | 0 | 1 | 1 | 2 | 1 | 2 |
-| 20 | M | 0 | 0 | 0 | 0 | 0 | 1 |
-| 20 | | 0 | 1 | 1 | 2 | 1 | 1 |
-| 30 | F | 0 | 0 | 0 | 0 | 0 | 2 |
-| 30 | | 0 | 1 | 1 | 2 | 1 | 2 |
-| 50 | F | 0 | 0 | 0 | 0 | 0 | 1 |
-| 50 | M | 0 | 0 | 0 | 0 | 0 | 1 |
-| 50 | | 0 | 1 | 1 | 2 | 1 | 2 |
-| 60 | F | 0 | 0 | 0 | 0 | 0 | 1 |
-| 60 | | 0 | 1 | 1 | 2 | 1 | 1 |
-| | F | 0 | 0 | 0 | 0 | 0 | 1 |
-| | F | 1 | 0 | 2 | 1 | 2 | 6 |
-| | M | 1 | 0 | 2 | 1 | 2 | 3 |
-| | | 0 | 1 | 1 | 2 | 1 | 1 |
-| | | 1 | 1 | 3 | 3 | 3 | 9 |
-+--------+--------+----+----+----+----+-----+---+
-(17 rows)
-
-!ok
-
-!use scott
-
-# [KYLIN-751] Max on negative double values is not working
-# [CALCITE-735] Primitive.DOUBLE.min should be large and negative
-select max(v) as x, min(v) as n
-from (values cast(-86.4 as double), cast(-100 as double)) as t(v);
-+-------+--------+
-| X | N |
-+-------+--------+
-| -86.4 | -100.0 |
-+-------+--------+
-(1 row)
-
-!ok
-
-select max(v) as x, min(v) as n
-from (values cast(-86.4 as double), cast(-100 as double), cast(2 as double)) as t(v);
-+-----+--------+
-| X | N |
-+-----+--------+
-| 2.0 | -100.0 |
-+-----+--------+
-(1 row)
-
-!ok
-
-select max(v) as x, min(v) as n
-from (values cast(-86.4 as float), cast(-100 as float)) as t(v);
-+-------+--------+
-| X | N |
-+-------+--------+
-| -86.4 | -100.0 |
-+-------+--------+
-(1 row)
-
-!ok
-
-# COLLECT
-select deptno, collect(empno) as empnos
-from "scott".emp
-group by deptno;
-+--------+--------------------------------------+
-| DEPTNO | EMPNOS |
-+--------+--------------------------------------+
-| 10 | [7782, 7839, 7934] |
-| 20 | [7369, 7566, 7788, 7876, 7902] |
-| 30 | [7499, 7521, 7654, 7698, 7844, 7900] |
-+--------+--------------------------------------+
-(3 rows)
-
-!ok
-
-# COLLECT DISTINCT
-# Disabled in JDK 1.7 because order of values is different
-!if (jdk18) {
-select deptno, collect(distinct job) as jobs
-from "scott".emp
-group by deptno;
-+--------+-----------------------------+
-| DEPTNO | JOBS |
-+--------+-----------------------------+
-| 10 | [MANAGER, CLERK, PRESIDENT] |
-| 20 | [CLERK, ANALYST, MANAGER] |
-| 30 | [SALESMAN, MANAGER, CLERK] |
-+--------+-----------------------------+
-(3 rows)
-
-!ok
-!}
-
-# COLLECT ... FILTER
-select deptno, collect(empno) filter (where empno < 7550) as empnos
-from "scott".emp
-group by deptno;
-+--------+--------------+
-| DEPTNO | EMPNOS |
-+--------+--------------+
-| 10 | [] |
-| 20 | [7369] |
-| 30 | [7499, 7521] |
-+--------+--------------+
-(3 rows)
-
-!ok
-
-# Aggregate FILTER
-select deptno,
- sum(sal) filter (where job = 'CLERK') c_sal,
- sum(sal) filter (where job = 'CLERK' and deptno > 10) c10_sal,
- max(sal) filter (where job = 'CLERK') as max_c,
- min(sal) filter (where job = 'CLERK') as min_c,
- max(sal) filter (where job = 'CLERK')
- - min(sal) filter (where job = 'CLERK') as range_c,
- max(sal) filter (where job = 'SALESMAN')
- - min(sal) filter (where job = 'SALESMAN') as range_m
-from "scott".emp
-group by deptno;
-+--------+---------+---------+---------+---------+---------+---------+
-| DEPTNO | C_SAL | C10_SAL | MAX_C | MIN_C | RANGE_C | RANGE_M |
-+--------+---------+---------+---------+---------+---------+---------+
-| 10 | 1300.00 | | 1300.00 | 1300.00 | 0.00 | |
-| 20 | 1900.00 | 1900.00 | 1100.00 | 800.00 | 300.00 | |
-| 30 | 950.00 | 950.00 | 950.00 | 950.00 | 0.00 | 350.00 |
-+--------+---------+---------+---------+---------+---------+---------+
-(3 rows)
-
-!ok
-
-# Aggregate FILTER on condition in GROUP BY
-select deptno,
- sum(sal) filter (where deptno = 10) sal_10
-from "scott".emp
-group by deptno;
-DEPTNO TINYINT(3)
-SAL_10 DECIMAL(7, 2)
-!type
-+--------+---------+
-| DEPTNO | SAL_10 |
-+--------+---------+
-| 10 | 8750.00 |
-| 20 | |
-| 30 | |
-+--------+---------+
-(3 rows)
-
-!ok
-
-# Aggregate FILTER with HAVING
-select deptno
-from "scott".emp
-group by deptno
-having sum(sal) filter (where job = 'CLERK') > 1000;
-+--------+
-| DEPTNO |
-+--------+
-| 10 |
-| 20 |
-+--------+
-(2 rows)
-
-!ok
-
-# Aggregate FILTER with ORDER BY
-select deptno
-from "scott".emp
-group by deptno
-order by sum(sal) filter (where job = 'CLERK');
-+--------+
-| DEPTNO |
-+--------+
-| 30 |
-| 10 |
-| 20 |
-+--------+
-(3 rows)
-
-!ok
-
-# Aggregate FILTER with JOIN
-select dept.deptno,
- sum(sal) filter (where 1 < 2) as s,
- sum(sal) as s1,
- count(*) filter (where emp.ename < dept.dname) as c
-from "scott".emp
-join "scott".dept using (deptno)
-group by dept.deptno;
-+--------+----------+----------+---+
-| DEPTNO | S | S1 | C |
-+--------+----------+----------+---+
-| 10 | 8750.00 | 8750.00 | 0 |
-| 20 | 10875.00 | 10875.00 | 3 |
-| 30 | 9400.00 | 9400.00 | 4 |
-+--------+----------+----------+---+
-(3 rows)
-
-!ok
-
-# Aggregate FILTER with DISTINCT
-select deptno,
- count(distinct job) as cdj
-from "scott".emp
-group by deptno;
-+--------+-----+
-| DEPTNO | CDJ |
-+--------+-----+
-| 10 | 3 |
-| 20 | 3 |
-| 30 | 3 |
-+--------+-----+
-(3 rows)
-
-!ok
-
-select deptno,
- count(distinct job) filter (where job <> 'SALESMAN') as cdj
-from "scott".emp
-group by deptno;
-+--------+-----+
-| DEPTNO | CDJ |
-+--------+-----+
-| 10 | 3 |
-| 20 | 3 |
-| 30 | 2 |
-+--------+-----+
-(3 rows)
-
-!ok
-
-# Multiple distinct count
-select deptno,
- count(distinct job) as j, count(distinct mgr) as m
-from "scott".emp
-group by deptno;
-+--------+---+---+
-| DEPTNO | J | M |
-+--------+---+---+
-| 10 | 3 | 2 |
-| 20 | 3 | 4 |
-| 30 | 3 | 2 |
-+--------+---+---+
-(3 rows)
-
-!ok
-
-# Multiple distinct count and non-distinct aggregates
-select deptno,
- count(distinct job) as dj,
- count(job) as j,
- count(distinct mgr) as m,
- sum(sal) as s
-from "scott".emp
-group by deptno;
-+--------+----+---+---+----------+
-| DEPTNO | DJ | J | M | S |
-+--------+----+---+---+----------+
-| 10 | 3 | 3 | 2 | 8750.00 |
-| 20 | 3 | 5 | 4 | 10875.00 |
-| 30 | 3 | 6 | 2 | 9400.00 |
-+--------+----+---+---+----------+
-(3 rows)
-
-!ok
-
-# Multiple distinct count and non-distinct aggregates, no GROUP BY
-select count(distinct job) as dj,
- count(job) as j,
- count(distinct mgr) as m,
- sum(sal) as s
-from "scott".emp;
-+----+----+---+----------+
-| DJ | J | M | S |
-+----+----+---+----------+
-| 5 | 14 | 6 | 29025.00 |
-+----+----+---+----------+
-(1 row)
-
-!ok
-
-# [CALCITE-280] BigDecimal underflow
-# Previously threw "java.lang.ArithmeticException: Non-terminating decimal
-# expansion; no exact representable decimal result"
-select avg(comm) as a, count(comm) as c from "scott".emp where empno < 7844;
-+-------------------+---+
-| A | C |
-+-------------------+---+
-| 733.3333333333333 | 3 |
-+-------------------+---+
-(1 row)
-
-!ok
-
-# [CALCITE-846] Push aggregate with FILTER through UNION ALL
-select deptno, count(*) filter (where job = 'CLERK') as cf, count(*) as c
-from (
- select * from "scott".emp where deptno < 20
- union all
- select * from "scott".emp where deptno > 20)
-group by deptno;
-+--------+----+---+
-| DEPTNO | CF | C |
-+--------+----+---+
-| 10 | 1 | 3 |
-| 30 | 1 | 6 |
-+--------+----+---+
-(2 rows)
-
-!ok
-EnumerableAggregate(group=[{0}], CF=[COUNT() FILTER $1], C=[COUNT()])
- EnumerableCalc(expr#0..1=[{inputs}], expr#2=['CLERK'], expr#3=[=($t0, $t2)], DEPTNO=[$t1], $f1=[$t3])
- EnumerableUnion(all=[true])
- EnumerableCalc(expr#0..7=[{inputs}], expr#8=[20], expr#9=[<($t7, $t8)], JOB=[$t2], DEPTNO=[$t7], $condition=[$t9])
- EnumerableTableScan(table=[[scott, EMP]])
- EnumerableCalc(expr#0..7=[{inputs}], expr#8=[20], expr#9=[>($t7, $t8)], JOB=[$t2], DEPTNO=[$t7], $condition=[$t9])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# [CALCITE-751] Aggregate join transpose
-select count(*)
-from "scott".emp join "scott".dept using (deptno);
-+--------+
-| EXPR$0 |
-+--------+
-| 14 |
-+--------+
-(1 row)
-
-!ok
-EnumerableAggregate(group=[{}], EXPR$0=[COUNT()])
- EnumerableJoin(condition=[=($0, $2)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# Push sum: splits into sum * count
-select sum(sal)
-from "scott".emp join "scott".dept using (deptno);
-+----------+
-| EXPR$0 |
-+----------+
-| 29025.00 |
-+----------+
-(1 row)
-
-!ok
-EnumerableAggregate(group=[{}], EXPR$0=[SUM($2)])
- EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# Push sum; no aggregate needed after join
-select sum(sal)
-from "scott".emp join "scott".dept using (deptno)
-group by emp.deptno, dept.deptno;
-+----------+
-| EXPR$0 |
-+----------+
-| 10875.00 |
-| 8750.00 |
-| 9400.00 |
-+----------+
-(3 rows)
-
-!ok
-EnumerableCalc(expr#0..2=[{inputs}], EXPR$0=[$t2])
- EnumerableAggregate(group=[{0, 3}], EXPR$0=[SUM($2)])
- EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# Push sum; group by only one of the join keys
-select sum(sal)
-from "scott".emp join "scott".dept using (deptno)
-group by emp.deptno;
-+----------+
-| EXPR$0 |
-+----------+
-| 10875.00 |
-| 8750.00 |
-| 9400.00 |
-+----------+
-(3 rows)
-
-!ok
-EnumerableCalc(expr#0..1=[{inputs}], EXPR$0=[$t1])
- EnumerableAggregate(group=[{3}], EXPR$0=[SUM($2)])
- EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# Push min; Join-Aggregate is optimized to SemiJoin
-select min(sal)
-from "scott".emp join "scott".dept using (deptno)
-group by emp.deptno;
-+---------+
-| EXPR$0 |
-+---------+
-| 1300.00 |
-| 800.00 |
-| 950.00 |
-+---------+
-(3 rows)
-
-!ok
-EnumerableCalc(expr#0..1=[{inputs}], EXPR$0=[$t1])
- EnumerableAggregate(group=[{3}], EXPR$0=[MIN($2)])
- EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# Push sum and count
-select count(*) as c, sum(sal) as s
-from "scott".emp join "scott".dept using (deptno);
-+----+----------+
-| C | S |
-+----+----------+
-| 14 | 29025.00 |
-+----+----------+
-(1 row)
-
-!ok
-EnumerableAggregate(group=[{}], C=[COUNT()], S=[SUM($2)])
- EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# Push sum and count, group by join key
-select count(*) as c, sum(sal) as s
-from "scott".emp join "scott".dept using (deptno) group by emp.deptno;
-+---+----------+
-| C | S |
-+---+----------+
-| 3 | 8750.00 |
-| 5 | 10875.00 |
-| 6 | 9400.00 |
-+---+----------+
-(3 rows)
-
-!ok
-# No aggregate on top, because output of join is unique
-EnumerableCalc(expr#0..2=[{inputs}], C=[$t1], S=[$t2])
- EnumerableAggregate(group=[{3}], C=[COUNT()], S=[SUM($2)])
- EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# Push sum and count, group by join key plus another column
-select count(*) as c, sum(sal) as s
-from "scott".emp join "scott".dept using (deptno) group by emp.job, dept.deptno;
-+---+---------+
-| C | S |
-+---+---------+
-| 1 | 1300.00 |
-| 1 | 2450.00 |
-| 1 | 2850.00 |
-| 1 | 2975.00 |
-| 1 | 5000.00 |
-| 1 | 950.00 |
-| 2 | 1900.00 |
-| 2 | 6000.00 |
-| 4 | 5600.00 |
-+---+---------+
-(9 rows)
-
-!ok
-EnumerableCalc(expr#0..3=[{inputs}], C=[$t2], S=[$t3])
- EnumerableAggregate(group=[{0, 2}], C=[COUNT()], S=[SUM($3)])
- EnumerableJoin(condition=[=($0, $4)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], JOB=[$t2], SAL=[$t5], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# Push sum and count, group by non-join column
-select count(*) as c, sum(sal) as s
-from "scott".emp join "scott".dept using (deptno) group by emp.job;
-+---+---------+
-| C | S |
-+---+---------+
-| 1 | 5000.00 |
-| 2 | 6000.00 |
-| 3 | 8275.00 |
-| 4 | 4150.00 |
-| 4 | 5600.00 |
-+---+---------+
-(5 rows)
-
-!ok
-EnumerableCalc(expr#0..2=[{inputs}], C=[$t1], S=[$t2])
- EnumerableAggregate(group=[{2}], C=[COUNT()], S=[SUM($3)])
- EnumerableJoin(condition=[=($0, $4)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], JOB=[$t2], SAL=[$t5], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# Push count and sum, group by superset of join key
-select count(*) as c, sum(sal) as s
-from "scott".emp join "scott".dept using (deptno) group by emp.job, dept.deptno;
-+---+---------+
-| C | S |
-+---+---------+
-| 1 | 5000.00 |
-| 2 | 6000.00 |
-| 4 | 5600.00 |
-| 1 | 1300.00 |
-| 1 | 2450.00 |
-| 1 | 2850.00 |
-| 1 | 2975.00 |
-| 1 | 950.00 |
-| 2 | 1900.00 |
-+---+---------+
-(9 rows)
-
-!ok
-EnumerableCalc(expr#0..3=[{inputs}], C=[$t2], S=[$t3])
- EnumerableAggregate(group=[{0, 2}], C=[COUNT()], S=[SUM($3)])
- EnumerableJoin(condition=[=($0, $4)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], JOB=[$t2], SAL=[$t5], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# Push count and sum, group by a column being aggregated
-select count(*) as c, sum(sal) as s
-from "scott".emp join "scott".dept using (deptno) group by emp.sal;
-+---+---------+
-| C | S |
-+---+---------+
-| 1 | 5000.00 |
-| 2 | 6000.00 |
-| 1 | 1100.00 |
-| 1 | 1300.00 |
-| 1 | 1500.00 |
-| 1 | 1600.00 |
-| 1 | 2450.00 |
-| 1 | 2850.00 |
-| 1 | 2975.00 |
-| 1 | 800.00 |
-| 1 | 950.00 |
-| 2 | 2500.00 |
-+---+---------+
-(12 rows)
-
-!ok
-EnumerableCalc(expr#0..2=[{inputs}], C=[$t1], S=[$t2])
- EnumerableAggregate(group=[{2}], C=[COUNT()], S=[SUM($2)])
- EnumerableJoin(condition=[=($0, $3)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# Push sum, self-join, returning one row with a null value
-select sum(e.sal) as s
-from "scott".emp e join "scott".emp m on e.mgr = e.empno;
-+---+
-| S |
-+---+
-| |
-+---+
-(1 row)
-
-!ok
-
-# Push sum, self-join
-select sum(e.sal) as s
-from "scott".emp e join "scott".emp m on e.mgr = m.empno;
-+----------+
-| S |
-+----------+
-| 24025.00 |
-+----------+
-(1 row)
-
-!ok
-
-# Push sum, self-join, cartesian product over nullable and non-nullable columns
-select sum(e.sal) as ss, count(e.sal) as cs, count(e.mgr) as cm
-from "scott".emp e
-join "scott".emp m on e.deptno = m.deptno
-group by e.deptno, m.deptno;
-+----------+----+----+
-| SS | CS | CM |
-+----------+----+----+
-| 26250.00 | 9 | 6 |
-| 54375.00 | 25 | 25 |
-| 56400.00 | 36 | 36 |
-+----------+----+----+
-(3 rows)
-
-!ok
-
-# Push sum, self-join, aggregate by column on "many" side
-select sum(e.sal) as s
-from "scott".emp e join "scott".emp m on e.mgr = m.empno
-group by m.empno;
-+---------+
-| S |
-+---------+
-| 1100.00 |
-| 1300.00 |
-| 6000.00 |
-| 6550.00 |
-| 800.00 |
-| 8275.00 |
-+---------+
-(6 rows)
-
-!ok
-
-# Push sum, self-join, aggregate by column on "one" side.
-# Note inflated totals due to cartesian product.
-select sum(m.sal) as s
-from "scott".emp e join "scott".emp m on e.mgr = m.empno
-group by m.empno;
-+----------+
-| S |
-+----------+
-| 14250.00 |
-| 15000.00 |
-| 2450.00 |
-| 3000.00 |
-| 3000.00 |
-| 5950.00 |
-+----------+
-(6 rows)
-
-!ok
-
-# Collation of LogicalAggregate ([CALCITE-783] and [CALCITE-822])
-select sum(x) as sum_cnt,
- count(distinct y) as cnt_dist
-from
- (
- select
- count(*) as x,
- t1.job as y,
- t1.deptno as z
- from
- "scott".emp t1
- group by t1.job, t1.deptno
- order by t1.job, t1.deptno
-) sq(x,y,z)
-group by z
-order by sum_cnt;
-
-+---------+----------+
-| SUM_CNT | CNT_DIST |
-+---------+----------+
-| 3 | 3 |
-| 5 | 3 |
-| 6 | 3 |
-+---------+----------+
-(3 rows)
-
-!ok
-
-# [CALCITE-938] Aggregate row count
-select empno, d.deptno
-from "scott".emp
-join (select distinct deptno from "scott".dept) d
-using (deptno);
-+-------+--------+
-| EMPNO | DEPTNO |
-+-------+--------+
-| 7369 | 20 |
-| 7499 | 30 |
-| 7521 | 30 |
-| 7566 | 20 |
-| 7654 | 30 |
-| 7698 | 30 |
-| 7782 | 10 |
-| 7788 | 20 |
-| 7839 | 10 |
-| 7844 | 30 |
-| 7876 | 20 |
-| 7900 | 30 |
-| 7902 | 20 |
-| 7934 | 10 |
-+-------+--------+
-(14 rows)
-
-!ok
-EnumerableCalc(expr#0..2=[{inputs}], EMPNO=[$t1], DEPTNO=[$t0])
- EnumerableJoin(condition=[=($0, $2)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# [CALCITE-729] IndexOutOfBoundsException in ROLLUP query on JDBC data source
-!use jdbc_scott
-select deptno, job, count(*) as c
-from jdbc_scott.emp
-group by rollup (deptno, job)
-order by 1, 2;
-+--------+-----------+----+
-| DEPTNO | JOB | C |
-+--------+-----------+----+
-| 10 | CLERK | 1 |
-| 10 | MANAGER | 1 |
-| 10 | PRESIDENT | 1 |
-| 10 | | 3 |
-| 20 | ANALYST | 2 |
-| 20 | CLERK | 2 |
-| 20 | MANAGER | 1 |
-| 20 | | 5 |
-| 30 | CLERK | 1 |
-| 30 | MANAGER | 1 |
-| 30 | SALESMAN | 4 |
-| 30 | | 6 |
-| | | 14 |
-+--------+-----------+----+
-(13 rows)
-
-!ok
-
-# [CALCITE-799] Incorrect result for "HAVING count(*) > 1"
-select d.deptno, min(e.empid) as empid
-from (values (100, 'Bill', 1),
- (200, 'Eric', 1),
- (150, 'Sebastian', 3)) as e(empid, name, deptno)
-join (values (1, 'LeaderShip'),
- (2, 'TestGroup'),
- (3, 'Development')) as d(deptno, name)
-on e.deptno = d.deptno
-group by d.deptno
-having count(*) > 1;
-+--------+-------+
-| DEPTNO | EMPID |
-+--------+-------+
-| 1 | 100 |
-+--------+-------+
-(1 row)
-
-!ok
-
-# Same, using USING (combining [CALCITE-799] and [CALCITE-801])
-select d.deptno, min(e.empid) as empid
-from (values (100, 'Bill', 1),
- (200, 'Eric', 1),
- (150, 'Sebastian', 3)) as e(empid, name, deptno)
-join (values (1, 'LeaderShip'),
- (2, 'TestGroup'),
- (3, 'Development')) as d(deptno, name)
-using (deptno)
-group by d.deptno
-having count(*) > 1;
-+--------+-------+
-| DEPTNO | EMPID |
-+--------+-------+
-| 1 | 100 |
-+--------+-------+
-(1 row)
-
-!ok
-
-# [CALCITE-886] System functions in the GROUP BY clause
-# Calls to system functions do not have "()", which may confuse the validator.
-select CURRENT_USER as CUSER
-from jdbc_scott.emp
-group by CURRENT_USER;
-+-------+
-| CUSER |
-+-------+
-| SCOTT |
-+-------+
-(1 row)
-
-!ok
-
-# [CALCITE-886] System functions in the GROUP BY clause
-# System function inside a GROUPING SETS.
-select CURRENT_USER as CUSER
-from jdbc_scott.emp
-group by grouping sets(CURRENT_USER);
-+-------+
-| CUSER |
-+-------+
-| SCOTT |
-+-------+
-(1 row)
-
-!ok
-
-# End agg.oq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/conditions.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/conditions.iq b/core/src/test/resources/sql/conditions.iq
new file mode 100644
index 0000000..bc565af
--- /dev/null
+++ b/core/src/test/resources/sql/conditions.iq
@@ -0,0 +1,261 @@
+# conditions.iq - conditions
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+!use catchall
+!set outputformat mysql
+
+# OR test
+
+with tmp(a, b) as (
+ values (1, 1), (1, 0), (1, cast(null as int))
+ , (0, 1), (0, 0), (0, cast(null as int))
+ , (cast(null as int), 1), (cast(null as int), 0), (cast(null as int), cast(null as int)))
+select *
+ from tmp
+ where a = 1 or b = 1
+ order by 1, 2;
+
++---+---+
+| A | B |
++---+---+
+| 0 | 1 |
+| 1 | 0 |
+| 1 | 1 |
+| 1 | |
+| | 1 |
++---+---+
+(5 rows)
+
+!ok
+
+with tmp(a, b) as (
+ values (1, 1), (1, 0), (1, cast(null as int))
+ , (0, 1), (0, 0), (0, cast(null as int))
+ , (cast(null as int), 1), (cast(null as int), 0), (cast(null as int), cast(null as int)))
+select *
+ from tmp
+ where not (a = 1 or b = 1)
+ order by 1, 2;
+
++---+---+
+| A | B |
++---+---+
+| 0 | 0 |
++---+---+
+(1 row)
+
+!ok
+
+# AND test
+
+with tmp(a, b) as (
+ values (1, 1), (1, 0), (1, cast(null as int))
+ , (0, 1), (0, 0), (0, cast(null as int))
+ , (cast(null as int), 1), (cast(null as int), 0), (cast(null as int), cast(null as int)))
+select *
+ from tmp
+ where a = 1 AND b = 1
+ order by 1, 2;
+
++---+---+
+| A | B |
++---+---+
+| 1 | 1 |
++---+---+
+(1 row)
+
+!ok
+
+with tmp(a, b) as (
+ values (1, 1), (1, 0), (1, cast(null as int))
+ , (0, 1), (0, 0), (0, cast(null as int))
+ , (cast(null as int), 1), (cast(null as int), 0), (cast(null as int), cast(null as int)))
+select *
+ from tmp
+ where not (a = 1 AND b = 1)
+ order by 1, 2;
+
++---+---+
+| A | B |
++---+---+
+| 0 | 0 |
+| 0 | 1 |
+| 0 | |
+| 1 | 0 |
+| | 0 |
++---+---+
+(5 rows)
+
+!ok
+
+# Test cases for CALCITE-980
+
+select "value" from "nullables" a where "value" = 'A' or "value" = 'B' order by 1;
+
++-------+
+| value |
++-------+
+| A |
+| B |
++-------+
+(2 rows)
+
+!ok
+
+select "value" from "nullables" a where not ("value" = 'A' or "value" = 'B') order by 1;
+
++-------+
+| value |
++-------+
+| C |
++-------+
+(1 row)
+
+!ok
+
+select "value" from "nullables" a where not (not ("value" = 'A' or "value" = 'B')) order by 1;
+
++-------+
+| value |
++-------+
+| A |
+| B |
++-------+
+(2 rows)
+
+!ok
+
+select "value" from "nullables" a where "value" = 'A' and "value" = 'B' order by 1;
+
++-------+
+| value |
++-------+
++-------+
+(0 rows)
+
+!ok
+
+select "value" from "nullables" a where not ("value" = 'A' and "value" = 'B') order by 1;
+
++-------+
+| value |
++-------+
+| A |
+| B |
+| C |
++-------+
+(3 rows)
+
+!ok
+
+select "value" from "nullables" a where not (not ("value" = 'A' and "value" = 'B')) order by 1;
+
++-------+
+| value |
++-------+
++-------+
+(0 rows)
+
+!ok
+
+select "value" from "nullables" a
+ where case when not ("value" = 'A' or "value" = 'B') then 1 else 0 end = 1
+ order by 1;
+
++-------+
+| value |
++-------+
+| C |
++-------+
+(1 row)
+
+!ok
+
+select "value" from "nullables" a
+ where
+ case when not ("value"='A' or "value"='B')
+ then
+ case when ("value"='A' or "value"='B') then 1 else 2 end
+ else 0
+ end = 2
+ order by 1;
+
++-------+
+| value |
++-------+
+| C |
++-------+
+(1 row)
+
+!ok
+
+select "value" from "nullables" a
+ where
+ case when not ("value"='A' or "value"='B')
+ then
+ case when not /* <--diff from above */ ("value"='A' or "value"='B') then 1 else 2 end
+ else 0
+ end = 1 /* <- diff from above*/
+ order by 1;
+
++-------+
+| value |
++-------+
+| C |
++-------+
+(1 row)
+
+!ok
+
+select "value" from "nullables" a
+ where
+ case when not ("value"='A' or "value"='B')
+ then
+ case when not ("value"='A' or "value"='B') then 1 else 2 end
+ else 0
+ end = 0 /* <- diff from above*/
+ order by 1;
+
++-------+
+| value |
++-------+
+| A |
+| B |
+| |
++-------+
+(3 rows)
+
+!ok
+
+select "value" from "nullables" a
+ where
+ case when not ("value"='A' or "value"='B')
+ then
+ case when not ("value"='A' or "value"='B') then 1 else 2 end
+ else 0
+ end = 2 /* <- diff from above*/
+ order by 1;
+
++-------+
+| value |
++-------+
++-------+
+(0 rows)
+
+!ok
+
+# End conditions.iq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/conditions.oq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/conditions.oq b/core/src/test/resources/sql/conditions.oq
deleted file mode 100644
index f7d7f51..0000000
--- a/core/src/test/resources/sql/conditions.oq
+++ /dev/null
@@ -1,259 +0,0 @@
-# conditions.oq - conditions
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to you under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-!use catchall
-!set outputformat mysql
-
-# OR test
-
-with tmp(a, b) as (
- values (1, 1), (1, 0), (1, cast(null as int))
- , (0, 1), (0, 0), (0, cast(null as int))
- , (cast(null as int), 1), (cast(null as int), 0), (cast(null as int), cast(null as int)))
-select *
- from tmp
- where a = 1 or b = 1
- order by 1, 2;
-
-+---+---+
-| A | B |
-+---+---+
-| 0 | 1 |
-| 1 | 0 |
-| 1 | 1 |
-| 1 | |
-| | 1 |
-+---+---+
-(5 rows)
-
-!ok
-
-with tmp(a, b) as (
- values (1, 1), (1, 0), (1, cast(null as int))
- , (0, 1), (0, 0), (0, cast(null as int))
- , (cast(null as int), 1), (cast(null as int), 0), (cast(null as int), cast(null as int)))
-select *
- from tmp
- where not (a = 1 or b = 1)
- order by 1, 2;
-
-+---+---+
-| A | B |
-+---+---+
-| 0 | 0 |
-+---+---+
-(1 row)
-
-!ok
-
-# AND test
-
-with tmp(a, b) as (
- values (1, 1), (1, 0), (1, cast(null as int))
- , (0, 1), (0, 0), (0, cast(null as int))
- , (cast(null as int), 1), (cast(null as int), 0), (cast(null as int), cast(null as int)))
-select *
- from tmp
- where a = 1 AND b = 1
- order by 1, 2;
-
-+---+---+
-| A | B |
-+---+---+
-| 1 | 1 |
-+---+---+
-(1 row)
-
-!ok
-
-with tmp(a, b) as (
- values (1, 1), (1, 0), (1, cast(null as int))
- , (0, 1), (0, 0), (0, cast(null as int))
- , (cast(null as int), 1), (cast(null as int), 0), (cast(null as int), cast(null as int)))
-select *
- from tmp
- where not (a = 1 AND b = 1)
- order by 1, 2;
-
-+---+---+
-| A | B |
-+---+---+
-| 0 | 0 |
-| 0 | 1 |
-| 0 | |
-| 1 | 0 |
-| | 0 |
-+---+---+
-(5 rows)
-
-!ok
-
-# Test cases for CALCITE-980
-
-select "value" from "nullables" a where "value" = 'A' or "value" = 'B' order by 1;
-
-+-------+
-| value |
-+-------+
-| A |
-| B |
-+-------+
-(2 rows)
-
-!ok
-
-select "value" from "nullables" a where not ("value" = 'A' or "value" = 'B') order by 1;
-
-+-------+
-| value |
-+-------+
-| C |
-+-------+
-(1 row)
-
-!ok
-
-select "value" from "nullables" a where not (not ("value" = 'A' or "value" = 'B')) order by 1;
-
-+-------+
-| value |
-+-------+
-| A |
-| B |
-+-------+
-(2 rows)
-
-!ok
-
-select "value" from "nullables" a where "value" = 'A' and "value" = 'B' order by 1;
-
-+-------+
-| value |
-+-------+
-+-------+
-(0 rows)
-
-!ok
-
-select "value" from "nullables" a where not ("value" = 'A' and "value" = 'B') order by 1;
-
-+-------+
-| value |
-+-------+
-| A |
-| B |
-| C |
-+-------+
-(3 rows)
-
-!ok
-
-select "value" from "nullables" a where not (not ("value" = 'A' and "value" = 'B')) order by 1;
-
-+-------+
-| value |
-+-------+
-+-------+
-(0 rows)
-
-!ok
-
-select "value" from "nullables" a
- where case when not ("value" = 'A' or "value" = 'B') then 1 else 0 end = 1
- order by 1;
-
-+-------+
-| value |
-+-------+
-| C |
-+-------+
-(1 row)
-
-!ok
-
-select "value" from "nullables" a
- where
- case when not ("value"='A' or "value"='B')
- then
- case when ("value"='A' or "value"='B') then 1 else 2 end
- else 0
- end = 2
- order by 1;
-
-+-------+
-| value |
-+-------+
-| C |
-+-------+
-(1 row)
-
-!ok
-
-select "value" from "nullables" a
- where
- case when not ("value"='A' or "value"='B')
- then
- case when not /* <--diff from above */ ("value"='A' or "value"='B') then 1 else 2 end
- else 0
- end = 1 /* <- diff from above*/
- order by 1;
-
-+-------+
-| value |
-+-------+
-| C |
-+-------+
-(1 row)
-
-!ok
-
-select "value" from "nullables" a
- where
- case when not ("value"='A' or "value"='B')
- then
- case when not ("value"='A' or "value"='B') then 1 else 2 end
- else 0
- end = 0 /* <- diff from above*/
- order by 1;
-
-+-------+
-| value |
-+-------+
-| A |
-| B |
-| |
-+-------+
-(3 rows)
-
-!ok
-
-select "value" from "nullables" a
- where
- case when not ("value"='A' or "value"='B')
- then
- case when not ("value"='A' or "value"='B') then 1 else 2 end
- else 0
- end = 2 /* <- diff from above*/
- order by 1;
-
-+-------+
-| value |
-+-------+
-+-------+
-(0 rows)
-
-!ok
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/dummy.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/dummy.iq b/core/src/test/resources/sql/dummy.iq
new file mode 100644
index 0000000..166e1b0
--- /dev/null
+++ b/core/src/test/resources/sql/dummy.iq
@@ -0,0 +1,23 @@
+# dummy.iq - Scratch space
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+!use post
+values 1;
+EXPR$0
+1
+!ok
+# End dummy.iq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/dummy.oq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/dummy.oq b/core/src/test/resources/sql/dummy.oq
deleted file mode 100644
index 10c37d5..0000000
--- a/core/src/test/resources/sql/dummy.oq
+++ /dev/null
@@ -1,23 +0,0 @@
-# dummy.oq - Scratch space
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to you under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-!use post
-values 1;
-EXPR$0
-1
-!ok
-# End dummy.oq
[2/7] calcite git commit: [CALCITE-1022] Rename ".oq" Quidem files to
".iq"
Posted by jh...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/misc.oq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/misc.oq b/core/src/test/resources/sql/misc.oq
deleted file mode 100644
index aa55654..0000000
--- a/core/src/test/resources/sql/misc.oq
+++ /dev/null
@@ -1,1111 +0,0 @@
-# misc.oq - Miscellaneous queries
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to you under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-!use post
-!set outputformat mysql
-
-# [CALCITE-356] Allow column references of the form schema.table.column
-select "hr"."emps"."empid"
-from "hr"."emps";
-+-------+
-| empid |
-+-------+
-| 100 |
-| 110 |
-| 150 |
-| 200 |
-+-------+
-(4 rows)
-
-!ok
-
-# [CALCITE-881] Allow schema.table.column references in GROUP BY
-select "hr"."emps"."empid", count(*) as c
-from "hr"."emps"
-group by "hr"."emps"."empid";
-+-------+---+
-| empid | C |
-+-------+---+
-| 100 | 1 |
-| 110 | 1 |
-| 150 | 1 |
-| 200 | 1 |
-+-------+---+
-(4 rows)
-
-!ok
-
-select distinct "hr"."emps"."empid" + 1 as e
-from "hr"."emps"
-group by "hr"."emps"."empid";
-+-----+
-| E |
-+-----+
-| 101 |
-| 111 |
-| 151 |
-| 201 |
-+-----+
-(4 rows)
-
-!ok
-
-# [CALCITE-307] CAST(timestamp AS DATE) gives ClassCastException
-# Based on [DRILL-1051]
-with data(c_row, c_timestamp) as (select * from (values
- (1, TIMESTAMP '1997-01-02 03:04:05'),
- (2, TIMESTAMP '1997-01-02 00:00:00'),
- (3, TIMESTAMP '2001-09-22 18:19:20'),
- (4, TIMESTAMP '1997-02-10 17:32:01'),
- (5, TIMESTAMP '1997-02-10 17:32:00'),
- (6, TIMESTAMP '1997-02-11 17:32:01'),
- (7, TIMESTAMP '1997-02-12 17:32:01'),
- (8, TIMESTAMP '1997-02-13 17:32:01'),
- (9, TIMESTAMP '1997-02-14 17:32:01'),
- (10, TIMESTAMP '1997-02-15 17:32:01'),
- (11, TIMESTAMP '1997-02-16 17:32:01'),
- (13, TIMESTAMP '0097-02-16 17:32:01'),
- (14, TIMESTAMP '0597-02-16 17:32:01'),
- (15, TIMESTAMP '1097-02-16 17:32:01'),
- (16, TIMESTAMP '1697-02-16 17:32:01'),
- (17, TIMESTAMP '1797-02-16 17:32:01'),
- (18, TIMESTAMP '1897-02-16 17:32:01'),
- (19, TIMESTAMP '1997-02-16 17:32:01'),
- (20, TIMESTAMP '2097-02-16 17:32:01'),
- (21, TIMESTAMP '1996-02-28 17:32:01'),
- (22, TIMESTAMP '1996-02-29 17:32:01'),
- (23, TIMESTAMP '1996-03-01 17:32:01')))
-select cast(c_timestamp as varchar(20)), cast(c_timestamp as date) from data where c_row <> 12;
-
-+---------------------+------------+
-| EXPR$0 | EXPR$1 |
-+---------------------+------------+
-| 1997-01-02 03:04:05 | 1997-01-02 |
-| 1997-01-02 00:00:00 | 1997-01-02 |
-| 2001-09-22 18:19:20 | 2001-09-22 |
-| 1997-02-10 17:32:01 | 1997-02-10 |
-| 1997-02-10 17:32:00 | 1997-02-10 |
-| 1997-02-11 17:32:01 | 1997-02-11 |
-| 1997-02-12 17:32:01 | 1997-02-12 |
-| 1997-02-13 17:32:01 | 1997-02-13 |
-| 1997-02-14 17:32:01 | 1997-02-14 |
-| 1997-02-15 17:32:01 | 1997-02-15 |
-| 1997-02-16 17:32:01 | 1997-02-16 |
-| 0097-02-14 17:32:01 | 0097-02-14 |
-| 0597-02-18 17:32:01 | 0597-02-18 |
-| 1097-02-22 17:32:01 | 1097-02-22 |
-| 1697-02-16 17:32:01 | 1697-02-16 |
-| 1797-02-16 17:32:01 | 1797-02-16 |
-| 1897-02-16 17:32:01 | 1897-02-16 |
-| 1997-02-16 17:32:01 | 1997-02-16 |
-| 2097-02-16 17:32:01 | 2097-02-16 |
-| 1996-02-28 17:32:01 | 1996-02-28 |
-| 1996-02-29 17:32:01 | 1996-02-29 |
-| 1996-03-01 17:32:01 | 1996-03-01 |
-+---------------------+------------+
-(22 rows)
-
-!ok
-
-# [DRILL-1149]
-select *, upper("name")
-from "hr"."emps";
-+-------+--------+-----------+---------+------------+-----------+
-| empid | deptno | name | salary | commission | EXPR$5 |
-+-------+--------+-----------+---------+------------+-----------+
-| 100 | 10 | Bill | 10000.0 | 1000 | BILL |
-| 110 | 10 | Theodore | 11500.0 | 250 | THEODORE |
-| 150 | 10 | Sebastian | 7000.0 | | SEBASTIAN |
-| 200 | 20 | Eric | 8000.0 | 500 | ERIC |
-+-------+--------+-----------+---------+------------+-----------+
-(4 rows)
-
-!ok
-
-# [DRILL-1199] Order by nested inside a where clause fails
-# (Not that it's right, but Tableau does it.)
-select * from (select * from "hr"."emps" order by "empid") where (0=1);
-+-------+--------+------+--------+------------+
-| empid | deptno | name | salary | commission |
-+-------+--------+------+--------+------------+
-+-------+--------+------+--------+------------+
-(0 rows)
-
-!ok
-
-# [DRILL-1842] Tableau, again
-select count(distinct "salary") as c
-from "hr"."emps"
-join "hr"."depts" on "emps"."deptno" = "depts"."deptno"
-having count(1) > 0;
-+---+
-| C |
-+---+
-| 3 |
-+---+
-(1 row)
-
-!ok
-
-# [CALCITE-340] SqlToRelConverter fails with complex join condition
-select e."deptno", d."deptno"
-from "hr"."emps" as e
-join "hr"."depts" as d
-on ( e."deptno" + 1 - 1 = d."deptno" + 2 - 2 and e."deptno" + 10 - 10 = d."deptno" + 20 - 20);
-+--------+--------+
-| deptno | deptno |
-+--------+--------+
-| 10 | 10 |
-| 10 | 10 |
-| 10 | 10 |
-+--------+--------+
-(3 rows)
-
-!ok
-
-# [CALCITE-340] SqlToRelConverter fails with complex join condition. Switch LHS and RHS.
-select e."deptno", d."deptno"
-from "hr"."emps" as e
-join "hr"."depts" as d
-on ( d."deptno" + 2 - 2 = e."deptno" + 1 - 1 and d."deptno" + 20 - 20 = e."deptno" + 10 - 10);
-+--------+--------+
-| deptno | deptno |
-+--------+--------+
-| 10 | 10 |
-| 10 | 10 |
-| 10 | 10 |
-+--------+--------+
-(3 rows)
-
-!ok
-
-# [CALCITE-340] SqlToRelConverter fails with complex join condition. Switch LHS and RHS.
-select e."deptno", d."deptno"
-from "hr"."emps" as e
-join "hr"."depts" as d
-on ( d."deptno" + 2 - 2 = e."deptno" + 1 - 1 and e."deptno" + 10 - 10 = d."deptno" + 20 - 20);
-+--------+--------+
-| deptno | deptno |
-+--------+--------+
-| 10 | 10 |
-| 10 | 10 |
-| 10 | 10 |
-+--------+--------+
-(3 rows)
-
-!ok
-
-# [CALCITE-377] Mixed equi and non-equi join
-select e."empid", d."name", e."name"
-from "hr"."emps" as e
-join "hr"."depts" as d
-on e."deptno" = d."deptno"
-and e."name" <> d."name";
-+-------+-------+-----------+
-| empid | name | name |
-+-------+-------+-----------+
-| 100 | Sales | Bill |
-| 110 | Sales | Theodore |
-| 150 | Sales | Sebastian |
-+-------+-------+-----------+
-(3 rows)
-
-!ok
-EnumerableCalc(expr#0..4=[{inputs}], expr#5=[CAST($t2):VARCHAR(1) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary"], expr#6=[CAST($t4):VARCHAR(1) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary"], expr#7=[<>($t5, $t6)], empid=[$t0], name=[$t4], name0=[$t2], $condition=[$t7])
- EnumerableJoin(condition=[=($1, $3)], joinType=[inner])
- EnumerableCalc(expr#0..4=[{inputs}], proj#0..2=[{exprs}])
- EnumerableTableScan(table=[[hr, emps]])
- EnumerableCalc(expr#0..3=[{inputs}], proj#0..1=[{exprs}])
- EnumerableTableScan(table=[[hr, depts]])
-!plan
-
-# Same query, expressed using WHERE.
-select e."empid", d."name", e."name"
-from "hr"."emps" as e,
- "hr"."depts" as d
-where e."deptno" = d."deptno"
-and e."name" <> d."name";
-+-------+-------+-----------+
-| empid | name | name |
-+-------+-------+-----------+
-| 100 | Sales | Bill |
-| 110 | Sales | Theodore |
-| 150 | Sales | Sebastian |
-+-------+-------+-----------+
-(3 rows)
-
-!ok
-EnumerableCalc(expr#0..4=[{inputs}], expr#5=[CAST($t2):VARCHAR(1) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary"], expr#6=[CAST($t4):VARCHAR(1) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary"], expr#7=[<>($t5, $t6)], empid=[$t0], name=[$t4], name0=[$t2], $condition=[$t7])
- EnumerableJoin(condition=[=($1, $3)], joinType=[inner])
- EnumerableCalc(expr#0..4=[{inputs}], proj#0..2=[{exprs}])
- EnumerableTableScan(table=[[hr, emps]])
- EnumerableCalc(expr#0..3=[{inputs}], proj#0..1=[{exprs}])
- EnumerableTableScan(table=[[hr, depts]])
-!plan
-
-# EXISTS
-select * from "hr"."emps"
-where exists (
- select 1 from "hr"."depts" where "depts"."deptno" = "emps"."deptno");
-+-------+--------+-----------+---------+------------+
-| empid | deptno | name | salary | commission |
-+-------+--------+-----------+---------+------------+
-| 100 | 10 | Bill | 10000.0 | 1000 |
-| 110 | 10 | Theodore | 11500.0 | 250 |
-| 150 | 10 | Sebastian | 7000.0 | |
-+-------+--------+-----------+---------+------------+
-(3 rows)
-
-!ok
-EnumerableSemiJoin(condition=[=($1, $5)], joinType=[inner])
- EnumerableTableScan(table=[[hr, emps]])
- EnumerableCalc(expr#0..4=[{inputs}], expr#5=[true], deptno0=[$t0], $f0=[$t5])
- EnumerableJoin(condition=[=($0, $1)], joinType=[inner])
- EnumerableAggregate(group=[{1}])
- EnumerableTableScan(table=[[hr, emps]])
- EnumerableTableScan(table=[[hr, depts]])
-!plan
-
-# NOT EXISTS
-# Right results, but it would be better if the plan used EnumerableSemiJoinRel; see [CALCITE-374]
-select * from "hr"."emps"
-where not exists (
- select 1 from "hr"."depts" where "depts"."deptno" = "emps"."deptno");
-+-------+--------+------+--------+------------+
-| empid | deptno | name | salary | commission |
-+-------+--------+------+--------+------------+
-| 200 | 20 | Eric | 8000.0 | 500 |
-+-------+--------+------+--------+------------+
-(1 row)
-
-!ok
-EnumerableCalc(expr#0..6=[{inputs}], expr#7=[IS NOT NULL($t6)], expr#8=[NOT($t7)], proj#0..4=[{exprs}], $condition=[$t8])
- EnumerableJoin(condition=[=($1, $5)], joinType=[left])
- EnumerableTableScan(table=[[hr, emps]])
- EnumerableAggregate(group=[{1}], agg#0=[MIN($0)])
- EnumerableCalc(expr#0..4=[{inputs}], expr#5=[true], $f0=[$t5], deptno0=[$t0])
- EnumerableJoin(condition=[=($0, $1)], joinType=[inner])
- EnumerableAggregate(group=[{1}])
- EnumerableTableScan(table=[[hr, emps]])
- EnumerableTableScan(table=[[hr, depts]])
-!plan
-
-# NOT EXISTS .. OR NOT EXISTS
-# Right results, but it would be better if the plan used EnumerableSemiJoinRel; see [CALCITE-374]
-select * from "hr"."emps"
-where not exists (
- select 1 from "hr"."depts" where "depts"."deptno" = "emps"."deptno")
-or not exists (
- select 1 from "hr"."depts" where "depts"."deptno" + 90 = "emps"."empid");
-
-+-------+--------+-----------+---------+------------+
-| empid | deptno | name | salary | commission |
-+-------+--------+-----------+---------+------------+
-| 110 | 10 | Theodore | 11500.0 | 250 |
-| 150 | 10 | Sebastian | 7000.0 | |
-| 200 | 20 | Eric | 8000.0 | 500 |
-+-------+--------+-----------+---------+------------+
-(3 rows)
-
-!ok
-EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NOT NULL($t5)], expr#9=[NOT($t8)], expr#10=[IS NOT NULL($t7)], expr#11=[NOT($t10)], expr#12=[OR($t9, $t11)], proj#0..4=[{exprs}], $condition=[$t12])
- EnumerableJoin(condition=[=($0, $6)], joinType=[left])
- EnumerableCalc(expr#0..6=[{inputs}], proj#0..4=[{exprs}], $f0=[$t6])
- EnumerableJoin(condition=[=($1, $5)], joinType=[left])
- EnumerableTableScan(table=[[hr, emps]])
- EnumerableAggregate(group=[{1}], agg#0=[MIN($0)])
- EnumerableCalc(expr#0..4=[{inputs}], expr#5=[true], $f0=[$t5], deptno0=[$t0])
- EnumerableJoin(condition=[=($0, $1)], joinType=[inner])
- EnumerableAggregate(group=[{1}])
- EnumerableTableScan(table=[[hr, emps]])
- EnumerableTableScan(table=[[hr, depts]])
- EnumerableAggregate(group=[{1}], agg#0=[MIN($0)])
- EnumerableCalc(expr#0..6=[{inputs}], expr#7=[true], $f0=[$t7], empid=[$t0])
- EnumerableJoin(condition=[=($1, $6)], joinType=[inner])
- EnumerableCalc(expr#0=[{inputs}], expr#1=[CAST($t0):INTEGER NOT NULL], proj#0..1=[{exprs}])
- EnumerableAggregate(group=[{0}])
- EnumerableSemiJoin(condition=[=($1, $6)], joinType=[inner])
- EnumerableTableScan(table=[[hr, emps]])
- EnumerableCalc(expr#0..4=[{inputs}], expr#5=[true], $f0=[$t5], deptno0=[$t0])
- EnumerableJoin(condition=[=($0, $1)], joinType=[inner])
- EnumerableAggregate(group=[{1}])
- EnumerableTableScan(table=[[hr, emps]])
- EnumerableTableScan(table=[[hr, depts]])
- EnumerableCalc(expr#0..3=[{inputs}], expr#4=[90], expr#5=[+($t0, $t4)], proj#0..3=[{exprs}], $f4=[$t5])
- EnumerableTableScan(table=[[hr, depts]])
-!plan
-
-# Filter combined with an OR filter.
-select * from (
- select * from "hr"."emps" as e
- where e."deptno" < 30) as e
-where e."deptno" > 10 or e."name" = 'Sebastian';
-+-------+--------+-----------+--------+------------+
-| empid | deptno | name | salary | commission |
-+-------+--------+-----------+--------+------------+
-| 150 | 10 | Sebastian | 7000.0 | |
-| 200 | 20 | Eric | 8000.0 | 500 |
-+-------+--------+-----------+--------+------------+
-(2 rows)
-
-!ok
-
-# Filter combined with an AND filter. Test case for
-# [CALCITE-389] MergeFilterRule should flatten AND condition
-select * from (
- select * from "hr"."emps" as e
- where e."deptno" < 30) as e
-where e."deptno" >= 10 and e."name" = 'Sebastian';
-+-------+--------+-----------+--------+------------+
-| empid | deptno | name | salary | commission |
-+-------+--------+-----------+--------+------------+
-| 150 | 10 | Sebastian | 7000.0 | |
-+-------+--------+-----------+--------+------------+
-(1 row)
-
-!ok
-
-# [CALCITE-393] If no fields are projected from a table, field trimmer should
-# project a dummy expression
-select 1 from "hr"."emps";
-+--------+
-| EXPR$0 |
-+--------+
-| 1 |
-| 1 |
-| 1 |
-| 1 |
-+--------+
-(4 rows)
-
-!ok
-EnumerableCalc(expr#0..4=[{inputs}], expr#5=[1], EXPR$0=[$t5])
- EnumerableTableScan(table=[[hr, emps]])
-!plan
-
-# [CALCITE-393] for table scan under join
-select count(*) as c from "hr"."emps", "hr"."depts";
-+----+
-| C |
-+----+
-| 12 |
-+----+
-(1 row)
-
-!ok
-EnumerableAggregate(group=[{}], C=[COUNT()])
- EnumerableJoin(condition=[true], joinType=[inner])
- EnumerableCalc(expr#0..3=[{inputs}], expr#4=[0], DUMMY=[$t4])
- EnumerableTableScan(table=[[hr, depts]])
- EnumerableCalc(expr#0..4=[{inputs}], expr#5=[0], DUMMY=[$t5])
- EnumerableTableScan(table=[[hr, emps]])
-!plan
-
-# [CALCITE-345] AssertionError in RexToLixTranslator comparing to date literal
-!use catchall
-select count(*) as c from "everyTypes" where "sqlDate" = DATE '1970-01-01';
-+---+
-| C |
-+---+
-| 1 |
-+---+
-(1 row)
-
-!ok
-select count(*) as c from "everyTypes" where "sqlDate" = DATE '1971-02-03';
-+---+
-| C |
-+---+
-| 0 |
-+---+
-(1 row)
-
-!ok
-select count(*) as c from "everyTypes" where "sqlDate" > DATE '1970-01-01';
-+---+
-| C |
-+---+
-| 0 |
-+---+
-(1 row)
-
-!ok
-select count(*) as c from "everyTypes" where "sqlTime" = TIME '01:23:45';
-+---+
-| C |
-+---+
-| 0 |
-+---+
-(1 row)
-
-!ok
-select count(*) as c from "everyTypes" where "sqlTimestamp" = TIMESTAMP '1970-01-01 01:23:45';
-+---+
-| C |
-+---+
-| 0 |
-+---+
-(1 row)
-
-!ok
-select count(*) as c from "everyTypes" where "utilDate" = TIMESTAMP '1970-01-01 01:23:45';
-+---+
-| C |
-+---+
-| 0 |
-+---+
-(1 row)
-
-!ok
-
-# [CALCITE-346] Add commutative join rule
-#
-# 3-way join that does not require bushy join. Best plan is: sales_fact_1997 as
-# left-most leaf, then customer (with filter), then product.
-!use foodmart
-select *
-from "sales_fact_1997" as s
- join "customer" as c using ("customer_id")
- join "product" as p using ("product_id")
-where c."city" = 'San Francisco';
-EnumerableJoin(condition=[=($0, $38)], joinType=[inner])
- EnumerableJoin(condition=[=($2, $8)], joinType=[inner])
- EnumerableTableScan(table=[[foodmart2, sales_fact_1997]])
- EnumerableCalc(expr#0..28=[{inputs}], expr#29=['San Francisco'], expr#30=[=($t9, $t29)], proj#0..28=[{exprs}], $condition=[$t30])
- EnumerableTableScan(table=[[foodmart2, customer]])
- EnumerableTableScan(table=[[foodmart2, product]])
-!plan
-
-# 4-way join whose optimal plan requires bushy join.
-#
-# In the plan, note that filters on customer.city and product_department are
-# pushed down. And the plan is a bushy join, with sub-joins (product_class,
-# product) and (sales_fact_1997, customer). However, scan(sales_fact_1997)
-# should be left-most leaf, but is not because CommutativeJoinRule is currently
-# disabled.
-!use foodmart
-select *
-from "sales_fact_1997" as s
- join "customer" as c using ("customer_id")
- join "product" as p using ("product_id")
- join "product_class" as pc using ("product_class_id")
-where c."city" = 'San Francisco'
- and pc."product_department" = 'Snacks';
-EnumerableCalc(expr#0..56=[{inputs}], product_id0=[$t20], time_id=[$t21], customer_id=[$t22], promotion_id=[$t23], store_id=[$t24], store_sales=[$t25], store_cost=[$t26], unit_sales=[$t27], customer_id0=[$t28], account_num=[$t29], lname=[$t30], fname=[$t31], mi=[$t32], address1=[$t33], address2=[$t34], address3=[$t35], address4=[$t36], city=[$t37], state_province=[$t38], postal_code=[$t39], country=[$t40], customer_region_id=[$t41], phone1=[$t42], phone2=[$t43], birthdate=[$t44], marital_status=[$t45], yearly_income=[$t46], gender=[$t47], total_children=[$t48], num_children_at_home=[$t49], education=[$t50], date_accnt_opened=[$t51], member_card=[$t52], occupation=[$t53], houseowner=[$t54], num_cars_owned=[$t55], fullname=[$t56], product_class_id0=[$t5], product_id=[$t6], brand_name=[$t7], product_name=[$t8], SKU=[$t9], SRP=[$t10], gross_weight=[$t11], net_weight=[$t12], recyclable_package=[$t13], low_fat=[$t14], units_per_case=[$t15], cases_per_pallet=[$t16], shelf_width=[$t17], she
lf_height=[$t18], shelf_depth=[$t19], product_class_id=[$t0], product_subcategory=[$t1], product_category=[$t2], product_department=[$t3], product_family=[$t4])
- EnumerableJoin(condition=[=($6, $20)], joinType=[inner])
- EnumerableJoin(condition=[=($0, $5)], joinType=[inner])
- EnumerableCalc(expr#0..4=[{inputs}], expr#5=['Snacks'], expr#6=[=($t3, $t5)], proj#0..4=[{exprs}], $condition=[$t6])
- EnumerableTableScan(table=[[foodmart2, product_class]])
- EnumerableTableScan(table=[[foodmart2, product]])
- EnumerableJoin(condition=[=($2, $8)], joinType=[inner])
- EnumerableTableScan(table=[[foodmart2, sales_fact_1997]])
- EnumerableCalc(expr#0..28=[{inputs}], expr#29=['San Francisco'], expr#30=[=($t9, $t29)], proj#0..28=[{exprs}], $condition=[$t30])
- EnumerableTableScan(table=[[foodmart2, customer]])
-!plan
-
-# Check that when filters are merged, duplicate conditions are eliminated.
-select * from (
- select * from "days"
- where "day" = 1)
-where "day" = 1;
-EnumerableCalc(expr#0..1=[{inputs}], expr#2=[1], expr#3=[=($t0, $t2)], proj#0..1=[{exprs}], $condition=[$t3])
- EnumerableTableScan(table=[[foodmart2, days]])
-!plan
-
-# [HIVE-5873] Semi-join to count subquery
-# [CALCITE-365] AssertionError while translating query with WITH and correlated sub-query
-!if (false) {
-with parts (PNum, OrderOnHand)
- as (select * from (values (3, 6), (10, 1), (8, 0)) as t(PNum, OrderOnHand)),
- supply (PNum, Qty)
- as (select * from (values (3, 4), (3, 2), (10, 1)))
-select pnum
-from parts p
-where orderOnHand
- in (select count(*) from supply s
- where s.pnum = p.pnum);
-+------+
-| PNUM |
-+------+
-| 8 |
-+------+
-(1 row)
-
-!ok
-!}
-
-# [HIVE-7362]
-# Just checking that HAVING-EXISTS works.
-with src (key, "value")
- as (select * from (values (1, 'a'), (2, 'z')) as t(key, "value"))
-select b.key, count(*) as c
-from src b
-group by b.key
-having exists
- (select a.key
- from src a
- where a.key = b.key and a."value" > 'val_9');
-+-----+---+
-| KEY | C |
-+-----+---+
-| 2 | 1 |
-+-----+---+
-(1 row)
-
-!ok
-
-# [CALCITE-411] Duplicate aliases
-select 1 as a, 2 as a from (values (true));
-+---+---+
-| A | A |
-+---+---+
-| 1 | 2 |
-+---+---+
-(1 row)
-
-!ok
-
-select "day", "day" from "days" where "day" < 3;
-+-----+-----+
-| day | day |
-+-----+-----+
-| 1 | 1 |
-| 2 | 2 |
-+-----+-----+
-(2 rows)
-
-!ok
-
-# [DERBY-5313] CASE expression in GROUP BY clause
-select case when a=1 then 1 else 2 end
-from "days" t1(a,x) join "days" t2(b,x) on a=b
-group by case when a=1 then 1 else 2 end;
-+--------+
-| EXPR$0 |
-+--------+
-| 1 |
-| 2 |
-+--------+
-(2 rows)
-
-!ok
-
-# [DERBY-4450] GROUP BY in an IN-subquery inside HAVING clause whose select list
-# is subset of group by columns.
-select sum("day") from "days" group by "week_day" having "week_day" in (
- select "week_day" from "days" group by "week_day", "day");
-+--------+
-| EXPR$0 |
-+--------+
-| 1 |
-| 2 |
-| 3 |
-| 4 |
-| 5 |
-| 6 |
-| 7 |
-+--------+
-(7 rows)
-
-!ok
-
-# [DERBY-4701] Aggregate function on a GROUP BY column also present in a HAVING
-# clause
-SELECT MAX("day") as m, COUNT(T."week_day") AS c
-FROM "days" T
-GROUP BY T."week_day"
-HAVING COUNT(T."week_day") = 1;
-+---+---+
-| M | C |
-+---+---+
-| 1 | 1 |
-| 2 | 1 |
-| 3 | 1 |
-| 4 | 1 |
-| 5 | 1 |
-| 6 | 1 |
-| 7 | 1 |
-+---+---+
-(7 rows)
-
-!ok
-
-# [DERBY-3616] Combinations of DISTINCT and GROUP BY
-!use post
-select distinct gender from emp group by gender;
-+--------+
-| GENDER |
-+--------+
-| F |
-| M |
-+--------+
-(2 rows)
-
-!ok
-select distinct gender from emp group by gender, deptno;
-+--------+
-| GENDER |
-+--------+
-| F |
-| M |
-+--------+
-(2 rows)
-
-!ok
-select gender, deptno from emp;
-+--------+--------+
-| GENDER | DEPTNO |
-+--------+--------+
-| F | 10 |
-| F | 30 |
-| F | 30 |
-| F | 50 |
-| F | 60 |
-| F | |
-| M | 10 |
-| M | 20 |
-| M | 50 |
-+--------+--------+
-(9 rows)
-
-!ok
-select distinct gender, deptno from emp group by gender, deptno, ename;
-+--------+--------+
-| GENDER | DEPTNO |
-+--------+--------+
-| F | 10 |
-| F | 30 |
-| F | 50 |
-| F | 60 |
-| F | |
-| M | 10 |
-| M | 20 |
-| M | 50 |
-+--------+--------+
-(8 rows)
-
-!ok
-select distinct gender, deptno from emp group by gender, deptno;
-+--------+--------+
-| GENDER | DEPTNO |
-+--------+--------+
-| F | 10 |
-| F | 30 |
-| F | 50 |
-| F | 60 |
-| F | |
-| M | 10 |
-| M | 20 |
-| M | 50 |
-+--------+--------+
-(8 rows)
-
-!ok
-select distinct gender, deptno from emp group by gender, ename, deptno;
-+--------+--------+
-| GENDER | DEPTNO |
-+--------+--------+
-| F | 10 |
-| F | 30 |
-| F | 50 |
-| F | 60 |
-| F | |
-| M | 10 |
-| M | 20 |
-| M | 50 |
-+--------+--------+
-(8 rows)
-
-!ok
-select distinct gender, sum(deptno) as s from emp group by gender, deptno;
-+--------+----+
-| GENDER | S |
-+--------+----+
-| F | 10 |
-| F | 50 |
-| F | 60 |
-| F | |
-| M | 10 |
-| M | 20 |
-| M | 50 |
-+--------+----+
-(7 rows)
-
-!ok
-select gender, sum(deptno) as s from emp group by gender, deptno;
-+--------+----+
-| GENDER | S |
-+--------+----+
-| F | 10 |
-| F | 50 |
-| F | 60 |
-| F | 60 |
-| F | |
-| M | 10 |
-| M | 20 |
-| M | 50 |
-+--------+----+
-(8 rows)
-
-!ok
-select gender, sum(deptno) as s from emp group by gender, ename;
-+--------+----+
-| GENDER | S |
-+--------+----+
-| F | 10 |
-| F | 30 |
-| F | 30 |
-| F | 50 |
-| F | 60 |
-| F | |
-| M | 10 |
-| M | 20 |
-| M | 50 |
-+--------+----+
-(9 rows)
-
-!ok
-select distinct gender, sum(deptno) as s from emp group by gender, ename;
-+--------+----+
-| GENDER | S |
-+--------+----+
-| F | 10 |
-| F | 30 |
-| F | 50 |
-| F | 60 |
-| F | |
-| M | 10 |
-| M | 20 |
-| M | 50 |
-+--------+----+
-(8 rows)
-
-!ok
-select gender, sum(deptno) as s from emp group by gender, deptno, ename;
-+--------+----+
-| GENDER | S |
-+--------+----+
-| F | 10 |
-| F | 30 |
-| F | 30 |
-| F | 50 |
-| F | 60 |
-| F | |
-| M | 10 |
-| M | 20 |
-| M | 50 |
-+--------+----+
-(9 rows)
-
-!ok
-select distinct gender, sum(deptno) as s from emp group by gender, deptno, ename;
-+--------+----+
-| GENDER | S |
-+--------+----+
-| F | 10 |
-| F | 30 |
-| F | 50 |
-| F | 60 |
-| F | |
-| M | 10 |
-| M | 20 |
-| M | 50 |
-+--------+----+
-(8 rows)
-
-!ok
-select distinct gender, sum(deptno) as s from emp group by gender;
-+--------+-----+
-| GENDER | S |
-+--------+-----+
-| F | 180 |
-| M | 80 |
-+--------+-----+
-(2 rows)
-
-!ok
-
-select distinct gender, deptno from emp group by gender;
-Expression 'DEPTNO' is not being grouped
-!error
-
-select distinct gender, deptno from emp group by gender, ename;
-Expression 'DEPTNO' is not being grouped
-!error
-
-select distinct gender, deptno, sum(deptno) as s from emp group by gender;
-Expression 'DEPTNO' is not being grouped
-!error
-
-!use scott
-
-# [CALCITE-613] Implicitly convert strings in comparisons
-select * from "scott".emp where hiredate < '1981-01-02';
-+-------+-------+-------+------+------------+--------+------+--------+
-| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
-+-------+-------+-------+------+------------+--------+------+--------+
-| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 |
-+-------+-------+-------+------+------------+--------+------+--------+
-(1 row)
-
-!ok
-EnumerableCalc(expr#0..7=[{inputs}], expr#8=['1981-01-02'], expr#9=[CAST($t8):DATE NOT NULL], expr#10=[<($t4, $t9)], proj#0..7=[{exprs}], $condition=[$t10])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-select * from "scott".emp where '1981-01-02' > hiredate;
-+-------+-------+-------+------+------------+--------+------+--------+
-| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
-+-------+-------+-------+------+------------+--------+------+--------+
-| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 |
-+-------+-------+-------+------+------------+--------+------+--------+
-(1 row)
-
-!ok
-select * from "scott".emp where hiredate between '1981-01-02' and '1981-06-01';
-+-------+-------+----------+------+------------+---------+--------+--------+
-| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
-+-------+-------+----------+------+------------+---------+--------+--------+
-| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
-| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
-| 7566 | JONES | MANAGER | 7839 | 1981-02-04 | 2975.00 | | 20 |
-| 7698 | BLAKE | MANAGER | 7839 | 1981-01-05 | 2850.00 | | 30 |
-+-------+-------+----------+------+------------+---------+--------+--------+
-(4 rows)
-
-!ok
-select * from "scott".emp where hiredate > '1986-01-02';
-+-------+-------+---------+------+------------+---------+------+--------+
-| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
-+-------+-------+---------+------+------------+---------+------+--------+
-| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | | 20 |
-| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | | 20 |
-+-------+-------+---------+------+------------+---------+------+--------+
-(2 rows)
-
-!ok
-select * from "scott".emp where '1986-01-02' < hiredate;
-+-------+-------+---------+------+------------+---------+------+--------+
-| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
-+-------+-------+---------+------+------------+---------+------+--------+
-| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | | 20 |
-| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | | 20 |
-+-------+-------+---------+------+------------+---------+------+--------+
-(2 rows)
-
-!ok
-select * from "scott".emp where '1986-' || '01-02' < hiredate;
-+-------+-------+---------+------+------------+---------+------+--------+
-| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
-+-------+-------+---------+------+------------+---------+------+--------+
-| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | | 20 |
-| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | | 20 |
-+-------+-------+---------+------+------------+---------+------+--------+
-(2 rows)
-
-!ok
-select * from "scott".emp where sal < '1100';
-+-------+-------+-------+------+------------+--------+------+--------+
-| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
-+-------+-------+-------+------+------------+--------+------+--------+
-| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 |
-| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | | 30 |
-+-------+-------+-------+------+------------+--------+------+--------+
-(2 rows)
-
-!ok
-select * from "scott".emp where empno in ('7369', '7876');
-+-------+-------+-------+------+------------+---------+------+--------+
-| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
-+-------+-------+-------+------+------------+---------+------+--------+
-| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 |
-| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | | 20 |
-+-------+-------+-------+------+------------+---------+------+--------+
-(2 rows)
-
-!ok
-select * from "scott".emp where empno between '7500' and '07600';
-+-------+-------+----------+------+------------+---------+--------+--------+
-| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
-+-------+-------+----------+------+------------+---------+--------+--------+
-| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
-| 7566 | JONES | MANAGER | 7839 | 1981-02-04 | 2975.00 | | 20 |
-+-------+-------+----------+------+------------+---------+--------+--------+
-(2 rows)
-
-!ok
-select * from "scott".emp where deptno between '7369' and '7876';
-+-------+-------+-----+-----+----------+-----+------+--------+
-| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
-+-------+-------+-----+-----+----------+-----+------+--------+
-+-------+-------+-----+-----+----------+-----+------+--------+
-(0 rows)
-
-!ok
-select * from "scott".emp where '7369' between empno and '7876';
-+-------+-------+-------+------+------------+--------+------+--------+
-| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
-+-------+-------+-------+------+------------+--------+------+--------+
-| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 |
-+-------+-------+-------+------+------------+--------+------+--------+
-(1 row)
-
-!ok
-
-# [CALCITE-546] Allow table, column and field called "*"
-# See [DRILL-3859], [DRILL-3860].
-SELECT * FROM (VALUES (0, 0)) AS T(A, "*");
-+---+---+
-| A | * |
-+---+---+
-| 0 | 0 |
-+---+---+
-(1 row)
-
-!ok
-
-SELECT a FROM (VALUES (0, 0)) AS T(A, "*");
-+---+
-| A |
-+---+
-| 0 |
-+---+
-(1 row)
-
-!ok
-
-SELECT b FROM (VALUES (0, 0)) AS T(A, "*");
-Column 'B' not found in any table
-!error
-
-# See [DRILL-3860].
-SELECT "a" FROM (VALUES (1, 2, 3, 4)) AS T("a", "A", ".", "*");
-+---+
-| a |
-+---+
-| 1 |
-+---+
-(1 row)
-
-!ok
-
-SELECT "A" FROM (VALUES (1, 2, 3, 4)) AS T("a", "A", ".", "*");
-+---+
-| A |
-+---+
-| 2 |
-+---+
-(1 row)
-
-!ok
-
-SELECT "." FROM (VALUES (1, 2, 3, 4)) AS T("a", "A", ".", "*");
-+---+
-| . |
-+---+
-| 3 |
-+---+
-(1 row)
-
-!ok
-
-SELECT "*" FROM (VALUES (1, 2, 3, 4)) AS T("a", "A", ".", "*");
-+---+
-| * |
-+---+
-| 4 |
-+---+
-(1 row)
-
-!ok
-
-SELECT * FROM (VALUES (1, 2, 3, 4)) AS T("a", "A", ".", "*");
-+---+---+---+---+
-| a | A | . | * |
-+---+---+---+---+
-| 1 | 2 | 3 | 4 |
-+---+---+---+---+
-(1 row)
-
-!ok
-
-# Implicit ROW
-select deptno, (empno, deptno) as r
-from "scott".emp;
-+--------+------------+
-| DEPTNO | R |
-+--------+------------+
-| 10 | {7782, 10} |
-| 10 | {7839, 10} |
-| 10 | {7934, 10} |
-| 20 | {7369, 20} |
-| 20 | {7566, 20} |
-| 20 | {7788, 20} |
-| 20 | {7876, 20} |
-| 20 | {7902, 20} |
-| 30 | {7499, 30} |
-| 30 | {7521, 30} |
-| 30 | {7654, 30} |
-| 30 | {7698, 30} |
-| 30 | {7844, 30} |
-| 30 | {7900, 30} |
-+--------+------------+
-(14 rows)
-
-!ok
-
-# Explicit ROW
-select deptno, row (empno, deptno) as r
-from "scott".emp;
-ROW expression encountered in illegal context
-!error
-
-# [CALCITE-877] Allow ROW as argument to COLLECT
-select deptno, collect(r) as empnos
-from (select deptno, (empno, deptno) as r
- from "scott".emp)
-group by deptno;
-+--------+--------------------------------------------------------------------------+
-| DEPTNO | EMPNOS |
-+--------+--------------------------------------------------------------------------+
-| 10 | [{7782, 10}, {7839, 10}, {7934, 10}] |
-| 20 | [{7369, 20}, {7566, 20}, {7788, 20}, {7876, 20}, {7902, 20}] |
-| 30 | [{7499, 30}, {7521, 30}, {7654, 30}, {7698, 30}, {7844, 30}, {7900, 30}] |
-+--------+--------------------------------------------------------------------------+
-(3 rows)
-
-!ok
-
-# [CALCITE-922] Value of INTERVAL literal
-select deptno * interval '2' day as d2,
- deptno * interval -'3' hour as h3,
- deptno * interval -'-4' hour as h4,
- deptno * interval -'4:30' hour to minute as h4_5,
- deptno * interval -'-1-3' year to month as y1_25
-from "scott".dept;
-+-----+------+------+---------+--------+
-| D2 | H3 | H4 | H4_5 | Y1_25 |
-+-----+------+------+---------+--------+
-| +20 | -30 | +40 | -45:00 | +12-06 |
-| +40 | -60 | +80 | -90:00 | +25-00 |
-| +60 | -90 | +120 | -135:00 | +37-06 |
-| +80 | -120 | +160 | -180:00 | +50-00 |
-+-----+------+------+---------+--------+
-(4 rows)
-
-!ok
-
-# End misc.oq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/outer.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/outer.iq b/core/src/test/resources/sql/outer.iq
new file mode 100644
index 0000000..af8e259
--- /dev/null
+++ b/core/src/test/resources/sql/outer.iq
@@ -0,0 +1,349 @@
+# outer.iq - Various kinds of outer join
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+!use post
+!set outputformat mysql
+
+select * from emp;
++-------+--------+--------+
+| ENAME | DEPTNO | GENDER |
++-------+--------+--------+
+| Jane | 10 | F |
+| Bob | 10 | M |
+| Eric | 20 | M |
+| Susan | 30 | F |
+| Alice | 30 | F |
+| Adam | 50 | M |
+| Eve | 50 | F |
+| Grace | 60 | F |
+| Wilma | | F |
++-------+--------+--------+
+(9 rows)
+
+!ok
+select * from emp join dept on emp.deptno = dept.deptno;
++-------+--------+--------+---------+-------------+
+| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
++-------+--------+--------+---------+-------------+
+| Jane | 10 | F | 10 | Sales |
+| Bob | 10 | M | 10 | Sales |
+| Eric | 20 | M | 20 | Marketing |
+| Susan | 30 | F | 30 | Engineering |
+| Alice | 30 | F | 30 | Engineering |
++-------+--------+--------+---------+-------------+
+(5 rows)
+
+!ok
+
+# The following test is disabled, because we cannot handle non-equi-join.
+# Following it are the results from MySQL.
+!if (false) {
+select * from emp join dept on emp.deptno = dept.deptno and emp.gender = 'F';
+ ename | deptno | gender | deptno | dname
+-------+--------+--------+--------+-------------
+ Jane | 10 | F | 10 | Sales
+ Susan | 30 | F | 30 | Engineering
+ Alice | 30 | F | 30 | Engineering
+
+!ok
+!}
+
+select * from emp join dept on emp.deptno = dept.deptno where emp.gender = 'F';
++-------+--------+--------+---------+-------------+
+| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
++-------+--------+--------+---------+-------------+
+| Jane | 10 | F | 10 | Sales |
+| Susan | 30 | F | 30 | Engineering |
+| Alice | 30 | F | 30 | Engineering |
++-------+--------+--------+---------+-------------+
+(3 rows)
+
+!ok
+
+select * from (select * from emp where gender ='F') as emp join dept on emp.deptno = dept.deptno;
++-------+--------+--------+---------+-------------+
+| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
++-------+--------+--------+---------+-------------+
+| Jane | 10 | F | 10 | Sales |
+| Susan | 30 | F | 30 | Engineering |
+| Alice | 30 | F | 30 | Engineering |
++-------+--------+--------+---------+-------------+
+(3 rows)
+
+!ok
+
+# The following test is disabled, because we cannot handle non-equi-join.
+# Following it are the results from MySQL.
+!if (false) {
+select * from emp left join dept on emp.deptno = dept.deptno and emp.gender = 'F';
+ ename | deptno | gender | deptno | dname
+-------+--------+--------+--------+-------------
+ Jane | 10 | F | 10 | Sales
+ Susan | 30 | F | 30 | Engineering
+ Alice | 30 | F | 30 | Engineering
+ Bob | 10 | M | NULL | NULL
+ Eric | 20 | M | NULL | NULL
+ Adam | 50 | M | NULL | NULL
+ Eve | 50 | F | NULL | NULL
+ Grace | 60 | F | NULL | NULL
+!ok
+!}
+
+select * from emp left join dept on emp.deptno = dept.deptno where emp.gender = 'F';
++-------+--------+--------+---------+-------------+
+| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
++-------+--------+--------+---------+-------------+
+| Jane | 10 | F | 10 | Sales |
+| Susan | 30 | F | 30 | Engineering |
+| Alice | 30 | F | 30 | Engineering |
+| Eve | 50 | F | | |
+| Grace | 60 | F | | |
+| Wilma | | F | | |
++-------+--------+--------+---------+-------------+
+(6 rows)
+
+!ok
+
+select * from (select * from emp where gender ='F') as emp left join dept on emp.deptno = dept.deptno;
++-------+--------+--------+---------+-------------+
+| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
++-------+--------+--------+---------+-------------+
+| Jane | 10 | F | 10 | Sales |
+| Susan | 30 | F | 30 | Engineering |
+| Alice | 30 | F | 30 | Engineering |
+| Eve | 50 | F | | |
+| Grace | 60 | F | | |
+| Wilma | | F | | |
++-------+--------+--------+---------+-------------+
+(6 rows)
+
+!ok
+
+# The following test is disabled, because we cannot handle non-equi-join.
+# Following it are the results from MySQL.
+!if (false) {
+select * from emp right join dept on emp.deptno = dept.deptno and emp.gender = 'F';
++-------+--------+--------+--------+-------------+
+| ename | deptno | gender | deptno | dname |
++-------+--------+--------+--------+-------------+
+| Jane | 10 | F | 10 | Sales |
+| Susan | 30 | F | 30 | Engineering |
+| Alice | 30 | F | 30 | Engineering |
+| NULL | NULL | NULL | 20 | Marketing |
+| NULL | NULL | NULL | 40 | Empty |
++-------+--------+--------+--------+-------------+
+!ok
+!}
+
+select * from emp right join dept on emp.deptno = dept.deptno where emp.gender = 'F';
++-------+--------+--------+---------+-------------+
+| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
++-------+--------+--------+---------+-------------+
+| Jane | 10 | F | 10 | Sales |
+| Susan | 30 | F | 30 | Engineering |
+| Alice | 30 | F | 30 | Engineering |
++-------+--------+--------+---------+-------------+
+(3 rows)
+
+!ok
+
+select * from (select * from emp where gender ='F') as emp right join dept on emp.deptno = dept.deptno;
++-------+--------+--------+---------+-------------+
+| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
++-------+--------+--------+---------+-------------+
+| Jane | 10 | F | 10 | Sales |
+| Susan | 30 | F | 30 | Engineering |
+| Alice | 30 | F | 30 | Engineering |
+| | | | 20 | Marketing |
+| | | | 40 | Empty |
++-------+--------+--------+---------+-------------+
+(5 rows)
+
+!ok
+
+!if (false) {
+select * from emp full join dept on emp.deptno = dept.deptno and emp.gender = 'F';
+ ename | deptno | gender | deptno | dname
+-------+--------+--------+--------+-------------
+ Jane | 10 | F | 10 | Sales
+ | | | 20 | Marketing
+ Alice | 30 | F | 30 | Engineering
+ Susan | 30 | F | 30 | Engineering
+ | | | 40 | Empty
+ Wilma | | F | |
+ Eric | 20 | M | |
+ Bob | 10 | M | |
+ Eve | 50 | F | |
+ Adam | 50 | M | |
+ Grace | 60 | F | |
+(11 rows)
+
+!ok
+!}
+
+
+select * from emp full join dept on emp.deptno = dept.deptno where emp.gender = 'F';
++-------+--------+--------+---------+-------------+
+| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
++-------+--------+--------+---------+-------------+
+| Jane | 10 | F | 10 | Sales |
+| Susan | 30 | F | 30 | Engineering |
+| Alice | 30 | F | 30 | Engineering |
+| Eve | 50 | F | | |
+| Grace | 60 | F | | |
+| Wilma | | F | | |
++-------+--------+--------+---------+-------------+
+(6 rows)
+
+!ok
+
+select * from (select * from emp where gender ='F') as emp full join dept on emp.deptno = dept.deptno;
++-------+--------+--------+---------+-------------+
+| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
++-------+--------+--------+---------+-------------+
+| Jane | 10 | F | 10 | Sales |
+| Susan | 30 | F | 30 | Engineering |
+| Alice | 30 | F | 30 | Engineering |
+| Eve | 50 | F | | |
+| Grace | 60 | F | | |
+| Wilma | | F | | |
+| | | | 20 | Marketing |
+| | | | 40 | Empty |
++-------+--------+--------+---------+-------------+
+(8 rows)
+
+!ok
+
+# same as above, but expressed as a theta-join
+select * from (select * from emp where gender ='F') as emp full join dept on emp.deptno - dept.deptno = 0;
++-------+--------+--------+---------+-------------+
+| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
++-------+--------+--------+---------+-------------+
+| Jane | 10 | F | 10 | Sales |
+| Susan | 30 | F | 30 | Engineering |
+| Alice | 30 | F | 30 | Engineering |
+| Eve | 50 | F | | |
+| Grace | 60 | F | | |
+| Wilma | | F | | |
+| | | | 20 | Marketing |
+| | | | 40 | Empty |
++-------+--------+--------+---------+-------------+
+(8 rows)
+
+!ok
+EnumerableThetaJoin(condition=[=(-($1, $3), 0)], joinType=[full])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=['F'], expr#4=[=($t2, $t3)], proj#0..2=[{exprs}], $condition=[$t4])
+ EnumerableUnion(all=[true])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Jane'], expr#2=[10], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Bob'], expr#2=[10], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Eric'], expr#2=[20], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Susan'], expr#2=[30], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Alice'], expr#2=[30], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Adam'], expr#2=[50], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Eve'], expr#2=[50], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Grace'], expr#2=[60], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Wilma'], expr#2=[null], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableValues(tuples=[[{ 10, 'Sales ' }, { 20, 'Marketing ' }, { 30, 'Engineering' }, { 40, 'Empty ' }]])
+!plan
+
+# [CALCITE-554] Outer join over NULL keys generates wrong result
+with t1(x) as (select * from (values (1),(2), (case when 1 = 1 then null else 3 end)) as t(x)),
+ t2(x) as (select * from (values (1),(case when 1 = 1 then null else 3 end)) as t(x))
+select t1.x from t1 left join t2 on t1.x = t2.x;
++---+
+| X |
++---+
+| 1 |
+| 2 |
+| |
++---+
+(3 rows)
+
+!ok
+
+# Equivalent query, using CAST, and skipping unnecessary aliases
+# (Postgres doesn't like the missing alias, or the missing parentheses.)
+with t1(x) as (select * from (values 1, 2, cast(null as integer))),
+ t2(x) as (select * from (values 1, cast(null as integer)))
+select t1.x from t1 left join t2 on t1.x = t2.x;
++---+
+| X |
++---+
+| 1 |
+| 2 |
+| |
++---+
+(3 rows)
+
+!ok
+
+# Similar query, projecting left and right key columns
+with t1(x) as (select * from (values (1), (2), (cast(null as integer))) as t),
+ t2(x) as (select * from (values (1), (cast(null as integer))) as t)
+select t1.x, t2.x from t1 left join t2 on t1.x = t2.x;
++---+---+
+| X | X |
++---+---+
+| 1 | 1 |
+| 2 | |
+| | |
++---+---+
+(3 rows)
+
+!ok
+
+# Similar, with 2 columns on each side projecting both columns
+with t1(x, y) as (select * from (values (1, 10), (2, 20), (cast(null as integer), 30)) as t),
+ t2(x, y) as (select * from (values (1, 100), (cast(null as integer), 200)) as t)
+select * from t1 left join t2 on t1.x = t2.x;
++---+----+----+-----+
+| X | Y | X0 | Y0 |
++---+----+----+-----+
+| 1 | 10 | 1 | 100 |
+| 2 | 20 | | |
+| | 30 | | |
++---+----+----+-----+
+(3 rows)
+
+!ok
+
+# Similar, full join
+with t1(x, y) as (select * from (values (1, 10), (2, 20), (cast(null as integer), 30)) as t),
+ t2(x, y) as (select * from (values (1,100), (cast(null as integer), 200)) as t)
+select * from t1 full join t2 on t1.x = t2.x;
++---+----+----+-----+
+| X | Y | X0 | Y0 |
++---+----+----+-----+
+| 1 | 10 | 1 | 100 |
+| 2 | 20 | | |
+| | 30 | | |
+| | | | 200 |
++---+----+----+-----+
+(4 rows)
+
+!ok
+
+# End outer.iq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/outer.oq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/outer.oq b/core/src/test/resources/sql/outer.oq
deleted file mode 100644
index 5d08047..0000000
--- a/core/src/test/resources/sql/outer.oq
+++ /dev/null
@@ -1,349 +0,0 @@
-# outer.oq - Various kinds of outer join
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to you under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-!use post
-!set outputformat mysql
-
-select * from emp;
-+-------+--------+--------+
-| ENAME | DEPTNO | GENDER |
-+-------+--------+--------+
-| Jane | 10 | F |
-| Bob | 10 | M |
-| Eric | 20 | M |
-| Susan | 30 | F |
-| Alice | 30 | F |
-| Adam | 50 | M |
-| Eve | 50 | F |
-| Grace | 60 | F |
-| Wilma | | F |
-+-------+--------+--------+
-(9 rows)
-
-!ok
-select * from emp join dept on emp.deptno = dept.deptno;
-+-------+--------+--------+---------+-------------+
-| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
-+-------+--------+--------+---------+-------------+
-| Jane | 10 | F | 10 | Sales |
-| Bob | 10 | M | 10 | Sales |
-| Eric | 20 | M | 20 | Marketing |
-| Susan | 30 | F | 30 | Engineering |
-| Alice | 30 | F | 30 | Engineering |
-+-------+--------+--------+---------+-------------+
-(5 rows)
-
-!ok
-
-# The following test is disabled, because we cannot handle non-equi-join.
-# Following it are the results from MySQL.
-!if (false) {
-select * from emp join dept on emp.deptno = dept.deptno and emp.gender = 'F';
- ename | deptno | gender | deptno | dname
--------+--------+--------+--------+-------------
- Jane | 10 | F | 10 | Sales
- Susan | 30 | F | 30 | Engineering
- Alice | 30 | F | 30 | Engineering
-
-!ok
-!}
-
-select * from emp join dept on emp.deptno = dept.deptno where emp.gender = 'F';
-+-------+--------+--------+---------+-------------+
-| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
-+-------+--------+--------+---------+-------------+
-| Jane | 10 | F | 10 | Sales |
-| Susan | 30 | F | 30 | Engineering |
-| Alice | 30 | F | 30 | Engineering |
-+-------+--------+--------+---------+-------------+
-(3 rows)
-
-!ok
-
-select * from (select * from emp where gender ='F') as emp join dept on emp.deptno = dept.deptno;
-+-------+--------+--------+---------+-------------+
-| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
-+-------+--------+--------+---------+-------------+
-| Jane | 10 | F | 10 | Sales |
-| Susan | 30 | F | 30 | Engineering |
-| Alice | 30 | F | 30 | Engineering |
-+-------+--------+--------+---------+-------------+
-(3 rows)
-
-!ok
-
-# The following test is disabled, because we cannot handle non-equi-join.
-# Following it are the results from MySQL.
-!if (false) {
-select * from emp left join dept on emp.deptno = dept.deptno and emp.gender = 'F';
- ename | deptno | gender | deptno | dname
--------+--------+--------+--------+-------------
- Jane | 10 | F | 10 | Sales
- Susan | 30 | F | 30 | Engineering
- Alice | 30 | F | 30 | Engineering
- Bob | 10 | M | NULL | NULL
- Eric | 20 | M | NULL | NULL
- Adam | 50 | M | NULL | NULL
- Eve | 50 | F | NULL | NULL
- Grace | 60 | F | NULL | NULL
-!ok
-!}
-
-select * from emp left join dept on emp.deptno = dept.deptno where emp.gender = 'F';
-+-------+--------+--------+---------+-------------+
-| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
-+-------+--------+--------+---------+-------------+
-| Jane | 10 | F | 10 | Sales |
-| Susan | 30 | F | 30 | Engineering |
-| Alice | 30 | F | 30 | Engineering |
-| Eve | 50 | F | | |
-| Grace | 60 | F | | |
-| Wilma | | F | | |
-+-------+--------+--------+---------+-------------+
-(6 rows)
-
-!ok
-
-select * from (select * from emp where gender ='F') as emp left join dept on emp.deptno = dept.deptno;
-+-------+--------+--------+---------+-------------+
-| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
-+-------+--------+--------+---------+-------------+
-| Jane | 10 | F | 10 | Sales |
-| Susan | 30 | F | 30 | Engineering |
-| Alice | 30 | F | 30 | Engineering |
-| Eve | 50 | F | | |
-| Grace | 60 | F | | |
-| Wilma | | F | | |
-+-------+--------+--------+---------+-------------+
-(6 rows)
-
-!ok
-
-# The following test is disabled, because we cannot handle non-equi-join.
-# Following it are the results from MySQL.
-!if (false) {
-select * from emp right join dept on emp.deptno = dept.deptno and emp.gender = 'F';
-+-------+--------+--------+--------+-------------+
-| ename | deptno | gender | deptno | dname |
-+-------+--------+--------+--------+-------------+
-| Jane | 10 | F | 10 | Sales |
-| Susan | 30 | F | 30 | Engineering |
-| Alice | 30 | F | 30 | Engineering |
-| NULL | NULL | NULL | 20 | Marketing |
-| NULL | NULL | NULL | 40 | Empty |
-+-------+--------+--------+--------+-------------+
-!ok
-!}
-
-select * from emp right join dept on emp.deptno = dept.deptno where emp.gender = 'F';
-+-------+--------+--------+---------+-------------+
-| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
-+-------+--------+--------+---------+-------------+
-| Jane | 10 | F | 10 | Sales |
-| Susan | 30 | F | 30 | Engineering |
-| Alice | 30 | F | 30 | Engineering |
-+-------+--------+--------+---------+-------------+
-(3 rows)
-
-!ok
-
-select * from (select * from emp where gender ='F') as emp right join dept on emp.deptno = dept.deptno;
-+-------+--------+--------+---------+-------------+
-| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
-+-------+--------+--------+---------+-------------+
-| Jane | 10 | F | 10 | Sales |
-| Susan | 30 | F | 30 | Engineering |
-| Alice | 30 | F | 30 | Engineering |
-| | | | 20 | Marketing |
-| | | | 40 | Empty |
-+-------+--------+--------+---------+-------------+
-(5 rows)
-
-!ok
-
-!if (false) {
-select * from emp full join dept on emp.deptno = dept.deptno and emp.gender = 'F';
- ename | deptno | gender | deptno | dname
--------+--------+--------+--------+-------------
- Jane | 10 | F | 10 | Sales
- | | | 20 | Marketing
- Alice | 30 | F | 30 | Engineering
- Susan | 30 | F | 30 | Engineering
- | | | 40 | Empty
- Wilma | | F | |
- Eric | 20 | M | |
- Bob | 10 | M | |
- Eve | 50 | F | |
- Adam | 50 | M | |
- Grace | 60 | F | |
-(11 rows)
-
-!ok
-!}
-
-
-select * from emp full join dept on emp.deptno = dept.deptno where emp.gender = 'F';
-+-------+--------+--------+---------+-------------+
-| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
-+-------+--------+--------+---------+-------------+
-| Jane | 10 | F | 10 | Sales |
-| Susan | 30 | F | 30 | Engineering |
-| Alice | 30 | F | 30 | Engineering |
-| Eve | 50 | F | | |
-| Grace | 60 | F | | |
-| Wilma | | F | | |
-+-------+--------+--------+---------+-------------+
-(6 rows)
-
-!ok
-
-select * from (select * from emp where gender ='F') as emp full join dept on emp.deptno = dept.deptno;
-+-------+--------+--------+---------+-------------+
-| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
-+-------+--------+--------+---------+-------------+
-| Jane | 10 | F | 10 | Sales |
-| Susan | 30 | F | 30 | Engineering |
-| Alice | 30 | F | 30 | Engineering |
-| Eve | 50 | F | | |
-| Grace | 60 | F | | |
-| Wilma | | F | | |
-| | | | 20 | Marketing |
-| | | | 40 | Empty |
-+-------+--------+--------+---------+-------------+
-(8 rows)
-
-!ok
-
-# same as above, but expressed as a theta-join
-select * from (select * from emp where gender ='F') as emp full join dept on emp.deptno - dept.deptno = 0;
-+-------+--------+--------+---------+-------------+
-| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
-+-------+--------+--------+---------+-------------+
-| Jane | 10 | F | 10 | Sales |
-| Susan | 30 | F | 30 | Engineering |
-| Alice | 30 | F | 30 | Engineering |
-| Eve | 50 | F | | |
-| Grace | 60 | F | | |
-| Wilma | | F | | |
-| | | | 20 | Marketing |
-| | | | 40 | Empty |
-+-------+--------+--------+---------+-------------+
-(8 rows)
-
-!ok
-EnumerableThetaJoin(condition=[=(-($1, $3), 0)], joinType=[full])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=['F'], expr#4=[=($t2, $t3)], proj#0..2=[{exprs}], $condition=[$t4])
- EnumerableUnion(all=[true])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Jane'], expr#2=[10], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Bob'], expr#2=[10], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Eric'], expr#2=[20], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Susan'], expr#2=[30], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Alice'], expr#2=[30], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Adam'], expr#2=[50], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Eve'], expr#2=[50], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Grace'], expr#2=[60], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Wilma'], expr#2=[null], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableValues(tuples=[[{ 10, 'Sales ' }, { 20, 'Marketing ' }, { 30, 'Engineering' }, { 40, 'Empty ' }]])
-!plan
-
-# [CALCITE-554] Outer join over NULL keys generates wrong result
-with t1(x) as (select * from (values (1),(2), (case when 1 = 1 then null else 3 end)) as t(x)),
- t2(x) as (select * from (values (1),(case when 1 = 1 then null else 3 end)) as t(x))
-select t1.x from t1 left join t2 on t1.x = t2.x;
-+---+
-| X |
-+---+
-| 1 |
-| 2 |
-| |
-+---+
-(3 rows)
-
-!ok
-
-# Equivalent query, using CAST, and skipping unnecessary aliases
-# (Postgres doesn't like the missing alias, or the missing parentheses.)
-with t1(x) as (select * from (values 1, 2, cast(null as integer))),
- t2(x) as (select * from (values 1, cast(null as integer)))
-select t1.x from t1 left join t2 on t1.x = t2.x;
-+---+
-| X |
-+---+
-| 1 |
-| 2 |
-| |
-+---+
-(3 rows)
-
-!ok
-
-# Similar query, projecting left and right key columns
-with t1(x) as (select * from (values (1), (2), (cast(null as integer))) as t),
- t2(x) as (select * from (values (1), (cast(null as integer))) as t)
-select t1.x, t2.x from t1 left join t2 on t1.x = t2.x;
-+---+---+
-| X | X |
-+---+---+
-| 1 | 1 |
-| 2 | |
-| | |
-+---+---+
-(3 rows)
-
-!ok
-
-# Similar, with 2 columns on each side projecting both columns
-with t1(x, y) as (select * from (values (1, 10), (2, 20), (cast(null as integer), 30)) as t),
- t2(x, y) as (select * from (values (1, 100), (cast(null as integer), 200)) as t)
-select * from t1 left join t2 on t1.x = t2.x;
-+---+----+----+-----+
-| X | Y | X0 | Y0 |
-+---+----+----+-----+
-| 1 | 10 | 1 | 100 |
-| 2 | 20 | | |
-| | 30 | | |
-+---+----+----+-----+
-(3 rows)
-
-!ok
-
-# Similar, full join
-with t1(x, y) as (select * from (values (1, 10), (2, 20), (cast(null as integer), 30)) as t),
- t2(x, y) as (select * from (values (1,100), (cast(null as integer), 200)) as t)
-select * from t1 full join t2 on t1.x = t2.x;
-+---+----+----+-----+
-| X | Y | X0 | Y0 |
-+---+----+----+-----+
-| 1 | 10 | 1 | 100 |
-| 2 | 20 | | |
-| | 30 | | |
-| | | | 200 |
-+---+----+----+-----+
-(4 rows)
-
-!ok
-
-# End outer.oq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/scalar.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/scalar.iq b/core/src/test/resources/sql/scalar.iq
new file mode 100644
index 0000000..283f5c3
--- /dev/null
+++ b/core/src/test/resources/sql/scalar.iq
@@ -0,0 +1,216 @@
+# scalar.iq - Scalar sub-queries
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+!set outputformat mysql
+!use scott
+
+select deptno, (select min(empno) from "scott".emp where deptno = dept.deptno) as x from "scott".dept;
++--------+------+
+| DEPTNO | X |
++--------+------+
+| 10 | 7782 |
+| 20 | 7369 |
+| 30 | 7499 |
+| 40 | |
++--------+------+
+(4 rows)
+
+!ok
+
+select deptno, (select count(*) from "scott".emp where deptno = dept.deptno) as x from "scott".dept;
++--------+---+
+| DEPTNO | X |
++--------+---+
+| 10 | 3 |
+| 20 | 5 |
+| 30 | 6 |
+| 40 | 0 |
++--------+---+
+(4 rows)
+
+!ok
+
+select deptno, (select count(*) from "scott".emp where deptno = dept.deptno group by deptno) as x from "scott".dept;
++--------+---+
+| DEPTNO | X |
++--------+---+
+| 10 | 3 |
+| 20 | 5 |
+| 30 | 6 |
+| 40 | |
++--------+---+
+(4 rows)
+
+!ok
+
+# cast necessary to prevent overflow
+select deptno, (select sum(cast(empno as int)) from "scott".emp where deptno = dept.deptno group by deptno) as x from "scott".dept;
++--------+-------+
+| DEPTNO | X |
++--------+-------+
+| 10 | 23555 |
+| 20 | 38501 |
+| 30 | 46116 |
+| 40 | |
++--------+-------+
+(4 rows)
+
+!ok
+
+select deptno, (select count(*) from "scott".emp where 1 = 0) as x from "scott".dept;
++--------+---+
+| DEPTNO | X |
++--------+---+
+| 10 | 0 |
+| 20 | 0 |
+| 30 | 0 |
+| 40 | 0 |
++--------+---+
+(4 rows)
+
+!ok
+
+select deptno, (select count(*) from "scott".emp where 1 = 0 group by ()) as x from "scott".dept;
++--------+---+
+| DEPTNO | X |
++--------+---+
+| 10 | 0 |
+| 20 | 0 |
+| 30 | 0 |
+| 40 | 0 |
++--------+---+
+(4 rows)
+
+!ok
+
+select deptno, (select sum(empno) from "scott".emp where 1 = 0) as x from "scott".dept;
++--------+---+
+| DEPTNO | X |
++--------+---+
+| 10 | |
+| 20 | |
+| 30 | |
+| 40 | |
++--------+---+
+(4 rows)
+
+!ok
+
+select deptno, (select sum(empno) from "scott".emp where 1 = 0 group by ()) as x from "scott".dept;
++--------+---+
+| DEPTNO | X |
++--------+---+
+| 10 | |
+| 20 | |
+| 30 | |
+| 40 | |
++--------+---+
+(4 rows)
+
+!ok
+
+# [CALCITE-709] Errors with LIMIT inside scalar sub-query
+!if (false) {
+select deptno, (select sum(empno) from "scott".emp where deptno = dept.deptno limit 1) as x from "scott".dept;
++--------+----------------------+
+| DEPTNO | X |
++--------+----------------------+
+| 10 | 23555 |
+| 20 | 38501 |
+| 30 | 46116 |
+| 40 | null |
++--------+----------------------+
+(4 rows)
+
+!ok
+!}
+
+# [CALCITE-709] Errors with LIMIT inside scalar sub-query
+!if (false) {
+select deptno, (select sum(empno) from "scott".emp where deptno = dept.deptno limit 0) as x from "scott".dept;
++--------+----------------------+
+| DEPTNO | X |
++--------+----------------------+
+| 10 | 23555 |
+| 20 | 38501 |
+| 30 | 46116 |
+| 40 | null |
++--------+----------------------+
+(4 rows)
+
+!ok
+!}
+
+# [CALCITE-709] Errors with LIMIT inside scalar sub-query
+!if (false) {
+select deptno, (select deptno from "scott".emp where deptno = dept.deptno limit 1) as x from "scott".dept;
++--------+------+
+| DEPTNO | X |
++--------+------+
+| 10 | 10 |
+| 20 | 20 |
+| 30 | 30 |
+| 40 | null |
++--------+------+
+(4 rows)
+
+!ok
+!}
+
+select deptno, (select deptno from "scott".emp where deptno = dept.deptno limit 0) as x from "scott".dept;
++--------+---+
+| DEPTNO | X |
++--------+---+
+| 10 | |
+| 20 | |
+| 30 | |
+| 40 | |
++--------+---+
+(4 rows)
+
+!ok
+
+# [CALCITE-709] Errors with LIMIT inside scalar sub-query
+!if (false) {
+select deptno, (select empno from "scott".emp where deptno = dept.deptno order by empno limit 1) as x from "scott".dept;
++--------+--------+
+| DEPTNO | X |
++--------+--------+
+| 10 | 7369 |
+| 20 | 7369 |
+| 30 | 7369 |
+| 40 | 7369 |
++--------+--------+
+(4 rows)
+
+!ok
+!}
+
+select deptno, (select empno from "scott".emp order by empno limit 1) as x from "scott".dept;
++--------+------+
+| DEPTNO | X |
++--------+------+
+| 10 | 7369 |
+| 20 | 7369 |
+| 30 | 7369 |
+| 40 | 7369 |
++--------+------+
+(4 rows)
+
+!ok
+
+# End scalar.iq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/scalar.oq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/scalar.oq b/core/src/test/resources/sql/scalar.oq
deleted file mode 100644
index 103df29..0000000
--- a/core/src/test/resources/sql/scalar.oq
+++ /dev/null
@@ -1,216 +0,0 @@
-# scalar.oq - Scalar sub-queries
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to you under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-!set outputformat mysql
-!use scott
-
-select deptno, (select min(empno) from "scott".emp where deptno = dept.deptno) as x from "scott".dept;
-+--------+------+
-| DEPTNO | X |
-+--------+------+
-| 10 | 7782 |
-| 20 | 7369 |
-| 30 | 7499 |
-| 40 | |
-+--------+------+
-(4 rows)
-
-!ok
-
-select deptno, (select count(*) from "scott".emp where deptno = dept.deptno) as x from "scott".dept;
-+--------+---+
-| DEPTNO | X |
-+--------+---+
-| 10 | 3 |
-| 20 | 5 |
-| 30 | 6 |
-| 40 | 0 |
-+--------+---+
-(4 rows)
-
-!ok
-
-select deptno, (select count(*) from "scott".emp where deptno = dept.deptno group by deptno) as x from "scott".dept;
-+--------+---+
-| DEPTNO | X |
-+--------+---+
-| 10 | 3 |
-| 20 | 5 |
-| 30 | 6 |
-| 40 | |
-+--------+---+
-(4 rows)
-
-!ok
-
-# cast necessary to prevent overflow
-select deptno, (select sum(cast(empno as int)) from "scott".emp where deptno = dept.deptno group by deptno) as x from "scott".dept;
-+--------+-------+
-| DEPTNO | X |
-+--------+-------+
-| 10 | 23555 |
-| 20 | 38501 |
-| 30 | 46116 |
-| 40 | |
-+--------+-------+
-(4 rows)
-
-!ok
-
-select deptno, (select count(*) from "scott".emp where 1 = 0) as x from "scott".dept;
-+--------+---+
-| DEPTNO | X |
-+--------+---+
-| 10 | 0 |
-| 20 | 0 |
-| 30 | 0 |
-| 40 | 0 |
-+--------+---+
-(4 rows)
-
-!ok
-
-select deptno, (select count(*) from "scott".emp where 1 = 0 group by ()) as x from "scott".dept;
-+--------+---+
-| DEPTNO | X |
-+--------+---+
-| 10 | 0 |
-| 20 | 0 |
-| 30 | 0 |
-| 40 | 0 |
-+--------+---+
-(4 rows)
-
-!ok
-
-select deptno, (select sum(empno) from "scott".emp where 1 = 0) as x from "scott".dept;
-+--------+---+
-| DEPTNO | X |
-+--------+---+
-| 10 | |
-| 20 | |
-| 30 | |
-| 40 | |
-+--------+---+
-(4 rows)
-
-!ok
-
-select deptno, (select sum(empno) from "scott".emp where 1 = 0 group by ()) as x from "scott".dept;
-+--------+---+
-| DEPTNO | X |
-+--------+---+
-| 10 | |
-| 20 | |
-| 30 | |
-| 40 | |
-+--------+---+
-(4 rows)
-
-!ok
-
-# [CALCITE-709] Errors with LIMIT inside scalar sub-query
-!if (false) {
-select deptno, (select sum(empno) from "scott".emp where deptno = dept.deptno limit 1) as x from "scott".dept;
-+--------+----------------------+
-| DEPTNO | X |
-+--------+----------------------+
-| 10 | 23555 |
-| 20 | 38501 |
-| 30 | 46116 |
-| 40 | null |
-+--------+----------------------+
-(4 rows)
-
-!ok
-!}
-
-# [CALCITE-709] Errors with LIMIT inside scalar sub-query
-!if (false) {
-select deptno, (select sum(empno) from "scott".emp where deptno = dept.deptno limit 0) as x from "scott".dept;
-+--------+----------------------+
-| DEPTNO | X |
-+--------+----------------------+
-| 10 | 23555 |
-| 20 | 38501 |
-| 30 | 46116 |
-| 40 | null |
-+--------+----------------------+
-(4 rows)
-
-!ok
-!}
-
-# [CALCITE-709] Errors with LIMIT inside scalar sub-query
-!if (false) {
-select deptno, (select deptno from "scott".emp where deptno = dept.deptno limit 1) as x from "scott".dept;
-+--------+------+
-| DEPTNO | X |
-+--------+------+
-| 10 | 10 |
-| 20 | 20 |
-| 30 | 30 |
-| 40 | null |
-+--------+------+
-(4 rows)
-
-!ok
-!}
-
-select deptno, (select deptno from "scott".emp where deptno = dept.deptno limit 0) as x from "scott".dept;
-+--------+---+
-| DEPTNO | X |
-+--------+---+
-| 10 | |
-| 20 | |
-| 30 | |
-| 40 | |
-+--------+---+
-(4 rows)
-
-!ok
-
-# [CALCITE-709] Errors with LIMIT inside scalar sub-query
-!if (false) {
-select deptno, (select empno from "scott".emp where deptno = dept.deptno order by empno limit 1) as x from "scott".dept;
-+--------+--------+
-| DEPTNO | X |
-+--------+--------+
-| 10 | 7369 |
-| 20 | 7369 |
-| 30 | 7369 |
-| 40 | 7369 |
-+--------+--------+
-(4 rows)
-
-!ok
-!}
-
-select deptno, (select empno from "scott".emp order by empno limit 1) as x from "scott".dept;
-+--------+------+
-| DEPTNO | X |
-+--------+------+
-| 10 | 7369 |
-| 20 | 7369 |
-| 30 | 7369 |
-| 40 | 7369 |
-+--------+------+
-(4 rows)
-
-!ok
-
-# End scalar.oq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/sequence.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/sequence.iq b/core/src/test/resources/sql/sequence.iq
new file mode 100644
index 0000000..be79eaa
--- /dev/null
+++ b/core/src/test/resources/sql/sequence.iq
@@ -0,0 +1,79 @@
+# sequence.iq - Sequences
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+!use seq
+!set outputformat mysql
+
+select next value for "my_seq" as c from (values 1, 2);
++---+
+| C |
++---+
+| 1 |
+| 2 |
++---+
+(2 rows)
+
+!ok
+select current value for "my_seq" as c from (values 1, 2);
++---+
+| C |
++---+
+| 2 |
+| 2 |
++---+
+(2 rows)
+
+!ok
+
+select next value for "my_seq" as c from (values 1, 2);
+C BIGINT(19) NOT NULL
+!type
+
+# Qualified with schema name
+select next value for "s"."my_seq" as c from (values 1, 2);
+C BIGINT(19) NOT NULL
+!type
+
+select next value for "unknown_seq" as c from (values 1, 2);
+From line 1, column 23 to line 1, column 35: Table 'unknown_seq' not found
+!error
+
+# Qualified with bad schema name
+select next value for "unknown_schema"."my_seq" as c from (values 1, 2);
+From line 1, column 23 to line 1, column 47: Table 'unknown_schema.my_seq' not found
+!error
+
+# Table found, but not a sequence
+select next value for "metadata".tables as c from (values 1, 2);
+From line 1, column 23 to line 1, column 39: Table 'metadata.TABLES' is not a sequence
+!error
+
+# Sequences appear in the catalog as tables of type 'SEQUENCE'
+select * from "metadata".tables;
++----------+------------+-----------+--------------+---------+---------+-----------+----------+------------------------+---------------+
+| tableCat | tableSchem | tableName | tableType | remarks | typeCat | typeSchem | typeName | selfReferencingColName | refGeneration |
++----------+------------+-----------+--------------+---------+---------+-----------+----------+------------------------+---------------+
+| | metadata | COLUMNS | SYSTEM_TABLE | | | | | | |
+| | metadata | TABLES | SYSTEM_TABLE | | | | | | |
+| | s | my_seq | SEQUENCE | | | | | | |
++----------+------------+-----------+--------------+---------+---------+-----------+----------+------------------------+---------------+
+(3 rows)
+
+!ok
+
+# End sequence.iq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/sequence.oq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/sequence.oq b/core/src/test/resources/sql/sequence.oq
deleted file mode 100644
index 4f338de..0000000
--- a/core/src/test/resources/sql/sequence.oq
+++ /dev/null
@@ -1,79 +0,0 @@
-# sequence.oq - Sequences
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to you under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-!use seq
-!set outputformat mysql
-
-select next value for "my_seq" as c from (values 1, 2);
-+---+
-| C |
-+---+
-| 1 |
-| 2 |
-+---+
-(2 rows)
-
-!ok
-select current value for "my_seq" as c from (values 1, 2);
-+---+
-| C |
-+---+
-| 2 |
-| 2 |
-+---+
-(2 rows)
-
-!ok
-
-select next value for "my_seq" as c from (values 1, 2);
-C BIGINT(19) NOT NULL
-!type
-
-# Qualified with schema name
-select next value for "s"."my_seq" as c from (values 1, 2);
-C BIGINT(19) NOT NULL
-!type
-
-select next value for "unknown_seq" as c from (values 1, 2);
-From line 1, column 23 to line 1, column 35: Table 'unknown_seq' not found
-!error
-
-# Qualified with bad schema name
-select next value for "unknown_schema"."my_seq" as c from (values 1, 2);
-From line 1, column 23 to line 1, column 47: Table 'unknown_schema.my_seq' not found
-!error
-
-# Table found, but not a sequence
-select next value for "metadata".tables as c from (values 1, 2);
-From line 1, column 23 to line 1, column 39: Table 'metadata.TABLES' is not a sequence
-!error
-
-# Sequences appear in the catalog as tables of type 'SEQUENCE'
-select * from "metadata".tables;
-+----------+------------+-----------+--------------+---------+---------+-----------+----------+------------------------+---------------+
-| tableCat | tableSchem | tableName | tableType | remarks | typeCat | typeSchem | typeName | selfReferencingColName | refGeneration |
-+----------+------------+-----------+--------------+---------+---------+-----------+----------+------------------------+---------------+
-| | metadata | COLUMNS | SYSTEM_TABLE | | | | | | |
-| | metadata | TABLES | SYSTEM_TABLE | | | | | | |
-| | s | my_seq | SEQUENCE | | | | | | |
-+----------+------------+-----------+--------------+---------+---------+-----------+----------+------------------------+---------------+
-(3 rows)
-
-!ok
-
-# End sequence.oq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/sort.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/sort.iq b/core/src/test/resources/sql/sort.iq
new file mode 100644
index 0000000..0be2add
--- /dev/null
+++ b/core/src/test/resources/sql/sort.iq
@@ -0,0 +1,179 @@
+# sort.iq - Sorting and collation
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+!use foodmart
+!set outputformat mysql
+
+# The ArrayTable "days" is sorted by "day", so plan must not contain sort
+select * from "days" order by "day";
+!verify
+EnumerableTableScan(table=[[foodmart2, days]])
+!plan
+
+# The ArrayTable "days" is sorted by "day", so the plan does not sort, only applies limit
+select * from "days" order by "day" limit 2;
++-----+----------+
+| day | week_day |
++-----+----------+
+| 1 | Sunday |
+| 2 | Monday |
++-----+----------+
+(2 rows)
+
+!ok
+EnumerableLimit(fetch=[2])
+ EnumerableTableScan(table=[[foodmart2, days]])
+!plan
+
+# The ArrayTable "days" is sorted by "day", so the plan must not contain Sort
+select * from "days" where "day" between 2 and 4 order by "day";
++-----+-----------+
+| day | week_day |
++-----+-----------+
+| 2 | Monday |
+| 3 | Tuesday |
+| 4 | Wednesday |
++-----+-----------+
+(3 rows)
+
+!ok
+EnumerableCalc(expr#0..1=[{inputs}], expr#2=[2], expr#3=[>=($t0, $t2)], expr#4=[4], expr#5=[<=($t0, $t4)], expr#6=[AND($t3, $t5)], proj#0..1=[{exprs}], $condition=[$t6])
+ EnumerableTableScan(table=[[foodmart2, days]])
+!plan
+
+# [CALCITE-970] Default collation of NULL values
+# Nulls high, i.e. first if DESC
+select "store_id", "grocery_sqft" from "store"
+where "store_id" < 3
+order by 2 DESC;
++----------+--------------+
+| store_id | grocery_sqft |
++----------+--------------+
+| 0 | |
+| 2 | 22271 |
+| 1 | 17475 |
++----------+--------------+
+(3 rows)
+
+!ok
+
+# Nulls high, i.e. first if DESC, composite sort
+select "store_id", "grocery_sqft" from "store"
+where "store_id" < 3
+order by "florist", 2 DESC;
++----------+--------------+
+| store_id | grocery_sqft |
++----------+--------------+
+| 0 | |
+| 2 | 22271 |
+| 1 | 17475 |
++----------+--------------+
+(3 rows)
+
+!ok
+
+# Nulls high, i.e. last if ASC
+select "store_id", "grocery_sqft" from "store"
+where "store_id" < 3
+order by 2;
++----------+--------------+
+| store_id | grocery_sqft |
++----------+--------------+
+| 1 | 17475 |
+| 2 | 22271 |
+| 0 | |
++----------+--------------+
+(3 rows)
+
+!ok
+
+# [CALCITE-969] Composite EnumerableSort with DESC wrongly sorts NULL values low
+# Nulls high, i.e. last if ASC, composite sort
+select "store_id", "grocery_sqft" from "store"
+where "store_id" < 3
+order by "florist", 2;
++----------+--------------+
+| store_id | grocery_sqft |
++----------+--------------+
+| 1 | 17475 |
+| 2 | 22271 |
+| 0 | |
++----------+--------------+
+(3 rows)
+
+!ok
+
+!use post
+
+# [CALCITE-603] WITH ... ORDER BY cannot find table
+with e as (select "empid" as empid from "hr"."emps" where "empid" < 120)
+select * from e as e1, e as e2 order by e1.empid + e2.empid, e1.empid;
++-------+--------+
+| EMPID | EMPID0 |
++-------+--------+
+| 100 | 100 |
+| 100 | 110 |
+| 110 | 100 |
+| 110 | 110 |
++-------+--------+
+(4 rows)
+
+!ok
+
+# WITH ... LIMIT
+with e as (select "empid" as empid from "hr"."emps" where "empid" < 200)
+select * from e where empid > 100 limit 5;
++-------+
+| EMPID |
++-------+
+| 150 |
+| 110 |
++-------+
+(2 rows)
+
+!ok
+
+# [CALCITE-634] Allow ORDER BY aggregate function in SELECT DISTINCT, provided
+# that it occurs in SELECT clause
+select distinct "deptno", count(*) as c
+from "hr"."emps"
+group by "deptno"
+order by count(*) desc;
++--------+---+
+| deptno | C |
++--------+---+
+| 10 | 3 |
+| 20 | 1 |
++--------+---+
+(2 rows)
+
+!ok
+
+select distinct count("empid") as c
+from "hr"."emps"
+group by "empid"
+order by 1;
++---+
+| C |
++---+
+| 1 |
++---+
+(1 row)
+
+!ok
+
+# End sort.iq
[6/7] calcite git commit: [CALCITE-1023] Planner rule that removes
Aggregate keys that are constant
Posted by jh...@apache.org.
[CALCITE-1023] Planner rule that removes Aggregate keys that are constant
Recognize that if there is a "CAST(c) = literal" predicate, and the cast is widening, then c must be constant.
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/5197a714
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/5197a714
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/5197a714
Branch: refs/heads/master
Commit: 5197a714705c7bfaa6a46a0907267b47870b18d1
Parents: d55ff83
Author: Julian Hyde <jh...@apache.org>
Authored: Fri Dec 11 16:32:47 2015 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Sat Dec 12 13:41:15 2015 -0800
----------------------------------------------------------------------
.../calcite/plan/RelOptPredicateList.java | 20 ++-
.../org/apache/calcite/plan/RelOptUtil.java | 2 +
.../calcite/rel/metadata/RelMdPredicates.java | 25 +++-
.../rel/rules/AggregateConstantKeyRule.java | 130 +++++++++++++++++++
.../rel/rules/ReduceExpressionsRule.java | 87 +++++++++----
.../main/java/org/apache/calcite/util/Bug.java | 5 +
.../java/org/apache/calcite/test/JdbcTest.java | 16 ++-
.../apache/calcite/test/RelOptRulesTest.java | 43 +++++-
.../org/apache/calcite/test/RelOptRulesTest.xml | 89 ++++++++++++-
core/src/test/resources/sql/agg.iq | 27 ++++
10 files changed, 408 insertions(+), 36 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/5197a714/core/src/main/java/org/apache/calcite/plan/RelOptPredicateList.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptPredicateList.java b/core/src/main/java/org/apache/calcite/plan/RelOptPredicateList.java
index aad89b4..658ae7f 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptPredicateList.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptPredicateList.java
@@ -20,7 +20,6 @@ import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexUtil;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
/**
* Predicates that are known to hold in the output of a particular relational
@@ -74,10 +73,21 @@ public class RelOptPredicateList {
public RelOptPredicateList union(RelOptPredicateList list) {
return RelOptPredicateList.of(
- Iterables.concat(pulledUpPredicates, list.pulledUpPredicates),
- Iterables.concat(leftInferredPredicates, list.leftInferredPredicates),
- Iterables.concat(rightInferredPredicates,
- list.rightInferredPredicates));
+ concat(pulledUpPredicates, list.pulledUpPredicates),
+ concat(leftInferredPredicates, list.leftInferredPredicates),
+ concat(rightInferredPredicates, list.rightInferredPredicates));
+ }
+
+ /** Concatenates two immutable lists, avoiding a copy it possible. */
+ private static <E> ImmutableList<E> concat(ImmutableList<E> list1,
+ ImmutableList<E> list2) {
+ if (list1.isEmpty()) {
+ return list2;
+ } else if (list2.isEmpty()) {
+ return list1;
+ } else {
+ return ImmutableList.<E>builder().addAll(list1).addAll(list2).build();
+ }
}
public RelOptPredicateList shift(int offset) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/5197a714/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
index acbd512..a7b3e08 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -39,6 +39,7 @@ import org.apache.calcite.rel.logical.LogicalCalc;
import org.apache.calcite.rel.logical.LogicalFilter;
import org.apache.calcite.rel.logical.LogicalJoin;
import org.apache.calcite.rel.logical.LogicalProject;
+import org.apache.calcite.rel.rules.AggregateConstantKeyRule;
import org.apache.calcite.rel.rules.AggregateProjectPullUpConstantsRule;
import org.apache.calcite.rel.rules.FilterMergeRule;
import org.apache.calcite.rel.rules.MultiJoin;
@@ -1564,6 +1565,7 @@ public abstract class RelOptUtil {
public static void registerAbstractRels(RelOptPlanner planner) {
planner.addRule(AggregateProjectPullUpConstantsRule.INSTANCE);
+ planner.addRule(AggregateConstantKeyRule.INSTANCE);
planner.addRule(PruneEmptyRules.UNION_INSTANCE);
planner.addRule(PruneEmptyRules.PROJECT_INSTANCE);
planner.addRule(PruneEmptyRules.FILTER_INSTANCE);
http://git-wip-us.apache.org/repos/asf/calcite/blob/5197a714/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
index 7b20b68..35eb56b 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdPredicates.java
@@ -21,6 +21,7 @@ import org.apache.calcite.linq4j.Ord;
import org.apache.calcite.linq4j.function.Predicate1;
import org.apache.calcite.plan.RelOptPredicateList;
import org.apache.calcite.plan.RelOptUtil;
+import org.apache.calcite.plan.volcano.RelSubset;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Aggregate;
import org.apache.calcite.rel.core.Exchange;
@@ -44,8 +45,10 @@ import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlOperator;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.util.BitSets;
+import org.apache.calcite.util.Bug;
import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.Util;
import org.apache.calcite.util.mapping.Mapping;
import org.apache.calcite.util.mapping.MappingType;
import org.apache.calcite.util.mapping.Mappings;
@@ -207,9 +210,10 @@ public class RelMdPredicates {
RelOptPredicateList childInfo =
RelMetadataQuery.getPulledUpPredicates(child);
- return RelOptPredicateList.of(
- Iterables.concat(childInfo.pulledUpPredicates,
- RelOptUtil.conjunctions(filter.getCondition())));
+ return Util.first(childInfo, RelOptPredicateList.EMPTY)
+ .union(
+ RelOptPredicateList.of(
+ RelOptUtil.conjunctions(filter.getCondition())));
}
/** Infers predicates for a {@link org.apache.calcite.rel.core.SemiJoin}. */
@@ -330,6 +334,21 @@ public class RelMdPredicates {
return RelMetadataQuery.getPulledUpPredicates(child);
}
+ /** @see RelMetadataQuery#getPulledUpPredicates(RelNode) */
+ public RelOptPredicateList getPredicates(RelSubset r) {
+ if (!Bug.CALCITE_794_FIXED) {
+ return RelOptPredicateList.EMPTY;
+ }
+ RelOptPredicateList list = null;
+ for (RelNode r2 : r.getRels()) {
+ RelOptPredicateList list2 = RelMetadataQuery.getPulledUpPredicates(r2);
+ if (list2 != null) {
+ list = list == null ? list2 : list.union(list2);
+ }
+ }
+ return Util.first(list, RelOptPredicateList.EMPTY);
+ }
+
/**
* Utility to infer predicates from one side of the join that apply on the
* other side.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5197a714/core/src/main/java/org/apache/calcite/rel/rules/AggregateConstantKeyRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/AggregateConstantKeyRule.java b/core/src/main/java/org/apache/calcite/rel/rules/AggregateConstantKeyRule.java
new file mode 100644
index 0000000..ea31178
--- /dev/null
+++ b/core/src/main/java/org/apache/calcite/rel/rules/AggregateConstantKeyRule.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.rel.rules;
+
+import org.apache.calcite.plan.RelOptPredicateList;
+import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.rel.core.Aggregate;
+import org.apache.calcite.rel.core.RelFactories;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
+import org.apache.calcite.rel.type.RelDataTypeField;
+import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexLiteral;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.tools.RelBuilder;
+import org.apache.calcite.tools.RelBuilderFactory;
+import org.apache.calcite.util.ImmutableBitSet;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.NavigableMap;
+import java.util.TreeMap;
+
+/**
+ * Planner rule that removes constant keys from an
+ * a {@link Aggregate}.
+ *
+ * <p>It never removes the last column, because {@code Aggregate([])} returns
+ * 1 row even if its input is empty.
+ */
+public class AggregateConstantKeyRule extends RelOptRule {
+ public static final AggregateConstantKeyRule INSTANCE =
+ new AggregateConstantKeyRule(RelFactories.LOGICAL_BUILDER,
+ "AggregateConstantKeyRule");
+
+ //~ Constructors -----------------------------------------------------------
+
+ /** Creates an AggregateConstantKeyRule. */
+ private AggregateConstantKeyRule(RelBuilderFactory relBuilderFactory,
+ String description) {
+ super(operand(Aggregate.class, null, Aggregate.IS_SIMPLE, any()),
+ relBuilderFactory, description);
+ }
+
+ //~ Methods ----------------------------------------------------------------
+
+ public void onMatch(RelOptRuleCall call) {
+ final Aggregate aggregate = call.rel(0);
+ assert !aggregate.indicator : "predicate ensured no grouping sets";
+
+ final RexBuilder rexBuilder = aggregate.getCluster().getRexBuilder();
+ final RelOptPredicateList predicates =
+ RelMetadataQuery.getPulledUpPredicates(aggregate.getInput());
+ if (predicates == null) {
+ return;
+ }
+ final ImmutableMap<RexNode, RexLiteral> constants =
+ ReduceExpressionsRule.predicateConstants(rexBuilder, predicates);
+ final NavigableMap<Integer, RexLiteral> map = new TreeMap<>();
+ for (int key : aggregate.getGroupSet()) {
+ final RexInputRef ref =
+ rexBuilder.makeInputRef(aggregate.getInput(), key);
+ if (constants.containsKey(ref)) {
+ map.put(key, constants.get(ref));
+ }
+ }
+
+ if (map.isEmpty()) {
+ return; // none of the keys are constant
+ }
+
+ if (map.size() == aggregate.getGroupCount()) {
+ if (map.size() == 1) {
+ // There is one key, and it is constant. We cannot remove it.
+ return;
+ }
+ map.remove(map.descendingKeySet().descendingIterator().next());
+ }
+
+ ImmutableBitSet newGroupSet = aggregate.getGroupSet();
+ for (int key : map.keySet()) {
+ newGroupSet = newGroupSet.clear(key);
+ }
+ final Aggregate newAggregate =
+ aggregate.copy(aggregate.getTraitSet(), aggregate.getInput(),
+ false, newGroupSet, ImmutableList.of(newGroupSet),
+ aggregate.getAggCallList());
+ final RelBuilder relBuilder = call.builder();
+ relBuilder.push(newAggregate);
+
+ final List<RexNode> projects = new ArrayList<>();
+ int offset = 0;
+ for (RelDataTypeField field : aggregate.getRowType().getFieldList()) {
+ RexNode node = null;
+ if (field.getIndex() < aggregate.getGroupCount()) {
+ node = map.get(aggregate.getGroupSet().nth(field.getIndex()));
+ if (node != null) {
+ node = relBuilder.getRexBuilder().makeCast(field.getType(), node, true);
+ node = relBuilder.alias(node, field.getName());
+ ++offset;
+ }
+ }
+ if (node == null) {
+ node = relBuilder.field(field.getIndex() - offset);
+ }
+ projects.add(node);
+ }
+ call.transformTo(relBuilder.project(projects).build());
+ }
+}
+
+// End AggregateConstantKeyRule.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5197a714/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
index 75943b8..8be202e 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
@@ -396,7 +396,7 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
List<Boolean> addCasts = Lists.newArrayList();
final List<RexNode> removableCasts = Lists.newArrayList();
final ImmutableMap<RexNode, RexLiteral> constants =
- predicateConstants(predicates);
+ predicateConstants(rexBuilder, predicates);
findReducibleExps(rel.getCluster().getTypeFactory(), expList, constants,
constExps, addCasts, removableCasts);
if (constExps.isEmpty() && removableCasts.isEmpty()) {
@@ -508,7 +508,7 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
}
protected static ImmutableMap<RexNode, RexLiteral> predicateConstants(
- RelOptPredicateList predicates) {
+ RexBuilder rexBuilder, RelOptPredicateList predicates) {
// We cannot use an ImmutableMap.Builder here. If there are multiple entries
// with the same key (e.g. "WHERE deptno = 1 AND deptno = 2"), it doesn't
// matter which we take, so the latter will replace the former.
@@ -521,7 +521,7 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
final Map<RexNode, RexLiteral> map = new HashMap<>();
final Set<RexNode> excludeSet = new HashSet<>();
for (RexNode predicate : predicates.pulledUpPredicates) {
- gatherConstraints(map, predicate, excludeSet);
+ gatherConstraints(predicate, map, excludeSet, rexBuilder);
}
final ImmutableMap.Builder<RexNode, RexLiteral> builder =
ImmutableMap.builder();
@@ -559,8 +559,9 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
}
}
- private static void gatherConstraints(Map<RexNode, RexLiteral> map,
- RexNode predicate, Set<RexNode> excludeSet) {
+ private static void gatherConstraints(RexNode predicate,
+ Map<RexNode, RexLiteral> map, Set<RexNode> excludeSet,
+ RexBuilder rexBuilder) {
if (predicate.getKind() != SqlKind.EQUALS) {
decompose(excludeSet, predicate);
return;
@@ -575,28 +576,68 @@ public abstract class ReduceExpressionsRule extends RelOptRule {
final RexNode right = operands.get(1);
// note that literals are immutable too and they can only be compared through
// values.
- if (right instanceof RexLiteral && !excludeSet.contains(left)) {
- RexLiteral existedValue = map.get(left);
- if (existedValue == null) {
- map.put(left, (RexLiteral) right);
- } else {
- if (!existedValue.getValue().equals(((RexLiteral) right).getValue())) {
- // we found conflict values.
- map.remove(left);
- excludeSet.add(left);
+ if (right instanceof RexLiteral) {
+ foo(left, (RexLiteral) right, map, excludeSet, rexBuilder);
+ }
+ if (left instanceof RexLiteral) {
+ foo(right, (RexLiteral) left, map, excludeSet, rexBuilder);
+ }
+ }
+
+ private static void foo(RexNode left, RexLiteral right,
+ Map<RexNode, RexLiteral> map, Set<RexNode> excludeSet,
+ RexBuilder rexBuilder) {
+ if (excludeSet.contains(left)) {
+ return;
+ }
+ final RexLiteral existedValue = map.get(left);
+ if (existedValue == null) {
+ switch (left.getKind()) {
+ case CAST:
+ // Convert "CAST(c) = literal" to "c = literal", as long as it is a
+ // widening cast.
+ final RexNode operand = ((RexCall) left).getOperands().get(0);
+ if (canAssignFrom(left.getType(), operand.getType())) {
+ final RexNode castRight =
+ rexBuilder.makeCast(operand.getType(), right);
+ if (castRight instanceof RexLiteral) {
+ left = operand;
+ right = (RexLiteral) castRight;
+ }
}
}
- } else if (left instanceof RexLiteral && !excludeSet.contains(right)) {
- RexLiteral existedValue = map.get(right);
- if (existedValue == null) {
- map.put(right, (RexLiteral) left);
- } else {
- if (!existedValue.getValue().equals(((RexLiteral) left).getValue())) {
- map.remove(right);
- excludeSet.add(right);
- }
+ map.put(left, right);
+ } else {
+ if (!existedValue.getValue().equals(right.getValue())) {
+ // we found conflicting values, e.g. left = 10 and left = 20
+ map.remove(left);
+ excludeSet.add(left);
+ }
+ }
+ }
+
+ /** Returns whether a value of {@code type2} can be assigned to a variable
+ * of {@code type1}.
+ *
+ * <p>For example:
+ * <ul>
+ * <li>{@code canAssignFrom(BIGINT, TINYINT)} returns {@code true}</li>
+ * <li>{@code canAssignFrom(TINYINT, BIGINT)} returns {@code false}</li>
+ * <li>{@code canAssignFrom(BIGINT, VARCHAR)} returns {@code false}</li>
+ * </ul>
+ */
+ private static boolean canAssignFrom(RelDataType type1, RelDataType type2) {
+ final SqlTypeName name1 = type1.getSqlTypeName();
+ final SqlTypeName name2 = type2.getSqlTypeName();
+ if (name1.getFamily() == name2.getFamily()) {
+ switch (name1.getFamily()) {
+ case NUMERIC:
+ return name1.compareTo(name2) >= 0;
+ default:
+ return true;
}
}
+ return false;
}
/** Pushes predicates into a CASE.
http://git-wip-us.apache.org/repos/asf/calcite/blob/5197a714/core/src/main/java/org/apache/calcite/util/Bug.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/util/Bug.java b/core/src/main/java/org/apache/calcite/util/Bug.java
index a1309ab..6248684 100644
--- a/core/src/main/java/org/apache/calcite/util/Bug.java
+++ b/core/src/main/java/org/apache/calcite/util/Bug.java
@@ -170,6 +170,11 @@ public abstract class Bug {
* Timeout executing joins against MySQL</a> is fixed. */
public static final boolean CALCITE_673_FIXED = false;
+ /** Whether
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-794">[CALCITE-794]
+ * Detect cycles when computing statistics</a> is fixed. */
+ public static final boolean CALCITE_794_FIXED = false;
+
/**
* Use this to flag temporary code.
*/
http://git-wip-us.apache.org/repos/asf/calcite/blob/5197a714/core/src/test/java/org/apache/calcite/test/JdbcTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
index 9d2597f..0eccd4a 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java
@@ -4688,10 +4688,22 @@ public class JdbcTest {
final Function<String, Object> env =
new Function<String, Object>() {
public Object apply(String varName) {
- if (varName.equals("jdk18")) {
+ switch (varName) {
+ case "jdk18":
return System.getProperty("java.version").startsWith("1.8");
+ case "fixed":
+ return new Function<String, Object>() {
+ public Object apply(String v) {
+ switch (v) {
+ case "calcite794":
+ return Bug.CALCITE_794_FIXED;
+ }
+ return null;
+ }
+ };
+ default:
+ return null;
}
- return null;
}
};
final Quidem.NewConnectionFactory connectionFactory =
http://git-wip-us.apache.org/repos/asf/calcite/blob/5197a714/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index 1be8331..4061b0d 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -36,6 +36,7 @@ import org.apache.calcite.rel.metadata.CachingRelMetadataProvider;
import org.apache.calcite.rel.metadata.ChainedRelMetadataProvider;
import org.apache.calcite.rel.metadata.DefaultRelMetadataProvider;
import org.apache.calcite.rel.metadata.RelMetadataProvider;
+import org.apache.calcite.rel.rules.AggregateConstantKeyRule;
import org.apache.calcite.rel.rules.AggregateExpandDistinctAggregatesRule;
import org.apache.calcite.rel.rules.AggregateFilterTransposeRule;
import org.apache.calcite.rel.rules.AggregateJoinTransposeRule;
@@ -486,7 +487,7 @@ public class RelOptRulesTest extends RelOptTestBase {
.addRuleInstance(ReduceExpressionsRule.JOIN_INSTANCE)
.build();
final String sql = "select e1.sal\n"
- + " from (select * from emp where deptno = 200) as e1\n"
+ + "from (select * from emp where deptno = 200) as e1\n"
+ "where e1.deptno in (\n"
+ " select e2.deptno from emp e2 where e2.sal = 100)";
checkPlanning(tester.withDecorrelation(false).withTrim(true), preProgram,
@@ -2021,6 +2022,46 @@ public class RelOptRulesTest extends RelOptTestBase {
checkPlanning(tester, preProgram, new HepPlanner(program), sql);
}
+ /** Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-1023">[CALCITE-1023]
+ * Planner rule that removes Aggregate keys that are constant</a>. */
+ @Test public void testAggregateConstantKeyRule() {
+ final HepProgram program = new HepProgramBuilder()
+ .addRuleInstance(AggregateConstantKeyRule.INSTANCE)
+ .build();
+ final String sql = "select count(*) as c\n"
+ + "from sales.emp\n"
+ + "where deptno = 10\n"
+ + "group by deptno, sal";
+ checkPlanning(new HepPlanner(program), sql);
+ }
+
+ /** Tests {@link AggregateConstantKeyRule} where reduction is not possible
+ * because "deptno" is the only key. */
+ @Test public void testAggregateConstantKeyRule2() {
+ final HepProgram program = new HepProgramBuilder()
+ .addRuleInstance(AggregateConstantKeyRule.INSTANCE)
+ .build();
+ final String sql = "select count(*) as c\n"
+ + "from sales.emp\n"
+ + "where deptno = 10\n"
+ + "group by deptno";
+ checkPlanUnchanged(new HepPlanner(program), sql);
+ }
+
+ /** Tests {@link AggregateConstantKeyRule} where both keys are constants but
+ * only one can be removed. */
+ @Test public void testAggregateConstantKeyRule3() {
+ final HepProgram program = new HepProgramBuilder()
+ .addRuleInstance(AggregateConstantKeyRule.INSTANCE)
+ .build();
+ final String sql = "select job\n"
+ + "from sales.emp\n"
+ + "where sal is null and job = 'Clerk'\n"
+ + "group by sal, job\n"
+ + "having count(*) > 3";
+ checkPlanning(new HepPlanner(program), sql);
+ }
}
// End RelOptRulesTest.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5197a714/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index fc82b09..38edf69 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -199,7 +199,8 @@ ProjectRel(EXPR$0=[1])
</TestCase>
<TestCase name="testSemiJoinReduceConstants">
<Resource name="sql">
- <![CDATA[select e1.sal from (select * from emp where deptno = 200) as e1
+ <![CDATA[select e1.sal
+from (select * from emp where deptno = 200) as e1
where e1.deptno in (
select e2.deptno from emp e2 where e2.sal = 100)]]>
</Resource>
@@ -3914,7 +3915,8 @@ LogicalAggregate(group=[{}], EXPR$0=[COUNT()])
</TestCase>
<TestCase name="testPushFilterPastAggThree">
<Resource name="sql">
- <![CDATA[select deptno from emp group by deptno having count(*) > 1]]>
+ <![CDATA[select deptno from emp
+group by deptno having count(*) > 1]]>
</Resource>
<Resource name="planBefore">
<![CDATA[
@@ -4234,4 +4236,87 @@ LogicalSort(sort0=[$0], dir0=[ASC], fetch=[0])
]]>
</Resource>
</TestCase>
+ <TestCase name="testAggregateConstantKeyRule">
+ <Resource name="sql">
+ <![CDATA[select count(*) as c
+from sales.emp
+where deptno = 10
+group by deptno, sal]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalProject(C=[$2])
+ LogicalAggregate(group=[{0, 1}], C=[COUNT()])
+ LogicalProject(DEPTNO=[$7], SAL=[$5])
+ LogicalFilter(condition=[=($7, 10)])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalProject(C=[$2])
+ LogicalProject(DEPTNO=[10], SAL=[$0], C=[$1])
+ LogicalAggregate(group=[{1}], C=[COUNT()])
+ LogicalProject(DEPTNO=[$7], SAL=[$5])
+ LogicalFilter(condition=[=($7, 10)])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testAggregateConstantKeyRule2">
+ <Resource name="sql">
+ <![CDATA[select count(*) as c
+from sales.emp
+where deptno = 10
+group by deptno]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalProject(C=[$1])
+ LogicalAggregate(group=[{0}], C=[COUNT()])
+ LogicalProject(DEPTNO=[$7])
+ LogicalFilter(condition=[=($7, 10)])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalProject(C=[$1])
+ LogicalAggregate(group=[{0}], C=[COUNT()])
+ LogicalProject(DEPTNO=[$7])
+ LogicalFilter(condition=[=($7, 10)])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testAggregateConstantKeyRule3">
+ <Resource name="sql">
+ <![CDATA[select job
+from sales.emp
+where sal is null and job = 'Clerk'
+group by sal, job
+having count(*) > 3]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalProject(JOB=[$1])
+ LogicalFilter(condition=[>($2, 3)])
+ LogicalAggregate(group=[{0, 1}], agg#0=[COUNT()])
+ LogicalProject(SAL=[$5], JOB=[$2])
+ LogicalFilter(condition=[AND(IS NULL($5), =($2, 'Clerk'))])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalProject(JOB=[$1])
+ LogicalFilter(condition=[>($2, 3)])
+ LogicalProject(SAL=[$0], JOB=['Clerk'], $f1=[$1])
+ LogicalAggregate(group=[{0}], agg#0=[COUNT()])
+ LogicalProject(SAL=[$5], JOB=[$2])
+ LogicalFilter(condition=[AND(IS NULL($5), =($2, 'Clerk'))])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
</Root>
http://git-wip-us.apache.org/repos/asf/calcite/blob/5197a714/core/src/test/resources/sql/agg.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/agg.iq b/core/src/test/resources/sql/agg.iq
index 28aca38..720b3df 100644
--- a/core/src/test/resources/sql/agg.iq
+++ b/core/src/test/resources/sql/agg.iq
@@ -1378,6 +1378,33 @@ select count('1') from "scott".emp join "scott".dept using (deptno) where false;
!ok
+# [CALCITE-1023] Planner rule that removes Aggregate keys that are constant
+select job, sum(sal) as sum_sal, deptno
+from "scott".emp
+where deptno = 10
+group by deptno, job;
++-----------+---------+--------+
+| JOB | SUM_SAL | DEPTNO |
++-----------+---------+--------+
+| CLERK | 1300.00 | 10 |
+| MANAGER | 2450.00 | 10 |
+| PRESIDENT | 5000.00 | 10 |
++-----------+---------+--------+
+(3 rows)
+
+!ok
+!if (fixed.calcite794) {
+select job, sum(sal) as sum_sal, deptno
+from "scott".emp
+where deptno = 10
+group by deptno, job;
+EnumerableCalc(expr#0..2=[{inputs}], JOB=[$t0], SUM_SAL=[$t2], DEPTNO=[$t1])
+ EnumerableAggregate(group=[{2, 7}], SUM_SAL=[SUM($5)])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[CAST($t7):INTEGER], expr#9=[10], expr#10=[=($t8, $t9)], proj#0..7=[{exprs}], $condition=[$t10])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+!}
+
# [CALCITE-729] IndexOutOfBoundsException in ROLLUP query on JDBC data source
!use jdbc_scott
select deptno, job, count(*) as c
[3/7] calcite git commit: [CALCITE-1022] Rename ".oq" Quidem files to
".iq"
Posted by jh...@apache.org.
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/join.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/join.iq b/core/src/test/resources/sql/join.iq
new file mode 100644
index 0000000..357ddc5
--- /dev/null
+++ b/core/src/test/resources/sql/join.iq
@@ -0,0 +1,288 @@
+# join.iq - Join query tests
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+!use post
+!set outputformat mysql
+
+# OR is a theta join
+select *
+from emp
+join dept
+on emp.deptno = dept.deptno or emp.ename = dept.dname;
++-------+--------+--------+---------+-------------+
+| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
++-------+--------+--------+---------+-------------+
+| Alice | 30 | F | 30 | Engineering |
+| Bob | 10 | M | 10 | Sales |
+| Eric | 20 | M | 20 | Marketing |
+| Jane | 10 | F | 10 | Sales |
+| Susan | 30 | F | 30 | Engineering |
++-------+--------+--------+---------+-------------+
+(5 rows)
+
+!ok
+
+# As an INNER join, it can be executed as an equi-join followed by a filter
+EnumerableCalc(expr#0..4=[{inputs}], expr#5=[=($t1, $t3)], expr#6=[CAST($t0):CHAR(11) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary" NOT NULL], expr#7=[=($t6, $t4)], expr#8=[OR($t5, $t7)], proj#0..4=[{exprs}], $condition=[$t8])
+ EnumerableJoin(condition=[true], joinType=[inner])
+ EnumerableUnion(all=[true])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Jane'], expr#2=[10], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Bob'], expr#2=[10], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Eric'], expr#2=[20], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Susan'], expr#2=[30], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Alice'], expr#2=[30], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Adam'], expr#2=[50], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Eve'], expr#2=[50], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Grace'], expr#2=[60], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Wilma'], expr#2=[null], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableValues(tuples=[[{ 10, 'Sales ' }, { 20, 'Marketing ' }, { 30, 'Engineering' }, { 40, 'Empty ' }]])
+!plan
+
+# Now the same, but LEFT join
+select *
+from emp
+left join dept
+on emp.deptno = dept.deptno or emp.ename = dept.dname;
++-------+--------+--------+---------+-------------+
+| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
++-------+--------+--------+---------+-------------+
+| Adam | 50 | M | | |
+| Alice | 30 | F | 30 | Engineering |
+| Bob | 10 | M | 10 | Sales |
+| Eric | 20 | M | 20 | Marketing |
+| Eve | 50 | F | | |
+| Grace | 60 | F | | |
+| Jane | 10 | F | 10 | Sales |
+| Susan | 30 | F | 30 | Engineering |
+| Wilma | | F | | |
++-------+--------+--------+---------+-------------+
+(9 rows)
+
+!ok
+
+# Cannot be decomposed into an equi-join; plan uses EnumerableThetaJoin
+EnumerableThetaJoin(condition=[OR(=($1, $3), =(CAST($0):CHAR(11) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary" NOT NULL, $4))], joinType=[left])
+ EnumerableUnion(all=[true])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Jane'], expr#2=[10], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Bob'], expr#2=[10], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Eric'], expr#2=[20], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Susan'], expr#2=[30], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Alice'], expr#2=[30], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Adam'], expr#2=[50], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Eve'], expr#2=[50], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Grace'], expr#2=[60], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=['Wilma'], expr#2=[null], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
+ EnumerableValues(tuples=[[{ 0 }]])
+ EnumerableValues(tuples=[[{ 10, 'Sales ' }, { 20, 'Marketing ' }, { 30, 'Engineering' }, { 40, 'Empty ' }]])
+!plan
+
+!use scott
+
+# Push aggregate through join
+select distinct dept.deptno, emp.deptno
+from "scott".emp join "scott".dept using (deptno);
++--------+--------+
+| DEPTNO | DEPTNO |
++--------+--------+
+| 10 | 10 |
+| 20 | 20 |
+| 30 | 30 |
++--------+--------+
+(3 rows)
+
+!ok
+EnumerableAggregate(group=[{0, 2}])
+ EnumerableJoin(condition=[=($0, $2)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+select distinct dept.deptno
+from "scott".emp join "scott".dept using (deptno);
++--------+
+| DEPTNO |
++--------+
+| 10 |
+| 20 |
+| 30 |
++--------+
+(3 rows)
+
+!ok
+EnumerableAggregate(group=[{0}])
+ EnumerableJoin(condition=[=($0, $2)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], DEPTNO=[$t7])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+# [CALCITE-676] AssertionError in GROUPING SETS query
+select emp.deptno as e, dept.deptno as d
+from "scott".emp join "scott".dept using (deptno)
+group by cube(emp.deptno, dept.deptno);
++----+----+
+| E | D |
++----+----+
+| 10 | 10 |
+| 10 | |
+| 20 | 20 |
+| 20 | |
+| 30 | 30 |
+| 30 | |
+| | 10 |
+| | 20 |
+| | 30 |
+| | |
++----+----+
+(10 rows)
+
+!ok
+
+# [CALCITE-688] splitCondition does not behave correctly
+# when one side of the condition references columns from
+# different inputs
+select distinct emp1.deptno, emp3.ename
+from "scott".emp emp1 join "scott".emp emp2 on (emp1.deptno = emp2.deptno)
+join "scott".emp emp3 on (emp1.deptno + emp2.deptno = emp3.deptno + 10);
++--------+--------+
+| DEPTNO | ENAME |
++--------+--------+
+| 10 | CLARK |
+| 10 | KING |
+| 10 | MILLER |
+| 20 | ALLEN |
+| 20 | BLAKE |
+| 20 | JAMES |
+| 20 | MARTIN |
+| 20 | TURNER |
+| 20 | WARD |
++--------+--------+
+(9 rows)
+
+!ok
+
+EnumerableCalc(expr#0..1=[{inputs}], DEPTNO0=[$t1], ENAME=[$t0])
+ EnumerableAggregate(group=[{1, 16}])
+ EnumerableJoin(condition=[=($8, $25)], joinType=[inner])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[10], expr#9=[+($t7, $t8)], proj#0..7=[{exprs}], $f8=[$t9])
+ EnumerableTableScan(table=[[scott, EMP]])
+ EnumerableCalc(expr#0..15=[{inputs}], expr#16=[+($t7, $t15)], expr#17=[CAST($t16):INTEGER], proj#0..15=[{exprs}], $f16=[$t17])
+ EnumerableJoin(condition=[=($7, $15)], joinType=[inner])
+ EnumerableTableScan(table=[[scott, EMP]])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+
+
+# [CALCITE-457] Non-ansi join should push condition with expression into join
+select e.deptno, d.deptno
+from "scott".dept D , "scott".emp E
+where e.deptno + 10 = d.deptno * 2;
++--------+--------+
+| DEPTNO | DEPTNO |
++--------+--------+
+| 10 | 10 |
+| 10 | 10 |
+| 10 | 10 |
+| 30 | 20 |
+| 30 | 20 |
+| 30 | 20 |
+| 30 | 20 |
+| 30 | 20 |
+| 30 | 20 |
++--------+--------+
+(9 rows)
+
+!ok
+EnumerableCalc(expr#0..4=[{inputs}], DEPTNO=[$t3], DEPTNO0=[$t0])
+ EnumerableJoin(condition=[=($1, $4)], joinType=[inner])
+ EnumerableCalc(expr#0..2=[{inputs}], expr#3=[2], expr#4=[*($t0, $t3)], DEPTNO=[$t0], $f1=[$t4])
+ EnumerableTableScan(table=[[scott, DEPT]])
+ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[10], expr#9=[+($t7, $t8)], EMPNO=[$t0], DEPTNO=[$t7], $f2=[$t9])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
+### [CALCITE-801] NullPointerException using USING on table alias with column aliases
+select *
+from (values (100, 'Bill', 1),
+ (200, 'Eric', 1),
+ (150, 'Sebastian', 3)) as e(empid, name, deptno)
+join (values (1, 'LeaderShip'),
+ (2, 'TestGroup'),
+ (3, 'Development')) as d(deptno, name)
+using (deptno);
++-------+-----------+--------+---------+-------------+
+| EMPID | NAME | DEPTNO | DEPTNO0 | NAME0 |
++-------+-----------+--------+---------+-------------+
+| 100 | Bill | 1 | 1 | LeaderShip |
+| 150 | Sebastian | 3 | 3 | Development |
+| 200 | Eric | 1 | 1 | LeaderShip |
++-------+-----------+--------+---------+-------------+
+(3 rows)
+
+!ok
+
+### [CALCITE-1018] SortJoinTransposeRule not firing due to getMaxRowCount(RelSubset) returning null
+select * from (select * from "scott".emp) e left join (
+ select * from "scott".dept d) using (deptno)
+order by empno limit 10;
++-------+--------+-----------+------+------------+---------+---------+--------+---------+------------+----------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | DEPTNO0 | DNAME | LOC |
++-------+--------+-----------+------+------------+---------+---------+--------+---------+------------+----------+
+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 | 20 | RESEARCH | DALLAS |
+| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 | 30 | SALES | CHICAGO |
+| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 | 30 | SALES | CHICAGO |
+| 7566 | JONES | MANAGER | 7839 | 1981-02-04 | 2975.00 | | 20 | 20 | RESEARCH | DALLAS |
+| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 | 30 | SALES | CHICAGO |
+| 7698 | BLAKE | MANAGER | 7839 | 1981-01-05 | 2850.00 | | 30 | 30 | SALES | CHICAGO |
+| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | | 10 | 10 | ACCOUNTING | NEW YORK |
+| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | | 20 | 20 | RESEARCH | DALLAS |
+| 7839 | KING | PRESIDENT | | 1981-11-17 | 5000.00 | | 10 | 10 | ACCOUNTING | NEW YORK |
+| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 | 30 | SALES | CHICAGO |
++-------+--------+-----------+------+------------+---------+---------+--------+---------+------------+----------+
+(10 rows)
+
+!ok
+EnumerableLimit(fetch=[10])
+ EnumerableSort(sort0=[$0], dir0=[ASC])
+ EnumerableJoin(condition=[=($7, $8)], joinType=[left])
+ EnumerableLimit(fetch=[10])
+ EnumerableTableScan(table=[[scott, EMP]])
+ EnumerableTableScan(table=[[scott, DEPT]])
+!plan
+
+# End join.iq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/join.oq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/join.oq b/core/src/test/resources/sql/join.oq
deleted file mode 100644
index 9cd9e2c..0000000
--- a/core/src/test/resources/sql/join.oq
+++ /dev/null
@@ -1,288 +0,0 @@
-# join.oq - Join query tests
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to you under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-!use post
-!set outputformat mysql
-
-# OR is a theta join
-select *
-from emp
-join dept
-on emp.deptno = dept.deptno or emp.ename = dept.dname;
-+-------+--------+--------+---------+-------------+
-| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
-+-------+--------+--------+---------+-------------+
-| Alice | 30 | F | 30 | Engineering |
-| Bob | 10 | M | 10 | Sales |
-| Eric | 20 | M | 20 | Marketing |
-| Jane | 10 | F | 10 | Sales |
-| Susan | 30 | F | 30 | Engineering |
-+-------+--------+--------+---------+-------------+
-(5 rows)
-
-!ok
-
-# As an INNER join, it can be executed as an equi-join followed by a filter
-EnumerableCalc(expr#0..4=[{inputs}], expr#5=[=($t1, $t3)], expr#6=[CAST($t0):CHAR(11) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary" NOT NULL], expr#7=[=($t6, $t4)], expr#8=[OR($t5, $t7)], proj#0..4=[{exprs}], $condition=[$t8])
- EnumerableJoin(condition=[true], joinType=[inner])
- EnumerableUnion(all=[true])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Jane'], expr#2=[10], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Bob'], expr#2=[10], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Eric'], expr#2=[20], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Susan'], expr#2=[30], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Alice'], expr#2=[30], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Adam'], expr#2=[50], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Eve'], expr#2=[50], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Grace'], expr#2=[60], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Wilma'], expr#2=[null], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableValues(tuples=[[{ 10, 'Sales ' }, { 20, 'Marketing ' }, { 30, 'Engineering' }, { 40, 'Empty ' }]])
-!plan
-
-# Now the same, but LEFT join
-select *
-from emp
-left join dept
-on emp.deptno = dept.deptno or emp.ename = dept.dname;
-+-------+--------+--------+---------+-------------+
-| ENAME | DEPTNO | GENDER | DEPTNO0 | DNAME |
-+-------+--------+--------+---------+-------------+
-| Adam | 50 | M | | |
-| Alice | 30 | F | 30 | Engineering |
-| Bob | 10 | M | 10 | Sales |
-| Eric | 20 | M | 20 | Marketing |
-| Eve | 50 | F | | |
-| Grace | 60 | F | | |
-| Jane | 10 | F | 10 | Sales |
-| Susan | 30 | F | 30 | Engineering |
-| Wilma | | F | | |
-+-------+--------+--------+---------+-------------+
-(9 rows)
-
-!ok
-
-# Cannot be decomposed into an equi-join; plan uses EnumerableThetaJoin
-EnumerableThetaJoin(condition=[OR(=($1, $3), =(CAST($0):CHAR(11) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary" NOT NULL, $4))], joinType=[left])
- EnumerableUnion(all=[true])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Jane'], expr#2=[10], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Bob'], expr#2=[10], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Eric'], expr#2=[20], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Susan'], expr#2=[30], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Alice'], expr#2=[30], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Adam'], expr#2=[50], expr#3=['M'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Eve'], expr#2=[50], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Grace'], expr#2=[60], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableCalc(expr#0=[{inputs}], expr#1=['Wilma'], expr#2=[null], expr#3=['F'], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t3])
- EnumerableValues(tuples=[[{ 0 }]])
- EnumerableValues(tuples=[[{ 10, 'Sales ' }, { 20, 'Marketing ' }, { 30, 'Engineering' }, { 40, 'Empty ' }]])
-!plan
-
-!use scott
-
-# Push aggregate through join
-select distinct dept.deptno, emp.deptno
-from "scott".emp join "scott".dept using (deptno);
-+--------+--------+
-| DEPTNO | DEPTNO |
-+--------+--------+
-| 10 | 10 |
-| 20 | 20 |
-| 30 | 30 |
-+--------+--------+
-(3 rows)
-
-!ok
-EnumerableAggregate(group=[{0, 2}])
- EnumerableJoin(condition=[=($0, $2)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-select distinct dept.deptno
-from "scott".emp join "scott".dept using (deptno);
-+--------+
-| DEPTNO |
-+--------+
-| 10 |
-| 20 |
-| 30 |
-+--------+
-(3 rows)
-
-!ok
-EnumerableAggregate(group=[{0}])
- EnumerableJoin(condition=[=($0, $2)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], DEPTNO=[$t0])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], DEPTNO=[$t7])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-# [CALCITE-676] AssertionError in GROUPING SETS query
-select emp.deptno as e, dept.deptno as d
-from "scott".emp join "scott".dept using (deptno)
-group by cube(emp.deptno, dept.deptno);
-+----+----+
-| E | D |
-+----+----+
-| 10 | 10 |
-| 10 | |
-| 20 | 20 |
-| 20 | |
-| 30 | 30 |
-| 30 | |
-| | 10 |
-| | 20 |
-| | 30 |
-| | |
-+----+----+
-(10 rows)
-
-!ok
-
-# [CALCITE-688] splitCondition does not behave correctly
-# when one side of the condition references columns from
-# different inputs
-select distinct emp1.deptno, emp3.ename
-from "scott".emp emp1 join "scott".emp emp2 on (emp1.deptno = emp2.deptno)
-join "scott".emp emp3 on (emp1.deptno + emp2.deptno = emp3.deptno + 10);
-+--------+--------+
-| DEPTNO | ENAME |
-+--------+--------+
-| 10 | CLARK |
-| 10 | KING |
-| 10 | MILLER |
-| 20 | ALLEN |
-| 20 | BLAKE |
-| 20 | JAMES |
-| 20 | MARTIN |
-| 20 | TURNER |
-| 20 | WARD |
-+--------+--------+
-(9 rows)
-
-!ok
-
-EnumerableCalc(expr#0..1=[{inputs}], DEPTNO0=[$t1], ENAME=[$t0])
- EnumerableAggregate(group=[{1, 16}])
- EnumerableJoin(condition=[=($8, $25)], joinType=[inner])
- EnumerableCalc(expr#0..7=[{inputs}], expr#8=[10], expr#9=[+($t7, $t8)], proj#0..7=[{exprs}], $f8=[$t9])
- EnumerableTableScan(table=[[scott, EMP]])
- EnumerableCalc(expr#0..15=[{inputs}], expr#16=[+($t7, $t15)], expr#17=[CAST($t16):INTEGER], proj#0..15=[{exprs}], $f16=[$t17])
- EnumerableJoin(condition=[=($7, $15)], joinType=[inner])
- EnumerableTableScan(table=[[scott, EMP]])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-
-
-# [CALCITE-457] Non-ansi join should push condition with expression into join
-select e.deptno, d.deptno
-from "scott".dept D , "scott".emp E
-where e.deptno + 10 = d.deptno * 2;
-+--------+--------+
-| DEPTNO | DEPTNO |
-+--------+--------+
-| 10 | 10 |
-| 10 | 10 |
-| 10 | 10 |
-| 30 | 20 |
-| 30 | 20 |
-| 30 | 20 |
-| 30 | 20 |
-| 30 | 20 |
-| 30 | 20 |
-+--------+--------+
-(9 rows)
-
-!ok
-EnumerableCalc(expr#0..4=[{inputs}], DEPTNO=[$t3], DEPTNO0=[$t0])
- EnumerableJoin(condition=[=($1, $4)], joinType=[inner])
- EnumerableCalc(expr#0..2=[{inputs}], expr#3=[2], expr#4=[*($t0, $t3)], DEPTNO=[$t0], $f1=[$t4])
- EnumerableTableScan(table=[[scott, DEPT]])
- EnumerableCalc(expr#0..7=[{inputs}], expr#8=[10], expr#9=[+($t7, $t8)], EMPNO=[$t0], DEPTNO=[$t7], $f2=[$t9])
- EnumerableTableScan(table=[[scott, EMP]])
-!plan
-
-### [CALCITE-801] NullPointerException using USING on table alias with column aliases
-select *
-from (values (100, 'Bill', 1),
- (200, 'Eric', 1),
- (150, 'Sebastian', 3)) as e(empid, name, deptno)
-join (values (1, 'LeaderShip'),
- (2, 'TestGroup'),
- (3, 'Development')) as d(deptno, name)
-using (deptno);
-+-------+-----------+--------+---------+-------------+
-| EMPID | NAME | DEPTNO | DEPTNO0 | NAME0 |
-+-------+-----------+--------+---------+-------------+
-| 100 | Bill | 1 | 1 | LeaderShip |
-| 150 | Sebastian | 3 | 3 | Development |
-| 200 | Eric | 1 | 1 | LeaderShip |
-+-------+-----------+--------+---------+-------------+
-(3 rows)
-
-!ok
-
-### [CALCITE-1018] SortJoinTransposeRule not firing due to getMaxRowCount(RelSubset) returning null
-select * from (select * from "scott".emp) e left join (
- select * from "scott".dept d) using (deptno)
-order by empno limit 10;
-+-------+--------+-----------+------+------------+---------+---------+--------+---------+------------+----------+
-| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | DEPTNO0 | DNAME | LOC |
-+-------+--------+-----------+------+------------+---------+---------+--------+---------+------------+----------+
-| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 | 20 | RESEARCH | DALLAS |
-| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 | 30 | SALES | CHICAGO |
-| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 | 30 | SALES | CHICAGO |
-| 7566 | JONES | MANAGER | 7839 | 1981-02-04 | 2975.00 | | 20 | 20 | RESEARCH | DALLAS |
-| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 | 30 | SALES | CHICAGO |
-| 7698 | BLAKE | MANAGER | 7839 | 1981-01-05 | 2850.00 | | 30 | 30 | SALES | CHICAGO |
-| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | | 10 | 10 | ACCOUNTING | NEW YORK |
-| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | | 20 | 20 | RESEARCH | DALLAS |
-| 7839 | KING | PRESIDENT | | 1981-11-17 | 5000.00 | | 10 | 10 | ACCOUNTING | NEW YORK |
-| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 | 30 | SALES | CHICAGO |
-+-------+--------+-----------+------+------------+---------+---------+--------+---------+------------+----------+
-(10 rows)
-
-!ok
-EnumerableLimit(fetch=[10])
- EnumerableSort(sort0=[$0], dir0=[ASC])
- EnumerableJoin(condition=[=($7, $8)], joinType=[left])
- EnumerableLimit(fetch=[10])
- EnumerableTableScan(table=[[scott, EMP]])
- EnumerableTableScan(table=[[scott, DEPT]])
-!plan
-
-# End join.oq
http://git-wip-us.apache.org/repos/asf/calcite/blob/8c2bc8f1/core/src/test/resources/sql/misc.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/misc.iq b/core/src/test/resources/sql/misc.iq
new file mode 100644
index 0000000..10d69fd
--- /dev/null
+++ b/core/src/test/resources/sql/misc.iq
@@ -0,0 +1,1111 @@
+# misc.iq - Miscellaneous queries
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to you under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+!use post
+!set outputformat mysql
+
+# [CALCITE-356] Allow column references of the form schema.table.column
+select "hr"."emps"."empid"
+from "hr"."emps";
++-------+
+| empid |
++-------+
+| 100 |
+| 110 |
+| 150 |
+| 200 |
++-------+
+(4 rows)
+
+!ok
+
+# [CALCITE-881] Allow schema.table.column references in GROUP BY
+select "hr"."emps"."empid", count(*) as c
+from "hr"."emps"
+group by "hr"."emps"."empid";
++-------+---+
+| empid | C |
++-------+---+
+| 100 | 1 |
+| 110 | 1 |
+| 150 | 1 |
+| 200 | 1 |
++-------+---+
+(4 rows)
+
+!ok
+
+select distinct "hr"."emps"."empid" + 1 as e
+from "hr"."emps"
+group by "hr"."emps"."empid";
++-----+
+| E |
++-----+
+| 101 |
+| 111 |
+| 151 |
+| 201 |
++-----+
+(4 rows)
+
+!ok
+
+# [CALCITE-307] CAST(timestamp AS DATE) gives ClassCastException
+# Based on [DRILL-1051]
+with data(c_row, c_timestamp) as (select * from (values
+ (1, TIMESTAMP '1997-01-02 03:04:05'),
+ (2, TIMESTAMP '1997-01-02 00:00:00'),
+ (3, TIMESTAMP '2001-09-22 18:19:20'),
+ (4, TIMESTAMP '1997-02-10 17:32:01'),
+ (5, TIMESTAMP '1997-02-10 17:32:00'),
+ (6, TIMESTAMP '1997-02-11 17:32:01'),
+ (7, TIMESTAMP '1997-02-12 17:32:01'),
+ (8, TIMESTAMP '1997-02-13 17:32:01'),
+ (9, TIMESTAMP '1997-02-14 17:32:01'),
+ (10, TIMESTAMP '1997-02-15 17:32:01'),
+ (11, TIMESTAMP '1997-02-16 17:32:01'),
+ (13, TIMESTAMP '0097-02-16 17:32:01'),
+ (14, TIMESTAMP '0597-02-16 17:32:01'),
+ (15, TIMESTAMP '1097-02-16 17:32:01'),
+ (16, TIMESTAMP '1697-02-16 17:32:01'),
+ (17, TIMESTAMP '1797-02-16 17:32:01'),
+ (18, TIMESTAMP '1897-02-16 17:32:01'),
+ (19, TIMESTAMP '1997-02-16 17:32:01'),
+ (20, TIMESTAMP '2097-02-16 17:32:01'),
+ (21, TIMESTAMP '1996-02-28 17:32:01'),
+ (22, TIMESTAMP '1996-02-29 17:32:01'),
+ (23, TIMESTAMP '1996-03-01 17:32:01')))
+select cast(c_timestamp as varchar(20)), cast(c_timestamp as date) from data where c_row <> 12;
+
++---------------------+------------+
+| EXPR$0 | EXPR$1 |
++---------------------+------------+
+| 1997-01-02 03:04:05 | 1997-01-02 |
+| 1997-01-02 00:00:00 | 1997-01-02 |
+| 2001-09-22 18:19:20 | 2001-09-22 |
+| 1997-02-10 17:32:01 | 1997-02-10 |
+| 1997-02-10 17:32:00 | 1997-02-10 |
+| 1997-02-11 17:32:01 | 1997-02-11 |
+| 1997-02-12 17:32:01 | 1997-02-12 |
+| 1997-02-13 17:32:01 | 1997-02-13 |
+| 1997-02-14 17:32:01 | 1997-02-14 |
+| 1997-02-15 17:32:01 | 1997-02-15 |
+| 1997-02-16 17:32:01 | 1997-02-16 |
+| 0097-02-14 17:32:01 | 0097-02-14 |
+| 0597-02-18 17:32:01 | 0597-02-18 |
+| 1097-02-22 17:32:01 | 1097-02-22 |
+| 1697-02-16 17:32:01 | 1697-02-16 |
+| 1797-02-16 17:32:01 | 1797-02-16 |
+| 1897-02-16 17:32:01 | 1897-02-16 |
+| 1997-02-16 17:32:01 | 1997-02-16 |
+| 2097-02-16 17:32:01 | 2097-02-16 |
+| 1996-02-28 17:32:01 | 1996-02-28 |
+| 1996-02-29 17:32:01 | 1996-02-29 |
+| 1996-03-01 17:32:01 | 1996-03-01 |
++---------------------+------------+
+(22 rows)
+
+!ok
+
+# [DRILL-1149]
+select *, upper("name")
+from "hr"."emps";
++-------+--------+-----------+---------+------------+-----------+
+| empid | deptno | name | salary | commission | EXPR$5 |
++-------+--------+-----------+---------+------------+-----------+
+| 100 | 10 | Bill | 10000.0 | 1000 | BILL |
+| 110 | 10 | Theodore | 11500.0 | 250 | THEODORE |
+| 150 | 10 | Sebastian | 7000.0 | | SEBASTIAN |
+| 200 | 20 | Eric | 8000.0 | 500 | ERIC |
++-------+--------+-----------+---------+------------+-----------+
+(4 rows)
+
+!ok
+
+# [DRILL-1199] Order by nested inside a where clause fails
+# (Not that it's right, but Tableau does it.)
+select * from (select * from "hr"."emps" order by "empid") where (0=1);
++-------+--------+------+--------+------------+
+| empid | deptno | name | salary | commission |
++-------+--------+------+--------+------------+
++-------+--------+------+--------+------------+
+(0 rows)
+
+!ok
+
+# [DRILL-1842] Tableau, again
+select count(distinct "salary") as c
+from "hr"."emps"
+join "hr"."depts" on "emps"."deptno" = "depts"."deptno"
+having count(1) > 0;
++---+
+| C |
++---+
+| 3 |
++---+
+(1 row)
+
+!ok
+
+# [CALCITE-340] SqlToRelConverter fails with complex join condition
+select e."deptno", d."deptno"
+from "hr"."emps" as e
+join "hr"."depts" as d
+on ( e."deptno" + 1 - 1 = d."deptno" + 2 - 2 and e."deptno" + 10 - 10 = d."deptno" + 20 - 20);
++--------+--------+
+| deptno | deptno |
++--------+--------+
+| 10 | 10 |
+| 10 | 10 |
+| 10 | 10 |
++--------+--------+
+(3 rows)
+
+!ok
+
+# [CALCITE-340] SqlToRelConverter fails with complex join condition. Switch LHS and RHS.
+select e."deptno", d."deptno"
+from "hr"."emps" as e
+join "hr"."depts" as d
+on ( d."deptno" + 2 - 2 = e."deptno" + 1 - 1 and d."deptno" + 20 - 20 = e."deptno" + 10 - 10);
++--------+--------+
+| deptno | deptno |
++--------+--------+
+| 10 | 10 |
+| 10 | 10 |
+| 10 | 10 |
++--------+--------+
+(3 rows)
+
+!ok
+
+# [CALCITE-340] SqlToRelConverter fails with complex join condition. Switch LHS and RHS.
+select e."deptno", d."deptno"
+from "hr"."emps" as e
+join "hr"."depts" as d
+on ( d."deptno" + 2 - 2 = e."deptno" + 1 - 1 and e."deptno" + 10 - 10 = d."deptno" + 20 - 20);
++--------+--------+
+| deptno | deptno |
++--------+--------+
+| 10 | 10 |
+| 10 | 10 |
+| 10 | 10 |
++--------+--------+
+(3 rows)
+
+!ok
+
+# [CALCITE-377] Mixed equi and non-equi join
+select e."empid", d."name", e."name"
+from "hr"."emps" as e
+join "hr"."depts" as d
+on e."deptno" = d."deptno"
+and e."name" <> d."name";
++-------+-------+-----------+
+| empid | name | name |
++-------+-------+-----------+
+| 100 | Sales | Bill |
+| 110 | Sales | Theodore |
+| 150 | Sales | Sebastian |
++-------+-------+-----------+
+(3 rows)
+
+!ok
+EnumerableCalc(expr#0..4=[{inputs}], expr#5=[CAST($t2):VARCHAR(1) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary"], expr#6=[CAST($t4):VARCHAR(1) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary"], expr#7=[<>($t5, $t6)], empid=[$t0], name=[$t4], name0=[$t2], $condition=[$t7])
+ EnumerableJoin(condition=[=($1, $3)], joinType=[inner])
+ EnumerableCalc(expr#0..4=[{inputs}], proj#0..2=[{exprs}])
+ EnumerableTableScan(table=[[hr, emps]])
+ EnumerableCalc(expr#0..3=[{inputs}], proj#0..1=[{exprs}])
+ EnumerableTableScan(table=[[hr, depts]])
+!plan
+
+# Same query, expressed using WHERE.
+select e."empid", d."name", e."name"
+from "hr"."emps" as e,
+ "hr"."depts" as d
+where e."deptno" = d."deptno"
+and e."name" <> d."name";
++-------+-------+-----------+
+| empid | name | name |
++-------+-------+-----------+
+| 100 | Sales | Bill |
+| 110 | Sales | Theodore |
+| 150 | Sales | Sebastian |
++-------+-------+-----------+
+(3 rows)
+
+!ok
+EnumerableCalc(expr#0..4=[{inputs}], expr#5=[CAST($t2):VARCHAR(1) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary"], expr#6=[CAST($t4):VARCHAR(1) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary"], expr#7=[<>($t5, $t6)], empid=[$t0], name=[$t4], name0=[$t2], $condition=[$t7])
+ EnumerableJoin(condition=[=($1, $3)], joinType=[inner])
+ EnumerableCalc(expr#0..4=[{inputs}], proj#0..2=[{exprs}])
+ EnumerableTableScan(table=[[hr, emps]])
+ EnumerableCalc(expr#0..3=[{inputs}], proj#0..1=[{exprs}])
+ EnumerableTableScan(table=[[hr, depts]])
+!plan
+
+# EXISTS
+select * from "hr"."emps"
+where exists (
+ select 1 from "hr"."depts" where "depts"."deptno" = "emps"."deptno");
++-------+--------+-----------+---------+------------+
+| empid | deptno | name | salary | commission |
++-------+--------+-----------+---------+------------+
+| 100 | 10 | Bill | 10000.0 | 1000 |
+| 110 | 10 | Theodore | 11500.0 | 250 |
+| 150 | 10 | Sebastian | 7000.0 | |
++-------+--------+-----------+---------+------------+
+(3 rows)
+
+!ok
+EnumerableSemiJoin(condition=[=($1, $5)], joinType=[inner])
+ EnumerableTableScan(table=[[hr, emps]])
+ EnumerableCalc(expr#0..4=[{inputs}], expr#5=[true], deptno0=[$t0], $f0=[$t5])
+ EnumerableJoin(condition=[=($0, $1)], joinType=[inner])
+ EnumerableAggregate(group=[{1}])
+ EnumerableTableScan(table=[[hr, emps]])
+ EnumerableTableScan(table=[[hr, depts]])
+!plan
+
+# NOT EXISTS
+# Right results, but it would be better if the plan used EnumerableSemiJoinRel; see [CALCITE-374]
+select * from "hr"."emps"
+where not exists (
+ select 1 from "hr"."depts" where "depts"."deptno" = "emps"."deptno");
++-------+--------+------+--------+------------+
+| empid | deptno | name | salary | commission |
++-------+--------+------+--------+------------+
+| 200 | 20 | Eric | 8000.0 | 500 |
++-------+--------+------+--------+------------+
+(1 row)
+
+!ok
+EnumerableCalc(expr#0..6=[{inputs}], expr#7=[IS NOT NULL($t6)], expr#8=[NOT($t7)], proj#0..4=[{exprs}], $condition=[$t8])
+ EnumerableJoin(condition=[=($1, $5)], joinType=[left])
+ EnumerableTableScan(table=[[hr, emps]])
+ EnumerableAggregate(group=[{1}], agg#0=[MIN($0)])
+ EnumerableCalc(expr#0..4=[{inputs}], expr#5=[true], $f0=[$t5], deptno0=[$t0])
+ EnumerableJoin(condition=[=($0, $1)], joinType=[inner])
+ EnumerableAggregate(group=[{1}])
+ EnumerableTableScan(table=[[hr, emps]])
+ EnumerableTableScan(table=[[hr, depts]])
+!plan
+
+# NOT EXISTS .. OR NOT EXISTS
+# Right results, but it would be better if the plan used EnumerableSemiJoinRel; see [CALCITE-374]
+select * from "hr"."emps"
+where not exists (
+ select 1 from "hr"."depts" where "depts"."deptno" = "emps"."deptno")
+or not exists (
+ select 1 from "hr"."depts" where "depts"."deptno" + 90 = "emps"."empid");
+
++-------+--------+-----------+---------+------------+
+| empid | deptno | name | salary | commission |
++-------+--------+-----------+---------+------------+
+| 110 | 10 | Theodore | 11500.0 | 250 |
+| 150 | 10 | Sebastian | 7000.0 | |
+| 200 | 20 | Eric | 8000.0 | 500 |
++-------+--------+-----------+---------+------------+
+(3 rows)
+
+!ok
+EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NOT NULL($t5)], expr#9=[NOT($t8)], expr#10=[IS NOT NULL($t7)], expr#11=[NOT($t10)], expr#12=[OR($t9, $t11)], proj#0..4=[{exprs}], $condition=[$t12])
+ EnumerableJoin(condition=[=($0, $6)], joinType=[left])
+ EnumerableCalc(expr#0..6=[{inputs}], proj#0..4=[{exprs}], $f0=[$t6])
+ EnumerableJoin(condition=[=($1, $5)], joinType=[left])
+ EnumerableTableScan(table=[[hr, emps]])
+ EnumerableAggregate(group=[{1}], agg#0=[MIN($0)])
+ EnumerableCalc(expr#0..4=[{inputs}], expr#5=[true], $f0=[$t5], deptno0=[$t0])
+ EnumerableJoin(condition=[=($0, $1)], joinType=[inner])
+ EnumerableAggregate(group=[{1}])
+ EnumerableTableScan(table=[[hr, emps]])
+ EnumerableTableScan(table=[[hr, depts]])
+ EnumerableAggregate(group=[{1}], agg#0=[MIN($0)])
+ EnumerableCalc(expr#0..6=[{inputs}], expr#7=[true], $f0=[$t7], empid=[$t0])
+ EnumerableJoin(condition=[=($1, $6)], joinType=[inner])
+ EnumerableCalc(expr#0=[{inputs}], expr#1=[CAST($t0):INTEGER NOT NULL], proj#0..1=[{exprs}])
+ EnumerableAggregate(group=[{0}])
+ EnumerableSemiJoin(condition=[=($1, $6)], joinType=[inner])
+ EnumerableTableScan(table=[[hr, emps]])
+ EnumerableCalc(expr#0..4=[{inputs}], expr#5=[true], $f0=[$t5], deptno0=[$t0])
+ EnumerableJoin(condition=[=($0, $1)], joinType=[inner])
+ EnumerableAggregate(group=[{1}])
+ EnumerableTableScan(table=[[hr, emps]])
+ EnumerableTableScan(table=[[hr, depts]])
+ EnumerableCalc(expr#0..3=[{inputs}], expr#4=[90], expr#5=[+($t0, $t4)], proj#0..3=[{exprs}], $f4=[$t5])
+ EnumerableTableScan(table=[[hr, depts]])
+!plan
+
+# Filter combined with an OR filter.
+select * from (
+ select * from "hr"."emps" as e
+ where e."deptno" < 30) as e
+where e."deptno" > 10 or e."name" = 'Sebastian';
++-------+--------+-----------+--------+------------+
+| empid | deptno | name | salary | commission |
++-------+--------+-----------+--------+------------+
+| 150 | 10 | Sebastian | 7000.0 | |
+| 200 | 20 | Eric | 8000.0 | 500 |
++-------+--------+-----------+--------+------------+
+(2 rows)
+
+!ok
+
+# Filter combined with an AND filter. Test case for
+# [CALCITE-389] MergeFilterRule should flatten AND condition
+select * from (
+ select * from "hr"."emps" as e
+ where e."deptno" < 30) as e
+where e."deptno" >= 10 and e."name" = 'Sebastian';
++-------+--------+-----------+--------+------------+
+| empid | deptno | name | salary | commission |
++-------+--------+-----------+--------+------------+
+| 150 | 10 | Sebastian | 7000.0 | |
++-------+--------+-----------+--------+------------+
+(1 row)
+
+!ok
+
+# [CALCITE-393] If no fields are projected from a table, field trimmer should
+# project a dummy expression
+select 1 from "hr"."emps";
++--------+
+| EXPR$0 |
++--------+
+| 1 |
+| 1 |
+| 1 |
+| 1 |
++--------+
+(4 rows)
+
+!ok
+EnumerableCalc(expr#0..4=[{inputs}], expr#5=[1], EXPR$0=[$t5])
+ EnumerableTableScan(table=[[hr, emps]])
+!plan
+
+# [CALCITE-393] for table scan under join
+select count(*) as c from "hr"."emps", "hr"."depts";
++----+
+| C |
++----+
+| 12 |
++----+
+(1 row)
+
+!ok
+EnumerableAggregate(group=[{}], C=[COUNT()])
+ EnumerableJoin(condition=[true], joinType=[inner])
+ EnumerableCalc(expr#0..3=[{inputs}], expr#4=[0], DUMMY=[$t4])
+ EnumerableTableScan(table=[[hr, depts]])
+ EnumerableCalc(expr#0..4=[{inputs}], expr#5=[0], DUMMY=[$t5])
+ EnumerableTableScan(table=[[hr, emps]])
+!plan
+
+# [CALCITE-345] AssertionError in RexToLixTranslator comparing to date literal
+!use catchall
+select count(*) as c from "everyTypes" where "sqlDate" = DATE '1970-01-01';
++---+
+| C |
++---+
+| 1 |
++---+
+(1 row)
+
+!ok
+select count(*) as c from "everyTypes" where "sqlDate" = DATE '1971-02-03';
++---+
+| C |
++---+
+| 0 |
++---+
+(1 row)
+
+!ok
+select count(*) as c from "everyTypes" where "sqlDate" > DATE '1970-01-01';
++---+
+| C |
++---+
+| 0 |
++---+
+(1 row)
+
+!ok
+select count(*) as c from "everyTypes" where "sqlTime" = TIME '01:23:45';
++---+
+| C |
++---+
+| 0 |
++---+
+(1 row)
+
+!ok
+select count(*) as c from "everyTypes" where "sqlTimestamp" = TIMESTAMP '1970-01-01 01:23:45';
++---+
+| C |
++---+
+| 0 |
++---+
+(1 row)
+
+!ok
+select count(*) as c from "everyTypes" where "utilDate" = TIMESTAMP '1970-01-01 01:23:45';
++---+
+| C |
++---+
+| 0 |
++---+
+(1 row)
+
+!ok
+
+# [CALCITE-346] Add commutative join rule
+#
+# 3-way join that does not require bushy join. Best plan is: sales_fact_1997 as
+# left-most leaf, then customer (with filter), then product.
+!use foodmart
+select *
+from "sales_fact_1997" as s
+ join "customer" as c using ("customer_id")
+ join "product" as p using ("product_id")
+where c."city" = 'San Francisco';
+EnumerableJoin(condition=[=($0, $38)], joinType=[inner])
+ EnumerableJoin(condition=[=($2, $8)], joinType=[inner])
+ EnumerableTableScan(table=[[foodmart2, sales_fact_1997]])
+ EnumerableCalc(expr#0..28=[{inputs}], expr#29=['San Francisco'], expr#30=[=($t9, $t29)], proj#0..28=[{exprs}], $condition=[$t30])
+ EnumerableTableScan(table=[[foodmart2, customer]])
+ EnumerableTableScan(table=[[foodmart2, product]])
+!plan
+
+# 4-way join whose optimal plan requires bushy join.
+#
+# In the plan, note that filters on customer.city and product_department are
+# pushed down. And the plan is a bushy join, with sub-joins (product_class,
+# product) and (sales_fact_1997, customer). However, scan(sales_fact_1997)
+# should be left-most leaf, but is not because CommutativeJoinRule is currently
+# disabled.
+!use foodmart
+select *
+from "sales_fact_1997" as s
+ join "customer" as c using ("customer_id")
+ join "product" as p using ("product_id")
+ join "product_class" as pc using ("product_class_id")
+where c."city" = 'San Francisco'
+ and pc."product_department" = 'Snacks';
+EnumerableCalc(expr#0..56=[{inputs}], product_id0=[$t20], time_id=[$t21], customer_id=[$t22], promotion_id=[$t23], store_id=[$t24], store_sales=[$t25], store_cost=[$t26], unit_sales=[$t27], customer_id0=[$t28], account_num=[$t29], lname=[$t30], fname=[$t31], mi=[$t32], address1=[$t33], address2=[$t34], address3=[$t35], address4=[$t36], city=[$t37], state_province=[$t38], postal_code=[$t39], country=[$t40], customer_region_id=[$t41], phone1=[$t42], phone2=[$t43], birthdate=[$t44], marital_status=[$t45], yearly_income=[$t46], gender=[$t47], total_children=[$t48], num_children_at_home=[$t49], education=[$t50], date_accnt_opened=[$t51], member_card=[$t52], occupation=[$t53], houseowner=[$t54], num_cars_owned=[$t55], fullname=[$t56], product_class_id0=[$t5], product_id=[$t6], brand_name=[$t7], product_name=[$t8], SKU=[$t9], SRP=[$t10], gross_weight=[$t11], net_weight=[$t12], recyclable_package=[$t13], low_fat=[$t14], units_per_case=[$t15], cases_per_pallet=[$t16], shelf_width=[$t17], she
lf_height=[$t18], shelf_depth=[$t19], product_class_id=[$t0], product_subcategory=[$t1], product_category=[$t2], product_department=[$t3], product_family=[$t4])
+ EnumerableJoin(condition=[=($6, $20)], joinType=[inner])
+ EnumerableJoin(condition=[=($0, $5)], joinType=[inner])
+ EnumerableCalc(expr#0..4=[{inputs}], expr#5=['Snacks'], expr#6=[=($t3, $t5)], proj#0..4=[{exprs}], $condition=[$t6])
+ EnumerableTableScan(table=[[foodmart2, product_class]])
+ EnumerableTableScan(table=[[foodmart2, product]])
+ EnumerableJoin(condition=[=($2, $8)], joinType=[inner])
+ EnumerableTableScan(table=[[foodmart2, sales_fact_1997]])
+ EnumerableCalc(expr#0..28=[{inputs}], expr#29=['San Francisco'], expr#30=[=($t9, $t29)], proj#0..28=[{exprs}], $condition=[$t30])
+ EnumerableTableScan(table=[[foodmart2, customer]])
+!plan
+
+# Check that when filters are merged, duplicate conditions are eliminated.
+select * from (
+ select * from "days"
+ where "day" = 1)
+where "day" = 1;
+EnumerableCalc(expr#0..1=[{inputs}], expr#2=[1], expr#3=[=($t0, $t2)], proj#0..1=[{exprs}], $condition=[$t3])
+ EnumerableTableScan(table=[[foodmart2, days]])
+!plan
+
+# [HIVE-5873] Semi-join to count subquery
+# [CALCITE-365] AssertionError while translating query with WITH and correlated sub-query
+!if (false) {
+with parts (PNum, OrderOnHand)
+ as (select * from (values (3, 6), (10, 1), (8, 0)) as t(PNum, OrderOnHand)),
+ supply (PNum, Qty)
+ as (select * from (values (3, 4), (3, 2), (10, 1)))
+select pnum
+from parts p
+where orderOnHand
+ in (select count(*) from supply s
+ where s.pnum = p.pnum);
++------+
+| PNUM |
++------+
+| 8 |
++------+
+(1 row)
+
+!ok
+!}
+
+# [HIVE-7362]
+# Just checking that HAVING-EXISTS works.
+with src (key, "value")
+ as (select * from (values (1, 'a'), (2, 'z')) as t(key, "value"))
+select b.key, count(*) as c
+from src b
+group by b.key
+having exists
+ (select a.key
+ from src a
+ where a.key = b.key and a."value" > 'val_9');
++-----+---+
+| KEY | C |
++-----+---+
+| 2 | 1 |
++-----+---+
+(1 row)
+
+!ok
+
+# [CALCITE-411] Duplicate aliases
+select 1 as a, 2 as a from (values (true));
++---+---+
+| A | A |
++---+---+
+| 1 | 2 |
++---+---+
+(1 row)
+
+!ok
+
+select "day", "day" from "days" where "day" < 3;
++-----+-----+
+| day | day |
++-----+-----+
+| 1 | 1 |
+| 2 | 2 |
++-----+-----+
+(2 rows)
+
+!ok
+
+# [DERBY-5313] CASE expression in GROUP BY clause
+select case when a=1 then 1 else 2 end
+from "days" t1(a,x) join "days" t2(b,x) on a=b
+group by case when a=1 then 1 else 2 end;
++--------+
+| EXPR$0 |
++--------+
+| 1 |
+| 2 |
++--------+
+(2 rows)
+
+!ok
+
+# [DERBY-4450] GROUP BY in an IN-subquery inside HAVING clause whose select list
+# is subset of group by columns.
+select sum("day") from "days" group by "week_day" having "week_day" in (
+ select "week_day" from "days" group by "week_day", "day");
++--------+
+| EXPR$0 |
++--------+
+| 1 |
+| 2 |
+| 3 |
+| 4 |
+| 5 |
+| 6 |
+| 7 |
++--------+
+(7 rows)
+
+!ok
+
+# [DERBY-4701] Aggregate function on a GROUP BY column also present in a HAVING
+# clause
+SELECT MAX("day") as m, COUNT(T."week_day") AS c
+FROM "days" T
+GROUP BY T."week_day"
+HAVING COUNT(T."week_day") = 1;
++---+---+
+| M | C |
++---+---+
+| 1 | 1 |
+| 2 | 1 |
+| 3 | 1 |
+| 4 | 1 |
+| 5 | 1 |
+| 6 | 1 |
+| 7 | 1 |
++---+---+
+(7 rows)
+
+!ok
+
+# [DERBY-3616] Combinations of DISTINCT and GROUP BY
+!use post
+select distinct gender from emp group by gender;
++--------+
+| GENDER |
++--------+
+| F |
+| M |
++--------+
+(2 rows)
+
+!ok
+select distinct gender from emp group by gender, deptno;
++--------+
+| GENDER |
++--------+
+| F |
+| M |
++--------+
+(2 rows)
+
+!ok
+select gender, deptno from emp;
++--------+--------+
+| GENDER | DEPTNO |
++--------+--------+
+| F | 10 |
+| F | 30 |
+| F | 30 |
+| F | 50 |
+| F | 60 |
+| F | |
+| M | 10 |
+| M | 20 |
+| M | 50 |
++--------+--------+
+(9 rows)
+
+!ok
+select distinct gender, deptno from emp group by gender, deptno, ename;
++--------+--------+
+| GENDER | DEPTNO |
++--------+--------+
+| F | 10 |
+| F | 30 |
+| F | 50 |
+| F | 60 |
+| F | |
+| M | 10 |
+| M | 20 |
+| M | 50 |
++--------+--------+
+(8 rows)
+
+!ok
+select distinct gender, deptno from emp group by gender, deptno;
++--------+--------+
+| GENDER | DEPTNO |
++--------+--------+
+| F | 10 |
+| F | 30 |
+| F | 50 |
+| F | 60 |
+| F | |
+| M | 10 |
+| M | 20 |
+| M | 50 |
++--------+--------+
+(8 rows)
+
+!ok
+select distinct gender, deptno from emp group by gender, ename, deptno;
++--------+--------+
+| GENDER | DEPTNO |
++--------+--------+
+| F | 10 |
+| F | 30 |
+| F | 50 |
+| F | 60 |
+| F | |
+| M | 10 |
+| M | 20 |
+| M | 50 |
++--------+--------+
+(8 rows)
+
+!ok
+select distinct gender, sum(deptno) as s from emp group by gender, deptno;
++--------+----+
+| GENDER | S |
++--------+----+
+| F | 10 |
+| F | 50 |
+| F | 60 |
+| F | |
+| M | 10 |
+| M | 20 |
+| M | 50 |
++--------+----+
+(7 rows)
+
+!ok
+select gender, sum(deptno) as s from emp group by gender, deptno;
++--------+----+
+| GENDER | S |
++--------+----+
+| F | 10 |
+| F | 50 |
+| F | 60 |
+| F | 60 |
+| F | |
+| M | 10 |
+| M | 20 |
+| M | 50 |
++--------+----+
+(8 rows)
+
+!ok
+select gender, sum(deptno) as s from emp group by gender, ename;
++--------+----+
+| GENDER | S |
++--------+----+
+| F | 10 |
+| F | 30 |
+| F | 30 |
+| F | 50 |
+| F | 60 |
+| F | |
+| M | 10 |
+| M | 20 |
+| M | 50 |
++--------+----+
+(9 rows)
+
+!ok
+select distinct gender, sum(deptno) as s from emp group by gender, ename;
++--------+----+
+| GENDER | S |
++--------+----+
+| F | 10 |
+| F | 30 |
+| F | 50 |
+| F | 60 |
+| F | |
+| M | 10 |
+| M | 20 |
+| M | 50 |
++--------+----+
+(8 rows)
+
+!ok
+select gender, sum(deptno) as s from emp group by gender, deptno, ename;
++--------+----+
+| GENDER | S |
++--------+----+
+| F | 10 |
+| F | 30 |
+| F | 30 |
+| F | 50 |
+| F | 60 |
+| F | |
+| M | 10 |
+| M | 20 |
+| M | 50 |
++--------+----+
+(9 rows)
+
+!ok
+select distinct gender, sum(deptno) as s from emp group by gender, deptno, ename;
++--------+----+
+| GENDER | S |
++--------+----+
+| F | 10 |
+| F | 30 |
+| F | 50 |
+| F | 60 |
+| F | |
+| M | 10 |
+| M | 20 |
+| M | 50 |
++--------+----+
+(8 rows)
+
+!ok
+select distinct gender, sum(deptno) as s from emp group by gender;
++--------+-----+
+| GENDER | S |
++--------+-----+
+| F | 180 |
+| M | 80 |
++--------+-----+
+(2 rows)
+
+!ok
+
+select distinct gender, deptno from emp group by gender;
+Expression 'DEPTNO' is not being grouped
+!error
+
+select distinct gender, deptno from emp group by gender, ename;
+Expression 'DEPTNO' is not being grouped
+!error
+
+select distinct gender, deptno, sum(deptno) as s from emp group by gender;
+Expression 'DEPTNO' is not being grouped
+!error
+
+!use scott
+
+# [CALCITE-613] Implicitly convert strings in comparisons
+select * from "scott".emp where hiredate < '1981-01-02';
++-------+-------+-------+------+------------+--------+------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+-------+------+------------+--------+------+--------+
+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 |
++-------+-------+-------+------+------------+--------+------+--------+
+(1 row)
+
+!ok
+EnumerableCalc(expr#0..7=[{inputs}], expr#8=['1981-01-02'], expr#9=[CAST($t8):DATE NOT NULL], expr#10=[<($t4, $t9)], proj#0..7=[{exprs}], $condition=[$t10])
+ EnumerableTableScan(table=[[scott, EMP]])
+!plan
+select * from "scott".emp where '1981-01-02' > hiredate;
++-------+-------+-------+------+------------+--------+------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+-------+------+------------+--------+------+--------+
+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 |
++-------+-------+-------+------+------------+--------+------+--------+
+(1 row)
+
+!ok
+select * from "scott".emp where hiredate between '1981-01-02' and '1981-06-01';
++-------+-------+----------+------+------------+---------+--------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+----------+------+------------+---------+--------+--------+
+| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
+| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
+| 7566 | JONES | MANAGER | 7839 | 1981-02-04 | 2975.00 | | 20 |
+| 7698 | BLAKE | MANAGER | 7839 | 1981-01-05 | 2850.00 | | 30 |
++-------+-------+----------+------+------------+---------+--------+--------+
+(4 rows)
+
+!ok
+select * from "scott".emp where hiredate > '1986-01-02';
++-------+-------+---------+------+------------+---------+------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+---------+------+------------+---------+------+--------+
+| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | | 20 |
+| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | | 20 |
++-------+-------+---------+------+------------+---------+------+--------+
+(2 rows)
+
+!ok
+select * from "scott".emp where '1986-01-02' < hiredate;
++-------+-------+---------+------+------------+---------+------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+---------+------+------------+---------+------+--------+
+| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | | 20 |
+| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | | 20 |
++-------+-------+---------+------+------------+---------+------+--------+
+(2 rows)
+
+!ok
+select * from "scott".emp where '1986-' || '01-02' < hiredate;
++-------+-------+---------+------+------------+---------+------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+---------+------+------------+---------+------+--------+
+| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | | 20 |
+| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | | 20 |
++-------+-------+---------+------+------------+---------+------+--------+
+(2 rows)
+
+!ok
+select * from "scott".emp where sal < '1100';
++-------+-------+-------+------+------------+--------+------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+-------+------+------------+--------+------+--------+
+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 |
+| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | | 30 |
++-------+-------+-------+------+------------+--------+------+--------+
+(2 rows)
+
+!ok
+select * from "scott".emp where empno in ('7369', '7876');
++-------+-------+-------+------+------------+---------+------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+-------+------+------------+---------+------+--------+
+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 |
+| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | | 20 |
++-------+-------+-------+------+------------+---------+------+--------+
+(2 rows)
+
+!ok
+select * from "scott".emp where empno between '7500' and '07600';
++-------+-------+----------+------+------------+---------+--------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+----------+------+------------+---------+--------+--------+
+| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
+| 7566 | JONES | MANAGER | 7839 | 1981-02-04 | 2975.00 | | 20 |
++-------+-------+----------+------+------------+---------+--------+--------+
+(2 rows)
+
+!ok
+select * from "scott".emp where deptno between '7369' and '7876';
++-------+-------+-----+-----+----------+-----+------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+-----+-----+----------+-----+------+--------+
++-------+-------+-----+-----+----------+-----+------+--------+
+(0 rows)
+
+!ok
+select * from "scott".emp where '7369' between empno and '7876';
++-------+-------+-------+------+------------+--------+------+--------+
+| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
++-------+-------+-------+------+------------+--------+------+--------+
+| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | | 20 |
++-------+-------+-------+------+------------+--------+------+--------+
+(1 row)
+
+!ok
+
+# [CALCITE-546] Allow table, column and field called "*"
+# See [DRILL-3859], [DRILL-3860].
+SELECT * FROM (VALUES (0, 0)) AS T(A, "*");
++---+---+
+| A | * |
++---+---+
+| 0 | 0 |
++---+---+
+(1 row)
+
+!ok
+
+SELECT a FROM (VALUES (0, 0)) AS T(A, "*");
++---+
+| A |
++---+
+| 0 |
++---+
+(1 row)
+
+!ok
+
+SELECT b FROM (VALUES (0, 0)) AS T(A, "*");
+Column 'B' not found in any table
+!error
+
+# See [DRILL-3860].
+SELECT "a" FROM (VALUES (1, 2, 3, 4)) AS T("a", "A", ".", "*");
++---+
+| a |
++---+
+| 1 |
++---+
+(1 row)
+
+!ok
+
+SELECT "A" FROM (VALUES (1, 2, 3, 4)) AS T("a", "A", ".", "*");
++---+
+| A |
++---+
+| 2 |
++---+
+(1 row)
+
+!ok
+
+SELECT "." FROM (VALUES (1, 2, 3, 4)) AS T("a", "A", ".", "*");
++---+
+| . |
++---+
+| 3 |
++---+
+(1 row)
+
+!ok
+
+SELECT "*" FROM (VALUES (1, 2, 3, 4)) AS T("a", "A", ".", "*");
++---+
+| * |
++---+
+| 4 |
++---+
+(1 row)
+
+!ok
+
+SELECT * FROM (VALUES (1, 2, 3, 4)) AS T("a", "A", ".", "*");
++---+---+---+---+
+| a | A | . | * |
++---+---+---+---+
+| 1 | 2 | 3 | 4 |
++---+---+---+---+
+(1 row)
+
+!ok
+
+# Implicit ROW
+select deptno, (empno, deptno) as r
+from "scott".emp;
++--------+------------+
+| DEPTNO | R |
++--------+------------+
+| 10 | {7782, 10} |
+| 10 | {7839, 10} |
+| 10 | {7934, 10} |
+| 20 | {7369, 20} |
+| 20 | {7566, 20} |
+| 20 | {7788, 20} |
+| 20 | {7876, 20} |
+| 20 | {7902, 20} |
+| 30 | {7499, 30} |
+| 30 | {7521, 30} |
+| 30 | {7654, 30} |
+| 30 | {7698, 30} |
+| 30 | {7844, 30} |
+| 30 | {7900, 30} |
++--------+------------+
+(14 rows)
+
+!ok
+
+# Explicit ROW
+select deptno, row (empno, deptno) as r
+from "scott".emp;
+ROW expression encountered in illegal context
+!error
+
+# [CALCITE-877] Allow ROW as argument to COLLECT
+select deptno, collect(r) as empnos
+from (select deptno, (empno, deptno) as r
+ from "scott".emp)
+group by deptno;
++--------+--------------------------------------------------------------------------+
+| DEPTNO | EMPNOS |
++--------+--------------------------------------------------------------------------+
+| 10 | [{7782, 10}, {7839, 10}, {7934, 10}] |
+| 20 | [{7369, 20}, {7566, 20}, {7788, 20}, {7876, 20}, {7902, 20}] |
+| 30 | [{7499, 30}, {7521, 30}, {7654, 30}, {7698, 30}, {7844, 30}, {7900, 30}] |
++--------+--------------------------------------------------------------------------+
+(3 rows)
+
+!ok
+
+# [CALCITE-922] Value of INTERVAL literal
+select deptno * interval '2' day as d2,
+ deptno * interval -'3' hour as h3,
+ deptno * interval -'-4' hour as h4,
+ deptno * interval -'4:30' hour to minute as h4_5,
+ deptno * interval -'-1-3' year to month as y1_25
+from "scott".dept;
++-----+------+------+---------+--------+
+| D2 | H3 | H4 | H4_5 | Y1_25 |
++-----+------+------+---------+--------+
+| +20 | -30 | +40 | -45:00 | +12-06 |
+| +40 | -60 | +80 | -90:00 | +25-00 |
+| +60 | -90 | +120 | -135:00 | +37-06 |
+| +80 | -120 | +160 | -180:00 | +50-00 |
++-----+------+------+---------+--------+
+(4 rows)
+
+!ok
+
+# End misc.iq
[7/7] calcite git commit: [CALCITE-1024] In a planner test,
if a rule should have no effect, state that explicitly
Posted by jh...@apache.org.
[CALCITE-1024] In a planner test, if a rule should have no effect, state that explicitly
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/d55ff83f
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/d55ff83f
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/d55ff83f
Branch: refs/heads/master
Commit: d55ff83ff3a45b6adffb840daefac3cd2aea34e5
Parents: 02e7ad6
Author: Julian Hyde <jh...@apache.org>
Authored: Fri Dec 11 16:30:19 2015 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Sat Dec 12 13:41:15 2015 -0800
----------------------------------------------------------------------
.../apache/calcite/test/RelOptRulesTest.java | 86 +++++++------
.../org/apache/calcite/test/RelOptTestBase.java | 45 ++++++-
.../org/apache/calcite/test/RelOptRulesTest.xml | 123 +++----------------
3 files changed, 100 insertions(+), 154 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/d55ff83f/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index 4c72ba5..1be8331 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -229,12 +229,11 @@ public class RelOptRulesTest extends RelOptTestBase {
HepProgram.builder()
.addRuleInstance(FilterJoinRule.FILTER_ON_JOIN)
.build();
+ final String sql = "select *\n"
+ + "from dept left join emp using (deptno)\n"
+ + "where emp.deptno is not null and emp.sal > 100";
checkPlanning(tester.withDecorrelation(true).withTrim(true), preProgram,
- new HepPlanner(program),
- "select * from dept where exists (\n"
- + " select * from emp\n"
- + " where emp.deptno = dept.deptno\n"
- + " and emp.sal > 100)");
+ new HepPlanner(program), sql);
}
@Test public void testFullOuterJoinSimplificationToLeftOuter() {
@@ -280,7 +279,8 @@ public class RelOptRulesTest extends RelOptTestBase {
+ " where dname = 'Charlie'");
}
- private void basePushFilterPastAggWithGroupingSets() throws Exception {
+ private void basePushFilterPastAggWithGroupingSets(boolean unchanged)
+ throws Exception {
final HepProgram preProgram =
HepProgram.builder()
.addRuleInstance(ProjectMergeRule.INSTANCE)
@@ -290,15 +290,16 @@ public class RelOptRulesTest extends RelOptTestBase {
HepProgram.builder()
.addRuleInstance(FilterAggregateTransposeRule.INSTANCE)
.build();
- checkPlanning(tester, preProgram, new HepPlanner(program), "${sql}");
+ checkPlanning(tester, preProgram, new HepPlanner(program), "${sql}",
+ unchanged);
}
@Test public void testPushFilterPastAggWithGroupingSets1() throws Exception {
- basePushFilterPastAggWithGroupingSets();
+ basePushFilterPastAggWithGroupingSets(true);
}
@Test public void testPushFilterPastAggWithGroupingSets2() throws Exception {
- basePushFilterPastAggWithGroupingSets();
+ basePushFilterPastAggWithGroupingSets(false);
}
/** Test case for
@@ -316,8 +317,13 @@ public class RelOptRulesTest extends RelOptTestBase {
* <a href="https://issues.apache.org/jira/browse/CALCITE-799">[CALCITE-799]
* Incorrect result for {@code HAVING count(*) > 1}</a>. */
@Test public void testPushFilterPastAggThree() {
- checkPlanning(FilterAggregateTransposeRule.INSTANCE,
- "select deptno from emp group by deptno having count(*) > 1");
+ final HepProgram program =
+ HepProgram.builder()
+ .addRuleInstance(FilterAggregateTransposeRule.INSTANCE)
+ .build();
+ final String sql = "select deptno from emp\n"
+ + "group by deptno having count(*) > 1";
+ checkPlanUnchanged(new HepPlanner(program), sql);
}
/** Test case for
@@ -473,18 +479,18 @@ public class RelOptRulesTest extends RelOptTestBase {
* ReduceExpressionsRule tries to reduce SemiJoin condition to non-equi
* condition</a>. */
@Test public void testSemiJoinReduceConstants() {
- final HepProgram preProgram = HepProgram.builder().addRuleInstance(
- SemiJoinRule.INSTANCE)
- .build();
-
- final HepProgram program = HepProgram.builder().addRuleInstance(
- ReduceExpressionsRule.JOIN_INSTANCE)
- .build();
+ final HepProgram preProgram = HepProgram.builder()
+ .addRuleInstance(SemiJoinRule.INSTANCE)
+ .build();
+ final HepProgram program = HepProgram.builder()
+ .addRuleInstance(ReduceExpressionsRule.JOIN_INSTANCE)
+ .build();
+ final String sql = "select e1.sal\n"
+ + " from (select * from emp where deptno = 200) as e1\n"
+ + "where e1.deptno in (\n"
+ + " select e2.deptno from emp e2 where e2.sal = 100)";
checkPlanning(tester.withDecorrelation(false).withTrim(true), preProgram,
- new HepPlanner(program),
- "select e1.sal from (select * from emp where deptno = 200) as e1\n"
- + "where e1.deptno in (\n"
- + " select e2.deptno from emp e2 where e2.sal = 100)");
+ new HepPlanner(program), sql, true);
}
protected void semiJoinTrim() {
@@ -845,10 +851,10 @@ public class RelOptRulesTest extends RelOptTestBase {
.addRuleInstance(ReduceExpressionsRule.JOIN_INSTANCE)
.build();
- checkPlanning(program,
- "select d.deptno"
- + " from dept d"
- + " where d.deptno=7 and d.deptno=8");
+ final String sql = "select d.deptno"
+ + " from dept d"
+ + " where d.deptno=7 and d.deptno=8";
+ checkPlanUnchanged(new HepPlanner(program), sql);
}
/** Test case for
@@ -980,8 +986,9 @@ public class RelOptRulesTest extends RelOptTestBase {
.setExecutor(null);
// Rule should not fire, but there should be no NPE
- checkPlanning(program,
- "select * from (values (1,2)) where 1 + 2 > 3 + CAST(NULL AS INTEGER)");
+ final String sql =
+ "select * from (values (1,2)) where 1 + 2 > 3 + CAST(NULL AS INTEGER)";
+ checkPlanUnchanged(new HepPlanner(program), sql);
}
@Test public void testAlreadyFalseEliminatesFilter() throws Exception {
@@ -1754,26 +1761,27 @@ public class RelOptRulesTest extends RelOptTestBase {
}
@Test public void testPushFilterWithRank() throws Exception {
- HepProgram program = new HepProgramBuilder().addRuleInstance(
- FilterProjectTransposeRule.INSTANCE).build();
+ HepProgram program = new HepProgramBuilder()
+ .addRuleInstance(FilterProjectTransposeRule.INSTANCE).build();
final String sql = "select e1.ename, r\n"
+ "from (\n"
+ " select ename, "
+ " rank() over(partition by deptno order by sal) as r "
+ " from emp) e1\n"
+ "where r < 2";
- checkPlanning(program, sql);
+ checkPlanUnchanged(new HepPlanner(program), sql);
}
@Test public void testPushFilterWithRankExpr() throws Exception {
- HepProgram program = new HepProgramBuilder().addRuleInstance(
- FilterProjectTransposeRule.INSTANCE).build();
- checkPlanning(program, "select e1.ename, r\n"
+ HepProgram program = new HepProgramBuilder()
+ .addRuleInstance(FilterProjectTransposeRule.INSTANCE).build();
+ final String sql = "select e1.ename, r\n"
+ "from (\n"
+ " select ename,\n"
+ " rank() over(partition by deptno order by sal) + 1 as r "
+ " from emp) e1\n"
- + "where r < 2");
+ + "where r < 2";
+ checkPlanUnchanged(new HepPlanner(program), sql);
}
/** Test case for
@@ -1853,7 +1861,7 @@ public class RelOptRulesTest extends RelOptTestBase {
+ "from (select * from sales.emp where empno = 10) as e "
+ "join sales.dept as d on e.empno < d.deptno "
+ "group by e.empno,d.deptno";
- checkPlanning(tester, preProgram, new HepPlanner(program), sql);
+ checkPlanning(tester, preProgram, new HepPlanner(program), sql, true);
}
/** SUM is the easiest aggregate function to split. */
@@ -1977,9 +1985,9 @@ public class RelOptRulesTest extends RelOptTestBase {
.build();
// This one cannot be pushed down
final String sql = "select * from sales.emp left join (\n"
- + "select * from sales.dept) using (deptno)\n"
- + "order by sal, name limit 10";
- checkPlanning(tester, preProgram, new HepPlanner(program), sql);
+ + "select * from sales.dept) using (deptno)\n"
+ + "order by sal, name limit 10";
+ checkPlanning(tester, preProgram, new HepPlanner(program), sql, true);
}
/** Test case for
http://git-wip-us.apache.org/repos/asf/calcite/blob/d55ff83f/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java b/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java
index 777991a..c6db96c 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptTestBase.java
@@ -32,6 +32,8 @@ import com.google.common.collect.Lists;
import java.util.List;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
@@ -85,6 +87,17 @@ abstract class RelOptTestBase extends SqlToRelTestBase {
}
/**
+ * Checks that the plan is the same before and after executing a given
+ * planner. Useful for checking circumstances where rules should not fire.
+ *
+ * @param planner Planner
+ * @param sql SQL query
+ */
+ protected void checkPlanUnchanged(RelOptPlanner planner, String sql) {
+ checkPlanning(tester, null, planner, sql, true);
+ }
+
+ /**
* Checks the plan for a SQL statement before/after executing a given rule,
* with a pre-program to prepare the tree.
*
@@ -93,11 +106,23 @@ abstract class RelOptTestBase extends SqlToRelTestBase {
* @param planner Planner
* @param sql SQL query
*/
- protected void checkPlanning(
- Tester tester,
- HepProgram preProgram,
- RelOptPlanner planner,
- String sql) {
+ protected void checkPlanning(Tester tester, HepProgram preProgram,
+ RelOptPlanner planner, String sql) {
+ checkPlanning(tester, preProgram, planner, sql, false);
+ }
+
+ /**
+ * Checks the plan for a SQL statement before/after executing a given rule,
+ * with a pre-program to prepare the tree.
+ *
+ * @param tester Tester
+ * @param preProgram Program to execute before comparing before state
+ * @param planner Planner
+ * @param sql SQL query
+ * @param unchanged Whether the rule is to have no effect
+ */
+ protected void checkPlanning(Tester tester, HepProgram preProgram,
+ RelOptPlanner planner, String sql, boolean unchanged) {
final DiffRepository diffRepos = getDiffRepos();
String sql2 = diffRepos.expand("sql", sql);
final RelRoot root = tester.convertSqlToRel(sql2);
@@ -132,7 +157,15 @@ abstract class RelOptTestBase extends SqlToRelTestBase {
RelNode relAfter = planner.findBestExp();
String planAfter = NL + RelOptUtil.toString(relAfter);
- diffRepos.assertEquals("planAfter", "${planAfter}", planAfter);
+ if (unchanged) {
+ assertThat(planAfter, is(planBefore));
+ } else {
+ diffRepos.assertEquals("planAfter", "${planAfter}", planAfter);
+ if (planBefore.equals(planAfter)) {
+ throw new AssertionError("Expected plan before and after is the same.\n"
+ + "You must use unchanged=true or call checkPlanUnchanged");
+ }
+ }
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/d55ff83f/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
----------------------------------------------------------------------
diff --git a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index 5c2e3c0..fc82b09 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -216,19 +216,6 @@ LogicalProject(SAL=[$0])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
- <Resource name="planAfter">
- <![CDATA[
-LogicalProject(SAL=[$0])
- SemiJoin(condition=[=($1, $2)], joinType=[inner])
- LogicalFilter(condition=[=($1, 200)])
- LogicalProject(SAL=[$5], DEPTNO=[$7])
- LogicalTableScan(table=[[CATALOG, SALES, EMP]])
- LogicalProject(DEPTNO=[$1])
- LogicalFilter(condition=[=($0, 100)])
- LogicalProject(SAL=[$5], DEPTNO=[$7])
- LogicalTableScan(table=[[CATALOG, SALES, EMP]])
-]]>
- </Resource>
</TestCase>
<TestCase name="testFullOuterJoinSimplificationToLeftOuter">
<Resource name="sql">
@@ -417,15 +404,6 @@ LogicalProject(DDEPTNO=[$0], DNAME=[$1], C=[$2])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
]]>
</Resource>
- <Resource name="planAfter">
- <![CDATA[
-LogicalProject(DDEPTNO=[$0], DNAME=[$1], C=[$2])
- LogicalProject(DDEPTNO=[CASE($2, null, $0)], DNAME=[CASE($3, null, $1)], C=[$4])
- LogicalFilter(condition=[=(CASE($3, null, $1), 'Charlie')])
- LogicalAggregate(group=[{0, 1}], groups=[[{0, 1}, {0}, {}]], indicator=[true], C=[COUNT()])
- LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
-]]>
- </Resource>
</TestCase>
<TestCase name="testPushFilterPastAggWithGroupingSets2">
<Resource name="sql">
@@ -644,13 +622,6 @@ LogicalProject(DEPTNO=[$0])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
]]>
</Resource>
- <Resource name="planAfter">
- <![CDATA[
-LogicalProject(DEPTNO=[$0])
- LogicalFilter(condition=[AND(=($0, 7), =($0, 8))])
- LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
-]]>
- </Resource>
</TestCase>
<TestCase name="testReduceConstantsEliminatesFilter">
<Resource name="sql">
@@ -2923,41 +2894,27 @@ LogicalProject(EMPNO=[10], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$
</TestCase>
<TestCase name="testStrengthenJoinType">
<Resource name="sql">
- <![CDATA[select * from dept where exists (
- select * from emp
- where emp.deptno = dept.deptno
- and emp.sal > 100)]]>
+ <![CDATA[select *
+from dept left join emp using (deptno)
+where emp.deptno is not null and emp.sal > 100]]>
</Resource>
<Resource name="planBefore">
<![CDATA[
-LogicalProject(DEPTNO=[$0], NAME=[$1])
- LogicalJoin(condition=[=($0, $2)], joinType=[inner])
- LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
- LogicalAggregate(group=[{0}])
- LogicalProject(DEPTNO0=[$2], $f0=[true])
- LogicalJoin(condition=[=($1, $2)], joinType=[inner])
- LogicalProject(SAL=[$5], DEPTNO=[$7])
- LogicalFilter(condition=[>($5, 100)])
- LogicalTableScan(table=[[CATALOG, SALES, EMP]])
- LogicalAggregate(group=[{0}])
- LogicalProject(DEPTNO=[$0])
- LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+LogicalProject(DEPTNO=[$0], NAME=[$1], EMPNO=[$2], ENAME=[$3], JOB=[$4], MGR=[$5], HIREDATE=[$6], SAL=[$7], COMM=[$8], DEPTNO0=[$9], SLACKER=[$10])
+ LogicalFilter(condition=[AND(IS NOT NULL($9), >($7, 100))])
+ LogicalJoin(condition=[=($0, $9)], joinType=[left])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
<Resource name="planAfter">
<![CDATA[
-LogicalProject(DEPTNO=[$0], NAME=[$1])
- LogicalJoin(condition=[=($0, $2)], joinType=[inner])
- LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
- LogicalAggregate(group=[{0}])
- LogicalProject(DEPTNO0=[$2], $f0=[true])
- LogicalJoin(condition=[=($1, $2)], joinType=[inner])
- LogicalProject(SAL=[$5], DEPTNO=[$7])
- LogicalFilter(condition=[>($5, 100)])
- LogicalTableScan(table=[[CATALOG, SALES, EMP]])
- LogicalAggregate(group=[{0}])
- LogicalProject(DEPTNO=[$0])
- LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+LogicalProject(DEPTNO=[$0], NAME=[$1], EMPNO=[$2], ENAME=[$3], JOB=[$4], MGR=[$5], HIREDATE=[$6], SAL=[$7], COMM=[$8], DEPTNO0=[$9], SLACKER=[$10])
+ LogicalProject(DEPTNO=[$0], NAME=[$1], EMPNO=[CAST($2):INTEGER], ENAME=[CAST($3):VARCHAR(20) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary"], JOB=[CAST($4):VARCHAR(10) CHARACTER SET "ISO-8859-1" COLLATE "ISO-8859-1$en_US$primary"], MGR=[$5], HIREDATE=[CAST($6):TIMESTAMP(0)], SAL=[CAST($7):INTEGER], COMM=[CAST($8):INTEGER], DEPTNO0=[CAST($9):INTEGER], SLACKER=[CAST($10):BOOLEAN])
+ LogicalJoin(condition=[=($0, $9)], joinType=[inner])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+ LogicalFilter(condition=[>($5, 100)])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
</TestCase>
@@ -3182,14 +3139,6 @@ LogicalProject(ENAME=[$0], R=[$1])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
- <Resource name="planAfter">
- <![CDATA[
-LogicalProject(ENAME=[$0], R=[$1])
- LogicalFilter(condition=[<($1, 2)])
- LogicalProject(ENAME=[$1], R=[RANK() OVER (PARTITION BY $7 ORDER BY $5 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)])
- LogicalTableScan(table=[[CATALOG, SALES, EMP]])
-]]>
- </Resource>
</TestCase>
<TestCase name="testPushFilterWithRankExpr">
<Resource name="sql">
@@ -3207,14 +3156,6 @@ LogicalProject(ENAME=[$0], R=[$1])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
- <Resource name="planAfter">
- <![CDATA[
-LogicalProject(ENAME=[$0], R=[$1])
- LogicalFilter(condition=[<($1, 2)])
- LogicalProject(ENAME=[$1], R=[+(RANK() OVER (PARTITION BY $7 ORDER BY $5 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), 1)])
- LogicalTableScan(table=[[CATALOG, SALES, EMP]])
-]]>
- </Resource>
</TestCase>
<TestCase name="testDistinctCount1">
<Resource name="sql">
@@ -3541,13 +3482,6 @@ LogicalProject(EXPR$0=[$0], EXPR$1=[$1])
LogicalValues(tuples=[[{ 1, 2 }]])
]]>
</Resource>
- <Resource name="planAfter">
- <![CDATA[
-LogicalProject(EXPR$0=[$0], EXPR$1=[$1])
- LogicalFilter(condition=[>(+(1, 2), +(3, null))])
- LogicalValues(tuples=[[{ 1, 2 }]])
-]]>
- </Resource>
</TestCase>
<TestCase name="testExpressionInWindowFunction">
<Resource name="sql">
@@ -3645,16 +3579,6 @@ LogicalAggregate(group=[{0, 9}])
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
]]>
</Resource>
- <Resource name="planAfter">
- <![CDATA[
-LogicalAggregate(group=[{0, 9}])
- LogicalJoin(condition=[<($0, $9)], joinType=[inner])
- LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
- LogicalFilter(condition=[=($0, 10)])
- LogicalTableScan(table=[[CATALOG, SALES, EMP]])
- LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
-]]>
- </Resource>
</TestCase>
<TestCase name="testPushAggregateSumThroughJoin">
<Resource name="sql">
@@ -4001,15 +3925,6 @@ LogicalProject(DEPTNO=[$0])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
- <Resource name="planAfter">
- <![CDATA[
-LogicalProject(DEPTNO=[$0])
- LogicalFilter(condition=[>($1, 1)])
- LogicalAggregate(group=[{0}], agg#0=[COUNT()])
- LogicalProject(DEPTNO=[$7])
- LogicalTableScan(table=[[CATALOG, SALES, EMP]])
-]]>
- </Resource>
</TestCase>
<TestCase name="testPushAggregateFunctionsThroughJoin">
<Resource name="sql">
@@ -4169,16 +4084,6 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$
LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
]]>
</Resource>
- <Resource name="planAfter">
- <![CDATA[
-LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$9], NAME=[$10])
- LogicalSort(sort0=[$5], sort1=[$10], dir0=[ASC], dir1=[ASC], fetch=[10])
- LogicalJoin(condition=[=($7, $9)], joinType=[left])
- LogicalTableScan(table=[[CATALOG, SALES, EMP]])
- LogicalProject(DEPTNO=[$0], NAME=[$1])
- LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
-]]>
- </Resource>
</TestCase>
<TestCase name="testSortJoinTranspose4">
<Resource name="sql">
[5/7] calcite git commit: [CALCITE-1016] "GROUP BY constant" on empty
relation should return 0 rows
Posted by jh...@apache.org.
[CALCITE-1016] "GROUP BY constant" on empty relation should return 0 rows
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/02e7ad61
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/02e7ad61
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/02e7ad61
Branch: refs/heads/master
Commit: 02e7ad61321f9690b41cc1c93c6b9c92fb925451
Parents: 8c2bc8f
Author: Julian Hyde <jh...@apache.org>
Authored: Fri Dec 11 13:57:24 2015 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Sat Dec 12 13:41:15 2015 -0800
----------------------------------------------------------------------
core/src/test/resources/sql/agg.iq | 129 ++++++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/02e7ad61/core/src/test/resources/sql/agg.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/agg.iq b/core/src/test/resources/sql/agg.iq
index 8e5770e..28aca38 100644
--- a/core/src/test/resources/sql/agg.iq
+++ b/core/src/test/resources/sql/agg.iq
@@ -1249,6 +1249,135 @@ EnumerableCalc(expr#0..2=[{inputs}], EMPNO=[$t1], DEPTNO=[$t0])
EnumerableTableScan(table=[[scott, EMP]])
!plan
+# [CALCITE-1016] "GROUP BY constant" on empty relation should return 0 rows
+# Should return 0 rows
+select '1' from "scott".emp where false group by 1;
++--------+
+| EXPR$0 |
++--------+
++--------+
+(0 rows)
+
+!ok
+
+# Should return 0 rows
+select count('1') from "scott".emp where false group by 1;
++--------+
+| EXPR$0 |
++--------+
++--------+
+(0 rows)
+
+!ok
+
+# Should return 1 row
+select count('1') from "scott".emp where false group by ();
++--------+
+| EXPR$0 |
++--------+
+| 0 |
++--------+
+(1 row)
+
+!ok
+
+# Should return 1 row
+select count('1') from "scott".emp where false;
++--------+
+| EXPR$0 |
++--------+
+| 0 |
++--------+
+(1 row)
+
+!ok
+
+# As above, but on VALUES rather than table
+# Should return 0 rows
+select '1' from (values (1, 2), (3, 4)) where false group by 1;
++--------+
+| EXPR$0 |
++--------+
++--------+
+(0 rows)
+
+!ok
+
+# Should return 0 rows
+select count('1') from (values (1, 2), (3, 4)) where false group by 1;
++--------+
+| EXPR$0 |
++--------+
++--------+
+(0 rows)
+
+!ok
+
+# Should return 1 row
+select count('1') from (values (1, 2), (3, 4)) where false group by ();
++--------+
+| EXPR$0 |
++--------+
+| 0 |
++--------+
+(1 row)
+
+!ok
+
+# Should return 1 row
+select count('1') from (values (1, 2), (3, 4)) where false;
++--------+
+| EXPR$0 |
++--------+
+| 0 |
++--------+
+(1 row)
+
+!ok
+
+# As above, but on join
+# Should return 0 rows
+select '1' from "scott".emp join "scott".dept using (deptno) where false group by 1;
++--------+
+| EXPR$0 |
++--------+
++--------+
+(0 rows)
+
+!ok
+
+# Should return 0 rows
+select count('1') from "scott".emp join "scott".dept using (deptno) where false group by 1;
++--------+
+| EXPR$0 |
++--------+
++--------+
+(0 rows)
+
+!ok
+
+# Should return 1 row
+select count('1') from "scott".emp join "scott".dept using (deptno) where false group by ();
++--------+
+| EXPR$0 |
++--------+
+| 0 |
++--------+
+(1 row)
+
+!ok
+
+# Should return 1 row
+select count('1') from "scott".emp join "scott".dept using (deptno) where false;
++--------+
+| EXPR$0 |
++--------+
+| 0 |
++--------+
+(1 row)
+
+!ok
+
# [CALCITE-729] IndexOutOfBoundsException in ROLLUP query on JDBC data source
!use jdbc_scott
select deptno, job, count(*) as c