/Users/deen/code/yugabyte-db/src/yb/client/table_alterer.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #include "yb/client/table_alterer.h" |
15 | | |
16 | | #include "yb/client/client-internal.h" |
17 | | #include "yb/client/schema-internal.h" |
18 | | |
19 | | #include "yb/common/schema.h" |
20 | | #include "yb/common/transaction.h" |
21 | | |
22 | | #include "yb/master/master_ddl.pb.h" |
23 | | |
24 | | namespace yb { |
25 | | namespace client { |
26 | | |
27 | | struct YBTableAlterer::Step { |
28 | | master::AlterTableRequestPB::StepType step_type; |
29 | | std::unique_ptr<YBColumnSpec> spec; |
30 | | }; |
31 | | |
32 | | YBTableAlterer::YBTableAlterer(YBClient* client, const YBTableName& name) |
33 | 178 | : client_(client), table_name_(name) { |
34 | 178 | } |
35 | | |
36 | | YBTableAlterer::YBTableAlterer(YBClient* client, const string id) |
37 | 522 | : client_(client), table_id_(std::move(id)) { |
38 | 522 | } |
39 | | |
40 | 700 | YBTableAlterer::~YBTableAlterer() { |
41 | 700 | } |
42 | | |
43 | 115 | YBTableAlterer* YBTableAlterer::RenameTo(const YBTableName& new_name) { |
44 | 115 | rename_to_ = std::make_unique<YBTableName>(new_name); |
45 | 115 | return this; |
46 | 115 | } |
47 | | |
48 | 339 | YBColumnSpec* YBTableAlterer::AddColumn(const string& name) { |
49 | 339 | steps_.push_back({master::AlterTableRequestPB::ADD_COLUMN, std::make_unique<YBColumnSpec>(name)}); |
50 | 339 | return steps_.back().spec.get(); |
51 | 339 | } |
52 | | |
53 | 29 | YBColumnSpec* YBTableAlterer::AlterColumn(const string& name) { |
54 | 29 | steps_.push_back( |
55 | 29 | {master::AlterTableRequestPB::ALTER_COLUMN, std::make_unique<YBColumnSpec>(name)}); |
56 | 29 | return steps_.back().spec.get(); |
57 | 29 | } |
58 | | |
59 | 232 | YBTableAlterer* YBTableAlterer::DropColumn(const string& name) { |
60 | 232 | steps_.push_back( |
61 | 232 | {master::AlterTableRequestPB::DROP_COLUMN, std::make_unique<YBColumnSpec>(name)}); |
62 | 232 | return this; |
63 | 232 | } |
64 | | |
65 | 7 | YBTableAlterer* YBTableAlterer::SetTableProperties(const TableProperties& table_properties) { |
66 | 7 | table_properties_ = std::make_unique<TableProperties>(table_properties); |
67 | 7 | return this; |
68 | 7 | } |
69 | | |
70 | 4 | YBTableAlterer* YBTableAlterer::replication_info(const master::ReplicationInfoPB& ri) { |
71 | 4 | replication_info_ = std::make_unique<master::ReplicationInfoPB>(ri); |
72 | 4 | return this; |
73 | 4 | } |
74 | | |
75 | 1 | YBTableAlterer* YBTableAlterer::SetWalRetentionSecs(const uint32_t wal_retention_secs) { |
76 | 1 | wal_retention_secs_ = wal_retention_secs; |
77 | 1 | return this; |
78 | 1 | } |
79 | | |
80 | 522 | YBTableAlterer* YBTableAlterer::timeout(const MonoDelta& timeout) { |
81 | 522 | timeout_ = timeout; |
82 | 522 | return this; |
83 | 522 | } |
84 | | |
85 | 0 | YBTableAlterer* YBTableAlterer::wait(bool wait) { |
86 | 0 | wait_ = wait; |
87 | 0 | return this; |
88 | 0 | } |
89 | | |
90 | 522 | YBTableAlterer* YBTableAlterer::part_of_transaction(const TransactionMetadata* txn) { |
91 | 522 | txn_ = txn; |
92 | 522 | return this; |
93 | 522 | } |
94 | | |
95 | 700 | Status YBTableAlterer::Alter() { |
96 | 700 | master::AlterTableRequestPB req; |
97 | 700 | RETURN_NOT_OK(ToRequest(&req)); |
98 | | |
99 | 700 | MonoDelta timeout = timeout_.Initialized() ? |
100 | 522 | timeout_ : |
101 | 700 | client_->default_admin_operation_timeout()178 ; |
102 | 700 | auto deadline = CoarseMonoClock::Now() + timeout; |
103 | 700 | RETURN_NOT_OK(client_->data_->AlterTable(client_, req, deadline)); |
104 | 698 | if (wait_) { |
105 | 698 | YBTableName alter_name = rename_to_ ? *rename_to_115 : table_name_583 ; |
106 | 698 | RETURN_NOT_OK(client_->data_->WaitForAlterTableToFinish( |
107 | 698 | client_, alter_name, table_id_, deadline)); |
108 | 698 | } |
109 | | |
110 | 698 | return Status::OK(); |
111 | 698 | } |
112 | | |
113 | 700 | Status YBTableAlterer::ToRequest(master::AlterTableRequestPB* req) { |
114 | 700 | if (!status_.ok()) { |
115 | 0 | return status_; |
116 | 0 | } |
117 | | |
118 | 700 | if (!rename_to_ && steps_.empty()585 && !table_properties_12 && !wal_retention_secs_5 && |
119 | 700 | !replication_info_4 ) { |
120 | 0 | return STATUS(InvalidArgument, "No alter steps provided"); |
121 | 0 | } |
122 | | |
123 | 700 | req->Clear(); |
124 | | |
125 | 700 | if (table_name_.has_table()) { |
126 | 178 | table_name_.SetIntoTableIdentifierPB(req->mutable_table()); |
127 | 178 | } |
128 | | |
129 | 700 | if (!table_id_.empty()) { |
130 | 522 | (req->mutable_table())->set_table_id(table_id_); |
131 | 522 | } |
132 | | |
133 | 700 | if (rename_to_) { |
134 | 115 | req->set_new_table_name(rename_to_->table_name()); |
135 | | |
136 | 115 | if (rename_to_->has_namespace()) { |
137 | 115 | req->mutable_new_namespace()->set_name(rename_to_->namespace_name()); |
138 | 115 | } |
139 | 115 | } |
140 | | |
141 | 700 | for (const Step& s : steps_) { |
142 | 600 | auto* pb_step = req->add_alter_schema_steps(); |
143 | 600 | pb_step->set_type(s.step_type); |
144 | | |
145 | 600 | switch (s.step_type) { |
146 | 339 | case master::AlterTableRequestPB::ADD_COLUMN: |
147 | 339 | { |
148 | 339 | YBColumnSchema col; |
149 | 339 | RETURN_NOT_OK(s.spec->ToColumnSchema(&col)); |
150 | 339 | ColumnSchemaToPB(*col.col_, |
151 | 339 | pb_step->mutable_add_column()->mutable_schema()); |
152 | 339 | break; |
153 | 339 | } |
154 | 232 | case master::AlterTableRequestPB::DROP_COLUMN: |
155 | 232 | { |
156 | 232 | pb_step->mutable_drop_column()->set_name(s.spec->data_->name); |
157 | 232 | break; |
158 | 339 | } |
159 | 29 | case master::AlterTableRequestPB::ALTER_COLUMN: |
160 | | // TODO(KUDU-861): support altering a column in the wire protocol. |
161 | | // For now, we just give an error if the caller tries to do |
162 | | // any operation other than rename. |
163 | 29 | if (s.spec->data_->has_type || |
164 | 29 | s.spec->data_->has_nullable || |
165 | 29 | s.spec->data_->primary_key) { |
166 | 0 | return STATUS(NotSupported, "cannot support AlterColumn of this type", |
167 | 0 | s.spec->data_->name); |
168 | 0 | } |
169 | | // We only support rename column |
170 | 29 | if (!s.spec->data_->has_rename_to) { |
171 | 0 | return STATUS(InvalidArgument, "no alter operation specified", |
172 | 0 | s.spec->data_->name); |
173 | 0 | } |
174 | 29 | pb_step->mutable_rename_column()->set_old_name(s.spec->data_->name); |
175 | 29 | pb_step->mutable_rename_column()->set_new_name(s.spec->data_->rename_to); |
176 | 29 | pb_step->set_type(master::AlterTableRequestPB::RENAME_COLUMN); |
177 | 29 | break; |
178 | 0 | default: |
179 | 0 | LOG(FATAL) << "unknown step type " << s.step_type; |
180 | 600 | } |
181 | 600 | } |
182 | | |
183 | 700 | if (table_properties_) { |
184 | 7 | table_properties_->ToTablePropertiesPB(req->mutable_alter_properties()); |
185 | 7 | } |
186 | | |
187 | 700 | if (wal_retention_secs_) { |
188 | 1 | req->set_wal_retention_secs(*wal_retention_secs_); |
189 | 1 | } |
190 | | |
191 | 700 | if (replication_info_) { |
192 | | // TODO: Maybe add checks for the sanity of the replication_info. |
193 | 4 | req->mutable_replication_info()->CopyFrom(*replication_info_); |
194 | 4 | } |
195 | | |
196 | 700 | if (txn_) { |
197 | 522 | txn_->ToPB(req->mutable_transaction()); |
198 | 522 | } |
199 | | |
200 | 700 | return Status::OK(); |
201 | 700 | } |
202 | | |
203 | | } // namespace client |
204 | | } // namespace yb |