YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/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.65k
CHECKED_STATUS Executor::PTExprToPB(const PTBcall *bcall_pt, QLExpressionPB *expr_pb) {
30
1.65k
  if (!bcall_pt->is_server_operator()) {
31
    // Regular builtin function call.
32
420
    return BFCallToPB(bcall_pt, expr_pb);
33
1.23k
  } else {
34
    // Server builtin function call.
35
1.23k
    return TSCallToPB(bcall_pt, expr_pb);
36
1.23k
  }
37
1.65k
}
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.23k
CHECKED_STATUS Executor::TSCallToPB(const PTBcall *bcall_pt, QLExpressionPB *expr_pb) {
82
1.23k
  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.23k
  QLBCallPB *bcall_pb = expr_pb->mutable_tscall();
90
1.23k
  bcall_pb->set_opcode(bcall_pt->bfopcode());
91
1.23k
  int pindex = 0;
92
1.23k
  const MCVector<yb::bfql::BFOpcode>& cast_ops = bcall_pt->cast_ops();
93
1.23k
  const MCList<PTExpr::SharedPtr>& args = bcall_pt->args();
94
95
1.28k
  for (const PTExpr::SharedPtr& arg : args) {
96
    // Create PB for the argument "arg".
97
1.28k
    QLExpressionPB *operand_pb = bcall_pb->add_operands();
98
99
1.28k
    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.28k
    pindex++;
108
109
    // Process the argument and save the result to "operand_pb".
110
1.28k
    RETURN_NOT_OK(PTExprToPB(arg, operand_pb));
111
1.28k
  }
112
113
1.23k
  return Status::OK();
114
1.23k
}
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();
139
9
           key_it++, value_it++) {
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++) {
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++) {
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
0
    default:
203
0
      return STATUS(InternalError, "Invalid enum value");
204
10
  }
205
206
10
  return Status::OK();
207
10
}
208
209
}  // namespace ql
210
}  // namespace yb