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_expr.h
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
#ifndef YB_YQL_PGGATE_PG_EXPR_H_
16
#define YB_YQL_PGGATE_PG_EXPR_H_
17
18
#include "yb/common/common_fwd.h"
19
#include "yb/common/ql_datatype.h"
20
21
#include "yb/yql/pggate/util/pg_doc_data.h"
22
#include "yb/yql/pggate/util/pg_tuple.h"
23
#include "yb/bfpg/tserver_opcodes.h"
24
25
namespace yb {
26
namespace pggate {
27
28
class PgDml;
29
class PgExpr {
30
 public:
31
  enum class Opcode {
32
    PG_EXPR_CONSTANT,
33
    PG_EXPR_COLREF,
34
    PG_EXPR_VARIABLE,
35
36
    // The logical expression for defining the conditions when we support WHERE clause.
37
    PG_EXPR_NOT,
38
    PG_EXPR_EQ,
39
    PG_EXPR_NE,
40
    PG_EXPR_GE,
41
    PG_EXPR_GT,
42
    PG_EXPR_LE,
43
    PG_EXPR_LT,
44
45
    // Aggregate functions.
46
    PG_EXPR_AVG,
47
    PG_EXPR_SUM,
48
    PG_EXPR_COUNT,
49
    PG_EXPR_MAX,
50
    PG_EXPR_MIN,
51
52
    // Serialized YSQL/PG Expr node.
53
    PG_EXPR_EVAL_EXPR_CALL,
54
55
    PG_EXPR_GENERATE_ROWID,
56
  };
57
58
  // Public types.
59
  typedef std::shared_ptr<PgExpr> SharedPtr;
60
  typedef std::shared_ptr<const PgExpr> SharedPtrConst;
61
62
  typedef std::unique_ptr<PgExpr> UniPtr;
63
  typedef std::unique_ptr<const PgExpr> UniPtrConst;
64
65
  // Prepare expression when constructing a statement.
66
  virtual CHECKED_STATUS PrepareForRead(PgDml *pg_stmt, PgsqlExpressionPB *expr_pb);
67
68
  // Convert this expression structure to PB format.
69
  virtual CHECKED_STATUS Eval(PgsqlExpressionPB *expr_pb);
70
  virtual CHECKED_STATUS Eval(QLValuePB *result);
71
72
  // Access methods.
73
649M
  Opcode opcode() const {
74
649M
    return opcode_;
75
649M
  }
76
5.87M
  bool is_constant() const {
77
5.87M
    return opcode_ == Opcode::PG_EXPR_CONSTANT;
78
5.87M
  }
79
648M
  bool is_colref() const {
80
648M
    return opcode_ == Opcode::PG_EXPR_COLREF;
81
648M
  }
82
28.5M
  bool is_aggregate() const {
83
    // Only return true for pushdown supported aggregates.
84
28.5M
    return (opcode_ == Opcode::PG_EXPR_SUM ||
85
28.5M
            opcode_ == Opcode::PG_EXPR_COUNT ||
86
28.5M
            
opcode_ == Opcode::PG_EXPR_MAX28.5M
||
87
28.5M
            
opcode_ == Opcode::PG_EXPR_MIN28.5M
);
88
28.5M
  }
89
6.06k
  virtual bool is_ybbasetid() const {
90
6.06k
    return false;
91
6.06k
  }
92
93
  // Read the result from input buffer (yb_cursor) that was computed by and sent from DocDB.
94
  // Write the result to output buffer (pg_cursor) in Postgres format.
95
  CHECKED_STATUS ResultToPg(Slice *yb_cursor, Slice *pg_cursor);
96
97
  // Function translate_data_() reads the received data from DocDB and writes it to Postgres buffer
98
  // using to_datum().
99
  // - DocDB supports a number of datatypes, and we would need to provide one translate function for
100
  //   each datatype to read them correctly. The translate_data() function pointer must be setup
101
  //   correctly during the compilation of a statement.
102
  // - For each postgres data type, to_datum() function pointer must be setup properly during
103
  //   the compilation of a statement.
104
  void TranslateData(Slice *yb_cursor, const PgWireDataHeader& header, int index,
105
                     PgTuple *pg_tuple) const;
106
107
  static bool TranslateNumberHelper(
108
      const PgWireDataHeader& header, int index, const YBCPgTypeEntity *type_entity,
109
      PgTuple *pg_tuple);
110
111
  // Implementation for "translate_data()" for each supported datatype.
112
  // Translates DocDB-numeric datatypes.
113
  template<typename data_type>
114
  static void TranslateNumber(Slice *yb_cursor, const PgWireDataHeader& header, int index,
115
                              const YBCPgTypeEntity *type_entity, const PgTypeAttrs *type_attrs,
116
490M
                              PgTuple *pg_tuple) {
117
490M
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
62.1k
      return;
119
62.1k
    }
120
121
490M
    data_type result = 0;
122
490M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
490M
    yb_cursor->remove_prefix(read_size);
124
490M
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
490M
  }
void yb::pggate::PgExpr::TranslateNumber<signed char>(yb::Slice*, yb::pggate::PgWireDataHeader const&, int, PgTypeEntity const*, PgTypeAttrs const*, yb::pggate::PgTuple*)
Line
Count
Source
116
62.2M
                              PgTuple *pg_tuple) {
117
62.2M
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
0
      return;
119
0
    }
120
121
62.2M
    data_type result = 0;
122
62.2M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
62.2M
    yb_cursor->remove_prefix(read_size);
124
62.2M
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
62.2M
  }
void yb::pggate::PgExpr::TranslateNumber<short>(yb::Slice*, yb::pggate::PgWireDataHeader const&, int, PgTypeEntity const*, PgTypeAttrs const*, yb::pggate::PgTuple*)
Line
Count
Source
116
37.6M
                              PgTuple *pg_tuple) {
117
37.6M
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
0
      return;
119
0
    }
120
121
37.6M
    data_type result = 0;
122
37.6M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
37.6M
    yb_cursor->remove_prefix(read_size);
124
37.6M
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
37.6M
  }
void yb::pggate::PgExpr::TranslateNumber<int>(yb::Slice*, yb::pggate::PgWireDataHeader const&, int, PgTypeEntity const*, PgTypeAttrs const*, yb::pggate::PgTuple*)
Line
Count
Source
116
137M
                              PgTuple *pg_tuple) {
117
137M
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
12.5k
      return;
119
12.5k
    }
120
121
137M
    data_type result = 0;
122
137M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
137M
    yb_cursor->remove_prefix(read_size);
124
137M
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
137M
  }
void yb::pggate::PgExpr::TranslateNumber<long long>(yb::Slice*, yb::pggate::PgWireDataHeader const&, int, PgTypeEntity const*, PgTypeAttrs const*, yb::pggate::PgTuple*)
Line
Count
Source
116
896k
                              PgTuple *pg_tuple) {
117
896k
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
49.5k
      return;
119
49.5k
    }
120
121
847k
    data_type result = 0;
122
847k
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
847k
    yb_cursor->remove_prefix(read_size);
124
847k
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
847k
  }
void yb::pggate::PgExpr::TranslateNumber<unsigned int>(yb::Slice*, yb::pggate::PgWireDataHeader const&, int, PgTypeEntity const*, PgTypeAttrs const*, yb::pggate::PgTuple*)
Line
Count
Source
116
138M
                              PgTuple *pg_tuple) {
117
138M
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
0
      return;
119
0
    }
120
121
138M
    data_type result = 0;
122
138M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
138M
    yb_cursor->remove_prefix(read_size);
124
138M
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
138M
  }
void yb::pggate::PgExpr::TranslateNumber<unsigned long long>(yb::Slice*, yb::pggate::PgWireDataHeader const&, int, PgTypeEntity const*, PgTypeAttrs const*, yb::pggate::PgTuple*)
Line
Count
Source
116
24
                              PgTuple *pg_tuple) {
117
24
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
0
      return;
119
0
    }
120
121
24
    data_type result = 0;
122
24
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
24
    yb_cursor->remove_prefix(read_size);
124
24
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
24
  }
void yb::pggate::PgExpr::TranslateNumber<bool>(yb::Slice*, yb::pggate::PgWireDataHeader const&, int, PgTypeEntity const*, PgTypeAttrs const*, yb::pggate::PgTuple*)
Line
Count
Source
116
110M
                              PgTuple *pg_tuple) {
117
110M
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
14
      return;
119
14
    }
120
121
110M
    data_type result = 0;
122
110M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
110M
    yb_cursor->remove_prefix(read_size);
124
110M
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
110M
  }
void yb::pggate::PgExpr::TranslateNumber<float>(yb::Slice*, yb::pggate::PgWireDataHeader const&, int, PgTypeEntity const*, PgTypeAttrs const*, yb::pggate::PgTuple*)
Line
Count
Source
116
2.26M
                              PgTuple *pg_tuple) {
117
2.26M
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
9
      return;
119
9
    }
120
121
2.26M
    data_type result = 0;
122
2.26M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
2.26M
    yb_cursor->remove_prefix(read_size);
124
2.26M
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
2.26M
  }
void yb::pggate::PgExpr::TranslateNumber<double>(yb::Slice*, yb::pggate::PgWireDataHeader const&, int, PgTypeEntity const*, PgTypeAttrs const*, yb::pggate::PgTuple*)
Line
Count
Source
116
268k
                              PgTuple *pg_tuple) {
117
268k
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
23
      return;
119
23
    }
120
121
268k
    data_type result = 0;
122
268k
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
268k
    yb_cursor->remove_prefix(read_size);
124
268k
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
268k
  }
Unexecuted instantiation: void yb::pggate::PgExpr::TranslateNumber<unsigned char>(yb::Slice*, yb::pggate::PgWireDataHeader const&, int, PgTypeEntity const*, PgTypeAttrs const*, yb::pggate::PgTuple*)
126
127
  // Translates DocDB-char-based datatypes.
128
  static void TranslateText(Slice *yb_cursor, const PgWireDataHeader& header, int index,
129
                            const YBCPgTypeEntity *type_entity, const PgTypeAttrs *type_attrs,
130
                            PgTuple *pg_tuple);
131
132
  // Translates DocDB collated char-based datatypes.
133
  static void TranslateCollateText(Slice *yb_cursor, const PgWireDataHeader& header,
134
                                   int index, const YBCPgTypeEntity *type_entity,
135
                                   const PgTypeAttrs *type_attrs, PgTuple *pg_tuple);
136
137
  // Translates DocDB-binary-based datatypes.
138
  static void TranslateBinary(Slice *yb_cursor, const PgWireDataHeader& header, int index,
139
                              const YBCPgTypeEntity *type_entity, const PgTypeAttrs *type_attrs,
140
                              PgTuple *pg_tuple);
141
142
  // Translate DocDB-decimal datatype.
143
  static void TranslateDecimal(Slice *yb_cursor, const PgWireDataHeader& header, int index,
144
                               const YBCPgTypeEntity *type_entity, const PgTypeAttrs *type_attrs,
145
                               PgTuple *pg_tuple);
146
147
  // Translate system column.
148
  template<typename data_type>
149
8.12M
  static void TranslateSysCol(Slice *yb_cursor, const PgWireDataHeader& header, data_type *value) {
150
8.12M
    *value = 0;
151
8.12M
    if (header.is_null()) {
152
      // 0 is an invalid OID.
153
0
      return;
154
0
    }
155
8.12M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, value);
156
8.12M
    yb_cursor->remove_prefix(read_size);
157
8.12M
  }
Unexecuted instantiation: void yb::pggate::PgExpr::TranslateSysCol<unsigned long long>(yb::Slice*, yb::pggate::PgWireDataHeader const&, unsigned long long*)
void yb::pggate::PgExpr::TranslateSysCol<unsigned int>(yb::Slice*, yb::pggate::PgWireDataHeader const&, unsigned int*)
Line
Count
Source
149
8.12M
  static void TranslateSysCol(Slice *yb_cursor, const PgWireDataHeader& header, data_type *value) {
150
8.12M
    *value = 0;
151
8.12M
    if (header.is_null()) {
152
      // 0 is an invalid OID.
153
0
      return;
154
0
    }
155
8.12M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, value);
156
8.12M
    yb_cursor->remove_prefix(read_size);
157
8.12M
  }
158
159
  static void TranslateSysCol(Slice *yb_cursor, const PgWireDataHeader& header,
160
                              PgTuple *pg_tuple, uint8_t **value);
161
  static void TranslateCtid(Slice *yb_cursor, const PgWireDataHeader& header, int index,
162
                            const YBCPgTypeEntity *type_entity, const PgTypeAttrs *type_attrs,
163
                            PgTuple *pg_tuple);
164
  static void TranslateOid(Slice *yb_cursor, const PgWireDataHeader& header, int index,
165
                           const YBCPgTypeEntity *type_entity, const PgTypeAttrs *type_attrs,
166
                           PgTuple *pg_tuple);
167
  static void TranslateXmin(Slice *yb_cursor, const PgWireDataHeader& header, int index,
168
                            const YBCPgTypeEntity *type_entity, const PgTypeAttrs *type_attrs,
169
                            PgTuple *pg_tuple);
170
  static void TranslateCmin(Slice *yb_cursor, const PgWireDataHeader& header, int index,
171
                            const YBCPgTypeEntity *type_entity, const PgTypeAttrs *type_attrs,
172
                            PgTuple *pg_tuple);
173
  static void TranslateXmax(Slice *yb_cursor, const PgWireDataHeader& header, int index,
174
                            const YBCPgTypeEntity *type_entity, const PgTypeAttrs *type_attrs,
175
                            PgTuple *pg_tuple);
176
  static void TranslateCmax(Slice *yb_cursor, const PgWireDataHeader& header, int index,
177
                            const YBCPgTypeEntity *type_entity, const PgTypeAttrs *type_attrs,
178
                            PgTuple *pg_tuple);
179
  static void TranslateTableoid(Slice *yb_cursor, const PgWireDataHeader& header, int index,
180
                                const YBCPgTypeEntity *type_entity, const PgTypeAttrs *type_attrs,
181
                                PgTuple *pg_tuple);
182
  static void TranslateYBCtid(Slice *yb_cursor, const PgWireDataHeader& header, int index,
183
                              const YBCPgTypeEntity *type_entity, const PgTypeAttrs *type_attrs,
184
                              PgTuple *pg_tuple);
185
  static void TranslateYBBasectid(Slice *yb_cursor, const PgWireDataHeader& header, int index,
186
                                  const YBCPgTypeEntity *type_entity, const PgTypeAttrs *type_attrs,
187
                                  PgTuple *pg_tuple);
188
189
  // Get expression type.
190
  InternalType internal_type() const;
191
192
  // Get Postgres data type information: type Oid, type mod and collation
193
  int get_pg_typid() const;
194
  int get_pg_typmod() const;
195
  int get_pg_collid() const;
196
197
  // Find opcode.
198
  static CHECKED_STATUS CheckOperatorName(const char *name);
199
  static Opcode NameToOpcode(const char *name);
200
  static bfpg::TSOpcode PGOpcodeToTSOpcode(const PgExpr::Opcode opcode);
201
  static bfpg::TSOpcode OperandTypeToSumTSOpcode(InternalType type);
202
203
 protected:
204
  PgExpr(
205
      Opcode opcode, const YBCPgTypeEntity *type_entity, bool collate_is_valid_non_c,
206
      const PgTypeAttrs *type_attrs = nullptr);
207
62.3M
  virtual ~PgExpr() = default;
208
209
  void InitializeTranslateData();
210
211
  // Data members.
212
  Opcode opcode_;
213
  const PgTypeEntity *type_entity_;
214
  bool collate_is_valid_non_c_;
215
  const PgTypeAttrs type_attrs_;
216
  std::function<void(Slice *, const PgWireDataHeader&, int, const YBCPgTypeEntity *,
217
                     const PgTypeAttrs *, PgTuple *)> translate_data_;
218
};
219
220
class PgConstant : public PgExpr {
221
 public:
222
  // Public types.
223
  typedef std::shared_ptr<PgConstant> SharedPtr;
224
  typedef std::shared_ptr<const PgConstant> SharedPtrConst;
225
226
  typedef std::unique_ptr<PgConstant> UniPtr;
227
  typedef std::unique_ptr<const PgConstant> UniPtrConst;
228
229
  PgConstant(const YBCPgTypeEntity *type_entity,
230
             bool collate_is_valid_non_c,
231
             const char* collation_sortkey,
232
             uint64_t datum,
233
             bool is_null,
234
             PgExpr::Opcode opcode = PgExpr::Opcode::PG_EXPR_CONSTANT);
235
  PgConstant(const YBCPgTypeEntity *type_entity,
236
             bool collate_is_valid_non_c,
237
             PgDatumKind datum_kind,
238
             PgExpr::Opcode opcode = PgExpr::Opcode::PG_EXPR_CONSTANT);
239
240
  // Update numeric.
241
  void UpdateConstant(int8_t value, bool is_null);
242
  void UpdateConstant(int16_t value, bool is_null);
243
  void UpdateConstant(int32_t value, bool is_null);
244
  void UpdateConstant(int64_t value, bool is_null);
245
  void UpdateConstant(float value, bool is_null);
246
  void UpdateConstant(double value, bool is_null);
247
248
  // Update text.
249
  void UpdateConstant(const char *value, bool is_null);
250
  void UpdateConstant(const void *value, size_t bytes, bool is_null);
251
252
  // Expression to PB.
253
  CHECKED_STATUS Eval(PgsqlExpressionPB *expr_pb) override;
254
  CHECKED_STATUS Eval(QLValuePB *result) override;
255
256
  // Read binary value.
257
0
  const std::string &binary_value() {
258
0
    return ql_value_.binary_value();
259
0
  }
260
261
 private:
262
  QLValuePB ql_value_;
263
  const char *collation_sortkey_;
264
};
265
266
class PgColumnRef : public PgExpr {
267
 public:
268
  // Public types.
269
  typedef std::shared_ptr<PgColumnRef> SharedPtr;
270
  typedef std::shared_ptr<const PgColumnRef> SharedPtrConst;
271
272
  typedef std::unique_ptr<PgColumnRef> UniPtr;
273
  typedef std::unique_ptr<const PgColumnRef> UniPtrConst;
274
275
  PgColumnRef(int attr_num,
276
              const PgTypeEntity *type_entity,
277
              bool collate_is_valid_non_c,
278
              const PgTypeAttrs *type_attrs);
279
  // Setup ColumnRef expression when constructing statement.
280
  CHECKED_STATUS PrepareForRead(PgDml *pg_stmt, PgsqlExpressionPB *expr_pb) override;
281
282
648M
  int attr_num() const {
283
648M
    return attr_num_;
284
648M
  }
285
286
  bool is_ybbasetid() const override;
287
288
 private:
289
  int attr_num_;
290
};
291
292
class PgOperator : public PgExpr {
293
 public:
294
  // Public types.
295
  typedef std::shared_ptr<PgOperator> SharedPtr;
296
  typedef std::shared_ptr<const PgOperator> SharedPtrConst;
297
298
  typedef std::unique_ptr<PgOperator> UniPtr;
299
  typedef std::unique_ptr<const PgOperator> UniPtrConst;
300
301
  PgOperator(const char *name,
302
             const YBCPgTypeEntity *type_entity,
303
             bool collate_is_valid_non_c);
304
305
  // Append arguments.
306
  void AppendArg(PgExpr *arg);
307
308
  // Setup operator expression when constructing statement.
309
  virtual CHECKED_STATUS PrepareForRead(PgDml *pg_stmt, PgsqlExpressionPB *expr_pb);
310
311
 private:
312
  const std::string opname_;
313
  std::vector<PgExpr*> args_;
314
};
315
316
}  // namespace pggate
317
}  // namespace yb
318
319
#endif // YB_YQL_PGGATE_PG_EXPR_H_