blob: 3cfe0131aa11f87f1353ac0848f6bcf3c947674f [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/OneToOne.hpp"
#include <memory>
#include <vector>
#include "query_optimizer/LogicalToPhysicalMapper.hpp"
#include "query_optimizer/OptimizerContext.hpp"
#include "query_optimizer/expressions/AttributeReference.hpp"
#include "query_optimizer/expressions/ExpressionUtil.hpp"
#include "query_optimizer/logical/CopyFrom.hpp"
#include "query_optimizer/logical/CopyTo.hpp"
#include "query_optimizer/logical/CreateIndex.hpp"
#include "query_optimizer/logical/CreateTable.hpp"
#include "query_optimizer/logical/DeleteTuples.hpp"
#include "query_optimizer/logical/DropTable.hpp"
#include "query_optimizer/logical/InsertSelection.hpp"
#include "query_optimizer/logical/InsertTuple.hpp"
#include "query_optimizer/logical/LogicalType.hpp"
#include "query_optimizer/logical/Sample.hpp"
#include "query_optimizer/logical/SetOperation.hpp"
#include "query_optimizer/logical/SharedSubplanReference.hpp"
#include "query_optimizer/logical/Sort.hpp"
#include "query_optimizer/logical/TableGenerator.hpp"
#include "query_optimizer/logical/TableReference.hpp"
#include "query_optimizer/logical/TopLevelPlan.hpp"
#include "query_optimizer/logical/UpdateTable.hpp"
#include "query_optimizer/logical/WindowAggregate.hpp"
#include "query_optimizer/physical/Aggregate.hpp"
#include "query_optimizer/physical/CopyFrom.hpp"
#include "query_optimizer/physical/CopyTo.hpp"
#include "query_optimizer/physical/CreateIndex.hpp"
#include "query_optimizer/physical/CreateTable.hpp"
#include "query_optimizer/physical/DeleteTuples.hpp"
#include "query_optimizer/physical/DropTable.hpp"
#include "query_optimizer/physical/InsertSelection.hpp"
#include "query_optimizer/physical/InsertTuple.hpp"
#include "query_optimizer/physical/Sample.hpp"
#include "query_optimizer/physical/SharedSubplanReference.hpp"
#include "query_optimizer/physical/Sort.hpp"
#include "query_optimizer/physical/TableGenerator.hpp"
#include "query_optimizer/physical/TableReference.hpp"
#include "query_optimizer/physical/TopLevelPlan.hpp"
#include "query_optimizer/physical/UnionAll.hpp"
#include "query_optimizer/physical/UpdateTable.hpp"
#include "query_optimizer/physical/WindowAggregate.hpp"
namespace quickstep {
namespace optimizer {
namespace strategy {
namespace E = ::quickstep::optimizer::expressions;
namespace L = ::quickstep::optimizer::logical;
namespace P = ::quickstep::optimizer::physical;
bool OneToOne::generatePlan(const L::LogicalPtr &logical_input,
P::PhysicalPtr *physical_output) {
switch (logical_input->getLogicalType()) {
case L::LogicalType::kTopLevelPlan: {
const L::TopLevelPlanPtr top_level_plan = std::static_pointer_cast<const L::TopLevelPlan>(logical_input);
const P::PhysicalPtr main_physical_plan =
physical_mapper_->createOrGetPhysicalFromLogical(top_level_plan->plan());
std::vector<P::PhysicalPtr> shared_physical_subplans;
for (const L::LogicalPtr &shared_logical_subplan : top_level_plan->shared_subplans()) {
shared_physical_subplans.emplace_back(
physical_mapper_->createOrGetPhysicalFromLogical(shared_logical_subplan));
}
*physical_output = P::TopLevelPlan::Create(main_physical_plan,
shared_physical_subplans);
return true;
}
case L::LogicalType::kSharedSubplanReference: {
const L::SharedSubplanReferencePtr shared_subplan_reference =
std::static_pointer_cast<const L::SharedSubplanReference>(logical_input);
*physical_output = P::SharedSubplanReference::Create(shared_subplan_reference->subplan_id(),
shared_subplan_reference->referenced_attributes(),
shared_subplan_reference->output_attributes());
return true;
}
case L::LogicalType::kTableReference: {
const L::TableReferencePtr table_reference =
std::static_pointer_cast<const L::TableReference>(logical_input);
*physical_output = P::TableReference::Create(table_reference->catalog_relation(),
table_reference->relation_alias(),
table_reference->attribute_list());
return true;
}
case L::LogicalType::kCopyFrom: {
const L::CopyFromPtr copy_from =
std::static_pointer_cast<const L::CopyFrom>(logical_input);
*physical_output = P::CopyFrom::Create(copy_from->catalog_relation(),
copy_from->file_name(),
copy_from->options());
return true;
}
case L::LogicalType::kCopyTo: {
const L::CopyToPtr copy_to =
std::static_pointer_cast<const L::CopyTo>(logical_input);
*physical_output = P::CopyTo::Create(
physical_mapper_->createOrGetPhysicalFromLogical(copy_to->input()),
copy_to->file_name(),
copy_to->options());
return true;
}
case L::LogicalType::kCreateIndex: {
const L::CreateIndexPtr create_index =
std::static_pointer_cast<const L::CreateIndex>(logical_input);
*physical_output = P::CreateIndex::Create(
physical_mapper_->createOrGetPhysicalFromLogical(create_index->input()),
create_index->index_name(),
create_index->index_attributes(),
create_index->index_description());
return true;
}
case L::LogicalType::kCreateTable: {
const L::CreateTablePtr create_table =
std::static_pointer_cast<const L::CreateTable>(logical_input);
*physical_output = P::CreateTable::Create(create_table->relation_name(),
create_table->attributes(),
create_table->block_properties(),
create_table->partition_scheme_header_proto());
return true;
}
case L::LogicalType::kDeleteTuples: {
const L::DeleteTuplesPtr delete_tuples =
std::static_pointer_cast<const L::DeleteTuples>(logical_input);
*physical_output = P::DeleteTuples::Create(
physical_mapper_->createOrGetPhysicalFromLogical(delete_tuples->input()),
delete_tuples->predicate());
return true;
}
case L::LogicalType::kDropTable: {
const L::DropTablePtr drop_table =
std::static_pointer_cast<const L::DropTable>(logical_input);
*physical_output = P::DropTable::Create(drop_table->catalog_relation());
return true;
}
case L::LogicalType::kInsertSelection: {
const L::InsertSelectionPtr insert_selection =
std::static_pointer_cast<const L::InsertSelection>(logical_input);
*physical_output = P::InsertSelection::Create(
physical_mapper_->createOrGetPhysicalFromLogical(insert_selection->destination()),
physical_mapper_->createOrGetPhysicalFromLogical(insert_selection->selection()));
return true;
}
case L::LogicalType::kInsertTuple: {
const L::InsertTuplePtr insert_tuple =
std::static_pointer_cast<const L::InsertTuple>(logical_input);
*physical_output = P::InsertTuple::Create(
physical_mapper_->createOrGetPhysicalFromLogical(insert_tuple->input()),
insert_tuple->column_values());
return true;
}
case L::LogicalType::kSample: {
const L::SamplePtr sample =
std::static_pointer_cast<const L::Sample>(logical_input);
*physical_output = P::Sample::Create(
physical_mapper_->createOrGetPhysicalFromLogical(sample->input()),
sample->is_block_sample(),
sample->percentage());
return true;
}
case L::LogicalType::kSetOperation: {
const L::SetOperationPtr set_operation =
std::static_pointer_cast<const L::SetOperation>(logical_input);
std::vector<P::PhysicalPtr> physical_operands;
for (const L::LogicalPtr &logical : set_operation->getOperands()) {
physical_operands.push_back(physical_mapper_->createOrGetPhysicalFromLogical(logical));
}
if (set_operation->getSetOperationType() == L::SetOperation::kUnionAll) {
// For UnionAll operation, convert it into a physical UnionAll.
*physical_output = P::UnionAll::Create(physical_operands,
set_operation->getOutputAttributes());
return true;
} else if (set_operation->getSetOperationType() == L::SetOperation::kUnion) {
// For Union operation, convert it into a physical UnionAll followed by an Aggregate.
P::PhysicalPtr union_all = P::UnionAll::Create(physical_operands,
set_operation->getOutputAttributes());
*physical_output = P::Aggregate::Create(
union_all,
E::ToNamedExpressions(set_operation->getOutputAttributes()),
{} /* aggregate_expression */,
nullptr /* filter_predicate */);
return true;
} else {
// INTERSECT is in Join.cpp
return false;
}
}
case L::LogicalType::kSort: {
const L::Sort *sort =
static_cast<const L::Sort*>(logical_input.get());
const P::PhysicalPtr physical_input =
physical_mapper_->createOrGetPhysicalFromLogical(sort->input());
// Find non-sort attributes.
const std::vector<E::AttributeReferencePtr> input_attributes =
physical_input->getOutputAttributes();
E::UnorderedNamedExpressionSet sort_attributes_set(sort->sort_attributes().begin(),
sort->sort_attributes().end());
std::vector<E::AttributeReferencePtr> non_sort_attributes;
for (const E::AttributeReferencePtr &input_attribute : input_attributes) {
if (sort_attributes_set.find(input_attribute) == sort_attributes_set.end()) {
non_sort_attributes.emplace_back(input_attribute);
}
}
*physical_output = P::Sort::Create(
physical_mapper_->createOrGetPhysicalFromLogical(sort->input()),
sort->sort_attributes(),
non_sort_attributes,
sort->sort_ascending(),
sort->nulls_first_flags(),
sort->limit());
return true;
}
case L::LogicalType::kTableGenerator: {
const L::TableGeneratorPtr table_generator =
std::static_pointer_cast<const L::TableGenerator>(logical_input);
*physical_output = P::TableGenerator::Create(
table_generator->generator_function_handle(),
table_generator->table_alias(),
table_generator->attribute_list());
return true;
}
case L::LogicalType::kUpdateTable: {
const L::UpdateTablePtr update_table =
std::static_pointer_cast<const L::UpdateTable>(logical_input);
*physical_output = P::UpdateTable::Create(
physical_mapper_->createOrGetPhysicalFromLogical(update_table->input()),
update_table->assignees(),
update_table->assignment_expressions(),
update_table->predicate());
return true;
}
case L::LogicalType::kWindowAggregate: {
const L::WindowAggregatePtr window_aggregate =
std::static_pointer_cast<const L::WindowAggregate>(logical_input);
*physical_output = P::WindowAggregate::Create(
physical_mapper_->createOrGetPhysicalFromLogical(window_aggregate->input()),
window_aggregate->window_aggregate_expression());
return true;
}
default:
return false;
}
}
} // namespace strategy
} // namespace optimizer
} // namespace quickstep