10
10
//
11
11
// ===----------------------------------------------------------------------===//
12
12
13
- #include " executor/alter_executor.h"
14
-
15
13
#include " catalog/catalog.h"
14
+ #include " catalog/table_catalog.h"
16
15
#include " common/logger.h"
16
+ #include " executor/alter_executor.h"
17
17
#include " executor/executor_context.h"
18
+ #include " storage/data_table.h"
18
19
19
20
namespace peloton {
20
21
namespace executor {
21
22
22
23
// Constructor for alter table executor
23
24
AlterExecutor::AlterExecutor (const planner::AbstractPlan *node,
24
25
ExecutorContext *executor_context)
25
- : AbstractExecutor(node, executor_context),
26
- isAlter_ (
27
- !reinterpret_cast <const planner::AlterPlan *>(node)->IsRename()) {}
26
+ : AbstractExecutor(node, executor_context) {}
28
27
29
28
// Initialize executor
30
29
// Nothing to initialize for now
@@ -38,24 +37,20 @@ bool AlterExecutor::DInit() {
38
37
bool AlterExecutor::DExecute () {
39
38
LOG_TRACE (" Executing Alter..." );
40
39
bool result = false ;
41
- if (!isAlter_) {
42
- const planner::AlterPlan &node = GetPlanNode<planner::AlterPlan>();
43
- auto current_txn = executor_context_->GetTransaction ();
44
- result = RenameColumn (node, current_txn);
45
- } else {
46
- const planner::AlterPlan &node = GetPlanNode<planner::AlterPlan>();
47
- auto current_txn = executor_context_->GetTransaction ();
48
- AlterType type = node.GetAlterTableType ();
49
- switch (type) {
50
- case AlterType::ALTER:
51
- result = DropColumn (node, current_txn);
52
- break ;
53
- default :
54
- throw NotImplementedException (StringUtil::Format (
55
- " Alter Type not supported, %s" , AlterTypeToString (type).c_str ()));
56
- }
40
+ const planner::AlterPlan &node = GetPlanNode<planner::AlterPlan>();
41
+ auto current_txn = executor_context_->GetTransaction ();
42
+ AlterType type = node.GetAlterTableType ();
43
+ switch (type) {
44
+ case AlterType::RENAME:
45
+ result = RenameColumn (node, current_txn);
46
+ break ;
47
+ case AlterType::ALTER:
48
+ result = AlterTable (node, current_txn);
49
+ break ;
50
+ default :
51
+ throw NotImplementedException (StringUtil::Format (
52
+ " Alter Type not supported, %s" , AlterTypeToString (type).c_str ()));
57
53
}
58
-
59
54
return result;
60
55
}
61
56
@@ -82,23 +77,109 @@ bool AlterExecutor::RenameColumn(
82
77
return false ;
83
78
}
84
79
85
- bool AlterExecutor::DropColumn (const peloton::planner::AlterPlan &node,
80
+ bool AlterExecutor::AlterTable (const peloton::planner::AlterPlan &node,
86
81
peloton::concurrency::TransactionContext *txn) {
87
82
auto database_name = node.GetDatabaseName ();
88
83
auto table_name = node.GetTableName ();
89
- auto drop_columns = node.GetDroppedColumns ();
90
84
91
- ResultType result = catalog::Catalog::GetInstance ()->DropColumn (
92
- database_name, table_name, drop_columns, txn);
93
- txn->SetResult (result);
85
+ auto table_catalog_obj = catalog::Catalog::GetInstance ()->GetTableObject (
86
+ database_name, table_name, txn);
87
+ oid_t database_oid = table_catalog_obj->GetDatabaseOid ();
88
+ oid_t table_oid = table_catalog_obj->GetTableOid ();
89
+
90
+ auto old_table = catalog::Catalog::GetInstance ()->GetTableWithName (
91
+ database_name, table_name, txn);
92
+ auto old_schema = old_table->GetSchema ();
93
+ std::vector<oid_t > column_ids;
94
+
95
+ // Step 1: remove drop columns from old schema
96
+ for (oid_t i = 0 ; i < old_schema->GetColumnCount (); ++i) {
97
+ bool is_found = false ;
98
+ for (auto drop_column : node.GetDroppedColumns ()) {
99
+ if (old_schema->GetColumn (i).GetName () == drop_column) {
100
+ is_found = true ;
101
+ }
102
+ }
103
+ if (!is_found) {
104
+ column_ids.push_back (i);
105
+ }
106
+ }
107
+ // Check if dropped column exists
108
+ if (column_ids.size () + node.GetDroppedColumns ().size () !=
109
+ old_schema->GetColumnCount ()) {
110
+ LOG_TRACE (" Dropped column not exists" );
111
+ txn->SetResult (ResultType::FAILURE);
112
+ return false ;
113
+ }
114
+ std::unique_ptr<catalog::Schema> temp_schema (
115
+ catalog::Schema::CopySchema (old_schema, column_ids));
116
+
117
+ // Step 2: change column type if exists
118
+ for (auto change_pair : node.GetChangedTypeColumns ()) {
119
+ bool is_found = false ;
120
+ oid_t i = 0 ;
121
+ for (; i < temp_schema->GetColumnCount (); ++i) {
122
+ if (temp_schema->GetColumn (i).GetName () == change_pair.first ) {
123
+ is_found = true ;
124
+ break ;
125
+ }
126
+ }
127
+ if (!is_found) {
128
+ LOG_TRACE (" Change column type failed: Column %s does not exists" ,
129
+ change_pair.first .c_str ());
130
+ txn->SetResult (ResultType::FAILURE);
131
+ return false ;
132
+ } else {
133
+ temp_schema->ChangeColumnType (i, change_pair.second );
134
+ }
135
+ }
94
136
95
- if (txn->GetResult () == ResultType::SUCCESS) {
96
- LOG_TRACE (" Drop column succeed!" );
137
+ // Step 3: append add column to new schema
138
+ // construct add column schema
139
+ std::vector<catalog::Column> add_columns;
140
+ for (size_t i = 0 ; i < node.GetAddedColumns ().size (); ++i) {
141
+ for (auto column : node.GetAddedColumns ()[i]->GetColumns ()) {
142
+ add_columns.push_back (column);
143
+ }
144
+ }
145
+ std::unique_ptr<catalog::Schema> add_column_schema (
146
+ new catalog::Schema (add_columns));
147
+ // Check if added column exists
148
+ for (auto new_column : add_column_schema->GetColumns ()) {
149
+ for (auto old_column : old_schema->GetColumns ()) {
150
+ if (new_column.GetName () == old_column.GetName ()) {
151
+ LOG_TRACE (" Add column failed: Column %s already exists" ,
152
+ new_column.GetName ().c_str ());
153
+ txn->SetResult (ResultType::FAILURE);
154
+ return false ;
155
+ }
156
+ }
157
+ }
97
158
98
- // TODO: Add on succeed logic if necessary
99
- executor_context_->num_processed = 1 ;
100
- } else {
101
- LOG_TRACE (" Result is: %s" , ResultTypeToString (txn->GetResult ()).c_str ());
159
+ // Construct new schema
160
+ std::unique_ptr<catalog::Schema> new_schema (catalog::Schema::AppendSchema (
161
+ temp_schema.get (), add_column_schema.get ()));
162
+
163
+ // Copy and replace table content to new schema in catalog
164
+ ResultType result = catalog::Catalog::GetInstance ()->AlterTable (
165
+ database_oid, table_oid, new_schema, txn);
166
+ txn->SetResult (result);
167
+
168
+ switch (txn->GetResult ()) {
169
+ case ResultType::SUCCESS:
170
+ LOG_TRACE (" Alter table succeed!" );
171
+
172
+ // TODO: Add on succeed logic if necessary
173
+ executor_context_->num_processed = 1 ;
174
+ break ;
175
+ case ResultType::FAILURE:
176
+ LOG_TRACE (" Alter table failed!" );
177
+
178
+ // TODO: Add on failed logic if necessary
179
+ break ;
180
+ default :
181
+ LOG_TRACE (" Result is: %s" , ResultTypeToString (txn->GetResult ()).c_str ());
182
+ break ;
102
183
}
103
184
return false ;
104
185
}
0 commit comments