YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/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