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_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
227M
  Opcode opcode() const {
74
227M
    return opcode_;
75
227M
  }
76
1.78M
  bool is_constant() const {
77
1.78M
    return opcode_ == Opcode::PG_EXPR_CONSTANT;
78
1.78M
  }
79
227M
  bool is_colref() const {
80
227M
    return opcode_ == Opcode::PG_EXPR_COLREF;
81
227M
  }
82
9.54M
  bool is_aggregate() const {
83
    // Only return true for pushdown supported aggregates.
84
9.54M
    return (opcode_ == Opcode::PG_EXPR_SUM ||
85
9.54M
            opcode_ == Opcode::PG_EXPR_COUNT ||
86
9.54M
            opcode_ == Opcode::PG_EXPR_MAX ||
87
9.54M
            opcode_ == Opcode::PG_EXPR_MIN);
88
9.54M
  }
89
221
  virtual bool is_ybbasetid() const {
90
221
    return false;
91
221
  }
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
172M
                              PgTuple *pg_tuple) {
117
172M
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
26.5k
      return;
119
26.5k
    }
120
121
172M
    data_type result = 0;
122
172M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
172M
    yb_cursor->remove_prefix(read_size);
124
172M
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
172M
  }
_ZN2yb6pggate6PgExpr15TranslateNumberIaEEvPNS_5SliceERKNS0_16PgWireDataHeaderEiPK12PgTypeEntityPK11PgTypeAttrsPNS0_7PgTupleE
Line
Count
Source
116
21.1M
                              PgTuple *pg_tuple) {
117
21.1M
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
0
      return;
119
0
    }
120
121
21.1M
    data_type result = 0;
122
21.1M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
21.1M
    yb_cursor->remove_prefix(read_size);
124
21.1M
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
21.1M
  }
_ZN2yb6pggate6PgExpr15TranslateNumberIsEEvPNS_5SliceERKNS0_16PgWireDataHeaderEiPK12PgTypeEntityPK11PgTypeAttrsPNS0_7PgTupleE
Line
Count
Source
116
12.2M
                              PgTuple *pg_tuple) {
117
12.2M
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
0
      return;
119
0
    }
120
121
12.2M
    data_type result = 0;
122
12.2M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
12.2M
    yb_cursor->remove_prefix(read_size);
124
12.2M
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
12.2M
  }
_ZN2yb6pggate6PgExpr15TranslateNumberIiEEvPNS_5SliceERKNS0_16PgWireDataHeaderEiPK12PgTypeEntityPK11PgTypeAttrsPNS0_7PgTupleE
Line
Count
Source
116
53.3M
                              PgTuple *pg_tuple) {
117
53.3M
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
6.06k
      return;
119
6.06k
    }
120
121
53.3M
    data_type result = 0;
122
53.3M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
53.3M
    yb_cursor->remove_prefix(read_size);
124
53.3M
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
53.3M
  }
_ZN2yb6pggate6PgExpr15TranslateNumberIxEEvPNS_5SliceERKNS0_16PgWireDataHeaderEiPK12PgTypeEntityPK11PgTypeAttrsPNS0_7PgTupleE
Line
Count
Source
116
547k
                              PgTuple *pg_tuple) {
117
547k
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
20.5k
      return;
119
20.5k
    }
120
121
527k
    data_type result = 0;
122
527k
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
527k
    yb_cursor->remove_prefix(read_size);
124
527k
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
527k
  }
_ZN2yb6pggate6PgExpr15TranslateNumberIjEEvPNS_5SliceERKNS0_16PgWireDataHeaderEiPK12PgTypeEntityPK11PgTypeAttrsPNS0_7PgTupleE
Line
Count
Source
116
47.4M
                              PgTuple *pg_tuple) {
117
47.4M
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
0
      return;
119
0
    }
120
121
47.4M
    data_type result = 0;
122
47.4M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
47.4M
    yb_cursor->remove_prefix(read_size);
124
47.4M
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
47.4M
  }
Unexecuted instantiation: _ZN2yb6pggate6PgExpr15TranslateNumberIyEEvPNS_5SliceERKNS0_16PgWireDataHeaderEiPK12PgTypeEntityPK11PgTypeAttrsPNS0_7PgTupleE
_ZN2yb6pggate6PgExpr15TranslateNumberIbEEvPNS_5SliceERKNS0_16PgWireDataHeaderEiPK12PgTypeEntityPK11PgTypeAttrsPNS0_7PgTupleE
Line
Count
Source
116
36.6M
                              PgTuple *pg_tuple) {
117
36.6M
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
0
      return;
119
0
    }
120
121
36.6M
    data_type result = 0;
122
36.6M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
36.6M
    yb_cursor->remove_prefix(read_size);
124
36.6M
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
36.6M
  }
_ZN2yb6pggate6PgExpr15TranslateNumberIfEEvPNS_5SliceERKNS0_16PgWireDataHeaderEiPK12PgTypeEntityPK11PgTypeAttrsPNS0_7PgTupleE
Line
Count
Source
116
694k
                              PgTuple *pg_tuple) {
117
694k
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
0
      return;
119
0
    }
120
121
694k
    data_type result = 0;
122
694k
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
694k
    yb_cursor->remove_prefix(read_size);
124
694k
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
694k
  }
_ZN2yb6pggate6PgExpr15TranslateNumberIdEEvPNS_5SliceERKNS0_16PgWireDataHeaderEiPK12PgTypeEntityPK11PgTypeAttrsPNS0_7PgTupleE
Line
Count
Source
116
60.8k
                              PgTuple *pg_tuple) {
117
60.8k
    if (TranslateNumberHelper(header, index, type_entity, pg_tuple)) {
118
0
      return;
119
0
    }
120
121
60.8k
    data_type result = 0;
122
60.8k
    size_t read_size = PgDocData::ReadNumber(yb_cursor, &result);
123
60.8k
    yb_cursor->remove_prefix(read_size);
124
60.8k
    pg_tuple->WriteDatum(index, type_entity->yb_to_datum(&result, read_size, type_attrs));
125
60.8k
  }
Unexecuted instantiation: _ZN2yb6pggate6PgExpr15TranslateNumberIhEEvPNS_5SliceERKNS0_16PgWireDataHeaderEiPK12PgTypeEntityPK11PgTypeAttrsPNS0_7PgTupleE
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
2.42M
  static void TranslateSysCol(Slice *yb_cursor, const PgWireDataHeader& header, data_type *value) {
150
2.42M
    *value = 0;
151
2.42M
    if (header.is_null()) {
152
      // 0 is an invalid OID.
153
0
      return;
154
0
    }
155
2.42M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, value);
156
2.42M
    yb_cursor->remove_prefix(read_size);
157
2.42M
  }
Unexecuted instantiation: _ZN2yb6pggate6PgExpr15TranslateSysColIyEEvPNS_5SliceERKNS0_16PgWireDataHeaderEPT_
_ZN2yb6pggate6PgExpr15TranslateSysColIjEEvPNS_5SliceERKNS0_16PgWireDataHeaderEPT_
Line
Count
Source
149
2.42M
  static void TranslateSysCol(Slice *yb_cursor, const PgWireDataHeader& header, data_type *value) {
150
2.42M
    *value = 0;
151
2.42M
    if (header.is_null()) {
152
      // 0 is an invalid OID.
153
0
      return;
154
0
    }
155
2.42M
    size_t read_size = PgDocData::ReadNumber(yb_cursor, value);
156
2.42M
    yb_cursor->remove_prefix(read_size);
157
2.42M
  }
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
21.2M
  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
227M
  int attr_num() const {
283
227M
    return attr_num_;
284
227M
  }
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_