|
10 | 10 | //
|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 |
|
| 13 | +#include "planner/plan_util.h" |
13 | 14 | #include <set>
|
14 | 15 | #include <string>
|
15 |
| - |
16 | 16 | #include "catalog/catalog_cache.h"
|
17 | 17 | #include "catalog/column_catalog.h"
|
18 | 18 | #include "catalog/database_catalog.h"
|
19 | 19 | #include "catalog/index_catalog.h"
|
20 | 20 | #include "catalog/table_catalog.h"
|
| 21 | +#include "common/statement.h" |
| 22 | +#include "concurrency/transaction_manager_factory.h" |
| 23 | +#include "expression/abstract_expression.h" |
| 24 | +#include "expression/expression_util.h" |
| 25 | +#include "optimizer/abstract_optimizer.h" |
| 26 | +#include "optimizer/optimizer.h" |
21 | 27 | #include "parser/delete_statement.h"
|
22 | 28 | #include "parser/insert_statement.h"
|
23 | 29 | #include "parser/sql_statement.h"
|
24 | 30 | #include "parser/update_statement.h"
|
25 |
| -#include "planner/plan_util.h" |
26 | 31 | #include "util/set_util.h"
|
27 | 32 |
|
28 | 33 | namespace peloton {
|
@@ -96,5 +101,98 @@ const std::set<oid_t> PlanUtil::GetAffectedIndexes(
|
96 | 101 | return (index_oids);
|
97 | 102 | }
|
98 | 103 |
|
| 104 | +const std::vector<col_triplet> PlanUtil::GetIndexableColumns( |
| 105 | + catalog::CatalogCache &catalog_cache, |
| 106 | + std::unique_ptr<parser::SQLStatementList> sql_stmt_list, |
| 107 | + const std::string &db_name) { |
| 108 | + std::vector<col_triplet> column_oids; |
| 109 | + std::string table_name; |
| 110 | + oid_t database_id, table_id; |
| 111 | + |
| 112 | + // Assume that there is only one SQLStatement in the list |
| 113 | + auto sql_stmt = sql_stmt_list->GetStatement(0); |
| 114 | + switch (sql_stmt->GetType()) { |
| 115 | + // 1) use optimizer to get the plan tree |
| 116 | + // 2) aggregate results from all the leaf scan nodes |
| 117 | + case StatementType::UPDATE: |
| 118 | + PELOTON_FALLTHROUGH; |
| 119 | + case StatementType::DELETE: |
| 120 | + PELOTON_FALLTHROUGH; |
| 121 | + case StatementType::SELECT: { |
| 122 | + std::unique_ptr<optimizer::AbstractOptimizer> optimizer = |
| 123 | + std::unique_ptr<optimizer::AbstractOptimizer>( |
| 124 | + new optimizer::Optimizer()); |
| 125 | + |
| 126 | + auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance(); |
| 127 | + auto txn = txn_manager.BeginTransaction(); |
| 128 | + |
| 129 | + try { |
| 130 | + auto plan = optimizer->BuildPelotonPlanTree(sql_stmt_list, txn); |
| 131 | + |
| 132 | + auto db_object = catalog_cache.GetDatabaseObject(db_name); |
| 133 | + database_id = db_object->GetDatabaseOid(); |
| 134 | + |
| 135 | + // Perform a breadth first search on plan tree |
| 136 | + std::queue<const AbstractPlan *> scan_queue; |
| 137 | + const AbstractPlan *temp_ptr; |
| 138 | + scan_queue.emplace(plan.get()); |
| 139 | + |
| 140 | + while (!scan_queue.empty()) { |
| 141 | + temp_ptr = scan_queue.front(); |
| 142 | + scan_queue.pop(); |
| 143 | + |
| 144 | + // Leaf scanning node |
| 145 | + if (PlanNodeType::SEQSCAN == temp_ptr->GetPlanNodeType() || |
| 146 | + PlanNodeType::INDEXSCAN == temp_ptr->GetPlanNodeType()) { |
| 147 | + auto temp_scan_ptr = static_cast<const AbstractScan *>(temp_ptr); |
| 148 | + |
| 149 | + table_id = temp_scan_ptr->GetTable()->GetOid(); |
| 150 | + |
| 151 | + // Aggregate columns scanned in predicates |
| 152 | + ExprSet expr_set; |
| 153 | + auto predicate_ptr = temp_scan_ptr->GetPredicate(); |
| 154 | + std::unique_ptr<expression::AbstractExpression> copied_predicate; |
| 155 | + if (nullptr == predicate_ptr) { |
| 156 | + copied_predicate = nullptr; |
| 157 | + } else { |
| 158 | + copied_predicate = |
| 159 | + std::unique_ptr<expression::AbstractExpression>( |
| 160 | + predicate_ptr->Copy()); |
| 161 | + } |
| 162 | + expression::ExpressionUtil::GetTupleValueExprs( |
| 163 | + expr_set, copied_predicate.get()); |
| 164 | + |
| 165 | + for (const auto expr : expr_set) { |
| 166 | + auto tuple_value_expr = |
| 167 | + static_cast<const expression::TupleValueExpression *>(expr); |
| 168 | + |
| 169 | + table_id = |
| 170 | + db_object->GetTableObject(tuple_value_expr->GetTableName()) |
| 171 | + ->GetTableOid(); |
| 172 | + column_oids.emplace_back(database_id, table_id, |
| 173 | + (oid_t)tuple_value_expr->GetColumnId()); |
| 174 | + } |
| 175 | + |
| 176 | + } else { |
| 177 | + for (uint32_t idx = 0; idx < temp_ptr->GetChildrenSize(); ++idx) { |
| 178 | + scan_queue.emplace(temp_ptr->GetChild(idx)); |
| 179 | + } |
| 180 | + } |
| 181 | + } |
| 182 | + |
| 183 | + } catch (Exception &e) { |
| 184 | + LOG_ERROR("Error in BuildPelotonPlanTree: %s", e.what()); |
| 185 | + } |
| 186 | + |
| 187 | + // TODO: should transaction commit or not? |
| 188 | + txn_manager.AbortTransaction(txn); |
| 189 | + } break; |
| 190 | + default: |
| 191 | + LOG_TRACE("Return nothing for query type: %d", |
| 192 | + static_cast<int>(sql_stmt->GetType())); |
| 193 | + } |
| 194 | + return (column_oids); |
| 195 | +} |
| 196 | + |
99 | 197 | } // namespace planner
|
100 | 198 | } // namespace peloton
|
0 commit comments