/Users/deen/code/yugabyte-db/src/yb/yql/pggate/pg_tabledesc.cc
Line | Count | Source (jump to first uncovered line) |
1 | | //-------------------------------------------------------------------------------------------------- |
2 | | // Copyright (c) YugaByte, Inc. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
5 | | // in compliance with the License. You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
10 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
11 | | // or implied. See the License for the specific language governing permissions and limitations |
12 | | // under the License. |
13 | | // |
14 | | //-------------------------------------------------------------------------------------------------- |
15 | | |
16 | | #include "yb/yql/pggate/pg_tabledesc.h" |
17 | | |
18 | | #include "yb/client/schema.h" |
19 | | #include "yb/client/table.h" |
20 | | #include "yb/client/yb_op.h" |
21 | | |
22 | | #include "yb/common/partition.h" |
23 | | #include "yb/common/pg_system_attr.h" |
24 | | #include "yb/common/schema.h" |
25 | | |
26 | | #include "yb/docdb/doc_key.h" |
27 | | |
28 | | #include "yb/gutil/casts.h" |
29 | | |
30 | | #include "yb/util/result.h" |
31 | | #include "yb/util/status_format.h" |
32 | | |
33 | | namespace yb { |
34 | | namespace pggate { |
35 | | |
36 | | PgTableDesc::PgTableDesc(const PgObjectId& id, const client::YBTablePtr& table) |
37 | 64.5k | : id_(id), table_(table), table_partitions_(table_->GetVersionedPartitions()) { |
38 | | |
39 | 64.5k | size_t idx = 0; |
40 | 565k | for (const auto& column : schema().columns()) { |
41 | 565k | attr_num_map_.emplace(column.order(), idx++); |
42 | 565k | } |
43 | 64.5k | } |
44 | | |
45 | 17.6M | Result<size_t> PgTableDesc::FindColumn(int attr_num) const { |
46 | | // Find virtual columns. |
47 | 17.6M | if (attr_num == static_cast<int>(PgSystemAttrNum::kYBTupleId)) { |
48 | 2.28M | return num_columns(); |
49 | 2.28M | } |
50 | | |
51 | | // Find physical column. |
52 | 15.3M | const auto itr = attr_num_map_.find(attr_num); |
53 | 15.3M | if (itr != attr_num_map_.end()) { |
54 | 15.3M | return itr->second; |
55 | 15.3M | } |
56 | | |
57 | 18.4E | return STATUS_FORMAT(InvalidArgument, "Invalid column number $0", attr_num); |
58 | 18.4E | } |
59 | | |
60 | 27.3M | Result<YBCPgColumnInfo> PgTableDesc::GetColumnInfo(int16_t attr_number) const { |
61 | 27.3M | YBCPgColumnInfo column_info { |
62 | 27.3M | .is_primary = false, |
63 | 27.3M | .is_hash = false |
64 | 27.3M | }; |
65 | 27.3M | const auto itr = attr_num_map_.find(attr_number); |
66 | 27.3M | if (itr != attr_num_map_.end()) { |
67 | 23.1M | column_info.is_primary = itr->second < schema().num_key_columns(); |
68 | 23.1M | column_info.is_hash = itr->second < schema().num_hash_key_columns(); |
69 | 23.1M | } |
70 | 27.3M | return column_info; |
71 | 27.3M | } |
72 | | |
73 | 1.91k | bool PgTableDesc::IsColocated() const { |
74 | 1.91k | return table_->colocated(); |
75 | 1.91k | } |
76 | | |
77 | 796k | bool PgTableDesc::IsHashPartitioned() const { |
78 | 796k | return schema().num_hash_key_columns() > 0; |
79 | 796k | } |
80 | | |
81 | 1.57M | bool PgTableDesc::IsRangePartitioned() const { |
82 | 1.57M | return schema().num_hash_key_columns() == 0; |
83 | 1.57M | } |
84 | | |
85 | 2.07k | const std::vector<std::string>& PgTableDesc::GetPartitions() const { |
86 | 2.07k | return table_partitions_->keys; |
87 | 2.07k | } |
88 | | |
89 | 1.90M | const std::string& PgTableDesc::LastPartition() const { |
90 | 1.90M | return table_partitions_->keys.back(); |
91 | 1.90M | } |
92 | | |
93 | 798k | size_t PgTableDesc::GetPartitionCount() const { |
94 | 798k | return table_partitions_->keys.size(); |
95 | 798k | } |
96 | | |
97 | 796k | Result<string> PgTableDesc::DecodeYbctid(const Slice& ybctid) const { |
98 | | // TODO(neil) If a partition schema can have both hash and range partitioning, this function needs |
99 | | // to be updated to return appropriate primary key. |
100 | 796k | RSTATUS_DCHECK(!IsHashPartitioned() || !IsRangePartitioned(), InvalidArgument, |
101 | 796k | "Partitioning schema by both hash and range is not yet supported"); |
102 | | |
103 | | // Use range key if there's no hash columns. |
104 | | // NOTE: Also see bug github #5832. |
105 | 796k | if (IsRangePartitioned()) { |
106 | | // Decoding using range partitioning method. |
107 | 19.3k | return ybctid.ToBuffer(); |
108 | 19.3k | } |
109 | | |
110 | | // Decoding using hash partitioning method. |
111 | | // Do not check with predicate IsHashPartitioning() for now to use existing behavior by default. |
112 | 777k | uint16 hash_code = VERIFY_RESULT(docdb::DocKey::DecodeHash(ybctid)); |
113 | 777k | return PartitionSchema::EncodeMultiColumnHashValue(hash_code); |
114 | 777k | } |
115 | | |
116 | 796k | Result<size_t> PgTableDesc::FindPartitionIndex(const Slice& ybctid) const { |
117 | | // Find partition index based on ybctid value. |
118 | | // - Hash Partition: ybctid -> hashcode -> key -> partition index. |
119 | | // - Range Partition: ybctid == key -> partition index. |
120 | 796k | string partition_key = VERIFY_RESULT(DecodeYbctid(ybctid)); |
121 | 796k | return client::FindPartitionStartIndex(table_partitions_->keys, partition_key); |
122 | 796k | } |
123 | | |
124 | | Status PgTableDesc::SetScanBoundary(PgsqlReadRequestPB *req, |
125 | | const string& partition_lower_bound, |
126 | | bool lower_bound_is_inclusive, |
127 | | const string& partition_upper_bound, |
128 | 3.40k | bool upper_bound_is_inclusive) { |
129 | | // Setup lower boundary. |
130 | 3.40k | if (!partition_lower_bound.empty()) { |
131 | 1.95k | req->mutable_lower_bound()->set_key(partition_lower_bound); |
132 | 1.95k | req->mutable_lower_bound()->set_is_inclusive(lower_bound_is_inclusive); |
133 | 1.95k | } |
134 | | |
135 | | // Setup upper boundary. |
136 | 3.40k | if (!partition_upper_bound.empty()) { |
137 | 2.45k | req->mutable_upper_bound()->set_key(partition_upper_bound); |
138 | 2.45k | req->mutable_upper_bound()->set_is_inclusive(upper_bound_is_inclusive); |
139 | 2.45k | } |
140 | | |
141 | 3.40k | return Status::OK(); |
142 | 3.40k | } |
143 | | |
144 | 0 | const client::YBTableName& PgTableDesc::table_name() const { |
145 | 0 | return table_->name(); |
146 | 0 | } |
147 | | |
148 | 11.3M | size_t PgTableDesc::num_hash_key_columns() const { |
149 | 11.3M | return schema().num_hash_key_columns(); |
150 | 11.3M | } |
151 | | |
152 | 7.69M | size_t PgTableDesc::num_key_columns() const { |
153 | 7.69M | return schema().num_key_columns(); |
154 | 7.69M | } |
155 | | |
156 | 5.68M | size_t PgTableDesc::num_columns() const { |
157 | 5.68M | return schema().num_columns(); |
158 | 5.68M | } |
159 | | |
160 | 5.60M | const PartitionSchema& PgTableDesc::partition_schema() const { |
161 | 5.60M | return table_->partition_schema(); |
162 | 5.60M | } |
163 | | |
164 | 111M | const Schema& PgTableDesc::schema() const { |
165 | 111M | return table_->InternalSchema(); |
166 | 111M | } |
167 | | |
168 | 2.69M | uint32_t PgTableDesc::schema_version() const { |
169 | 2.69M | return table_->schema().version(); |
170 | 2.69M | } |
171 | | |
172 | 54 | std::unique_ptr<client::YBPgsqlWriteOp> PgTableDesc::NewPgsqlInsert() { |
173 | 54 | return client::YBPgsqlWriteOp::NewInsert(table_); |
174 | 54 | } |
175 | | |
176 | 33 | std::unique_ptr<client::YBPgsqlWriteOp> PgTableDesc::NewPgsqlUpdate() { |
177 | 33 | return client::YBPgsqlWriteOp::NewUpdate(table_); |
178 | 33 | } |
179 | | |
180 | 48 | std::unique_ptr<client::YBPgsqlWriteOp> PgTableDesc::NewPgsqlDelete() { |
181 | 48 | return client::YBPgsqlWriteOp::NewDelete(table_); |
182 | 48 | } |
183 | | |
184 | 0 | std::unique_ptr<client::YBPgsqlWriteOp> PgTableDesc::NewPgsqlTruncateColocated() { |
185 | 0 | return client::YBPgsqlWriteOp::NewTruncateColocated(table_); |
186 | 0 | } |
187 | | |
188 | 69 | std::unique_ptr<client::YBPgsqlReadOp> PgTableDesc::NewPgsqlSelect() { |
189 | 69 | return client::YBPgsqlReadOp::NewSelect(table_); |
190 | 69 | } |
191 | | |
192 | 0 | std::unique_ptr<client::YBPgsqlReadOp> PgTableDesc::NewPgsqlSample() { |
193 | 0 | return client::YBPgsqlReadOp::NewSample(table_); |
194 | 0 | } |
195 | | |
196 | | } // namespace pggate |
197 | | } // namespace yb |