YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/docdb/ql_rocksdb_storage.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/docdb/ql_rocksdb_storage.h"
15
16
#include "yb/common/pgsql_protocol.pb.h"
17
#include "yb/common/ql_protocol.pb.h"
18
19
#include "yb/docdb/doc_key.h"
20
#include "yb/docdb/doc_rowwise_iterator.h"
21
#include "yb/docdb/doc_ql_scanspec.h"
22
#include "yb/docdb/primitive_value_util.h"
23
24
#include "yb/util/result.h"
25
26
namespace yb {
27
namespace docdb {
28
29
QLRocksDBStorage::QLRocksDBStorage(const DocDB& doc_db)
30
276k
    : doc_db_(doc_db) {
31
276k
}
32
33
//--------------------------------------------------------------------------------------------------
34
35
Status QLRocksDBStorage::GetIterator(const QLReadRequestPB& request,
36
                                     const Schema& projection,
37
                                     const Schema& schema,
38
                                     const TransactionOperationContext& txn_op_context,
39
                                     CoarseTimePoint deadline,
40
                                     const ReadHybridTime& read_time,
41
                                     const QLScanSpec& spec,
42
7.24M
                                     std::unique_ptr<YQLRowwiseIteratorIf> *iter) const {
43
44
7.24M
  auto doc_iter = std::make_unique<DocRowwiseIterator>(
45
7.24M
      projection, schema, txn_op_context, doc_db_, deadline, read_time);
46
7.24M
  RETURN_NOT_OK(doc_iter->Init(spec));
47
7.24M
  *iter = std::move(doc_iter);
48
7.24M
  return Status::OK();
49
7.24M
}
50
51
Status QLRocksDBStorage::BuildYQLScanSpec(const QLReadRequestPB& request,
52
                                          const ReadHybridTime& read_time,
53
                                          const Schema& schema,
54
                                          const bool include_static_columns,
55
                                          const Schema& static_projection,
56
                                          std::unique_ptr<QLScanSpec>* spec,
57
7.27M
                                          std::unique_ptr<QLScanSpec>* static_row_spec) const {
58
  // Populate dockey from QL key columns.
59
7.27M
  auto hash_code = request.has_hash_code() ?
60
7.26M
      boost::make_optional<int32_t>(request.hash_code()) : 
boost::none11.5k
;
61
7.27M
  auto max_hash_code = request.has_max_hash_code() ?
62
7.18M
      boost::make_optional<int32_t>(request.max_hash_code()) : 
boost::none93.9k
;
63
64
7.27M
  vector<PrimitiveValue> hashed_components;
65
7.27M
  RETURN_NOT_OK(QLKeyColumnValuesToPrimitiveValues(
66
7.27M
      request.hashed_column_values(), schema, 0, schema.num_hash_key_columns(),
67
7.27M
      &hashed_components));
68
69
7.27M
  SubDocKey start_sub_doc_key;
70
  // Decode the start SubDocKey from the paging state and set scan start key and hybrid time.
71
7.27M
  if (request.has_paging_state() &&
72
7.27M
      
request.paging_state().has_next_row_key()35.0k
&&
73
7.27M
      
!request.paging_state().next_row_key().empty()35.0k
) {
74
75
750
    KeyBytes start_key_bytes(request.paging_state().next_row_key());
76
750
    RETURN_NOT_OK(start_sub_doc_key.FullyDecodeFrom(start_key_bytes.AsSlice()));
77
78
    // If we start the scan with a specific primary key, the normal scan spec we return below will
79
    // not include the static columns if any for the start key. We need to return a separate scan
80
    // spec to fetch those static columns.
81
750
    const DocKey& start_doc_key = start_sub_doc_key.doc_key();
82
750
    if (include_static_columns && 
!start_doc_key.range_group().empty()0
) {
83
0
      const DocKey hashed_doc_key(start_doc_key.hash(), start_doc_key.hashed_group());
84
0
      static_row_spec->reset(new DocQLScanSpec(static_projection, hashed_doc_key,
85
0
          request.query_id(), request.is_forward_scan()));
86
0
    }
87
7.27M
  } else if (!request.is_forward_scan() && 
include_static_columns4.66k
) {
88
3
      const DocKey hashed_doc_key(hash_code ? *hash_code : 
00
, hashed_components);
89
3
      static_row_spec->reset(new DocQLScanSpec(static_projection, hashed_doc_key,
90
3
          request.query_id(), /* is_forward_scan = */ true));
91
3
  }
92
93
  // Construct the scan spec basing on the WHERE condition.
94
7.27M
  spec->reset(new DocQLScanSpec(schema, hash_code, max_hash_code, hashed_components,
95
7.27M
      request.has_where_expr() ? 
&request.where_expr().condition()13.7k
:
nullptr7.26M
,
96
7.27M
      request.has_if_expr() ? 
&request.if_expr().condition()784
:
nullptr7.27M
,
97
7.27M
      request.query_id(), request.is_forward_scan(),
98
7.27M
      request.is_forward_scan() && 
include_static_columns7.25M
, start_sub_doc_key.doc_key()));
99
7.27M
  return Status::OK();
100
7.27M
}
101
102
//--------------------------------------------------------------------------------------------------
103
104
Status QLRocksDBStorage::CreateIterator(const Schema& projection,
105
                                        const Schema& schema,
106
                                        const TransactionOperationContext& txn_op_context,
107
                                        CoarseTimePoint deadline,
108
                                        const ReadHybridTime& read_time,
109
0
                                        YQLRowwiseIteratorIf::UniPtr* iter) const {
110
0
  auto doc_iter = std::make_unique<DocRowwiseIterator>(
111
0
      projection, schema, txn_op_context, doc_db_, deadline, read_time);
112
0
  *iter = std::move(doc_iter);
113
0
  return Status::OK();
114
0
}
115
116
Status QLRocksDBStorage::InitIterator(YQLRowwiseIteratorIf* iter,
117
                                      const PgsqlReadRequestPB& request,
118
                                      const Schema& schema,
119
0
                                      const QLValuePB& ybctid) const {
120
  // Populate dockey from ybctid.
121
0
  DocKey range_doc_key(schema);
122
0
  RETURN_NOT_OK(range_doc_key.DecodeFrom(ybctid.binary_value()));
123
0
  DocRowwiseIterator *doc_iter = static_cast<DocRowwiseIterator*>(iter);
124
0
  RETURN_NOT_OK(doc_iter->Init(DocPgsqlScanSpec(schema, request.stmt_id(), range_doc_key)));
125
0
  return Status::OK();
126
0
}
127
128
Status QLRocksDBStorage::GetIterator(uint64 stmt_id,
129
                                     const Schema& projection,
130
                                     const Schema& schema,
131
                                     const TransactionOperationContext& txn_op_context,
132
                                     CoarseTimePoint deadline,
133
                                     const ReadHybridTime& read_time,
134
                                     const QLValuePB& ybctid,
135
1.55M
                                     YQLRowwiseIteratorIf::UniPtr* iter) const {
136
1.55M
  DocKey range_doc_key(schema);
137
1.55M
  RETURN_NOT_OK(range_doc_key.DecodeFrom(ybctid.binary_value()));
138
1.55M
  auto doc_iter = std::make_unique<DocRowwiseIterator>(
139
1.55M
      projection, schema, txn_op_context, doc_db_, deadline, read_time);
140
1.55M
  RETURN_NOT_OK(doc_iter->Init(DocPgsqlScanSpec(schema, stmt_id, range_doc_key)));
141
1.55M
  *iter = std::move(doc_iter);
142
1.55M
  return Status::OK();
143
1.55M
}
144
145
Status QLRocksDBStorage::GetIterator(const PgsqlReadRequestPB& request,
146
                                     const Schema& projection,
147
                                     const Schema& schema,
148
                                     const TransactionOperationContext& txn_op_context,
149
                                     CoarseTimePoint deadline,
150
                                     const ReadHybridTime& read_time,
151
                                     const DocKey& start_doc_key,
152
3.91M
                                     YQLRowwiseIteratorIf::UniPtr* iter) const {
153
  // Populate dockey from QL key columns.
154
3.91M
  auto hashed_components = VERIFY_RESULT(InitKeyColumnPrimitiveValues(
155
3.91M
      request.partition_column_values(), schema, 0 /* start_idx */));
156
157
3.91M
  auto range_components = VERIFY_RESULT(InitKeyColumnPrimitiveValues(
158
3.91M
      request.range_column_values(), schema, schema.num_hash_key_columns()));
159
160
0
  auto doc_iter = std::make_unique<DocRowwiseIterator>(
161
3.91M
      projection, schema, txn_op_context, doc_db_, deadline, read_time);
162
163
164
3.91M
  if (range_components.size() == schema.num_range_key_columns()) {
165
    // Construct the scan spec basing on the RANGE condition as all range columns are specified.
166
883k
    RETURN_NOT_OK(doc_iter->Init(DocPgsqlScanSpec(
167
883k
        schema,
168
883k
        request.stmt_id(),
169
883k
        hashed_components.empty()
170
883k
          ? DocKey(schema, std::move(range_components))
171
883k
          : DocKey(schema,
172
883k
                   request.hash_code(),
173
883k
                   std::move(hashed_components),
174
883k
                   std::move(range_components)),
175
883k
        request.has_hash_code() ? boost::make_optional<int32_t>(request.hash_code())
176
883k
                                    : boost::none,
177
883k
        request.has_max_hash_code() ? boost::make_optional<int32_t>(
178
883k
                                        request.max_hash_code())
179
883k
                                    : boost::none,
180
883k
        start_doc_key,
181
883k
        request.is_forward_scan())));
182
3.03M
  } else {
183
    // Construct the scan spec basing on the HASH condition.
184
185
3.03M
    DocKey lower_doc_key(schema);
186
3.03M
    if (request.has_lower_bound()
187
3.03M
        && 
schema.num_hash_key_columns() == 01.09k
) {
188
101
        Slice lower_key_slice = request.lower_bound().key();
189
101
        RETURN_NOT_OK(lower_doc_key.DecodeFrom(&lower_key_slice,
190
101
                            DocKeyPart::kWholeDocKey,
191
101
                            AllowSpecial::kTrue));
192
101
        if (request.lower_bound().has_is_inclusive()
193
102
            && !request.lower_bound().is_inclusive()) {
194
14
            lower_doc_key.AddRangeComponent(
195
14
                PrimitiveValue(docdb::ValueType::kHighest));
196
14
        }
197
101
    }
198
199
3.03M
    DocKey upper_doc_key(schema);
200
3.03M
    if (request.has_upper_bound()
201
3.03M
        && 
schema.num_hash_key_columns() == 0157k
) {
202
156k
        Slice upper_key_slice = request.upper_bound().key();
203
156k
        RETURN_NOT_OK(upper_doc_key.DecodeFrom(&upper_key_slice,
204
156k
                            DocKeyPart::kWholeDocKey,
205
156k
                            AllowSpecial::kTrue));
206
156k
        if (request.upper_bound().has_is_inclusive()
207
156k
            && request.upper_bound().is_inclusive()) {
208
156k
            upper_doc_key.AddRangeComponent(
209
156k
                PrimitiveValue(docdb::ValueType::kHighest));
210
156k
        }
211
156k
    }
212
213
214
3.03M
    SCHECK(!request.has_where_expr(),
215
3.03M
           InternalError,
216
3.03M
           "WHERE clause is not yet supported in docdb::pgsql");
217
3.03M
    RETURN_NOT_OK(doc_iter->Init(DocPgsqlScanSpec(
218
3.03M
        schema,
219
3.03M
        request.stmt_id(),
220
3.03M
        hashed_components,
221
3.03M
        range_components,
222
3.03M
        request.has_condition_expr() ? &request.condition_expr().condition() : nullptr,
223
3.03M
        request.hash_code(),
224
3.03M
        request.has_max_hash_code() ? boost::make_optional<int32_t>(request.max_hash_code())
225
3.03M
                                    : boost::none,
226
3.03M
        nullptr /* where_expr */,
227
3.03M
        start_doc_key,
228
3.03M
        request.is_forward_scan(),
229
3.03M
        lower_doc_key,
230
3.03M
        upper_doc_key)));
231
3.03M
  }
232
233
3.91M
  *iter = std::move(doc_iter);
234
3.91M
  return Status::OK();
235
3.91M
}
236
237
}  // namespace docdb
238
}  // namespace yb