/Users/deen/code/yugabyte-db/src/yb/yql/cql/ql/util/statement_result.cc
Line | Count | Source (jump to first uncovered line) |
1 | | //-------------------------------------------------------------------------------------------------- |
2 | | // Copyright (c) YugaByte, Inc. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
5 | | // in compliance with the License. You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
10 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
11 | | // or implied. See the License for the specific language governing permissions and limitations |
12 | | // under the License. |
13 | | // |
14 | | // |
15 | | // Different results of processing a statement. |
16 | | //-------------------------------------------------------------------------------------------------- |
17 | | #include "yb/yql/cql/ql/util/statement_result.h" |
18 | | |
19 | | #include "yb/client/table.h" |
20 | | #include "yb/client/yb_op.h" |
21 | | #include "yb/common/ql_protocol.pb.h" |
22 | | #include "yb/common/ql_protocol_util.h" |
23 | | #include "yb/common/ql_rowblock.h" |
24 | | #include "yb/common/schema.h" |
25 | | #include "yb/common/wire_protocol.h" |
26 | | #include "yb/util/debug-util.h" |
27 | | #include "yb/yql/cql/ql/ptree/list_node.h" |
28 | | #include "yb/yql/cql/ql/ptree/pt_dml.h" |
29 | | #include "yb/yql/cql/ql/ptree/pt_expr.h" |
30 | | #include "yb/yql/cql/ql/ptree/tree_node.h" |
31 | | |
32 | | namespace yb { |
33 | | namespace ql { |
34 | | |
35 | | using std::string; |
36 | | using std::vector; |
37 | | using std::unique_ptr; |
38 | | using std::shared_ptr; |
39 | | using std::make_shared; |
40 | | using strings::Substitute; |
41 | | |
42 | | using client::YBOperation; |
43 | | using client::YBqlOp; |
44 | | using client::YBqlReadOp; |
45 | | using client::YBqlWriteOp; |
46 | | using client::YBTableName; |
47 | | |
48 | | //------------------------------------------------------------------------------------------------ |
49 | | namespace { |
50 | | |
51 | | // Get bind column schemas for DML. |
52 | | void GetBindVariableSchemasFromDmlStmt(const PTDmlStmt& stmt, |
53 | | vector<ColumnSchema>* schemas, |
54 | 1.70k | vector<YBTableName>* table_names = nullptr) { |
55 | | // Only add the bind variables if the table name is determined |
56 | 1.70k | if (stmt.bind_table()) { |
57 | 1.70k | schemas->reserve(schemas->size() + stmt.bind_variables().size()); |
58 | 1.70k | if (table_names != nullptr) { |
59 | 51 | table_names->reserve(table_names->size() + stmt.bind_variables().size()); |
60 | 51 | } |
61 | | |
62 | 5.71k | for (const PTBindVar *var : stmt.bind_variables()) { |
63 | 5.71k | DCHECK_NOTNULL(var->name().get()); |
64 | 5.71k | schemas->emplace_back(var->name() ? string(var->name()->c_str()) : string(), var->ql_type()); |
65 | 5.71k | if (table_names != nullptr) { |
66 | 93 | table_names->emplace_back(stmt.bind_table()->name()); |
67 | 93 | } |
68 | 5.71k | } |
69 | 1.70k | } |
70 | 1.70k | } |
71 | | |
72 | 3.94M | shared_ptr<vector<ColumnSchema>> GetColumnSchemasFromOp(const YBqlOp& op, const PTDmlStmt *tnode) { |
73 | 3.94M | switch (op.type()) { |
74 | 3.94M | case YBOperation::Type::QL_READ: { |
75 | | // For actual execution "tnode" is always not null. |
76 | 3.94M | if (tnode != nullptr) { |
77 | 0 | return tnode->selected_schemas(); |
78 | 0 | } |
79 | | |
80 | 3.94M | return std::make_shared<vector<ColumnSchema>>( |
81 | 3.94M | static_cast<const YBqlReadOp&>(op).MakeColumnSchemasFromRequest()); |
82 | 3.94M | } |
83 | | |
84 | 273 | case YBOperation::Type::QL_WRITE: { |
85 | 273 | shared_ptr<vector<ColumnSchema>> column_schemas = make_shared<vector<ColumnSchema>>(); |
86 | 273 | const auto& write_op = static_cast<const YBqlWriteOp&>(op); |
87 | 273 | column_schemas->reserve(write_op.response().column_schemas_size()); |
88 | 922 | for (const auto& column_schema : write_op.response().column_schemas()) { |
89 | 922 | column_schemas->emplace_back(ColumnSchemaFromPB(column_schema)); |
90 | 922 | } |
91 | 273 | return column_schemas; |
92 | 3.94M | } |
93 | | |
94 | 0 | case YBOperation::Type::PGSQL_READ: FALLTHROUGH_INTENDED; |
95 | 0 | case YBOperation::Type::PGSQL_WRITE: FALLTHROUGH_INTENDED; |
96 | 0 | case YBOperation::Type::REDIS_READ: FALLTHROUGH_INTENDED; |
97 | 0 | case YBOperation::Type::REDIS_WRITE: |
98 | 0 | break; |
99 | | // default: fallthrough |
100 | 0 | } |
101 | | |
102 | 0 | LOG(FATAL) << "Internal error: invalid or unknown QL operation: " << op.type(); |
103 | 0 | return nullptr; |
104 | 0 | } |
105 | | |
106 | 3.93M | QLClient GetClientFromOp(const YBqlOp& op) { |
107 | 3.93M | switch (op.type()) { |
108 | 3.93M | case YBOperation::Type::QL_READ: |
109 | 3.93M | return static_cast<const YBqlReadOp&>(op).request().client(); |
110 | 273 | case YBOperation::Type::QL_WRITE: |
111 | 273 | return static_cast<const YBqlWriteOp&>(op).request().client(); |
112 | 0 | case YBOperation::Type::PGSQL_READ: FALLTHROUGH_INTENDED; |
113 | 0 | case YBOperation::Type::PGSQL_WRITE: FALLTHROUGH_INTENDED; |
114 | 0 | case YBOperation::Type::REDIS_READ: FALLTHROUGH_INTENDED; |
115 | 0 | case YBOperation::Type::REDIS_WRITE: |
116 | 0 | break; |
117 | | // default: fallthrough |
118 | 0 | } |
119 | 0 | LOG(FATAL) << "Internal error: invalid or unknown QL operation: " << op.type(); |
120 | | |
121 | | // Inactive code: It's only meant to avoid compilation warning. |
122 | 0 | return QLClient(); |
123 | 0 | } |
124 | | |
125 | | } // namespace |
126 | | |
127 | | //------------------------------------------------------------------------------------------------ |
128 | | PreparedResult::PreparedResult(const PTDmlStmt& stmt) |
129 | | : table_name_(stmt.bind_table() ? stmt.bind_table()->name() : YBTableName()), |
130 | | hash_col_indices_(stmt.hash_col_indices()), |
131 | 4.50k | column_schemas_(stmt.selected_schemas()) { |
132 | 4.50k | GetBindVariableSchemasFromDmlStmt(stmt, &bind_variable_schemas_); |
133 | 4.50k | if (column_schemas_ == nullptr) { |
134 | 4.16k | column_schemas_ = make_shared<vector<ColumnSchema>>(); |
135 | 4.16k | } |
136 | 4.50k | } |
137 | | |
138 | | PreparedResult::PreparedResult(const PTListNode& stmt) |
139 | 15 | : column_schemas_(make_shared<vector<ColumnSchema>>()) { |
140 | 87 | for (TreeNode::SharedPtr tnode : stmt.node_list()) { |
141 | 87 | switch (tnode->opcode()) { |
142 | 57 | case TreeNodeOpcode::kPTInsertStmt: FALLTHROUGH_INTENDED; |
143 | 57 | case TreeNodeOpcode::kPTUpdateStmt: FALLTHROUGH_INTENDED; |
144 | 57 | case TreeNodeOpcode::kPTDeleteStmt: { |
145 | 57 | const auto& dml = static_cast<const PTDmlStmt&>(*tnode); |
146 | 57 | GetBindVariableSchemasFromDmlStmt(dml, &bind_variable_schemas_, &bind_table_names_); |
147 | 57 | if (hash_col_indices_.empty()) { |
148 | 27 | hash_col_indices_ = dml.hash_col_indices(); |
149 | 27 | } |
150 | 57 | break; |
151 | 57 | } |
152 | 30 | default: |
153 | 30 | break; |
154 | 87 | } |
155 | 87 | } |
156 | 15 | } |
157 | | |
158 | 4.51k | PreparedResult::~PreparedResult() { |
159 | 4.51k | } |
160 | | |
161 | | //------------------------------------------------------------------------------------------------ |
162 | | RowsResult::RowsResult(const PTDmlStmt *tnode) |
163 | | : table_name_(tnode->table()->name()), |
164 | | column_schemas_(tnode->selected_schemas()), |
165 | | client_(YQL_CLIENT_CQL), |
166 | 62 | rows_data_(QLRowBlock::ZeroRowsData(YQL_CLIENT_CQL)) { |
167 | 62 | if (column_schemas_ == nullptr) { |
168 | 0 | column_schemas_ = make_shared<vector<ColumnSchema>>(); |
169 | 0 | } |
170 | 62 | } |
171 | | |
172 | | RowsResult::RowsResult(YBqlOp *op, const PTDmlStmt *tnode) |
173 | | : table_name_(op->table()->name()), |
174 | | column_schemas_(GetColumnSchemasFromOp(*op, tnode)), |
175 | | client_(GetClientFromOp(*op)), |
176 | 3.94M | rows_data_(std::move(*op->mutable_rows_data())) { |
177 | 3.94M | if (column_schemas_ == nullptr) { |
178 | 0 | column_schemas_ = make_shared<vector<ColumnSchema>>(); |
179 | 0 | } |
180 | 3.94M | SetPagingState(op); |
181 | 3.94M | } |
182 | | |
183 | | RowsResult::RowsResult(const YBTableName& table_name, |
184 | | const shared_ptr<vector<ColumnSchema>>& column_schemas, |
185 | | const std::string& rows_data) |
186 | | : table_name_(table_name), |
187 | | column_schemas_(column_schemas), |
188 | | client_(QLClient::YQL_CLIENT_CQL), |
189 | 167 | rows_data_(rows_data) { |
190 | 167 | } |
191 | | |
192 | 3.90M | RowsResult::~RowsResult() { |
193 | 3.90M | } |
194 | | |
195 | 20 | void RowsResult::set_column_schema(int col_index, const std::shared_ptr<QLType>& type) { |
196 | 20 | (*column_schemas_)[col_index].set_type(type); |
197 | 20 | } |
198 | | |
199 | 39.3k | Status RowsResult::Append(RowsResult&& other) { |
200 | 39.3k | column_schemas_ = std::move(other.column_schemas_); |
201 | 39.3k | if (rows_data_.empty()) { |
202 | 1.52k | rows_data_ = std::move(other.rows_data_); |
203 | 37.8k | } else { |
204 | 37.8k | RETURN_NOT_OK(QLRowBlock::AppendRowsData(other.client_, other.rows_data_, &rows_data_)); |
205 | 37.8k | } |
206 | 39.3k | paging_state_ = std::move(other.paging_state_); |
207 | 39.3k | return Status::OK(); |
208 | 39.3k | } |
209 | | |
210 | 3.93M | void RowsResult::SetPagingState(YBqlOp *op) { |
211 | | // If there is a paging state in the response, fill in the table ID also and serialize the |
212 | | // paging state as bytes. |
213 | 3.93M | if (op->response().has_paging_state()) { |
214 | 33.6k | QLPagingStatePB *paging_state = op->mutable_response()->mutable_paging_state(); |
215 | 33.6k | paging_state->set_table_id(op->table()->id()); |
216 | 33.6k | SetPagingState(*paging_state); |
217 | 33.6k | } |
218 | 3.93M | } |
219 | | |
220 | 33.9k | void RowsResult::SetPagingState(const QLPagingStatePB& paging_state) { |
221 | 33.9k | paging_state_.clear(); |
222 | 33.9k | CHECK(paging_state.SerializeToString(&paging_state_)); |
223 | 33.9k | } |
224 | | |
225 | 87 | void RowsResult::SetPagingState(RowsResult&& other) { |
226 | 87 | paging_state_ = std::move(other.paging_state_); |
227 | 87 | } |
228 | | |
229 | 3.89M | void RowsResult::ClearPagingState() { |
230 | 5.89k | VLOG(3) << "Clear paging state " << GetStackTrace(); |
231 | 3.89M | paging_state_.clear(); |
232 | 3.89M | } |
233 | | |
234 | 187k | std::unique_ptr<QLRowBlock> RowsResult::GetRowBlock() const { |
235 | 187k | return CreateRowBlock(client_, Schema(*column_schemas_, 0), rows_data_); |
236 | 187k | } |
237 | | |
238 | | //------------------------------------------------------------------------------------------------ |
239 | | SchemaChangeResult::SchemaChangeResult( |
240 | | const string& change_type, const string& object_type, |
241 | | const string& keyspace_name, const string& object_name) |
242 | | : change_type_(change_type), object_type_(object_type), |
243 | 6.07k | keyspace_name_(keyspace_name), object_name_(object_name) { |
244 | 6.07k | } |
245 | | |
246 | 6.07k | SchemaChangeResult::~SchemaChangeResult() { |
247 | 6.07k | } |
248 | | |
249 | | |
250 | | } // namespace ql |
251 | | } // namespace yb |