/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 | 1.35M | Status ReviewResponsePagingState(const PgTableDesc& table, PgsqlReadOp* op) { |
37 | 1.35M | auto& response = op->response(); |
38 | 1.35M | if (table.num_hash_key_columns() > 0 || |
39 | 382k | op->read_request().is_forward_scan() || |
40 | 0 | !response.has_paging_state() || |
41 | 0 | !response.paging_state().has_next_partition_key() || |
42 | 1.35M | response.paging_state().has_next_row_key()) { |
43 | 1.35M | return Status::OK(); |
44 | 1.35M | } |
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 | 18.4E | const auto& current_next_partition_key = response.paging_state().next_partition_key(); |
50 | 18.4E | std::vector<docdb::PrimitiveValue> lower_bound, upper_bound; |
51 | 18.4E | RETURN_NOT_OK(client::GetRangePartitionBounds( |
52 | 18.4E | table.schema(), op->read_request(), &lower_bound, &upper_bound)); |
53 | 18.4E | if (!lower_bound.empty()) { |
54 | 0 | docdb::DocKey current_key(table.schema()); |
55 | 0 | VERIFY_RESULT(current_key.DecodeFrom( |
56 | 0 | current_next_partition_key, docdb::DocKeyPart::kWholeDocKey, docdb::AllowSpecial::kTrue)); |
57 | 0 | if (current_key.CompareTo(docdb::DocKey(std::move(lower_bound))) < 0) { |
58 | 0 | response.clear_paging_state(); |
59 | 0 | return Status::OK(); |
60 | 0 | } |
61 | 18.4E | } |
62 | 18.4E | const auto& partitions = table.GetPartitions(); |
63 | 18.4E | const auto idx = client::FindPartitionStartIndex(partitions, current_next_partition_key); |
64 | 18.4E | SCHECK_GT( |
65 | 18.4E | idx, 0ULL, |
66 | 18.4E | IllegalState, "Paging state for backward scan cannot point to first partition"); |
67 | 18.4E | SCHECK_EQ( |
68 | 18.4E | partitions[idx], current_next_partition_key, |
69 | 18.4E | IllegalState, "Paging state for backward scan must point to partition start key"); |
70 | 18.4E | const auto& next_partition_key = partitions[idx - 1]; |
71 | 18.4E | response.mutable_paging_state()->set_next_partition_key(next_partition_key); |
72 | 18.4E | return Status::OK(); |
73 | 18.4E | } |
74 | | |
75 | 0 | std::string PgsqlOp::ToString() const { |
76 | 0 | return Format("{ $0 active: $1 read_time: $2 }", |
77 | 0 | is_read() ? "READ" : "WRITE", active_, read_time_); |
78 | 0 | } |
79 | | |
80 | 562k | PgsqlReadOp::PgsqlReadOp(const PgTableDesc& desc) { |
81 | 562k | read_request_.set_client(YQL_CLIENT_PGSQL); |
82 | 562k | read_request_.set_table_id(desc.id().GetYBTableId()); |
83 | 562k | read_request_.set_schema_version(desc.schema_version()); |
84 | 562k | read_request_.set_stmt_id(reinterpret_cast<int64_t>(&read_request_)); |
85 | 562k | } |
86 | | |
87 | 1.90M | CHECKED_STATUS PgsqlReadOp::InitPartitionKey(const PgTableDesc& table) { |
88 | 1.90M | return client::InitPartitionKey( |
89 | 1.90M | table.schema(), table.partition_schema(), table.LastPartition(), &read_request_); |
90 | 1.90M | } |
91 | | |
92 | 2.12M | CHECKED_STATUS PgsqlWriteOp::InitPartitionKey(const PgTableDesc& table) { |
93 | 2.12M | return client::InitPartitionKey(table.schema(), table.partition_schema(), &write_request_); |
94 | 2.12M | } |
95 | | |
96 | | } // namespace pggate |
97 | | } // namespace yb |