/Users/deen/code/yugabyte-db/src/yb/yql/pggate/pg_op.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/yql/pggate/pg_op.h" |
15 | | |
16 | | #include "yb/client/table.h" |
17 | | #include "yb/client/yb_op.h" |
18 | | |
19 | | #include "yb/common/partition.h" |
20 | | #include "yb/common/pgsql_protocol.pb.h" |
21 | | #include "yb/common/ql_scanspec.h" |
22 | | #include "yb/common/ql_value.h" |
23 | | #include "yb/common/schema.h" |
24 | | |
25 | | #include "yb/docdb/doc_key.h" |
26 | | #include "yb/docdb/doc_scanspec_util.h" |
27 | | #include "yb/docdb/primitive_value_util.h" |
28 | | |
29 | | #include "yb/yql/pggate/pg_tabledesc.h" |
30 | | |
31 | | #include "yb/util/scope_exit.h" |
32 | | |
33 | | namespace yb { |
34 | | namespace pggate { |
35 | | |
36 | 3.17M | Status ReviewResponsePagingState(const PgTableDesc& table, PgsqlReadOp* op) { |
37 | 3.17M | auto& response = op->response(); |
38 | 3.17M | if (table.num_hash_key_columns() > 0 || |
39 | 3.17M | op->read_request().is_forward_scan()1.25M || |
40 | 3.17M | !response.has_paging_state()61 || |
41 | 3.17M | !response.paging_state().has_next_partition_key()41 || |
42 | 3.17M | response.paging_state().has_next_row_key()41 ) { |
43 | 3.17M | return Status::OK(); |
44 | 3.17M | } |
45 | | // Backward scan of range key only table. next_row_key is not specified in paging state. |
46 | | // In this case next_partition_key must be corrected as now it points to the partition start key |
47 | | // of already scanned tablet. Partition start key of the preceding tablet must be used instead. |
48 | | // Also lower bound is checked here because DocDB can check upper bound only. |
49 | 863 | const auto& current_next_partition_key = response.paging_state().next_partition_key(); |
50 | 863 | std::vector<docdb::PrimitiveValue> lower_bound, upper_bound; |
51 | 863 | RETURN_NOT_OK(client::GetRangePartitionBounds( |
52 | 863 | table.schema(), op->read_request(), &lower_bound, &upper_bound)); |
53 | 863 | if (!lower_bound.empty()) { |
54 | 14 | docdb::DocKey current_key(table.schema()); |
55 | 14 | VERIFY_RESULT(current_key.DecodeFrom( |
56 | 0 | current_next_partition_key, docdb::DocKeyPart::kWholeDocKey, docdb::AllowSpecial::kTrue)); |
57 | 14 | if (current_key.CompareTo(docdb::DocKey(std::move(lower_bound))) < 0) { |
58 | 2 | response.clear_paging_state(); |
59 | 2 | return Status::OK(); |
60 | 2 | } |
61 | 14 | } |
62 | 861 | const auto& partitions = table.GetPartitions(); |
63 | 861 | const auto idx = client::FindPartitionStartIndex(partitions, current_next_partition_key); |
64 | 861 | SCHECK_GT( |
65 | 861 | idx, 0ULL, |
66 | 861 | IllegalState, "Paging state for backward scan cannot point to first partition"); |
67 | 861 | SCHECK_EQ( |
68 | 861 | partitions[idx], current_next_partition_key, |
69 | 861 | IllegalState, "Paging state for backward scan must point to partition start key"); |
70 | 861 | const auto& next_partition_key = partitions[idx - 1]; |
71 | 861 | response.mutable_paging_state()->set_next_partition_key(next_partition_key); |
72 | 861 | return Status::OK(); |
73 | 861 | } |
74 | | |
75 | 0 | std::string PgsqlOp::ToString() const { |
76 | 0 | return Format("{ $0 active: $1 read_time: $2 request: $3 }", |
77 | 0 | is_read() ? "READ" : "WRITE", active_, read_time_, RequestToString()); |
78 | 0 | } |
79 | | |
80 | 1.59M | PgsqlReadOp::PgsqlReadOp(const PgTableDesc& desc) { |
81 | 1.59M | read_request_.set_client(YQL_CLIENT_PGSQL); |
82 | 1.59M | read_request_.set_table_id(desc.id().GetYbTableId()); |
83 | 1.59M | read_request_.set_schema_version(desc.schema_version()); |
84 | 1.59M | read_request_.set_stmt_id(reinterpret_cast<int64_t>(&read_request_)); |
85 | 1.59M | } |
86 | | |
87 | 4.36M | CHECKED_STATUS PgsqlReadOp::InitPartitionKey(const PgTableDesc& table) { |
88 | 4.36M | return client::InitPartitionKey( |
89 | 4.36M | table.schema(), table.partition_schema(), table.LastPartition(), &read_request_); |
90 | 4.36M | } |
91 | | |
92 | 0 | std::string PgsqlReadOp::RequestToString() const { |
93 | 0 | return read_request_.ShortDebugString(); |
94 | 0 | } |
95 | | |
96 | 7.20M | CHECKED_STATUS PgsqlWriteOp::InitPartitionKey(const PgTableDesc& table) { |
97 | 7.20M | return client::InitPartitionKey(table.schema(), table.partition_schema(), &write_request_); |
98 | 7.20M | } |
99 | | |
100 | 0 | std::string PgsqlWriteOp::RequestToString() const { |
101 | 0 | return write_request_.ShortDebugString(); |
102 | 0 | } |
103 | | |
104 | | } // namespace pggate |
105 | | } // namespace yb |