blob: ecf94b2e2cc7f7b5b0fd55152f1585650f2dbd5d [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.
**/
#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