blob: 05d7df5c62174afc50b3d1d83fd2d9193c717849 [file] [log] [blame]
/*
* 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.drill.exec.physical.impl.lateraljoin;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertFalse;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.drill.PlanTestBase;
import org.apache.drill.common.exceptions.UserRemoteException;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.planner.physical.PlannerSettings;
import org.apache.drill.test.BaseTestQuery;
import org.apache.drill.test.ClientFixture;
import org.apache.drill.test.ClusterFixture;
import org.apache.drill.test.ClusterFixtureBuilder;
import org.junit.BeforeClass;
import org.junit.Test;
public class TestLateralPlans extends BaseTestQuery {
private static final String regularTestFile_1 = "cust_order_10_1.json";
private static final String regularTestFile_2 = "cust_order_10_2.json";
@BeforeClass
public static void enableUnnestLateral() throws Exception {
dirTestWatcher.copyResourceToRoot(Paths.get("lateraljoin", "multipleFiles", regularTestFile_1));
dirTestWatcher.copyResourceToRoot(Paths.get("lateraljoin", "multipleFiles", regularTestFile_2));
test("alter session set `planner.enable_unnest_lateral`=true");
}
@Test
public void testLateralSql() throws Exception {
String sql = "select t.c_name, t2.ord.o_shop as o_shop from cp.`lateraljoin/nested-customer.json` t," +
" unnest(t.orders) t2(ord) limit 1";
PlanTestBase.testPlanMatchingPatterns(sql, new String[]{"column excluded from output: =\\[\\`orders\\`\\]"},
new String[]{});
testBuilder()
.unOrdered()
.sqlQuery(sql)
.baselineColumns("c_name", "o_shop")
.baselineValues("customer1", "Meno Park 1st")
.go();
}
@Test
public void testExplainLateralSql() throws Exception {
String explainSql = "explain plan without implementation for select t.c_name, t2.ord.o_shop as o_shop from cp.`lateraljoin/nested-customer.json` t," +
" unnest(t.orders) t2(ord) limit 1";
String sql = "select t.c_name, t2.ord.o_shop as o_shop from cp.`lateraljoin/nested-customer.json` t," +
" unnest(t.orders) t2(ord) limit 1";
PlanTestBase.testPlanMatchingPatterns(sql, new String[]{"column excluded from output: =\\[\\`orders\\`\\]"},
new String[]{});
test(explainSql);
}
@Test
public void testFilterPushCorrelate() throws Exception {
test("alter session set `planner.slice_target`=1");
String sql = "select t.c_name, t2.ord.o_shop as o_shop from cp.`lateraljoin/nested-customer.json` t,"
+ " unnest(t.orders) t2(ord) where t.c_name='customer1' AND t2.ord.o_shop='Meno Park 1st' ";
PlanTestBase.testPlanMatchingPatterns(sql, new String[]{"LateralJoin(.*[\n\r])+.*Filter(.*[\n\r])+.*Scan(.*[\n\r])+.*Filter"},
new String[]{});
PlanTestBase.testPlanMatchingPatterns(sql, new String[]{"column excluded from output: =\\[\\`orders\\`\\]"},
new String[]{});
testBuilder()
.unOrdered()
.sqlQuery(sql)
.baselineColumns("c_name", "o_shop")
.baselineValues("customer1", "Meno Park 1st")
.go();
}
@Test
public void testLateralSqlPlainCol() throws Exception {
String sql = "select t.c_name, t2.phone as c_phone from cp.`lateraljoin/nested-customer.json` t,"
+ " unnest(t.c_phone) t2(phone) limit 1";
PlanTestBase.testPlanMatchingPatterns(sql, new String[]{"column excluded from output: =\\[\\`c_phone\\`\\]"},
new String[]{});
testBuilder()
.unOrdered()
.sqlQuery(sql)
.baselineColumns("c_name", "c_phone")
.baselineValues("customer1", "6505200001")
.go();
}
@Test
public void testLateralSqlStar() throws Exception {
String sql = "select * from cp.`lateraljoin/nested-customer.json` t, unnest(t.orders) Orders(ord) limit 0";
PlanTestBase.testPlanMatchingPatterns(sql, new String[]{},
new String[]{"column excluded from output: =\\[\\`orders\\`\\]"});
testBuilder()
.unOrdered()
.sqlQuery(sql)
.baselineColumns("c_name", "c_id", "c_phone", "orders", "c_address", "ord")
.expectsEmptyResultSet()
.go();
}
@Test
public void testLateralSqlStar2() throws Exception {
String Sql = "select c.* from cp.`lateraljoin/nested-customer.json` c, unnest(c.orders) Orders(ord) limit 0";
PlanTestBase.testPlanMatchingPatterns(Sql, new String[]{},
new String[]{"column excluded from output: =\\[\\`orders\\`\\]"});
testBuilder()
.unOrdered()
.sqlQuery(Sql)
.baselineColumns("c_name", "c_id", "c_phone", "orders", "c_address")
.expectsEmptyResultSet()
.go();
}
@Test
public void testLateralSqlStar3() throws Exception {
String sql = "select Orders.*, c.* from cp.`lateraljoin/nested-customer.json` c, unnest(c.orders) Orders(ord) limit 0";
PlanTestBase.testPlanMatchingPatterns(sql, new String[]{},
new String[]{"column excluded from output: =\\[\\`orders\\`\\]"});
testBuilder()
.unOrdered()
.sqlQuery(sql)
.baselineColumns("ord","c_name", "c_id", "c_phone", "orders", "c_address")
.expectsEmptyResultSet()
.go();
}
@Test
public void testLateralSqlStar4() throws Exception {
String sql = "select Orders.* from cp.`lateraljoin/nested-customer.json` c, unnest(c.orders) Orders(ord) limit 0";
PlanTestBase.testPlanMatchingPatterns(sql, new String[]{"column excluded from output: =\\[\\`orders\\`\\]"}, new String[]{});
testBuilder()
.unOrdered()
.sqlQuery(sql)
.baselineColumns("ord")
.expectsEmptyResultSet()
.go();
}
@Test
public void testLateralSqlWithAS() throws Exception {
String sql = "select t.c_name, t2.orders from cp.`lateraljoin/nested-customer.parquet` t,"
+ " unnest(t.orders) as t2(orders)";
String baselineQuery = "select t.c_name, t2.orders from cp.`lateraljoin/nested-customer.parquet` t inner join" +
" (select c_name, flatten(orders) from cp" +
".`lateraljoin/nested-customer.parquet` ) as t2(name, orders) on t.c_name = t2.name";
PlanTestBase.testPlanMatchingPatterns(sql, new String[]{"column excluded from output: =\\[\\`orders\\`\\]"}, new String[]{});
testBuilder()
.unOrdered()
.sqlQuery(sql)
.sqlBaselineQuery(baselineQuery)
.go();
}
@Test
public void testMultiUnnestLateralAtSameLevel() throws Exception {
String sql = "select t.c_name, t2.orders, t3.orders from cp.`lateraljoin/nested-customer.parquet` t," +
" LATERAL ( select t2.orders from unnest(t.orders) as t2(orders)) as t2, LATERAL " +
"(select t3.orders from unnest(t.orders) as t3(orders)) as t3";
String baselineQuery = "select t.c_name, t2.orders, t3.orders from cp.`lateraljoin/nested-customer.parquet` t inner join" +
" (select c_name, flatten(orders) from cp.`lateraljoin/nested-customer.parquet` ) as t2 (name, orders) on t.c_name = t2.name " +
" inner join (select c_name, flatten(orders) from cp.`lateraljoin/nested-customer.parquet` ) as t3(name, orders) on t.c_name = t3.name";
PlanTestBase.testPlanMatchingPatterns(sql, new String[]{"column excluded from output: =\\[\\`orders\\`\\]"}, new String[]{});
testBuilder()
.unOrdered()
.sqlQuery(sql)
.sqlBaselineQuery(baselineQuery)
.go();
}
@Test
public void testSubQuerySql() throws Exception {
String sql = "select t.c_name, d1.items as items0 , t3.items as items1 from cp.`lateraljoin/nested-customer.parquet` t," +
" lateral (select t2.ord.items as items from unnest(t.orders) t2(ord)) d1," +
" unnest(d1.items) t3(items)";
String baselineQuery = "select t.c_name, t3.orders.items as items0, t3.items as items1 from cp.`lateraljoin/nested-customer.parquet` t " +
" inner join (select c_name, f, flatten(t1.f.items) from (select c_name, flatten(orders) as f from cp.`lateraljoin/nested-customer.parquet`) as t1 ) " +
"t3(name, orders, items) on t.c_name = t3.name ";
PlanTestBase.testPlanMatchingPatterns(sql, new String[]{"column excluded from output: =\\[\\`orders\\`\\]"}, new String[]{"column excluded from output: =\\[\\`items\\`\\]"});
testBuilder()
.unOrdered()
.sqlQuery(sql)
.sqlBaselineQuery(baselineQuery)
.go();
}
@Test
public void testUnnestWithFilter() throws Exception {
String sql = "select t.c_name, d1.items as items0, t3.items as items1 from cp.`lateraljoin/nested-customer.parquet` t," +
" lateral (select t2.ord.items as items from unnest(t.orders) t2(ord)) d1," +
" unnest(d1.items) t3(items) where t.c_id > 1";
String baselineQuery = "select t.c_name, t3.orders.items as items0, t3.items as items1 from cp.`lateraljoin/nested-customer.parquet` t " +
" inner join (select c_name, f, flatten(t1.f.items) from (select c_name, flatten(orders) as f from cp.`lateraljoin/nested-customer.parquet`) as t1 ) " +
"t3(name, orders, items) on t.c_name = t3.name where t.c_id > 1";
PlanTestBase.testPlanMatchingPatterns(sql, new String[]{"column excluded from output: =\\[\\`orders\\`\\]"}, new String[]{"column excluded from output: =\\[\\`items\\`\\]"});
testBuilder()
.unOrdered()
.sqlQuery(sql)
.sqlBaselineQuery(baselineQuery)
.go();
}
@Test
public void testUnnestWithAggInSubquery() throws Exception {
String sql = "select t.c_name, sum(t4.items) from cp.`lateraljoin/nested-customer.parquet` t," +
" lateral (select t2.ord.items as items from unnest(t.orders) t2(ord)) d1," +
" lateral (select sum(t3.items.i_number) from unnest(d1.items) t3(items)) t4(items) where t.c_id > 1 group by t.c_name";
String baselineQuery = "select t.c_name, sum(t3.items.i_number) from cp.`lateraljoin/nested-customer.parquet` t " +
" inner join (select c_name, f, flatten(t1.f.items) from (select c_name, flatten(orders) as f from cp.`lateraljoin/nested-customer.parquet`) as t1 ) " +
"t3(name, orders, items) on t.c_name = t3.name where t.c_id > 1 group by t.c_name";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
client
.testBuilder()
.ordered()
.sqlBaselineQuery(baselineQuery)
.sqlQuery(sql)
.go();
}
}
@Test
public void testUnnestWithAggOnOuterTable() throws Exception {
String sql = "select avg(d2.inum) from cp.`lateraljoin/nested-customer.parquet` t," +
" lateral (select t2.ord.items as items from unnest(t.orders) t2(ord)) d1," +
" lateral (select t3.items.i_number as inum from unnest(d1.items) t3(items)) d2 where t.c_id > 1 group by t.c_id";
String baselineQuery = "select avg(t3.items.i_number) from cp.`lateraljoin/nested-customer.parquet` t " +
" inner join (select c_name, f, flatten(t1.f.items) from (select c_name, flatten(orders) as f from cp.`lateraljoin/nested-customer.parquet`) as t1 ) " +
"t3(name, orders, items) on t.c_name = t3.name where t.c_id > 1 group by t.c_id";
PlanTestBase.testPlanMatchingPatterns(sql, new String[]{"column excluded from output: =\\[\\`orders\\`\\]", "column excluded from output: =\\[\\`items\\`\\]"}, new String[]{});
testBuilder()
.unOrdered()
.sqlQuery(sql)
.sqlBaselineQuery(baselineQuery)
.go();
}
@Test
public void testUnnestTableAndColumnAlias() throws Exception {
String sql = "select t.c_name from cp.`lateraljoin/nested-customer.json` t, unnest(t.orders) ";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
client
.queryBuilder()
.sql(sql)
.run();
} catch (UserRemoteException ex) {
assertThat(ex.getMessage(), containsString("Alias table and column name are required for UNNEST"));
}
}
@Test
public void testUnnestColumnAlias() throws Exception {
String sql = "select t.c_name, t2.orders from cp.`lateraljoin/nested-customer.json` t, unnest(t.orders) t2";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
client
.queryBuilder()
.sql(sql)
.run();
} catch (UserRemoteException ex) {
assertThat(ex.getMessage(), containsString("Column 'orders' not found in table 't2'"));
}
}
/***********************************************************************************************
Following test cases are introduced to make sure no exchanges are present on right side of
Lateral join.
**********************************************************************************************/
@Test
public void testNoExchangeWithAggWithoutGrpBy() throws Exception {
String sql = "select d1.totalprice from dfs.`lateraljoin/multipleFiles` t," +
" lateral ( select sum(t2.ord.o_totalprice) as totalprice from unnest(t.c_orders) t2(ord)) d1";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true)
.setOptionDefault(ExecConstants.SLICE_TARGET, 1);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
String explain = client.queryBuilder().sql(sql).explainText();
String rightChild = getRightChildOfLateral(explain);
assertFalse(rightChild.contains("Exchange"));
}
}
@Test
public void testNoExchangeWithStreamAggWithGrpBy() throws Exception {
String sql = "select d1.totalprice from dfs.`lateraljoin/multipleFiles` t," +
" lateral ( select sum(t2.ord.o_totalprice) as totalprice from unnest(t.c_orders) t2(ord) group by t2.ord.o_orderkey) d1";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true)
.setOptionDefault(ExecConstants.SLICE_TARGET, 1)
.setOptionDefault(PlannerSettings.HASHAGG.getOptionName(), false)
.setOptionDefault(PlannerSettings.STREAMAGG.getOptionName(), true);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
String explain = client.queryBuilder().sql(sql).explainText();
String rightChild = getRightChildOfLateral(explain);
assertFalse(rightChild.contains("Exchange"));
}
}
@Test
public void testNoExchangeWithHashAggWithGrpBy() throws Exception {
String sql = "select d1.totalprice from dfs.`lateraljoin/multipleFiles` t," +
" lateral ( select sum(t2.ord.o_totalprice) as totalprice from unnest(t.c_orders) t2(ord) group by t2.ord.o_orderkey) d1";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true)
.setOptionDefault(ExecConstants.SLICE_TARGET, 1)
.setOptionDefault(PlannerSettings.HASHAGG.getOptionName(), true)
.setOptionDefault(PlannerSettings.STREAMAGG.getOptionName(), false);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
String explain = client.queryBuilder().sql(sql).explainText();
String rightChild = getRightChildOfLateral(explain);
assertFalse(rightChild.contains("Exchange"));
}
}
@Test
public void testNoExchangeWithOrderByWithoutLimit() throws Exception {
String Sql = "select d1.totalprice from dfs.`lateraljoin/multipleFiles` t," +
" lateral ( select t2.ord.o_totalprice as totalprice from unnest(t.c_orders) t2(ord) order by t2.ord.o_orderkey) d1";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true)
.setOptionDefault(ExecConstants.SLICE_TARGET, 1);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
String explain = client.queryBuilder().sql(Sql).explainText();
String rightChild = getRightChildOfLateral(explain);
assertFalse(rightChild.contains("Exchange"));
}
}
@Test
public void testNoExchangeWithOrderByLimit() throws Exception {
String sql = "select d1.totalprice from dfs.`lateraljoin/multipleFiles` t," +
" lateral ( select t2.ord.o_totalprice as totalprice from unnest(t.c_orders) t2(ord) order by t2.ord.o_orderkey limit 10) d1";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true)
.setOptionDefault(ExecConstants.SLICE_TARGET, 1);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
String explain = client.queryBuilder().sql(sql).explainText();
String rightChild = getRightChildOfLateral(explain);
assertFalse(rightChild.contains("Exchange"));
}
}
@Test
public void testNoExchangeWithLateralsDownStreamJoin() throws Exception {
String sql = "select d1.totalprice from dfs.`lateraljoin/multipleFiles` t, dfs.`lateraljoin/multipleFiles` t2, " +
" lateral ( select t2.ord.o_totalprice as totalprice from unnest(t.c_orders) t2(ord) order by t2.ord.o_orderkey limit 10) d1" +
" where t.c_name = t2.c_name";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true)
.setOptionDefault(ExecConstants.SLICE_TARGET, 1);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
String explain = client.queryBuilder().sql(sql).explainText();
String rightChild = getRightChildOfLateral(explain);
assertFalse(rightChild.contains("Exchange"));
}
}
@Test
public void testNoExchangeWithLateralsDownStreamUnion() throws Exception {
String sql = "select t.c_name from dfs.`lateraljoin/multipleFiles` t union all " +
" select t.c_name from dfs.`lateraljoin/multipleFiles` t, " +
" lateral ( select t2.ord.o_totalprice as totalprice from unnest(t.c_orders) t2(ord) order by t2.ord.o_orderkey limit 10) d1";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true)
.setOptionDefault(ExecConstants.SLICE_TARGET, 1);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
String explain = client.queryBuilder().sql(sql).explainText();
String rightChild = getRightChildOfLateral(explain);
assertFalse(rightChild.contains("Exchange"));
}
}
@Test
public void testNoExchangeWithLateralsDownStreamAgg() throws Exception {
String sql = "select sum(d1.totalprice) from dfs.`lateraljoin/multipleFiles` t, " +
" lateral ( select t2.ord.o_totalprice as totalprice from unnest(t.c_orders) t2(ord) order by t2.ord.o_orderkey limit 10) d1 group by t.c_custkey";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true)
.setOptionDefault(ExecConstants.SLICE_TARGET, 1)
.setOptionDefault(PlannerSettings.HASHAGG.getOptionName(), false)
.setOptionDefault(PlannerSettings.STREAMAGG.getOptionName(), true);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
String explain = client.queryBuilder().sql(sql).explainText();
String rightChild = getRightChildOfLateral(explain);
assertFalse(rightChild.contains("Exchange"));
}
}
private String getRightChildOfLateral(String explain) throws Exception {
Matcher matcher = Pattern.compile("LateralJoin.*Unnest", Pattern.MULTILINE | Pattern.DOTALL).matcher(explain);
assertTrue (matcher.find());
String CorrelateUnnest = matcher.group(0);
return CorrelateUnnest.substring(CorrelateUnnest.lastIndexOf("Scan"));
}
//The following test is for testing the explain plan contains relation between lateral and corresponding unnest.
@Test
public void testLateralAndUnnestExplainPlan() throws Exception {
String sql = "select c.* from cp.`lateraljoin/nested-customer.json` c, unnest(c.orders) Orders(ord)";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true)
.setOptionDefault(ExecConstants.SLICE_TARGET, 1);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
String explain = client.queryBuilder().sql(sql).explainText();
String srcOp = explain.substring(explain.indexOf("srcOp"));
assertTrue(srcOp != null && srcOp.length() > 0);
String correlateFragmentPattern = srcOp.substring(srcOp.indexOf("=")+1, srcOp.indexOf("]"));
assertTrue(correlateFragmentPattern != null && correlateFragmentPattern.length() > 0);
Matcher matcher = Pattern.compile(correlateFragmentPattern + ".*LateralJoin", Pattern.MULTILINE | Pattern.DOTALL).matcher(explain);
assertTrue(matcher.find());
}
}
@Test
public void testUnnestTopN() throws Exception {
String sql =
"select customer.c_custkey," +
"customer.c_name," +
"t.o.o_orderkey," +
"t.o.o_totalprice\n" +
"from dfs.`lateraljoin/multipleFiles` customer," +
"unnest(customer.c_orders) t(o)\n" +
"order by customer.c_custkey," +
"t.o.o_orderkey," +
"t.o.o_totalprice\n" +
"limit 50";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
String plan = client.queryBuilder()
.sql(sql)
.explainText();
assertThat("Query plan doesn't contain TopN operator",
plan, containsString("TopN(limit=[50])"));
assertThat("Query plan shouldn't contain Sort operator",
plan, not(containsString("Sort")));
}
}
@Test
public void testMultiUnnestQuery() throws Exception {
String sql = "SELECT t5.l_quantity FROM dfs.`lateraljoin/multipleFiles` t, " +
"LATERAL (SELECT t2.ordrs.o_lineitems FROM UNNEST(t.c_orders) t2(ordrs)) t3(lineitems), " +
"LATERAL (SELECT t4.lineitems.l_quantity FROM UNNEST(t3.lineitems) t4(lineitems)) t5(l_quantity) order by 1";
String baselineQuery = "select dt.lineitems.l_quantity as l_quantity from (select flatten(dt.orders.o_lineitems) as lineitems " +
"from (select flatten(c_orders) as orders from dfs.`lateraljoin/multipleFiles` t) dt)dt order by 1";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true)
.setOptionDefault(ExecConstants.SLICE_TARGET, 1);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
client.testBuilder()
.ordered()
.sqlBaselineQuery(baselineQuery)
.sqlQuery(sql)
.go();
}
}
@Test
public void testNestedColumnQuery() throws Exception {
String sql = "select dt.area_code as area_code, dt.ph as ph from cp.`lateraljoin/nested-customer-map.json` t," +
" lateral (select t2.ord.area_code as area_code , t2.ord.phone as ph from unnest(t.c_address.c_phone) t2(ord)) dt";
String baselineQuery = "select dt.c_ph.area_code as area_code, dt.c_ph.phone as ph from (select flatten(t.c_address.c_phone) as c_ph from cp.`lateraljoin/nested-customer-map.json` t) dt";
ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
.setOptionDefault(PlannerSettings.ENABLE_UNNEST_LATERAL_KEY, true);
try (ClusterFixture cluster = builder.build();
ClientFixture client = cluster.clientFixture()) {
client.testBuilder()
.ordered()
.sqlBaselineQuery(baselineQuery)
.sqlQuery(sql)
.go();
}
}
}