blob: b59e6d9a12963833203820b15ba743dd6bce433b [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.doris.nereids.properties;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.types.IntegerType;
import org.apache.doris.nereids.util.PlanChecker;
import org.apache.doris.utframe.TestWithFeService;
import com.google.common.collect.ImmutableSet;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Set;
class FdTest extends TestWithFeService {
Slot slot1 = new SlotReference("1", IntegerType.INSTANCE, false);
Slot slot2 = new SlotReference("2", IntegerType.INSTANCE, false);
Slot slot3 = new SlotReference("1", IntegerType.INSTANCE, false);
Slot slot4 = new SlotReference("1", IntegerType.INSTANCE, false);
@Override
protected void runBeforeAll() throws Exception {
createDatabase("test");
createTable("create table test.agg (\n"
+ "id int not null,\n"
+ "id2 int replace not null,\n"
+ "name varchar(128) replace not null )\n"
+ "AGGREGATE KEY(id)\n"
+ "distributed by hash(id) buckets 10\n"
+ "properties('replication_num' = '1');");
createTable("create table test.uni (\n"
+ "id int not null,\n"
+ "id2 int not null,\n"
+ "name varchar(128) not null)\n"
+ "UNIQUE KEY(id)\n"
+ "distributed by hash(id) buckets 10\n"
+ "properties('replication_num' = '1');");
connectContext.setDatabase("test");
connectContext.getSessionVariable().setDisableNereidsRules("PRUNE_EMPTY_PARTITION");
}
@Test
void testAgg() {
Plan plan = PlanChecker.from(connectContext)
.analyze("select sum(id2), id2 from agg group by id2")
.getPlan();
Set<Slot> output = ImmutableSet.copyOf(plan.getOutputSet());
System.out.println(plan.getLogicalProperties()
.getTrait().getAllValidFuncDeps(output));
Assertions.assertTrue(
plan.getLogicalProperties()
.getTrait().getAllValidFuncDeps(output)
.isFuncDeps(ImmutableSet.of(plan.getOutput().get(1)), ImmutableSet.of(plan.getOutput().get(0))));
}
@Test
void testTopNLimit() {
Plan plan = PlanChecker.from(connectContext)
.analyze("select id, id2 from agg group by id, id2 order by id limit 1")
.getPlan();
Set<Slot> output = ImmutableSet.copyOf(plan.getOutputSet());
System.out.println(plan.getLogicalProperties()
.getTrait().getAllValidFuncDeps(output));
Assertions.assertTrue(
plan.getLogicalProperties()
.getTrait().getAllValidFuncDeps(output)
.isFuncDeps(output, ImmutableSet.of(plan.getOutput().get(0))));
}
@Test
void testSetOp() {
Plan plan = PlanChecker.from(connectContext)
.analyze("select id, id2 from agg where id2 = id intersect select id, id2 from agg")
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isNullSafeEqual(plan.getOutput().get(0), plan.getOutput().get(1)));
plan = PlanChecker.from(connectContext)
.analyze("select id, id2 from agg where id2 = id except select id, id2 from agg")
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isNullSafeEqual(plan.getOutput().get(0), plan.getOutput().get(1)));
plan = PlanChecker.from(connectContext)
.analyze("select id, id2 from agg where id2 = id union all select id, id2 from agg")
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isEmpty());
plan = PlanChecker.from(connectContext)
.analyze("select id, id2 from agg union all select id, id2 from agg where id2 = id")
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isEmpty());
}
@Test
void testFilterHaving() {
Plan plan = PlanChecker.from(connectContext)
.analyze("select id, id2 from agg where id = 1")
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(0)), ImmutableSet.of(plan.getOutput().get(1))));
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(1)), ImmutableSet.of(plan.getOutput().get(0))));
plan = PlanChecker.from(connectContext)
.analyze("select id, id2 from agg group by id, id2 having id = 1")
.rewrite()
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(0)), ImmutableSet.of(plan.getOutput().get(1))));
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(1)), ImmutableSet.of(plan.getOutput().get(0))));
}
@Test
void testGenerate() {
Plan plan = PlanChecker.from(connectContext)
.analyze("select id, id2 from agg lateral view explode([1,2,3]) tmp1 as e1")
.rewrite()
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(0)), ImmutableSet.of(plan.getOutput().get(1))));
}
@Test
void testJoin() {
// inner join
Plan plan = PlanChecker.from(connectContext)
.analyze("select uni.id, agg.id, agg.id2 from agg join uni "
+ "where agg.id = uni.id")
.rewrite()
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(0)), ImmutableSet.of(plan.getOutput().get(1))));
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(1)), ImmutableSet.of(plan.getOutput().get(0))));
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(1)), ImmutableSet.of(plan.getOutput().get(2))));
// foj
plan = PlanChecker.from(connectContext)
.analyze("select t1.id, t1.id2, t2.id, t2.id2 "
+ "from uni as t1 full outer join uni as t2 on t1.id2 = t2.id2")
.rewrite()
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(0)), ImmutableSet.of(plan.getOutput().get(1))));
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(2)), ImmutableSet.of(plan.getOutput().get(3))));
// loj
plan = PlanChecker.from(connectContext)
.analyze("select t1.id, t1.id2, t2.id, t2.id2 "
+ "from uni as t1 left outer join uni as t2 on t1.id2 = t2.id2")
.rewrite()
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(0)), ImmutableSet.of(plan.getOutput().get(1))));
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(2)), ImmutableSet.of(plan.getOutput().get(3))));
// roj
plan = PlanChecker.from(connectContext)
.analyze("select t1.id, t1.id2, t2.id, t2.id2 "
+ "from uni as t1 right outer join uni as t2 on t1.id2 = t2.id2")
.rewrite()
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(0)), ImmutableSet.of(plan.getOutput().get(1))));
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(2)), ImmutableSet.of(plan.getOutput().get(3))));
}
@Test
void testOneRowRelation() {
Plan plan = PlanChecker.from(connectContext)
.analyze("select 1, 1")
.rewrite()
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(1)), ImmutableSet.of(plan.getOutput().get(0))));
}
@Test
void testProject() {
Plan plan = PlanChecker.from(connectContext)
.analyze("select id as o1, id as o2, id2 as o4, 1 as c1, 1 as c2 from uni where id = id2")
.rewrite()
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(1)), ImmutableSet.of(plan.getOutput().get(0))));
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(0)), ImmutableSet.of(plan.getOutput().get(1))));
}
@Test
void testSubQuery() {
Plan plan = PlanChecker.from(connectContext)
.analyze("select id, id2 from (select id, id2 from agg where id = id2) t")
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(0)), ImmutableSet.of(plan.getOutput().get(1))));
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(1)), ImmutableSet.of(plan.getOutput().get(0))));
}
@Test
void testWindow() {
// partition by uniform
Plan plan = PlanChecker.from(connectContext)
.analyze("select id, id2, row_number() over(partition by id) from agg where id = id2")
.rewrite()
.getPlan();
Assertions.assertTrue(plan.getLogicalProperties().getTrait()
.isDependent(ImmutableSet.of(plan.getOutput().get(1)), ImmutableSet.of(plan.getOutput().get(0))));
}
}