YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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
#include "yb/common/wire_protocol.h"
26
27
#include "yb/docdb/doc_key.h"
28
29
#include "yb/gutil/casts.h"
30
31
#include "yb/util/result.h"
32
#include "yb/util/status_format.h"
33
34
namespace yb {
35
namespace pggate {
36
37
PgTableDesc::PgTableDesc(
38
    const PgObjectId& id, const master::GetTableSchemaResponsePB& resp,
39
    std::shared_ptr<client::VersionedTablePartitionList> partitions)
40
191k
    : id_(id), resp_(resp),  table_partitions_(std::move(partitions)) {
41
191k
  table_name_.GetFromTableIdentifierPB(resp.identifier());
42
191k
}
43
44
191k
Status PgTableDesc::Init() {
45
191k
  RETURN_NOT_OK(SchemaFromPB(resp_.schema(), &schema_));
46
191k
  size_t idx = 0;
47
1.72M
  for (const auto& column : schema().columns()) {
48
1.72M
    attr_num_map_.emplace(column.order(), idx++);
49
1.72M
  }
50
191k
  return PartitionSchema::FromPB(resp_.partition_schema(), schema_, &partition_schema_);
51
191k
}
52
53
54.6M
Result<size_t> PgTableDesc::FindColumn(int attr_num) const {
54
  // Find virtual columns.
55
54.6M
  if (attr_num == static_cast<int>(PgSystemAttrNum::kYBTupleId)) {
56
7.26M
    return num_columns();
57
7.26M
  }
58
59
  // Find physical column.
60
47.3M
  const auto itr = attr_num_map_.find(attr_num);
61
47.3M
  if (
itr != attr_num_map_.end()47.3M
) {
62
47.3M
    return itr->second;
63
47.3M
  }
64
65
18.4E
  return STATUS_FORMAT(InvalidArgument, "Invalid column number $0", attr_num);
66
47.3M
}
67
68
83.9M
Result<YBCPgColumnInfo> PgTableDesc::GetColumnInfo(int16_t attr_number) const {
69
83.9M
  YBCPgColumnInfo column_info {
70
83.9M
    .is_primary = false,
71
83.9M
    .is_hash = false
72
83.9M
  };
73
83.9M
  const auto itr = attr_num_map_.find(attr_number);
74
83.9M
  if (itr != attr_num_map_.end()) {
75
71.5M
    column_info.is_primary = itr->second < schema().num_key_columns();
76
71.5M
    column_info.is_hash = itr->second < schema().num_hash_key_columns();
77
71.5M
  }
78
83.9M
  return column_info;
79
83.9M
}
80
81
5.63k
bool PgTableDesc::IsColocated() const {
82
5.63k
  return resp_.colocated();
83
5.63k
}
84
85
249
YBCPgOid PgTableDesc::GetColocationId() const {
86
249
  return schema().has_colocation_id() ? 
schema().colocation_id()79
:
kColocationIdNotSet170
;
87
249
}
88
89
1.54M
bool PgTableDesc::IsHashPartitioned() const {
90
1.54M
  return schema().num_hash_key_columns() > 0;
91
1.54M
}
92
93
3.07M
bool PgTableDesc::IsRangePartitioned() const {
94
3.07M
  return schema().num_hash_key_columns() == 0;
95
3.07M
}
96
97
14.0k
const std::vector<std::string>& PgTableDesc::GetPartitions() const {
98
14.0k
  return table_partitions_->keys;
99
14.0k
}
100
101
4.36M
const std::string& PgTableDesc::LastPartition() const {
102
4.36M
  return table_partitions_->keys.back();
103
4.36M
}
104
105
1.55M
size_t PgTableDesc::GetPartitionCount() const {
106
1.55M
  return table_partitions_->keys.size();
107
1.55M
}
108
109
1.54M
Result<string> PgTableDesc::DecodeYbctid(const Slice& ybctid) const {
110
  // TODO(neil) If a partition schema can have both hash and range partitioning, this function needs
111
  // to be updated to return appropriate primary key.
112
1.54M
  RSTATUS_DCHECK(!IsHashPartitioned() || !IsRangePartitioned(), InvalidArgument,
113
1.54M
                 "Partitioning schema by both hash and range is not yet supported");
114
115
  // Use range key if there's no hash columns.
116
  // NOTE: Also see bug github #5832.
117
1.54M
  if (IsRangePartitioned()) {
118
    // Decoding using range partitioning method.
119
19.4k
    return ybctid.ToBuffer();
120
19.4k
  }
121
122
  // Decoding using hash partitioning method.
123
  // Do not check with predicate IsHashPartitioning() for now to use existing behavior by default.
124
1.52M
  uint16 hash_code = VERIFY_RESULT(docdb::DocKey::DecodeHash(ybctid));
125
0
  return PartitionSchema::EncodeMultiColumnHashValue(hash_code);
126
1.52M
}
127
128
1.54M
Result<size_t> PgTableDesc::FindPartitionIndex(const Slice& ybctid) const {
129
  // Find partition index based on ybctid value.
130
  // - Hash Partition: ybctid -> hashcode -> key -> partition index.
131
  // - Range Partition: ybctid == key -> partition index.
132
1.54M
  string partition_key = VERIFY_RESULT(DecodeYbctid(ybctid));
133
0
  return client::FindPartitionStartIndex(table_partitions_->keys, partition_key);
134
1.54M
}
135
136
Status PgTableDesc::SetScanBoundary(PgsqlReadRequestPB *req,
137
                                    const string& partition_lower_bound,
138
                                    bool lower_bound_is_inclusive,
139
                                    const string& partition_upper_bound,
140
27.7k
                                    bool upper_bound_is_inclusive) {
141
  // Setup lower boundary.
142
27.7k
  if (!partition_lower_bound.empty()) {
143
17.5k
    req->mutable_lower_bound()->set_key(partition_lower_bound);
144
17.5k
    req->mutable_lower_bound()->set_is_inclusive(lower_bound_is_inclusive);
145
17.5k
  }
146
147
  // Setup upper boundary.
148
27.7k
  if (!partition_upper_bound.empty()) {
149
19.0k
    req->mutable_upper_bound()->set_key(partition_upper_bound);
150
19.0k
    req->mutable_upper_bound()->set_is_inclusive(upper_bound_is_inclusive);
151
19.0k
  }
152
153
27.7k
  return Status::OK();
154
27.7k
}
155
156
2
const client::YBTableName& PgTableDesc::table_name() const {
157
2
  return table_name_;
158
2
}
159
160
27.6M
size_t PgTableDesc::num_hash_key_columns() const {
161
27.6M
  return schema().num_hash_key_columns();
162
27.6M
}
163
164
19.6M
size_t PgTableDesc::num_key_columns() const {
165
19.6M
  return schema().num_key_columns();
166
19.6M
}
167
168
18.1M
size_t PgTableDesc::num_columns() const {
169
18.1M
  return schema().num_columns();
170
18.1M
}
171
172
15.9M
const PartitionSchema& PgTableDesc::partition_schema() const {
173
15.9M
  return partition_schema_;
174
15.9M
}
175
176
350M
const Schema& PgTableDesc::schema() const {
177
350M
  return schema_;
178
350M
}
179
180
8.80M
uint32_t PgTableDesc::schema_version() const {
181
8.80M
  return resp_.version();
182
8.80M
}
183
184
}  // namespace pggate
185
}  // namespace yb