/Users/deen/code/yugabyte-db/src/yb/yql/cql/ql/exec/eval_col.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/common/jsonb.h" |
17 | | #include "yb/common/ql_value.h" |
18 | | |
19 | | #include "yb/util/result.h" |
20 | | |
21 | | #include "yb/yql/cql/ql/exec/exec_context.h" |
22 | | #include "yb/yql/cql/ql/exec/executor.h" |
23 | | #include "yb/yql/cql/ql/ptree/column_arg.h" |
24 | | #include "yb/yql/cql/ql/ptree/column_desc.h" |
25 | | #include "yb/yql/cql/ql/ptree/pt_dml.h" |
26 | | #include "yb/yql/cql/ql/ptree/pt_expr.h" |
27 | | #include "yb/yql/cql/ql/ptree/pt_update.h" |
28 | | #include "yb/yql/cql/ql/util/statement_params.h" |
29 | | |
30 | | namespace yb { |
31 | | namespace ql { |
32 | | |
33 | | using std::shared_ptr; |
34 | | |
35 | | //-------------------------------------------------------------------------------------------------- |
36 | | |
37 | | CHECKED_STATUS Executor::ColumnRefsToPB(const PTDmlStmt *tnode, |
38 | 5.17M | QLReferencedColumnsPB *columns_pb) { |
39 | | // Write a list of columns to be read before executing the statement. |
40 | 5.17M | const MCSet<int32>& column_refs = tnode->column_refs(); |
41 | 13.0M | for (auto column_ref : column_refs) { |
42 | 13.0M | columns_pb->add_ids(column_ref); |
43 | 13.0M | } |
44 | | |
45 | 5.17M | const MCSet<int32>& static_column_refs = tnode->static_column_refs(); |
46 | 137 | for (auto column_ref : static_column_refs) { |
47 | 137 | columns_pb->add_static_ids(column_ref); |
48 | 137 | } |
49 | 5.17M | return Status::OK(); |
50 | 5.17M | } |
51 | | |
52 | 1.29M | CHECKED_STATUS Executor::ColumnArgsToPB(const PTDmlStmt *tnode, QLWriteRequestPB *req) { |
53 | 1.29M | const MCVector<ColumnArg>& column_args = tnode->column_args(); |
54 | | |
55 | 3.90M | for (const ColumnArg& col : column_args) { |
56 | 3.90M | if (!col.IsInitialized()) { |
57 | | // This column is not assigned a value, ignore it. We don't support default value yet. |
58 | 16.6k | continue; |
59 | 16.6k | } |
60 | | |
61 | 3.89M | const ColumnDesc *col_desc = col.desc(); |
62 | 895 | VLOG(3) << "WRITE request, column id = " << col_desc->id(); |
63 | | |
64 | 3.89M | const PTExpr::SharedPtr& expr = col.expr(); |
65 | 3.89M | if (expr != nullptr && expr->expr_op() == ExprOperator::kBindVar) { |
66 | 3.55M | const PTBindVar* bind_pt = static_cast<const PTBindVar*>(expr.get()); |
67 | 3.55M | DCHECK_NOTNULL(bind_pt->name().get()); |
68 | 3.55M | if(VERIFY_RESULT(exec_context_->params().IsBindVariableUnset(bind_pt->name()->c_str(), |
69 | 3 | bind_pt->pos()))) { |
70 | 0 | VLOG(3) << "Value unset for column: " << bind_pt->name()->c_str(); |
71 | 3 | continue; |
72 | 3 | } |
73 | 3.89M | } |
74 | | |
75 | 3.89M | QLExpressionPB *expr_pb = CreateQLExpression(req, *col_desc); |
76 | | |
77 | 3.89M | RETURN_NOT_OK(PTExprToPB(expr, expr_pb)); |
78 | | |
79 | 3.89M | if (col_desc->is_primary()) { |
80 | 2.53M | RETURN_NOT_OK(EvalExpr(expr_pb, QLTableRow::empty_row())); |
81 | 2.53M | } |
82 | | |
83 | | // Null values not allowed for primary key: checking here catches nulls introduced by bind. |
84 | 3.89M | if (col_desc->is_primary() && expr_pb->has_value() && IsNull(expr_pb->value())) { |
85 | 8 | LOG(INFO) << "Unexpected null value. Current request: " << req->DebugString(); |
86 | 8 | return exec_context_->Error(tnode, ErrorCode::NULL_ARGUMENT_FOR_PRIMARY_KEY); |
87 | 8 | } |
88 | 3.89M | } |
89 | | |
90 | 1.29M | const MCVector<SubscriptedColumnArg>& subcol_args = tnode->subscripted_col_args(); |
91 | 34 | for (const SubscriptedColumnArg& col : subcol_args) { |
92 | 34 | const ColumnDesc *col_desc = col.desc(); |
93 | 34 | QLColumnValuePB *col_pb = req->add_column_values(); |
94 | 34 | col_pb->set_column_id(col_desc->id()); |
95 | 34 | QLExpressionPB *expr_pb = col_pb->mutable_expr(); |
96 | 34 | RETURN_NOT_OK(PTExprToPB(col.expr(), expr_pb)); |
97 | 34 | for (auto& col_arg : col.args()->node_list()) { |
98 | 34 | QLExpressionPB *arg_pb = col_pb->add_subscript_args(); |
99 | 34 | RETURN_NOT_OK(PTExprToPB(col_arg, arg_pb)); |
100 | 34 | } |
101 | 34 | } |
102 | | |
103 | 1.29M | common::Jsonb jsonb_null; |
104 | 1.29M | RETURN_NOT_OK(jsonb_null.FromString("null")); |
105 | 1.29M | const MCVector<JsonColumnArg>& jsoncol_args = tnode->json_col_args(); |
106 | 176 | for (const JsonColumnArg& col : jsoncol_args) { |
107 | 176 | QLExpressionPB expr_pb; |
108 | 176 | RETURN_NOT_OK(PTExprToPB(col.expr(), &expr_pb)); |
109 | | |
110 | 176 | if (tnode->opcode() == TreeNodeOpcode::kPTUpdateStmt) { |
111 | 176 | const PTUpdateStmt* update_tnode = static_cast<const PTUpdateStmt*>(tnode); |
112 | 176 | if (update_tnode->update_properties() && |
113 | 142 | update_tnode->update_properties()->ignore_null_jsonb_attributes()) { |
114 | 82 | if (expr_pb.expr_case() == QLExpressionPB::kValue && |
115 | 82 | expr_pb.value().value_case() == QLValuePB::kJsonbValue && |
116 | 81 | expr_pb.value().jsonb_value() == jsonb_null.SerializedJsonb()) { |
117 | | // TODO(Piyush): Log attribute json path as well. |
118 | 0 | VLOG(1) << "Ignoring null for json attribute in UPDATE statement " \ |
119 | 0 | "for column " << col.desc()->MangledName(); |
120 | 68 | continue; |
121 | 68 | } |
122 | 108 | } |
123 | 176 | } |
124 | | |
125 | 108 | const ColumnDesc *col_desc = col.desc(); |
126 | 108 | QLColumnValuePB *col_pb = req->add_column_values(); |
127 | 108 | col_pb->set_column_id(col_desc->id()); |
128 | 108 | *(col_pb->mutable_expr()) = expr_pb; |
129 | | |
130 | 147 | for (auto& col_arg : col.args()->node_list()) { |
131 | 147 | QLJsonOperationPB *arg_pb = col_pb->add_json_args(); |
132 | 147 | RETURN_NOT_OK(PTJsonOperatorToPB(std::dynamic_pointer_cast<PTJsonOperator>(col_arg), arg_pb)); |
133 | 147 | } |
134 | 108 | } |
135 | | |
136 | 1.29M | return Status::OK(); |
137 | 1.29M | } |
138 | | |
139 | | } // namespace ql |
140 | | } // namespace yb |