YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/docdb/cql_operation.h
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
#ifndef YB_DOCDB_CQL_OPERATION_H
15
#define YB_DOCDB_CQL_OPERATION_H
16
17
#include "yb/common/ql_protocol.pb.h"
18
#include "yb/common/typedefs.h"
19
20
#include "yb/docdb/doc_expr.h"
21
#include "yb/docdb/doc_key.h"
22
#include "yb/docdb/doc_operation.h"
23
#include "yb/docdb/intent_aware_iterator.h"
24
25
namespace yb {
26
27
class IndexInfo;
28
class IndexMap;
29
class QLResultSet;
30
class QLRowBlock;
31
32
namespace docdb {
33
34
class QLWriteOperation :
35
    public DocOperationBase<DocOperationType::QL_WRITE_OPERATION, QLWriteRequestPB>,
36
    public DocExprExecutor {
37
 public:
38
  QLWriteOperation(std::reference_wrapper<const QLWriteRequestPB> request,
39
                   std::shared_ptr<const Schema> schema,
40
                   std::reference_wrapper<const IndexMap> index_map,
41
                   const Schema* unique_index_key_schema,
42
                   const TransactionOperationContext& txn_op_context);
43
  ~QLWriteOperation();
44
45
  // Construct a QLWriteOperation. Content of request will be swapped out by the constructor.
46
  CHECKED_STATUS Init(QLResponsePB* response);
47
48
4.51M
  bool RequireReadSnapshot() const override { return require_read_; }
49
50
  CHECKED_STATUS GetDocPaths(
51
      GetDocPathsMode mode, DocPathsToLock *paths, IsolationLevel *level) const override;
52
53
  CHECKED_STATUS Apply(const DocOperationApplyData& data) override;
54
55
  CHECKED_STATUS ApplyForJsonOperators(
56
    const ColumnSchema& column,
57
    const ColumnIdRep col_id,
58
    const std::unordered_map<ColumnIdRep, vector<int>>& col_map,
59
    const DocOperationApplyData& data,
60
    const DocPath& sub_path, const MonoDelta& ttl,
61
    const UserTimeMicros& user_timestamp,
62
    QLTableRow* current_row,
63
    bool is_insert);
64
65
  CHECKED_STATUS ApplyForSubscriptArgs(const QLColumnValuePB& column_value,
66
                                       const QLTableRow& current_row,
67
                                       const DocOperationApplyData& data,
68
                                       const MonoDelta& ttl,
69
                                       const UserTimeMicros& user_timestamp,
70
                                       const ColumnSchema& column,
71
                                       DocPath* sub_path);
72
73
  CHECKED_STATUS ApplyForRegularColumns(const QLColumnValuePB& column_value,
74
                                        const QLTableRow& current_row,
75
                                        const DocOperationApplyData& data,
76
                                        const DocPath& sub_path, const MonoDelta& ttl,
77
                                        const UserTimeMicros& user_timestamp,
78
                                        const ColumnSchema& column,
79
                                        const ColumnId& column_id,
80
                                        QLTableRow* new_row);
81
82
47.0k
  const QLWriteRequestPB& request() const { return request_; }
83
40.0k
  QLResponsePB* response() const { return response_; }
84
85
4.50M
  std::vector<std::pair<const IndexInfo*, QLWriteRequestPB>>* index_requests() {
86
4.50M
    return &index_requests_;
87
4.50M
  }
88
89
  // Rowblock to return the "[applied]" status for conditional DML.
90
4.49M
  const QLRowBlock* rowblock() const { return rowblock_.get(); }
91
92
  MonoDelta request_ttl() const;
93
94
 private:
95
0
  void ClearResponse() override {
96
0
    if (response_) {
97
0
      response_->Clear();
98
0
    }
99
0
  }
100
101
  // Initialize hashed_doc_key_ and/or pk_doc_key_.
102
  CHECKED_STATUS InitializeKeys(bool hashed_key, bool primary_key);
103
104
  CHECKED_STATUS ReadColumns(const DocOperationApplyData& data,
105
                             Schema *static_projection,
106
                             Schema *non_static_projection,
107
                             QLTableRow* table_row);
108
109
  CHECKED_STATUS PopulateConditionalDmlRow(const DocOperationApplyData& data,
110
                                           bool should_apply,
111
                                           const QLTableRow& table_row,
112
                                           Schema static_projection,
113
                                           Schema non_static_projection,
114
                                           std::unique_ptr<QLRowBlock>* rowblock);
115
116
  CHECKED_STATUS PopulateStatusRow(const DocOperationApplyData& data,
117
                                   bool should_apply,
118
                                   const QLTableRow& table_row,
119
                                   std::unique_ptr<QLRowBlock>* rowblock);
120
121
  Result<bool> HasDuplicateUniqueIndexValue(const DocOperationApplyData& data);
122
  Result<bool> HasDuplicateUniqueIndexValue(
123
      const DocOperationApplyData& data, yb::docdb::Direction direction);
124
  Result<bool> HasDuplicateUniqueIndexValue(
125
      const DocOperationApplyData& data, ReadHybridTime read_time);
126
  Result<HybridTime> FindOldestOverwrittenTimestamp(
127
      IntentAwareIterator* iter, const SubDocKey& sub_doc_key,
128
      HybridTime min_hybrid_time);
129
130
  CHECKED_STATUS DeleteRow(const DocPath& row_path, DocWriteBatch* doc_write_batch,
131
                           const ReadHybridTime& read_ht, CoarseTimePoint deadline);
132
133
  Result<bool> IsRowDeleted(const QLTableRow& current_row, const QLTableRow& new_row) const;
134
135
  CHECKED_STATUS UpdateIndexes(const QLTableRow& current_row, const QLTableRow& new_row);
136
137
  std::shared_ptr<const Schema> schema_;
138
  const IndexMap& index_map_;
139
  const Schema* unique_index_key_schema_ = nullptr;
140
141
  // Doc key and encoded Doc key for hashed key (i.e. without range columns). Present when there is
142
  // a static column being written.
143
  boost::optional<DocKey> hashed_doc_key_;
144
  RefCntPrefix encoded_hashed_doc_key_;
145
146
  // Doc key and encoded Doc key for primary key (i.e. with range columns). Present when there is a
147
  // non-static column being written or when writing the primary key alone (i.e. range columns are
148
  // present or table does not have range columns).
149
  boost::optional<DocKey> pk_doc_key_;
150
  RefCntPrefix encoded_pk_doc_key_;
151
152
  QLResponsePB* response_ = nullptr;
153
154
  std::vector<std::pair<const IndexInfo*, QLWriteRequestPB>> index_requests_;
155
156
  const TransactionOperationContext txn_op_context_;
157
158
  // The row that is returned to the CQL client for an INSERT/UPDATE/DELETE that has a
159
  // "... IF <condition> ..." clause. The row contains the "[applied]" status column
160
  // plus the values of all columns referenced in the if-clause if the condition is not satisfied.
161
  std::unique_ptr<QLRowBlock> rowblock_;
162
163
  // Does this write operation require a read?
164
  bool require_read_ = false;
165
166
  // Any indexes that may need update?
167
  bool update_indexes_ = false;
168
169
  // Is this an insert into a unique index?
170
  bool insert_into_unique_index_ = false;
171
172
  // Does the liveness column exist before the write operation?
173
  bool liveness_column_exists_ = false;
174
};
175
176
Result<QLWriteRequestPB*> CreateAndSetupIndexInsertRequest(
177
    QLExprExecutor* expr_executor,
178
    bool index_has_write_permission,
179
    const QLTableRow& existing_row,
180
    const QLTableRow& new_row,
181
    const IndexInfo* index,
182
    std::vector<std::pair<const IndexInfo*, QLWriteRequestPB>>* index_requests,
183
    bool* has_index_key_changed = nullptr,
184
    bool* index_pred_new_row = nullptr,
185
    bool index_pred_existing_row = true);
186
187
class QLReadOperation : public DocExprExecutor {
188
 public:
189
  QLReadOperation(
190
      const QLReadRequestPB& request,
191
      const TransactionOperationContext& txn_op_context)
192
7.54M
      : request_(request), txn_op_context_(txn_op_context) {}
193
194
  CHECKED_STATUS Execute(const YQLStorageIf& ql_storage,
195
                         CoarseTimePoint deadline,
196
                         const ReadHybridTime& read_time,
197
                         const Schema& schema,
198
                         const Schema& projection,
199
                         QLResultSet* result_set,
200
                         HybridTime* restart_read_ht);
201
202
  CHECKED_STATUS PopulateResultSet(const std::unique_ptr<QLScanSpec>& spec,
203
                                   const QLTableRow& table_row,
204
                                   QLResultSet *result_set);
205
206
  CHECKED_STATUS EvalAggregate(const QLTableRow& table_row);
207
  CHECKED_STATUS PopulateAggregate(const QLTableRow& table_row, QLResultSet *resultset);
208
209
  CHECKED_STATUS AddRowToResult(const std::unique_ptr<QLScanSpec>& spec,
210
                                const QLTableRow& row,
211
                                const size_t row_count_limit,
212
                                const size_t offset,
213
                                QLResultSet* resultset,
214
                                int* match_count,
215
                                size_t* num_rows_skipped);
216
217
  CHECKED_STATUS GetIntents(const Schema& schema, KeyValueWriteBatchPB* out);
218
219
7.53M
  QLResponsePB& response() { return response_; }
220
221
 private:
222
223
  // Checks whether we have processed enough rows for a page and sets the appropriate paging
224
  // state in the response object.
225
  CHECKED_STATUS SetPagingStateIfNecessary(const YQLRowwiseIteratorIf* iter,
226
                                           const QLResultSet* resultset,
227
                                           const size_t row_count_limit,
228
                                           const size_t num_rows_skipped,
229
                                           const ReadHybridTime& read_time);
230
231
  const QLReadRequestPB& request_;
232
  const TransactionOperationContext txn_op_context_;
233
  QLResponsePB response_;
234
};
235
236
}  // namespace docdb
237
}  // namespace yb
238
239
#endif // YB_DOCDB_CQL_OPERATION_H