YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

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