/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_ |