/Users/deen/code/yugabyte-db/src/yb/common/ql_protocol_util.cc
Line | Count | Source |
1 | | // Copyright (c) YugaByte, Inc. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
4 | | // in compliance with the License. You may obtain a copy of the License at |
5 | | // |
6 | | // http://www.apache.org/licenses/LICENSE-2.0 |
7 | | // |
8 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
9 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
10 | | // or implied. See the License for the specific language governing permissions and limitations |
11 | | // under the License. |
12 | | // |
13 | | |
14 | | #include "yb/common/ql_protocol_util.h" |
15 | | |
16 | | #include "yb/common/ql_protocol.pb.h" |
17 | | #include "yb/common/ql_rowblock.h" |
18 | | #include "yb/common/ql_type.h" |
19 | | #include "yb/common/schema.h" |
20 | | |
21 | | #include "yb/gutil/casts.h" |
22 | | |
23 | | #include "yb/util/result.h" |
24 | | #include "yb/util/status_log.h" |
25 | | |
26 | | namespace yb { |
27 | | |
28 | 3.86M | QLValuePB* QLPrepareColumn(QLWriteRequestPB* req, int column_id) { |
29 | 3.86M | auto column_value = req->add_column_values(); |
30 | 3.86M | column_value->set_column_id(column_id); |
31 | 3.86M | return column_value->mutable_expr()->mutable_value(); |
32 | 3.86M | } |
33 | | |
34 | 43.1k | QLValuePB* QLPrepareCondition(QLConditionPB* condition, int column_id, QLOperator op) { |
35 | 43.1k | condition->add_operands()->set_column_id(column_id); |
36 | 43.1k | condition->set_op(op); |
37 | 43.1k | return condition->add_operands()->mutable_value(); |
38 | 43.1k | } |
39 | | |
40 | | #define QL_PROTOCOL_TYPE_DEFINITIONS_IMPL(name, lname, type) \ |
41 | | void PP_CAT3(QLAdd, name, ColumnValue)( \ |
42 | 134k | QLWriteRequestPB* req, int column_id, type value) { \ |
43 | 134k | QLPrepareColumn(req, column_id)->PP_CAT3(set_, lname, _value)(value); \ |
44 | 134k | } \ Unexecuted instantiation: yb::QLAddInt8ColumnValue(yb::QLWriteRequestPB*, int, signed char) Unexecuted instantiation: yb::QLAddInt16ColumnValue(yb::QLWriteRequestPB*, int, short) yb::QLAddInt32ColumnValue(yb::QLWriteRequestPB*, int, int) Line | Count | Source | 42 | 53.7k | QLWriteRequestPB* req, int column_id, type value) { \ | 43 | 53.7k | QLPrepareColumn(req, column_id)->PP_CAT3(set_, lname, _value)(value); \ | 44 | 53.7k | } \ |
Unexecuted instantiation: yb::QLAddInt64ColumnValue(yb::QLWriteRequestPB*, int, long long) yb::QLAddStringColumnValue(yb::QLWriteRequestPB*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Line | Count | Source | 42 | 80.7k | QLWriteRequestPB* req, int column_id, type value) { \ | 43 | 80.7k | QLPrepareColumn(req, column_id)->PP_CAT3(set_, lname, _value)(value); \ | 44 | 80.7k | } \ |
Unexecuted instantiation: yb::QLAddBinaryColumnValue(yb::QLWriteRequestPB*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Unexecuted instantiation: yb::QLAddBoolColumnValue(yb::QLWriteRequestPB*, int, bool) Unexecuted instantiation: yb::QLAddFloatColumnValue(yb::QLWriteRequestPB*, int, float) Unexecuted instantiation: yb::QLAddDoubleColumnValue(yb::QLWriteRequestPB*, int, double) Unexecuted instantiation: yb::QLAddJsonbColumnValue(yb::QLWriteRequestPB*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Unexecuted instantiation: yb::QLAddTimestampColumnValue(yb::QLWriteRequestPB*, int, long long) |
45 | | \ |
46 | 2.23M | void PP_CAT3(QLSet, name, Expression)(QLExpressionPB* expr, type value) { \ |
47 | 2.23M | expr->mutable_value()->PP_CAT3(set_, lname, _value)(value); \ |
48 | 2.23M | } \ yb::QLSetInt8Expression(yb::QLExpressionPB*, signed char) Line | Count | Source | 46 | 135k | void PP_CAT3(QLSet, name, Expression)(QLExpressionPB* expr, type value) { \ | 47 | 135k | expr->mutable_value()->PP_CAT3(set_, lname, _value)(value); \ | 48 | 135k | } \ |
yb::QLSetInt16Expression(yb::QLExpressionPB*, short) Line | Count | Source | 46 | 71.3k | void PP_CAT3(QLSet, name, Expression)(QLExpressionPB* expr, type value) { \ | 47 | 71.3k | expr->mutable_value()->PP_CAT3(set_, lname, _value)(value); \ | 48 | 71.3k | } \ |
yb::QLSetInt32Expression(yb::QLExpressionPB*, int) Line | Count | Source | 46 | 1.77M | void PP_CAT3(QLSet, name, Expression)(QLExpressionPB* expr, type value) { \ | 47 | 1.77M | expr->mutable_value()->PP_CAT3(set_, lname, _value)(value); \ | 48 | 1.77M | } \ |
yb::QLSetInt64Expression(yb::QLExpressionPB*, long long) Line | Count | Source | 46 | 171k | void PP_CAT3(QLSet, name, Expression)(QLExpressionPB* expr, type value) { \ | 47 | 171k | expr->mutable_value()->PP_CAT3(set_, lname, _value)(value); \ | 48 | 171k | } \ |
yb::QLSetStringExpression(yb::QLExpressionPB*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Line | Count | Source | 46 | 82.3k | void PP_CAT3(QLSet, name, Expression)(QLExpressionPB* expr, type value) { \ | 47 | 82.3k | expr->mutable_value()->PP_CAT3(set_, lname, _value)(value); \ | 48 | 82.3k | } \ |
yb::QLSetBinaryExpression(yb::QLExpressionPB*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Line | Count | Source | 46 | 300 | void PP_CAT3(QLSet, name, Expression)(QLExpressionPB* expr, type value) { \ | 47 | 300 | expr->mutable_value()->PP_CAT3(set_, lname, _value)(value); \ | 48 | 300 | } \ |
Unexecuted instantiation: yb::QLSetBoolExpression(yb::QLExpressionPB*, bool) Unexecuted instantiation: yb::QLSetFloatExpression(yb::QLExpressionPB*, float) Unexecuted instantiation: yb::QLSetDoubleExpression(yb::QLExpressionPB*, double) Unexecuted instantiation: yb::QLSetJsonbExpression(yb::QLExpressionPB*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Unexecuted instantiation: yb::QLSetTimestampExpression(yb::QLExpressionPB*, long long) |
49 | | \ |
50 | | void PP_CAT3(QLSet, name, Condition)( \ |
51 | 43.1k | QLConditionPB* condition, int column_id, QLOperator op, type value) { \ |
52 | 43.1k | QLPrepareCondition(condition, column_id, op)->PP_CAT3(set_, lname, _value)(value); \ |
53 | 43.1k | } \ yb::QLSetInt8Condition(yb::QLConditionPB*, int, yb::QLOperator, signed char) Line | Count | Source | 51 | 41.6k | QLConditionPB* condition, int column_id, QLOperator op, type value) { \ | 52 | 41.6k | QLPrepareCondition(condition, column_id, op)->PP_CAT3(set_, lname, _value)(value); \ | 53 | 41.6k | } \ |
yb::QLSetInt16Condition(yb::QLConditionPB*, int, yb::QLOperator, short) Line | Count | Source | 51 | 14 | QLConditionPB* condition, int column_id, QLOperator op, type value) { \ | 52 | 14 | QLPrepareCondition(condition, column_id, op)->PP_CAT3(set_, lname, _value)(value); \ | 53 | 14 | } \ |
yb::QLSetInt32Condition(yb::QLConditionPB*, int, yb::QLOperator, int) Line | Count | Source | 51 | 896 | QLConditionPB* condition, int column_id, QLOperator op, type value) { \ | 52 | 896 | QLPrepareCondition(condition, column_id, op)->PP_CAT3(set_, lname, _value)(value); \ | 53 | 896 | } \ |
Unexecuted instantiation: yb::QLSetInt64Condition(yb::QLConditionPB*, int, yb::QLOperator, long long) yb::QLSetStringCondition(yb::QLConditionPB*, int, yb::QLOperator, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Line | Count | Source | 51 | 617 | QLConditionPB* condition, int column_id, QLOperator op, type value) { \ | 52 | 617 | QLPrepareCondition(condition, column_id, op)->PP_CAT3(set_, lname, _value)(value); \ | 53 | 617 | } \ |
Unexecuted instantiation: yb::QLSetBinaryCondition(yb::QLConditionPB*, int, yb::QLOperator, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Unexecuted instantiation: yb::QLSetBoolCondition(yb::QLConditionPB*, int, yb::QLOperator, bool) Unexecuted instantiation: yb::QLSetFloatCondition(yb::QLConditionPB*, int, yb::QLOperator, float) Unexecuted instantiation: yb::QLSetDoubleCondition(yb::QLConditionPB*, int, yb::QLOperator, double) Unexecuted instantiation: yb::QLSetJsonbCondition(yb::QLConditionPB*, int, yb::QLOperator, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Unexecuted instantiation: yb::QLSetTimestampCondition(yb::QLConditionPB*, int, yb::QLOperator, long long) |
54 | | \ |
55 | | void PP_CAT3(QLAdd, name, Condition)( \ |
56 | 42.2k | QLConditionPB* condition, int column_id, QLOperator op, type value) { \ |
57 | 42.2k | PP_CAT3(QLSet, name, Condition)( \ |
58 | 42.2k | condition->add_operands()->mutable_condition(), column_id, op, value); \ |
59 | 42.2k | } \ yb::QLAddInt8Condition(yb::QLConditionPB*, int, yb::QLOperator, signed char) Line | Count | Source | 56 | 41.6k | QLConditionPB* condition, int column_id, QLOperator op, type value) { \ | 57 | 41.6k | PP_CAT3(QLSet, name, Condition)( \ | 58 | 41.6k | condition->add_operands()->mutable_condition(), column_id, op, value); \ | 59 | 41.6k | } \ |
yb::QLAddInt16Condition(yb::QLConditionPB*, int, yb::QLOperator, short) Line | Count | Source | 56 | 11 | QLConditionPB* condition, int column_id, QLOperator op, type value) { \ | 57 | 11 | PP_CAT3(QLSet, name, Condition)( \ | 58 | 11 | condition->add_operands()->mutable_condition(), column_id, op, value); \ | 59 | 11 | } \ |
yb::QLAddInt32Condition(yb::QLConditionPB*, int, yb::QLOperator, int) Line | Count | Source | 56 | 6 | QLConditionPB* condition, int column_id, QLOperator op, type value) { \ | 57 | 6 | PP_CAT3(QLSet, name, Condition)( \ | 58 | 6 | condition->add_operands()->mutable_condition(), column_id, op, value); \ | 59 | 6 | } \ |
Unexecuted instantiation: yb::QLAddInt64Condition(yb::QLConditionPB*, int, yb::QLOperator, long long) yb::QLAddStringCondition(yb::QLConditionPB*, int, yb::QLOperator, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Line | Count | Source | 56 | 617 | QLConditionPB* condition, int column_id, QLOperator op, type value) { \ | 57 | 617 | PP_CAT3(QLSet, name, Condition)( \ | 58 | 617 | condition->add_operands()->mutable_condition(), column_id, op, value); \ | 59 | 617 | } \ |
Unexecuted instantiation: yb::QLAddBinaryCondition(yb::QLConditionPB*, int, yb::QLOperator, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Unexecuted instantiation: yb::QLAddBoolCondition(yb::QLConditionPB*, int, yb::QLOperator, bool) Unexecuted instantiation: yb::QLAddFloatCondition(yb::QLConditionPB*, int, yb::QLOperator, float) Unexecuted instantiation: yb::QLAddDoubleCondition(yb::QLConditionPB*, int, yb::QLOperator, double) Unexecuted instantiation: yb::QLAddJsonbCondition(yb::QLConditionPB*, int, yb::QLOperator, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Unexecuted instantiation: yb::QLAddTimestampCondition(yb::QLConditionPB*, int, yb::QLOperator, long long) |
60 | | |
61 | | #define QL_PROTOCOL_TYPE_DEFINITIONS(i, data, entry) QL_PROTOCOL_TYPE_DEFINITIONS_IMPL entry |
62 | | |
63 | | BOOST_PP_SEQ_FOR_EACH(QL_PROTOCOL_TYPE_DEFINITIONS, ~, QL_PROTOCOL_TYPES); |
64 | | |
65 | 2.58k | void QLAddNullColumnValue(QLWriteRequestPB* req, int column_id) { |
66 | 2.58k | QLPrepareColumn(req, column_id); |
67 | 2.58k | } |
68 | | |
69 | | void QLAddColumns(const Schema& schema, const std::vector<ColumnId>& columns, |
70 | 1.83k | QLReadRequestPB* req) { |
71 | 1.83k | if (columns.empty()) { |
72 | 918 | QLAddColumns(schema, schema.column_ids(), req); |
73 | 918 | return; |
74 | 918 | } |
75 | 918 | req->clear_selected_exprs(); |
76 | 918 | req->mutable_column_refs()->Clear(); |
77 | 918 | QLRSRowDescPB* rsrow_desc = req->mutable_rsrow_desc(); |
78 | 918 | rsrow_desc->Clear(); |
79 | 1.87k | for (const auto& id : columns) { |
80 | 1.87k | auto column = schema.column_by_id(id); |
81 | 1.87k | CHECK_OK(column); |
82 | 1.87k | req->add_selected_exprs()->set_column_id(id); |
83 | 1.87k | req->mutable_column_refs()->add_ids(id); |
84 | | |
85 | 1.87k | QLRSColDescPB* rscol_desc = rsrow_desc->add_rscol_descs(); |
86 | 1.87k | rscol_desc->set_name(column->name()); |
87 | 1.87k | column->type()->ToQLTypePB(rscol_desc->mutable_ql_type()); |
88 | 1.87k | } |
89 | 918 | } |
90 | | |
91 | 184k | std::unique_ptr<QLRowBlock> CreateRowBlock(QLClient client, const Schema& schema, Slice data) { |
92 | 184k | auto rowblock = std::make_unique<QLRowBlock>(schema); |
93 | 184k | if (!data.empty()) { |
94 | | // TODO: a better way to handle errors here? |
95 | 184k | CHECK_OK(rowblock->Deserialize(client, &data)); |
96 | 184k | } |
97 | 184k | return rowblock; |
98 | 184k | } |
99 | | |
100 | 9.26M | bool RequireReadForExpressions(const QLWriteRequestPB& request) { |
101 | | // A QLWriteOperation requires a read if it contains an IF clause or an UPDATE assignment that |
102 | | // involves an expresion with a column reference. If the IF clause contains a condition that |
103 | | // involves a column reference, the column will be included in "column_refs". However, we cannot |
104 | | // rely on non-empty "column_ref" alone to decide if a read is required because "IF EXISTS" and |
105 | | // "IF NOT EXISTS" do not involve a column reference explicitly. |
106 | 9.26M | return request.has_if_expr() || |
107 | 9.26M | (9.25M request.has_column_refs()9.25M && |
108 | 9.25M | (4.00M !request.column_refs().ids().empty()4.00M || !request.column_refs().static_ids().empty()3.92M )); |
109 | 9.26M | } |
110 | | |
111 | | // If range key portion is missing and there are no targeted columns this is a range operation |
112 | | // (e.g. range delete) -- it affects all rows within a hash key that match the where clause. |
113 | | // Note: If target columns are given this could just be e.g. a delete targeting a static column |
114 | | // which can also omit the range portion -- Analyzer will check these restrictions. |
115 | 9.28M | bool IsRangeOperation(const QLWriteRequestPB& request, const Schema& schema) { |
116 | 9.28M | return implicit_cast<size_t>(request.range_column_values().size()) < |
117 | 9.28M | schema.num_range_key_columns() && |
118 | 9.28M | request.column_values().empty()170 ; |
119 | 9.28M | } |
120 | | |
121 | 4.64M | bool RequireRead(const QLWriteRequestPB& request, const Schema& schema) { |
122 | | // In case of a user supplied timestamp, we need a read (and hence appropriate locks for read |
123 | | // modify write) but it is at the docdb level on a per key basis instead of a QL read of the |
124 | | // latest row. |
125 | 4.64M | bool has_user_timestamp = request.has_user_timestamp_usec(); |
126 | | |
127 | | // We need to read the rows in the given range to find out which rows to write to. |
128 | 4.64M | bool is_range_operation = IsRangeOperation(request, schema); |
129 | | |
130 | 4.64M | return RequireReadForExpressions(request) || has_user_timestamp4.58M || is_range_operation4.58M ; |
131 | 4.64M | } |
132 | | |
133 | 7.58M | Result<int32_t> CQLDecodeLength(Slice* data) { |
134 | 7.58M | RETURN_NOT_ENOUGH(data, sizeof(int32_t)); |
135 | 7.58M | const auto len = static_cast<int32_t>(NetworkByteOrder::Load32(data->data())); |
136 | 7.58M | data->remove_prefix(sizeof(int32_t)); |
137 | 7.58M | return len; |
138 | 7.58M | } |
139 | | |
140 | 56.6M | void CQLEncodeLength(const ssize_t length, faststring* buffer) { |
141 | 56.6M | uint32_t byte_value; |
142 | 56.6M | NetworkByteOrder::Store32(&byte_value, narrow_cast<int32_t>(length)); |
143 | 56.6M | buffer->append(&byte_value, sizeof(byte_value)); |
144 | 56.6M | } |
145 | | |
146 | | // Encode a 32-bit length into the buffer without extending the buffer. Caller should ensure the |
147 | | // buffer size is at least 4 bytes. |
148 | 10.9M | void CQLEncodeLength(const ssize_t length, void* buffer) { |
149 | 10.9M | NetworkByteOrder::Store32(buffer, narrow_cast<int32_t>(length)); |
150 | 10.9M | } |
151 | | |
152 | | } // namespace yb |