| /** |
| * 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. |
| **/ |
| |
| #include "query_optimizer/strategy/Aggregate.hpp" |
| |
| #include <memory> |
| #include <vector> |
| |
| #include "expressions/aggregation/AggregateFunctionFactory.hpp" |
| #include "expressions/aggregation/AggregationID.hpp" |
| #include "query_optimizer/OptimizerContext.hpp" |
| #include "query_optimizer/expressions/AggregateFunction.hpp" |
| #include "query_optimizer/expressions/Alias.hpp" |
| #include "query_optimizer/expressions/AttributeReference.hpp" |
| #include "query_optimizer/expressions/NamedExpression.hpp" |
| #include "query_optimizer/expressions/Predicate.hpp" |
| #include "query_optimizer/logical/Aggregate.hpp" |
| #include "query_optimizer/logical/Logical.hpp" |
| #include "query_optimizer/logical/Project.hpp" |
| #include "query_optimizer/logical/TableReference.hpp" |
| #include "query_optimizer/physical/Aggregate.hpp" |
| #include "query_optimizer/physical/Physical.hpp" |
| #include "query_optimizer/physical/Selection.hpp" |
| #include "query_optimizer/physical/TableReference.hpp" |
| #include "query_optimizer/strategy/tests/StrategyTest.hpp" |
| #include "types/TypeID.hpp" |
| #include "utility/Cast.hpp" |
| #include "utility/Macros.hpp" |
| |
| #include "glog/logging.h" |
| #include "gtest/gtest.h" |
| |
| namespace quickstep { |
| namespace optimizer { |
| namespace strategy { |
| |
| namespace E = ::quickstep::optimizer::expressions; |
| namespace L = ::quickstep::optimizer::logical; |
| namespace P = ::quickstep::optimizer::physical; |
| |
| class AggregateTest : public StrategyTest { |
| protected: |
| AggregateTest() : StrategyTest() {} |
| |
| ~AggregateTest() override {} |
| |
| void SetUp() override { StrategyTest::SetUp(); } |
| |
| void setupStrategy(std::unique_ptr<Strategy> *strategy) override { |
| strategy->reset(new Aggregate(physical_generator())); |
| } |
| |
| E::AggregateFunctionPtr createSum(const E::ScalarPtr &argument, |
| const bool is_vector_aggregate, |
| const bool is_distinct) { |
| std::vector<E::ScalarPtr> args(1, argument); |
| |
| return E::AggregateFunction::Create( |
| AggregateFunctionFactory::Get(AggregationID::kSum), |
| args, |
| is_vector_aggregate, |
| is_distinct); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(AggregateTest); |
| }; |
| |
| TEST_F(AggregateTest, BasicTest) { |
| for (const bool is_distinct : {true, false}) { |
| const E::AggregateFunctionPtr sum = createSum(add_literal_0_, |
| true /* is_vector_attribute */, |
| is_distinct); |
| const E::AliasPtr sum_alias = createAlias(sum, |
| "sum" /* attribute_name */, |
| "test_relation" /* relation_name */); |
| input_logical_ = L::Aggregate::Create( |
| logical_table_reference_0_, |
| {alias_0_} /* grouping_expressions */, |
| {sum_alias} /* aggregate_expressions */); |
| expected_physical_ = P::Aggregate::Create( |
| physical_table_reference_0_, |
| {alias_0_} /* grouping_expressions */, |
| {sum_alias} /* aggregate_expressions */, |
| nullptr /* filter_predicate */); |
| EXPECT_CORRECT_PHYSICAL(); |
| } |
| } |
| |
| TEST_F(AggregateTest, PullupSelection) { |
| for (const bool is_distinct : {true, false}) { |
| const E::AggregateFunctionPtr sum = createSum(E::ToRef(alias_add_literal_0_), |
| true /* is_vector_attribute */, |
| is_distinct); |
| const E::AliasPtr sum_alias = createAlias(sum, |
| "sum" /* attribute_name */, |
| "test_relation" /* relation_name */); |
| const E::AliasPtr alias_on_alias_reference = E::Alias::Create( |
| optimizer_context()->nextExprId(), |
| E::ToRef(alias_add_literal_0_), |
| "alias_on_alias_reference" /* attribute_name */, |
| "alias_on_alias_reference" /* attribute_alias */, |
| "test_relation" /* relation_name */); |
| |
| input_logical_ = L::Aggregate::Create( |
| logical_project_on_filter_0_, |
| {E::ToRef(alias_0_), alias_on_alias_reference} /* grouping_expressions */, |
| {sum_alias} /* aggregate_expressions */); |
| |
| const E::AggregateFunctionPtr sum_after_pullup = |
| std::static_pointer_cast<const E::AggregateFunction>( |
| sum->copyWithNewChildren({alias_add_literal_0_->expression()})); |
| const E::AliasPtr sum_alias_after_pullup = |
| std::static_pointer_cast<const E::Alias>(sum_alias->copyWithNewChildren({sum_after_pullup})); |
| const E::AliasPtr alias_on_alias_reference_after_pullup = |
| std::static_pointer_cast<const E::Alias>(alias_on_alias_reference->copyWithNewChildren( |
| {alias_add_literal_0_->expression()} /* new_children */)); |
| expected_physical_ = P::Aggregate::Create( |
| physical_table_reference_0_, |
| {alias_0_, |
| alias_on_alias_reference_after_pullup} /* grouping_expressions */, |
| {sum_alias_after_pullup} /* aggregate_expressions */, |
| logical_filter_0_->filter_predicate()); |
| |
| EXPECT_CORRECT_PHYSICAL(); |
| } |
| } |
| |
| } // namespace strategy |
| } // namespace optimizer |
| } // namespace quickstep |