/Users/deen/code/yugabyte-db/src/yb/yql/cql/ql/exec/eval_bcall.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/bfql/bfql.h" |
17 | | |
18 | | #include "yb/util/status_format.h" |
19 | | |
20 | | #include "yb/yql/cql/ql/exec/executor.h" |
21 | | #include "yb/yql/cql/ql/ptree/pt_bcall.h" |
22 | | |
23 | | namespace yb { |
24 | | namespace ql { |
25 | | |
26 | | using yb::bfql::BFOpcode; |
27 | | using yb::bfql::BFOPCODE_NOOP; |
28 | | |
29 | 1.45k | CHECKED_STATUS Executor::PTExprToPB(const PTBcall *bcall_pt, QLExpressionPB *expr_pb) { |
30 | 1.45k | if (!bcall_pt->is_server_operator()) { |
31 | | // Regular builtin function call. |
32 | 420 | return BFCallToPB(bcall_pt, expr_pb); |
33 | 1.03k | } else { |
34 | | // Server builtin function call. |
35 | 1.03k | return TSCallToPB(bcall_pt, expr_pb); |
36 | 1.03k | } |
37 | 1.45k | } |
38 | | |
39 | 420 | CHECKED_STATUS Executor::BFCallToPB(const PTBcall *bcall_pt, QLExpressionPB *expr_pb) { |
40 | 420 | if (bcall_pt->result_cast_op() != BFOPCODE_NOOP) { |
41 | 21 | QLBCallPB *cast_pb = expr_pb->mutable_bfcall(); |
42 | 21 | cast_pb->set_opcode(static_cast<int32_t>(bcall_pt->result_cast_op())); |
43 | | |
44 | | // Result of the bcall_pt is the input of this CAST. |
45 | 21 | expr_pb = cast_pb->add_operands(); |
46 | 21 | } |
47 | | |
48 | 420 | QLBCallPB *bcall_pb = expr_pb->mutable_bfcall(); |
49 | 420 | bcall_pb->set_opcode(bcall_pt->bfopcode()); |
50 | | |
51 | 420 | int pindex = 0; |
52 | 420 | const MCVector<yb::bfql::BFOpcode>& cast_ops = bcall_pt->cast_ops(); |
53 | 420 | const MCList<PTExpr::SharedPtr>& args = bcall_pt->args(); |
54 | | |
55 | 447 | for (const PTExpr::SharedPtr& arg : args) { |
56 | | // Create PB for the argument "arg". |
57 | 447 | QLExpressionPB *operand_pb = bcall_pb->add_operands(); |
58 | | |
59 | 447 | if (cast_ops[pindex] != BFOPCODE_NOOP) { |
60 | | // Apply the cast operator. The return value of CAST is the operand of the actual BCALL. |
61 | 31 | QLBCallPB *cast_pb = operand_pb->mutable_bfcall(); |
62 | 31 | cast_pb->set_opcode(static_cast<int32_t>(cast_ops[pindex])); |
63 | | |
64 | | // Result of the argument, operand_pb, is the input of CAST. |
65 | 31 | operand_pb = cast_pb->add_operands(); |
66 | 31 | } |
67 | 447 | pindex++; |
68 | | |
69 | | // Process the argument and save the result to "operand_pb". |
70 | 447 | RETURN_NOT_OK(PTExprToPB(arg, operand_pb)); |
71 | | |
72 | 443 | if (strcmp(bcall_pt->name()->c_str(), bfql::kCqlCastFuncName) == 0) { |
73 | | // For cql_cast, we just need one parameter. |
74 | 97 | break; |
75 | 97 | } |
76 | 443 | } |
77 | | |
78 | 416 | return Status::OK(); |
79 | 420 | } |
80 | | |
81 | 1.03k | CHECKED_STATUS Executor::TSCallToPB(const PTBcall *bcall_pt, QLExpressionPB *expr_pb) { |
82 | 1.03k | if (bcall_pt->result_cast_op() != BFOPCODE_NOOP) { |
83 | 0 | QLBCallPB *cast_pb = expr_pb->mutable_bfcall(); |
84 | 0 | cast_pb->set_opcode(static_cast<int32_t>(bcall_pt->result_cast_op())); |
85 | | |
86 | | // Result of the bcall_pt is the input of this CAST. |
87 | 0 | expr_pb = cast_pb->add_operands(); |
88 | 0 | } |
89 | 1.03k | QLBCallPB *bcall_pb = expr_pb->mutable_tscall(); |
90 | 1.03k | bcall_pb->set_opcode(bcall_pt->bfopcode()); |
91 | 1.03k | int pindex = 0; |
92 | 1.03k | const MCVector<yb::bfql::BFOpcode>& cast_ops = bcall_pt->cast_ops(); |
93 | 1.03k | const MCList<PTExpr::SharedPtr>& args = bcall_pt->args(); |
94 | | |
95 | 1.08k | for (const PTExpr::SharedPtr& arg : args) { |
96 | | // Create PB for the argument "arg". |
97 | 1.08k | QLExpressionPB *operand_pb = bcall_pb->add_operands(); |
98 | | |
99 | 1.08k | if (cast_ops[pindex] != BFOPCODE_NOOP) { |
100 | | // Apply the cast operator. The return value of CAST is the operand of the actual BCALL. |
101 | 0 | QLBCallPB *cast_pb = operand_pb->mutable_bfcall(); |
102 | 0 | cast_pb->set_opcode(static_cast<int32_t>(cast_ops[pindex])); |
103 | | |
104 | | // Result of the argument, operand_pb, is the input of CAST. |
105 | 0 | operand_pb = cast_pb->add_operands(); |
106 | 0 | } |
107 | 1.08k | pindex++; |
108 | | |
109 | | // Process the argument and save the result to "operand_pb". |
110 | 1.08k | RETURN_NOT_OK(PTExprToPB(arg, operand_pb)); |
111 | 1.08k | } |
112 | | |
113 | 1.03k | return Status::OK(); |
114 | 1.03k | } |
115 | | |
116 | | // Forming constructor call for collection and user-defined types. |
117 | 17 | CHECKED_STATUS Executor::PTExprToPB(const PTCollectionExpr *expr, QLExpressionPB *expr_pb) { |
118 | 17 | bool is_frozen = false; |
119 | 17 | DataType data_type = expr->ql_type()->main(); |
120 | 17 | if (data_type == FROZEN) { |
121 | 1 | is_frozen = true; |
122 | | // Use the nested collection type. |
123 | 1 | data_type = expr->ql_type()->param_type(0)->main(); |
124 | 1 | } |
125 | | |
126 | 17 | QLExpressionPB *arg_pb; |
127 | 17 | QLBCallPB *bcall_pb = expr_pb->mutable_bfcall(); |
128 | 17 | switch (data_type) { |
129 | 5 | case MAP: |
130 | 5 | if (is_frozen) { |
131 | 0 | bcall_pb->set_opcode(static_cast<int32_t>(BFOpcode::OPCODE_MAP_FROZEN)); |
132 | 5 | } else { |
133 | 5 | bcall_pb->set_opcode(static_cast<int32_t>(BFOpcode::OPCODE_MAP_CONSTRUCTOR)); |
134 | 5 | } |
135 | 5 | RSTATUS_DCHECK_EQ(expr->keys().size(), expr->values().size(), |
136 | 5 | InternalError, "Invalid MAP literal"); |
137 | 5 | for (auto key_it = expr->keys().begin(), value_it = expr->values().begin(); |
138 | 11 | key_it != expr->keys().end() && value_it != expr->values().end()9 ; |
139 | 9 | key_it++, value_it++6 ) { |
140 | 9 | arg_pb = bcall_pb->add_operands(); |
141 | 9 | RETURN_NOT_OK(PTExprToPB(*key_it, arg_pb)); |
142 | | |
143 | 6 | arg_pb = bcall_pb->add_operands(); |
144 | 6 | RETURN_NOT_OK(PTExprToPB(*value_it, arg_pb)); |
145 | 6 | } |
146 | 2 | break; |
147 | | |
148 | 3 | case SET: |
149 | 3 | if (is_frozen) { |
150 | 0 | bcall_pb->set_opcode(static_cast<int32_t>(BFOpcode::OPCODE_SET_FROZEN)); |
151 | 3 | } else { |
152 | 3 | bcall_pb->set_opcode(static_cast<int32_t>(BFOpcode::OPCODE_SET_CONSTRUCTOR)); |
153 | 3 | } |
154 | 5 | for (auto &elem : expr->values()) { |
155 | 5 | arg_pb = bcall_pb->add_operands(); |
156 | 5 | RETURN_NOT_OK(PTExprToPB(elem, arg_pb)); |
157 | 5 | } |
158 | 1 | break; |
159 | | |
160 | 5 | case LIST: |
161 | 5 | if (is_frozen) { |
162 | 0 | bcall_pb->set_opcode(static_cast<int32_t>(BFOpcode::OPCODE_LIST_FROZEN)); |
163 | 5 | } else { |
164 | 5 | bcall_pb->set_opcode(static_cast<int32_t>(BFOpcode::OPCODE_LIST_CONSTRUCTOR)); |
165 | 5 | } |
166 | 11 | for (auto &elem : expr->values()) { |
167 | 11 | arg_pb = bcall_pb->add_operands(); |
168 | 11 | RETURN_NOT_OK(PTExprToPB(elem, arg_pb)); |
169 | 11 | } |
170 | 3 | break; |
171 | | |
172 | 4 | case USER_DEFINED_TYPE: { |
173 | 4 | auto field_values = expr->udtype_field_values(); |
174 | 4 | if (is_frozen) { |
175 | 1 | bcall_pb->set_opcode(static_cast<int32_t>(BFOpcode::OPCODE_UDT_FROZEN)); |
176 | 4 | for (size_t i = 0; i < field_values.size(); i++3 ) { |
177 | | // Add values for all attributes in frozen UDT, including NULL values. |
178 | 3 | arg_pb = bcall_pb->add_operands(); |
179 | 3 | if (field_values[i] != nullptr) { |
180 | 2 | RETURN_NOT_OK(PTExprToPB(field_values[i], arg_pb)); |
181 | 2 | } |
182 | 3 | } |
183 | | |
184 | 3 | } else { |
185 | 3 | bcall_pb->set_opcode(static_cast<int32_t>(BFOpcode::OPCODE_UDT_CONSTRUCTOR)); |
186 | 15 | for (size_t i = 0; i < field_values.size(); i++12 ) { |
187 | | // Add [key, value] pairs to attributes if the value is not NULL. |
188 | 12 | if (field_values[i] != nullptr) { |
189 | | // Add key. |
190 | 10 | arg_pb = bcall_pb->add_operands(); |
191 | 10 | arg_pb->mutable_value()->set_int16_value(narrow_cast<int16_t>(i)); |
192 | | |
193 | | // Add value. |
194 | 10 | arg_pb = bcall_pb->add_operands(); |
195 | 10 | RETURN_NOT_OK(PTExprToPB(field_values[i], arg_pb)); |
196 | 10 | } |
197 | 12 | } |
198 | 3 | } |
199 | 4 | break; |
200 | 4 | } |
201 | | |
202 | 4 | default: |
203 | 0 | return STATUS(InternalError, "Invalid enum value"); |
204 | 17 | } |
205 | | |
206 | 10 | return Status::OK(); |
207 | 17 | } |
208 | | |
209 | | } // namespace ql |
210 | | } // namespace yb |