| /** |
| * 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 |