diff --git a/python/yb/lto.py b/python/yb/lto.py index 03f58850d785..2abe7402c9ca 100644 --- a/python/yb/lto.py +++ b/python/yb/lto.py @@ -298,8 +298,7 @@ def add_leaf_object_files(self) -> None: # Dedup .cc.o files already existing on the command line. continue - if (node.node_type == NodeType.OBJECT and - os.path.basename(os.path.dirname(node.path)) != 'yb_common_base.dir'): + if node.node_type == NodeType.OBJECT: self.new_args.add_new_arg(node.path) for arg in self.yb_pgbackend_link_cmd: diff --git a/src/yb/bfpg/bfpg-test.cc b/src/yb/bfpg/bfpg-test.cc index 32c38593db27..ba2d360a7824 100644 --- a/src/yb/bfpg/bfpg-test.cc +++ b/src/yb/bfpg/bfpg-test.cc @@ -42,10 +42,11 @@ class BFTestValue : public QLValue { ql_type_id_ = DataType::UNKNOWN_DATA; } - virtual DataType ql_type_id() const { + DataType ql_type_id() const { return ql_type_id_; } - virtual void set_ql_type_id(DataType ql_type_id) { + + void set_ql_type_id(DataType ql_type_id) { ql_type_id_ = ql_type_id; } diff --git a/src/yb/bfpg/bfunc_convert.h b/src/yb/bfpg/bfunc_convert.h index a0fa6250361e..643c4f0e771b 100644 --- a/src/yb/bfpg/bfunc_convert.h +++ b/src/yb/bfpg/bfunc_convert.h @@ -33,6 +33,9 @@ #include #include +#include "yb/common/ql_value.h" +#include "yb/common/value.messages.h" + #include "yb/gutil/casts.h" #include "yb/util/date_time.h" @@ -50,8 +53,8 @@ namespace bfpg { // Conversion for int8. template Status ConvertI8ToI8(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int8_value(source->int8_value()); } @@ -60,8 +63,8 @@ Status ConvertI8ToI8(PTypePtr source, RTypePtr target) { template Status ConvertI8ToI16(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int16_value(source->int8_value()); } @@ -70,8 +73,8 @@ Status ConvertI8ToI16(PTypePtr source, RTypePtr target) { template Status ConvertI8ToI32(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int32_value(source->int8_value()); } @@ -80,8 +83,8 @@ Status ConvertI8ToI32(PTypePtr source, RTypePtr target) { template Status ConvertI8ToI64(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int64_value(source->int8_value()); } @@ -90,8 +93,8 @@ Status ConvertI8ToI64(PTypePtr source, RTypePtr target) { template Status ConvertI8ToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_float_value(source->int8_value()); } @@ -100,8 +103,8 @@ Status ConvertI8ToFloat(PTypePtr source, RTypePtr target) { template Status ConvertI8ToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_double_value(source->int8_value()); } @@ -112,8 +115,8 @@ Status ConvertI8ToDouble(PTypePtr source, RTypePtr target) { template Status ConvertI16ToI8(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int8_value(source->int16_value()); } @@ -123,8 +126,8 @@ Status ConvertI16ToI8(PTypePtr source, RTypePtr target) { template Status ConvertI16ToI16(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int16_value(source->int16_value()); } @@ -133,8 +136,8 @@ Status ConvertI16ToI16(PTypePtr source, RTypePtr target) { template Status ConvertI16ToI32(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int32_value(source->int16_value()); } @@ -143,8 +146,8 @@ Status ConvertI16ToI32(PTypePtr source, RTypePtr target) { template Status ConvertI16ToI64(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int64_value(source->int16_value()); } @@ -153,8 +156,8 @@ Status ConvertI16ToI64(PTypePtr source, RTypePtr target) { template Status ConvertI16ToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_float_value(source->int16_value()); } @@ -163,8 +166,8 @@ Status ConvertI16ToFloat(PTypePtr source, RTypePtr target) { template Status ConvertI16ToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_double_value(source->int16_value()); } @@ -175,8 +178,8 @@ Status ConvertI16ToDouble(PTypePtr source, RTypePtr target) { template Status ConvertI32ToI8(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int8_value(source->int32_value()); } @@ -186,8 +189,8 @@ Status ConvertI32ToI8(PTypePtr source, RTypePtr target) { template Status ConvertI32ToI16(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int16_value(source->int32_value()); } @@ -196,8 +199,8 @@ Status ConvertI32ToI16(PTypePtr source, RTypePtr target) { template Status ConvertI32ToI32(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int32_value(source->int32_value()); } @@ -206,8 +209,8 @@ Status ConvertI32ToI32(PTypePtr source, RTypePtr target) { template Status ConvertI32ToI64(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int64_value(source->int32_value()); } @@ -216,8 +219,8 @@ Status ConvertI32ToI64(PTypePtr source, RTypePtr target) { template Status ConvertI32ToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_float_value(source->int32_value()); } @@ -226,8 +229,8 @@ Status ConvertI32ToFloat(PTypePtr source, RTypePtr target) { template Status ConvertI32ToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_double_value(source->int32_value()); } @@ -236,23 +239,23 @@ Status ConvertI32ToDouble(PTypePtr source, RTypePtr target) { // Conversion from int64 to others. template -Status ConvertI64ToI8(PTypePtr source, RTypePtr target) { +CHECKED_STATUS ConvertI64ToI8(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - target->set_int8_value(source->int64_value()); + target->set_int8_value(static_cast(source->int64_value())); } return Status::OK(); } template -Status ConvertI64ToI16(PTypePtr source, RTypePtr target) { +CHECKED_STATUS ConvertI64ToI16(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - target->set_int16_value(source->int64_value()); + target->set_int16_value(static_cast(source->int64_value())); } return Status::OK(); } @@ -260,8 +263,8 @@ Status ConvertI64ToI16(PTypePtr source, RTypePtr target) { template Status ConvertI64ToI32(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int32_value(static_cast(source->int64_value())); } @@ -271,8 +274,8 @@ Status ConvertI64ToI32(PTypePtr source, RTypePtr target) { template Status ConvertI64ToI64(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int64_value(source->int64_value()); } @@ -281,8 +284,8 @@ Status ConvertI64ToI64(PTypePtr source, RTypePtr target) { template Status ConvertI64ToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_float_value(source->int64_value()); } @@ -291,8 +294,8 @@ Status ConvertI64ToFloat(PTypePtr source, RTypePtr target) { template Status ConvertI64ToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_double_value(source->int64_value()); } @@ -302,8 +305,8 @@ Status ConvertI64ToDouble(PTypePtr source, RTypePtr target) { // Conversion from float to others. template Status ConvertFloatToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_float_value(source->float_value()); } @@ -312,8 +315,8 @@ Status ConvertFloatToFloat(PTypePtr source, RTypePtr target) { template Status ConvertFloatToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_double_value(source->float_value()); } @@ -323,8 +326,8 @@ Status ConvertFloatToDouble(PTypePtr source, RTypePtr target) { // Conversion from double to others. template Status ConvertDoubleToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_float_value(source->double_value()); } @@ -333,8 +336,8 @@ Status ConvertDoubleToFloat(PTypePtr source, RTypePtr target) { template Status ConvertDoubleToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_double_value(source->double_value()); } @@ -345,8 +348,8 @@ Status ConvertDoubleToDouble(PTypePtr source, RTypePtr target) { // The following functions are for timestamp conversion. template Status ConvertTimestampToI64(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int64_value(source->timestamp_value().ToInt64()); } @@ -355,8 +358,8 @@ Status ConvertTimestampToI64(PTypePtr source, RTypePtr target) { template Status ConvertI64ToTimestamp(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_timestamp_value(DateTime::TimestampFromInt(source->int64_value()).ToInt64()); } @@ -365,8 +368,8 @@ Status ConvertI64ToTimestamp(PTypePtr source, RTypePtr target) { template Status ConvertTimestampToString(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_string_value(source->timestamp_value().ToString()); } @@ -375,8 +378,8 @@ Status ConvertTimestampToString(PTypePtr source, RTypePtr target) { template Status ConvertStringToTimestamp(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { Timestamp ts; RETURN_NOT_OK(DateTime::TimestampFromString(source->string_value(), &ts)); @@ -389,8 +392,8 @@ Status ConvertStringToTimestamp(PTypePtr source, RTypePtr target) { // The following functions are for string conversion. template Status ConvertStringToString(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_string_value(source->string_value()); } @@ -399,8 +402,8 @@ Status ConvertStringToString(PTypePtr source, RTypePtr target) { template Status ConvertStringToInet(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_inetaddress_value(InetAddress( VERIFY_RESULT(HostToAddress(source->string_value())))); @@ -412,8 +415,8 @@ Status ConvertStringToInet(PTypePtr source, RTypePtr target) { // The following functions are for boolean conversion. template Status ConvertBoolToBool(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_bool_value(source->bool_value()); } @@ -686,41 +689,41 @@ Status ConvertToMinTimeuuid(PTypePtr source, RTypePtr target) { // The following functions are for conversions from VarInt to the other numeric types. template -Status ConvertVarintToI8(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); +CHECKED_STATUS ConvertVarintToI8(PTypePtr source, RTypePtr target) { + if (IsNull(*source)) { + SetNull(&*target); } else { - int64_t val = VERIFY_RESULT(source->varint_value().ToInt64()); + int64_t val = VERIFY_RESULT(QLValue::varint_value(*source).ToInt64()); if (val < INT8_MIN || val > INT8_MAX) { - return STATUS(InvalidArgument, "VarInt cannot be converted to int8 due to overflow"); + return STATUS(QLError, "VarInt cannot be converted to int8 due to overflow"); } - target->set_int8_value(val); + target->set_int8_value(static_cast(val)); } return Status::OK(); } template -Status ConvertVarintToI16(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); +CHECKED_STATUS ConvertVarintToI16(PTypePtr source, RTypePtr target) { + if (IsNull(*source)) { + SetNull(&*target); } else { - int64_t val = VERIFY_RESULT(source->varint_value().ToInt64()); + int64_t val = VERIFY_RESULT(QLValue::varint_value(*source).ToInt64()); if (val < INT16_MIN || val > INT16_MAX) { - return STATUS(InvalidArgument, "VarInt cannot be converted to int16 due to overflow"); + return STATUS(QLError, "VarInt cannot be converted to int16 due to overflow"); } - target->set_int16_value(val); + target->set_int16_value(static_cast(val)); } return Status::OK(); } template -Status ConvertVarintToI32(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); +CHECKED_STATUS ConvertVarintToI32(PTypePtr source, RTypePtr target) { + if (IsNull(*source)) { + SetNull(&*target); } else { - int64_t val = VERIFY_RESULT(source->varint_value().ToInt64()); + int64_t val = VERIFY_RESULT(QLValue::varint_value(*source).ToInt64()); if (val < INT32_MIN || val > INT32_MAX) { - return STATUS(InvalidArgument, "VarInt cannot be converted to int32 due to overflow"); + return STATUS(QLError, "VarInt cannot be converted to int32 due to overflow"); } target->set_int32_value(static_cast(val)); } @@ -728,36 +731,36 @@ Status ConvertVarintToI32(PTypePtr source, RTypePtr target) { } template -Status ConvertVarintToI64(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); +CHECKED_STATUS ConvertVarintToI64(PTypePtr source, RTypePtr target) { + if (IsNull(*source)) { + SetNull(&*target); } else { - int64_t val = VERIFY_RESULT(source->varint_value().ToInt64()); + int64_t val = VERIFY_RESULT(QLValue::varint_value(*source).ToInt64()); target->set_int64_value(val); } return Status::OK(); } template -Status ConvertVarintToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); +CHECKED_STATUS ConvertVarintToFloat(PTypePtr source, RTypePtr target) { + if (IsNull(*source)) { + SetNull(&*target); } else { // This may lose precision, it should return the closest float value to the input number. target->set_float_value(static_cast(VERIFY_RESULT(CheckedStold( - source->varint_value().ToString())))); + QLValue::varint_value(*source).ToString())))); } return Status::OK(); } template -Status ConvertVarintToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); +CHECKED_STATUS ConvertVarintToDouble(PTypePtr source, RTypePtr target) { + if (IsNull(*source)) { + SetNull(&*target); } else { // This may lose precision, it should return the closest double value to the input number. target->set_double_value(VERIFY_RESULT(CheckedStold( - source->varint_value().ToString()))); + QLValue::varint_value(*source).ToString()))); } return Status::OK(); } diff --git a/src/yb/bfpg/bfunc_standard.h b/src/yb/bfpg/bfunc_standard.h index 82ee1bce931d..20e7a408600c 100644 --- a/src/yb/bfpg/bfunc_standard.h +++ b/src/yb/bfpg/bfunc_standard.h @@ -66,8 +66,8 @@ CHECKED_STATUS ServerOperator(PTypePtr arg1, PTypePtr arg2, RTypePtr result) { template Status AddI64I64(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { result->set_int64_value(x->int64_value() + y->int64_value()); } @@ -76,8 +76,8 @@ Status AddI64I64(PTypePtr x, PTypePtr y, RTypePtr result) { template Status AddDoubleDouble(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { result->set_double_value(x->double_value() + y->double_value()); } @@ -86,38 +86,38 @@ Status AddDoubleDouble(PTypePtr x, PTypePtr y, RTypePtr result) { template Status AddStringString(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { - result->set_string_value(x->string_value() + y->string_value()); + ConcatStrings(x->string_value(), y->string_value(), &*result); } return Status::OK(); } template Status AddStringDouble(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { - result->set_string_value(x->string_value() + std::to_string(y->double_value())); + ConcatStrings(x->string_value(), std::to_string(y->double_value()), &*result); } return Status::OK(); } template Status AddDoubleString(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { - result->set_string_value(std::to_string(x->double_value()) + y->string_value()); + ConcatStrings(std::to_string(x->double_value()), y->string_value(), &*result); } return Status::OK(); } template Status SubI64I64(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { result->set_int64_value(x->int64_value() - y->int64_value()); } @@ -126,8 +126,8 @@ Status SubI64I64(PTypePtr x, PTypePtr y, RTypePtr result) { template Status SubDoubleDouble(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { result->set_double_value(x->double_value() - y->double_value()); } @@ -138,10 +138,10 @@ Status SubDoubleDouble(PTypePtr x, PTypePtr y, RTypePtr result) { // Comparison. template Status Equal(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { + if (IsNull(*x) || IsNull(*y)) { result->set_bool_value(false); } else { - result->set_bool_value(x->value() == y->value()); + result->set_bool_value(*x == *y); } return Status::OK(); } @@ -155,7 +155,7 @@ Status NowTimeUuid(RTypePtr result) { Uuid time_uuid(linux_time_uuid); CHECK_OK(time_uuid.IsTimeUuid()); CHECK_OK(time_uuid.HashMACAddress()); - result->set_timeuuid_value(time_uuid); + QLValue::set_timeuuid_value(time_uuid, &*result); return Status::OK(); } diff --git a/src/yb/bfql/bfql-test.cc b/src/yb/bfql/bfql-test.cc index f4605868296f..737791494fb0 100644 --- a/src/yb/bfql/bfql-test.cc +++ b/src/yb/bfql/bfql-test.cc @@ -45,10 +45,11 @@ class BFTestValue : public QLValue { ql_type_id_ = DataType::UNKNOWN_DATA; } - virtual DataType ql_type_id() const { + DataType ql_type_id() const { return ql_type_id_; } - virtual void set_ql_type_id(DataType ql_type_id) { + + void set_ql_type_id(DataType ql_type_id) { ql_type_id_ = ql_type_id; } diff --git a/src/yb/bfql/bfunc_convert.h b/src/yb/bfql/bfunc_convert.h index 888ca044a580..fdaed2774e62 100644 --- a/src/yb/bfql/bfunc_convert.h +++ b/src/yb/bfql/bfunc_convert.h @@ -35,6 +35,7 @@ #include "yb/common/ql_datatype.h" #include "yb/common/ql_type.h" +#include "yb/common/ql_value.h" #include "yb/gutil/casts.h" #include "yb/gutil/endian.h" @@ -64,14 +65,14 @@ static constexpr size_t kHexBase = 16; template CHECKED_STATUS SetNumericResult(SetResult set_result, PTypePtr source, DataType target_datatype, RTypePtr target) { - DataType source_datatype = InternalToDataType(source->type()); + auto source_datatype = InternalToDataType(source->value_case()); if (!QLType::IsExplicitlyConvertible(target_datatype, source_datatype)) { return STATUS_SUBSTITUTE(QLError, "Cannot convert $0 to $1", QLType::ToCQLString(source_datatype), QLType::ToCQLString(target_datatype)); } - switch(source->type()) { + switch(source->value_case()) { case InternalType::kInt8Value: RETURN_NOT_OK(set_result(source->int8_value(), target)); break; @@ -117,14 +118,14 @@ CHECKED_STATUS SetNumericResult(SetResult set_result, PTypePtr source, DataType template CHECKED_STATUS SetStringResult(PTypePtr source, RTypePtr target) { - DataType source_datatype = InternalToDataType(source->type()); + auto source_datatype = InternalToDataType(source->value_case()); if (!QLType::IsExplicitlyConvertible(DataType::STRING, source_datatype)) { return STATUS_SUBSTITUTE(QLError, "Cannot convert $0 to $1", QLType::ToCQLString(source_datatype), QLType::ToCQLString(DataType::STRING)); } - switch(source->type()) { + switch(source->value_case()) { case InternalType::kInt8Value: target->set_string_value(std::to_string(source->int8_value())); break; @@ -150,7 +151,7 @@ CHECKED_STATUS SetStringResult(PTypePtr source, RTypePtr target) { target->set_string_value(source->bool_value() ? "true" : "false"); break; case InternalType::kTimestampValue: - target->set_string_value(DateTime::TimestampToString(source->timestamp_value())); + target->set_string_value(DateTime::TimestampToString(QLValue::timestamp_value(*source))); break; case InternalType::kDateValue: target->set_string_value(VERIFY_RESULT(DateTime::DateToString(source->date_value()))); @@ -159,19 +160,16 @@ CHECKED_STATUS SetStringResult(PTypePtr source, RTypePtr target) { target->set_string_value(VERIFY_RESULT(DateTime::TimeToString(source->time_value()))); break; case InternalType::kUuidValue: - target->set_string_value(source->uuid_value().ToString()); + target->set_string_value(QLValue::uuid_value(*source).ToString()); break; case InternalType::kTimeuuidValue: - target->set_string_value(source->timeuuid_value().ToString()); + target->set_string_value(QLValue::timeuuid_value(*source).ToString()); break; case InternalType::kBinaryValue: target->set_string_value("0x" + b2a_hex(source->binary_value())); break; - case InternalType::kInetaddressValue: { - string strval; - RETURN_NOT_OK(source->inetaddress_value().ToString(&strval)); - target->set_string_value(strval); - } + case InternalType::kInetaddressValue: + RETURN_NOT_OK(QLValue::inetaddress_value(*source).ToString(target->mutable_string_value())); break; case InternalType::kDecimalValue: { util::Decimal d; @@ -189,26 +187,25 @@ CHECKED_STATUS SetStringResult(PTypePtr source, RTypePtr target) { template CHECKED_STATUS SetTimestampResult(PTypePtr source, RTypePtr target) { - DataType source_datatype = InternalToDataType(source->type()); + auto source_datatype = InternalToDataType(source->value_case()); if (!QLType::IsExplicitlyConvertible(DataType::TIMESTAMP, source_datatype)) { return STATUS_SUBSTITUTE(QLError, "Cannot convert $0 to $1", QLType::ToCQLString(source_datatype), QLType::ToCQLString(DataType::TIMESTAMP)); } - switch(source->type()) { + switch(source->value_case()) { case InternalType::kTimeuuidValue: { - Uuid time_uuid = source->timeuuid_value(); + auto time_uuid = QLValue::timeuuid_value(*source); int64_t unix_timestamp; RETURN_NOT_OK(time_uuid.ToUnixTimestamp(&unix_timestamp)); - target->set_timestamp_value(Timestamp(DateTime::AdjustPrecision - (unix_timestamp, - DateTime::kMillisecondPrecision, - DateTime::kInternalPrecision))); + target->set_timestamp_value(Timestamp(DateTime::AdjustPrecision( + unix_timestamp, DateTime::kMillisecondPrecision, DateTime::kInternalPrecision)) + .ToInt64()); break; } case InternalType::kDateValue: - target->set_timestamp_value(DateTime::DateToTimestamp(source->date_value())); + target->set_timestamp_value(DateTime::DateToTimestamp(source->date_value()).ToInt64()); break; default: return STATUS_SUBSTITUTE(QLError, "Cannot cast $0 to $1", @@ -220,19 +217,20 @@ CHECKED_STATUS SetTimestampResult(PTypePtr source, RTypePtr target) { template CHECKED_STATUS SetDateResult(PTypePtr source, RTypePtr target) { - DataType source_datatype = InternalToDataType(source->type()); + DataType source_datatype = InternalToDataType(source->value_case()); if (!QLType::IsExplicitlyConvertible(DataType::DATE, source_datatype)) { return STATUS_SUBSTITUTE(QLError, "Cannot convert $0 to $1", QLType::ToCQLString(source_datatype), QLType::ToCQLString(DataType::DATE)); } - switch(source->type()) { + switch(source->value_case()) { case InternalType::kTimestampValue: - target->set_date_value(VERIFY_RESULT(DateTime::DateFromTimestamp(source->timestamp_value()))); + target->set_date_value(VERIFY_RESULT(DateTime::DateFromTimestamp( + QLValue::timestamp_value(*source)))); break; case InternalType::kTimeuuidValue: { - Uuid time_uuid = source->timeuuid_value(); + Uuid time_uuid = QLValue::timeuuid_value(*source); int64_t unix_timestamp; RETURN_NOT_OK(time_uuid.ToUnixTimestamp(&unix_timestamp)); target->set_date_value(VERIFY_RESULT(DateTime::DateFromUnixTimestamp(unix_timestamp))); @@ -257,8 +255,8 @@ CHECKED_STATUS StringToNumeric(const string& str_val, RTypePtr target, StrToNum //-------------------------------------------------------------------------------------------------- template CHECKED_STATUS ConvertI8ToI8(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int8_value(source->int8_value()); } @@ -267,8 +265,8 @@ CHECKED_STATUS ConvertI8ToI8(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI8ToI16(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int16_value(source->int8_value()); } @@ -277,8 +275,8 @@ CHECKED_STATUS ConvertI8ToI16(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI8ToI32(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int32_value(source->int8_value()); } @@ -287,8 +285,8 @@ CHECKED_STATUS ConvertI8ToI32(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI8ToI64(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int64_value(source->int8_value()); } @@ -297,8 +295,8 @@ CHECKED_STATUS ConvertI8ToI64(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI8ToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_float_value(source->int8_value()); } @@ -307,8 +305,8 @@ CHECKED_STATUS ConvertI8ToFloat(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI8ToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_double_value(source->int8_value()); } @@ -319,8 +317,8 @@ CHECKED_STATUS ConvertI8ToDouble(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI16ToI8(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int8_value(source->int16_value()); } @@ -330,8 +328,8 @@ CHECKED_STATUS ConvertI16ToI8(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI16ToI16(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int16_value(source->int16_value()); } @@ -340,8 +338,8 @@ CHECKED_STATUS ConvertI16ToI16(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI16ToI32(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int32_value(source->int16_value()); } @@ -350,8 +348,8 @@ CHECKED_STATUS ConvertI16ToI32(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI16ToI64(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int64_value(source->int16_value()); } @@ -360,8 +358,8 @@ CHECKED_STATUS ConvertI16ToI64(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI16ToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_float_value(source->int16_value()); } @@ -370,8 +368,8 @@ CHECKED_STATUS ConvertI16ToFloat(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI16ToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_double_value(source->int16_value()); } @@ -382,8 +380,8 @@ CHECKED_STATUS ConvertI16ToDouble(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI32ToI8(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int8_value(source->int32_value()); } @@ -393,8 +391,8 @@ CHECKED_STATUS ConvertI32ToI8(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI32ToI16(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int16_value(source->int32_value()); } @@ -403,8 +401,8 @@ CHECKED_STATUS ConvertI32ToI16(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI32ToI32(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int32_value(source->int32_value()); } @@ -413,8 +411,8 @@ CHECKED_STATUS ConvertI32ToI32(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI32ToI64(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int64_value(source->int32_value()); } @@ -423,8 +421,8 @@ CHECKED_STATUS ConvertI32ToI64(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI32ToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_float_value(source->int32_value()); } @@ -433,8 +431,8 @@ CHECKED_STATUS ConvertI32ToFloat(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI32ToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_double_value(source->int32_value()); } @@ -445,10 +443,10 @@ CHECKED_STATUS ConvertI32ToDouble(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI64ToI8(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - target->set_int8_value(source->int64_value()); + target->set_int8_value(static_cast(source->int64_value())); } return Status::OK(); } @@ -456,10 +454,10 @@ CHECKED_STATUS ConvertI64ToI8(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI64ToI16(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - target->set_int16_value(source->int64_value()); + target->set_int16_value(static_cast(source->int64_value())); } return Status::OK(); } @@ -467,8 +465,8 @@ CHECKED_STATUS ConvertI64ToI16(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI64ToI32(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int32_value(static_cast(source->int64_value())); } @@ -478,8 +476,8 @@ CHECKED_STATUS ConvertI64ToI32(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI64ToI64(PTypePtr source, RTypePtr target) { // TODO(neil) Overflow? When we truely support expressions, these loose-ends must be fixed. - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int64_value(source->int64_value()); } @@ -488,8 +486,8 @@ CHECKED_STATUS ConvertI64ToI64(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI64ToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_float_value(source->int64_value()); } @@ -498,8 +496,8 @@ CHECKED_STATUS ConvertI64ToFloat(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertI64ToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_double_value(source->int64_value()); } @@ -509,8 +507,8 @@ CHECKED_STATUS ConvertI64ToDouble(PTypePtr source, RTypePtr target) { // Conversion from float to others. template CHECKED_STATUS ConvertFloatToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_float_value(source->float_value()); } @@ -519,8 +517,8 @@ CHECKED_STATUS ConvertFloatToFloat(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertFloatToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_double_value(source->float_value()); } @@ -530,8 +528,8 @@ CHECKED_STATUS ConvertFloatToDouble(PTypePtr source, RTypePtr target) { // Conversion from double to others. template CHECKED_STATUS ConvertDoubleToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_float_value(source->double_value()); } @@ -540,8 +538,8 @@ CHECKED_STATUS ConvertDoubleToFloat(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertDoubleToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_double_value(source->double_value()); } @@ -552,18 +550,18 @@ CHECKED_STATUS ConvertDoubleToDouble(PTypePtr source, RTypePtr target) { // The following functions are for timestamp conversion. template CHECKED_STATUS ConvertTimestampToI64(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - target->set_int64_value(source->timestamp_value().ToInt64()); + target->set_int64_value(QLValue::timestamp_value(*source).ToInt64()); } return Status::OK(); } template CHECKED_STATUS ConvertI64ToTimestamp(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_timestamp_value(DateTime::TimestampFromInt(source->int64_value()).ToInt64()); } @@ -572,18 +570,18 @@ CHECKED_STATUS ConvertI64ToTimestamp(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertTimestampToString(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - target->set_string_value(source->timestamp_value().ToString()); + target->set_string_value(QLValue::timestamp_value(*source).ToString()); } return Status::OK(); } template CHECKED_STATUS ConvertStringToTimestamp(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { Timestamp ts; RETURN_NOT_OK(DateTime::TimestampFromString(source->string_value(), &ts)); @@ -596,8 +594,8 @@ CHECKED_STATUS ConvertStringToTimestamp(PTypePtr source, RTypePtr target) { // The following functions are for string conversion. template CHECKED_STATUS ConvertStringToString(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_string_value(source->string_value()); } @@ -606,8 +604,8 @@ CHECKED_STATUS ConvertStringToString(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertStringToInet(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_inetaddress_value(InetAddress( VERIFY_RESULT(HostToAddress(source->string_value())))); @@ -619,8 +617,8 @@ CHECKED_STATUS ConvertStringToInet(PTypePtr source, RTypePtr target) { // The following functions are for boolean conversion. template CHECKED_STATUS ConvertBoolToBool(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_bool_value(source->bool_value()); } @@ -632,8 +630,8 @@ CHECKED_STATUS ConvertBoolToBool(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertStringToBlob(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { string target_val = source->string_value(); target->set_binary_value(target_val); @@ -643,8 +641,8 @@ CHECKED_STATUS ConvertStringToBlob(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertBoolToBlob(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { int8_t byte_stream = (source->bool_value()) ? 1 : 0; target->set_binary_value(reinterpret_cast (&byte_stream), kSizeBool); @@ -654,8 +652,8 @@ CHECKED_STATUS ConvertBoolToBlob(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertInt8ToBlob(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { int8_t byte_stream = source->int8_value(); target->set_binary_value(reinterpret_cast (&byte_stream), kSizeTinyInt); @@ -665,8 +663,8 @@ CHECKED_STATUS ConvertInt8ToBlob(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertInt16ToBlob(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { int16_t source_val = source->int16_value(); uint16* source_ptr = reinterpret_cast (&source_val); @@ -678,8 +676,8 @@ CHECKED_STATUS ConvertInt16ToBlob(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertInt32ToBlob(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { int32_t source_val = source->int32_value(); uint32* source_ptr = reinterpret_cast (&source_val); @@ -691,8 +689,8 @@ CHECKED_STATUS ConvertInt32ToBlob(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertInt64ToBlob(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { int64_t source_val = source->int64_value(); uint64* source_ptr = reinterpret_cast (&source_val); @@ -709,8 +707,8 @@ CHECKED_STATUS ConvertVarintToBlob(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertFloatToBlob(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { float source_val = source->float_value(); uint32* source_ptr = reinterpret_cast (&source_val); @@ -722,8 +720,8 @@ CHECKED_STATUS ConvertFloatToBlob(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertDoubleToBlob(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { double source_val = source->double_value(); uint64* source_ptr = reinterpret_cast (&source_val); @@ -750,10 +748,10 @@ CHECKED_STATUS ConvertTimeToBlob(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertTimestampToBlob(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - Timestamp source_val = source->timestamp_value(); + Timestamp source_val = QLValue::timestamp_value(*source); int64_t ts_int_value = source_val.ToInt64(); ts_int_value = DateTime::AdjustPrecision(ts_int_value, DateTime::kInternalPrecision, DateTime::kMillisecondPrecision); @@ -766,26 +764,22 @@ CHECKED_STATUS ConvertTimestampToBlob(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertUuidToBlob(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - string byte_stream; - const Uuid& source_val = source->uuid_value(); - source_val.ToBytes(&byte_stream); - target->set_binary_value(byte_stream); + const Uuid& source_val = QLValue::uuid_value(*source); + source_val.ToBytes(target->mutable_binary_value()); } return Status::OK(); } template CHECKED_STATUS ConvertTimeuuidToBlob(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - string byte_stream; - const Uuid& source_val = source->timeuuid_value(); - source_val.ToBytes(&byte_stream); - target->set_binary_value(byte_stream); + const Uuid& source_val = QLValue::timeuuid_value(*source); + source_val.ToBytes(target->mutable_binary_value()); } return Status::OK(); } @@ -819,8 +813,8 @@ CHECKED_STATUS ConvertTupleToBlob(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertBlobToString(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_string_value(source->binary_value()); } @@ -829,8 +823,8 @@ CHECKED_STATUS ConvertBlobToString(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertBlobToBool(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { string blob = source->binary_value(); if (blob.size() != kSizeBool) { @@ -843,8 +837,8 @@ CHECKED_STATUS ConvertBlobToBool(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertBlobToInt8(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { string blob = source->binary_value(); if (blob.size() != kSizeTinyInt) { @@ -857,8 +851,8 @@ CHECKED_STATUS ConvertBlobToInt8(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertBlobToInt16(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { string blob = source->binary_value(); if (blob.size() != kSizeSmallInt) { @@ -874,8 +868,8 @@ CHECKED_STATUS ConvertBlobToInt16(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertBlobToInt32(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { string blob = source->binary_value(); if (blob.size() != kSizeInt) { @@ -891,8 +885,8 @@ CHECKED_STATUS ConvertBlobToInt32(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertBlobToInt64(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { string blob = source->binary_value(); if (blob.size() != kSizeBigInt) { @@ -913,8 +907,8 @@ CHECKED_STATUS ConvertBlobToVarint(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertBlobToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { string blob = source->binary_value(); if (blob.size() != kSizeInt) { @@ -930,8 +924,8 @@ CHECKED_STATUS ConvertBlobToFloat(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertBlobToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { string blob = source->binary_value(); if (blob.size() != kSizeBigInt) { @@ -962,8 +956,8 @@ CHECKED_STATUS ConvertBlobToTime(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertBlobToTimestamp(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { string blob = source->binary_value(); if (blob.size() != kSizeBigInt) { @@ -976,15 +970,15 @@ CHECKED_STATUS ConvertBlobToTimestamp(PTypePtr source, RTypePtr target) { DateTime::kMillisecondPrecision, DateTime::kInternalPrecision); Timestamp ts(target_val); - target->set_timestamp_value(ts); + target->set_timestamp_value(ts.ToInt64()); } return Status::OK(); } template CHECKED_STATUS ConvertBlobToUuid(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { string blob = source->binary_value(); if (blob.size() != kSizeUuid) { @@ -992,15 +986,15 @@ CHECKED_STATUS ConvertBlobToUuid(PTypePtr source, RTypePtr target) { } Uuid target_val; RETURN_NOT_OK(target_val.FromBytes(blob)); - target->set_uuid_value(target_val); + QLValue::set_uuid_value(target_val, &*target); } return Status::OK(); } template CHECKED_STATUS ConvertBlobToTimeuuid(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { string blob = source->binary_value(); if (blob.size() != kSizeUuid) { @@ -1008,7 +1002,7 @@ CHECKED_STATUS ConvertBlobToTimeuuid(PTypePtr source, RTypePtr target) { } Uuid target_val; RETURN_NOT_OK(target_val.FromBytes(blob)); - target->set_timeuuid_value(target_val); + QLValue::set_timeuuid_value(target_val, &*target); } return Status::OK(); } @@ -1042,8 +1036,8 @@ CHECKED_STATUS ConvertBlobToTuple(PTypePtr source, RTypePtr target) { // The following functions are for conversions between date-time datatypes. template CHECKED_STATUS ConvertTimeuuidToDate(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); return Status::OK(); } return SetDateResult(source, target); @@ -1051,8 +1045,8 @@ CHECKED_STATUS ConvertTimeuuidToDate(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertTimestampToDate(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); return Status::OK(); } return SetDateResult(source, target); @@ -1070,8 +1064,8 @@ CHECKED_STATUS ConvertTimestampToTime(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertDateToTimestamp(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); return Status::OK(); } return SetTimestampResult(source, target); @@ -1079,8 +1073,8 @@ CHECKED_STATUS ConvertDateToTimestamp(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertTimeuuidToTimestamp(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); return Status::OK(); } return SetTimestampResult(source, target); @@ -1088,8 +1082,8 @@ CHECKED_STATUS ConvertTimeuuidToTimestamp(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertDateToUnixTimestamp(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { target->set_int64_value(DateTime::DateToUnixTimestamp(source->date_value())); } @@ -1098,10 +1092,10 @@ CHECKED_STATUS ConvertDateToUnixTimestamp(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertTimestampToUnixTimestamp(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - int64_t unix_timestamp = DateTime::AdjustPrecision(source->timestamp_value().ToInt64(), + int64_t unix_timestamp = DateTime::AdjustPrecision(QLValue::timestamp_value(*source).ToInt64(), DateTime::kInternalPrecision, DateTime::kMillisecondPrecision); target->set_int64_value(unix_timestamp); @@ -1111,10 +1105,10 @@ CHECKED_STATUS ConvertTimestampToUnixTimestamp(PTypePtr source, RTypePtr target) template CHECKED_STATUS ConvertTimeuuidToUnixTimestamp(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - Uuid time_uuid = source->timeuuid_value(); + Uuid time_uuid = QLValue::timeuuid_value(*source); int64_t unix_timestamp; RETURN_NOT_OK(time_uuid.ToUnixTimestamp(&unix_timestamp)); target->set_int64_value(unix_timestamp); @@ -1124,32 +1118,32 @@ CHECKED_STATUS ConvertTimeuuidToUnixTimestamp(PTypePtr source, RTypePtr target) template CHECKED_STATUS ConvertToMaxTimeuuid(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { + if (IsNull(*source)) { return STATUS(RuntimeError, "Cannot get max timeuuid of null"); } else { - int64_t timestamp_ms = DateTime::AdjustPrecision(source->timestamp_value().ToInt64(), + int64_t timestamp_ms = DateTime::AdjustPrecision(QLValue::timestamp_value(*source).ToInt64(), DateTime::kInternalPrecision, DateTime::kMillisecondPrecision); Uuid uuid; RETURN_NOT_OK(uuid.MaxFromUnixTimestamp(timestamp_ms)); - target->set_timeuuid_value(uuid); + QLValue::set_timeuuid_value(uuid, &*target); } return Status::OK(); } template CHECKED_STATUS ConvertToMinTimeuuid(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { + if (IsNull(*source)) { return STATUS(RuntimeError, "Cannot get max timeuuid of null"); } else { - int64_t timestamp_ms = DateTime::AdjustPrecision(source->timestamp_value().ToInt64(), + int64_t timestamp_ms = DateTime::AdjustPrecision(QLValue::timestamp_value(*source).ToInt64(), DateTime::kInternalPrecision, DateTime::kMillisecondPrecision); Uuid uuid; RETURN_NOT_OK(uuid.MinFromUnixTimestamp(timestamp_ms)); - target->set_timeuuid_value(uuid); + QLValue::set_timeuuid_value(uuid, &*target); } return Status::OK(); } @@ -1159,38 +1153,38 @@ CHECKED_STATUS ConvertToMinTimeuuid(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertVarintToI8(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - int64_t val = VERIFY_RESULT(source->varint_value().ToInt64()); + int64_t val = VERIFY_RESULT(QLValue::varint_value(*source).ToInt64()); if (val < INT8_MIN || val > INT8_MAX) { return STATUS(QLError, "VarInt cannot be converted to int8 due to overflow"); } - target->set_int8_value(val); + target->set_int8_value(static_cast(val)); } return Status::OK(); } template CHECKED_STATUS ConvertVarintToI16(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - int64_t val = VERIFY_RESULT(source->varint_value().ToInt64()); + int64_t val = VERIFY_RESULT(QLValue::varint_value(*source).ToInt64()); if (val < INT16_MIN || val > INT16_MAX) { return STATUS(QLError, "VarInt cannot be converted to int16 due to overflow"); } - target->set_int16_value(val); + target->set_int16_value(static_cast(val)); } return Status::OK(); } template CHECKED_STATUS ConvertVarintToI32(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - int64_t val = VERIFY_RESULT(source->varint_value().ToInt64()); + int64_t val = VERIFY_RESULT(QLValue::varint_value(*source).ToInt64()); if (val < INT32_MIN || val > INT32_MAX) { return STATUS(QLError, "VarInt cannot be converted to int32 due to overflow"); } @@ -1201,10 +1195,10 @@ CHECKED_STATUS ConvertVarintToI32(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertVarintToI64(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - int64_t val = VERIFY_RESULT(source->varint_value().ToInt64()); + int64_t val = VERIFY_RESULT(QLValue::varint_value(*source).ToInt64()); target->set_int64_value(val); } return Status::OK(); @@ -1212,64 +1206,67 @@ CHECKED_STATUS ConvertVarintToI64(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertVarintToFloat(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { // This may lose precision, it should return the closest float value to the input number. target->set_float_value(static_cast(VERIFY_RESULT(CheckedStold( - source->varint_value().ToString())))); + QLValue::varint_value(*source).ToString())))); } return Status::OK(); } template CHECKED_STATUS ConvertVarintToDouble(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { // This may lose precision, it should return the closest double value to the input number. target->set_double_value(VERIFY_RESULT(CheckedStold( - source->varint_value().ToString()))); + QLValue::varint_value(*source).ToString()))); } return Status::OK(); } template CHECKED_STATUS ConvertI8ToVarint(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - target->set_varint_value(util::VarInt(static_cast(source->int8_value()))); + target->set_varint_value( + util::VarInt(static_cast(source->int8_value())).EncodeToComparable()); } return Status::OK(); } template CHECKED_STATUS ConvertI16ToVarint(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - target->set_varint_value(util::VarInt(static_cast(source->int16_value()))); + target->set_varint_value( + util::VarInt(static_cast(source->int16_value())).EncodeToComparable()); } return Status::OK(); } template CHECKED_STATUS ConvertI32ToVarint(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - target->set_varint_value(util::VarInt(static_cast(source->int32_value()))); + target->set_varint_value( + util::VarInt(static_cast(source->int32_value())).EncodeToComparable()); } return Status::OK(); } template CHECKED_STATUS ConvertI64ToVarint(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); } else { - target->set_varint_value(util::VarInt(source->int64_value())); + target->set_varint_value(util::VarInt(source->int64_value()).EncodeToComparable()); } return Status::OK(); } @@ -1307,11 +1304,11 @@ CHECKED_STATUS ToDouble(double val, RTypePtr target) { template CHECKED_STATUS ConvertToNumeric(PTypePtr source, RTypePtr target, const DataType& data_type, StrToNum strToNum, ToNumeric toNumeric) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); return Status::OK(); } - if (source->type() == InternalType::kStringValue) { + if (source->value_case() == InternalType::kStringValue) { return StringToNumeric(source->string_value(), target, strToNum, toNumeric); } else { return SetNumericResult(toNumeric, source, data_type, target); @@ -1352,12 +1349,12 @@ YB_DEFINE_ENUM(ConvertDecimalVia, (kUnknown)(kString)(kVarint)(kDecimal)(kInt64) template CHECKED_STATUS ConvertToDecimal(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); return Status::OK(); } - const DataType source_datatype = InternalToDataType(source->type()); + const DataType source_datatype = InternalToDataType(source->value_case()); if (!QLType::IsExplicitlyConvertible(DataType::DECIMAL, source_datatype)) { return STATUS_SUBSTITUTE(QLError, "Cannot convert $0 to $1", QLType::ToCQLString(source_datatype), @@ -1368,7 +1365,7 @@ CHECKED_STATUS ConvertToDecimal(PTypePtr source, RTypePtr target) { double double_num = 0.; ConvertDecimalVia convert = ConvertDecimalVia::kUnknown; - switch(source->type()) { + switch(source->value_case()) { case InternalType::kStringValue: convert = ConvertDecimalVia::kString; break; @@ -1412,19 +1409,19 @@ CHECKED_STATUS ConvertToDecimal(PTypePtr source, RTypePtr target) { util::Decimal d; switch(convert) { case ConvertDecimalVia::kString: - RSTATUS_DCHECK_EQ(source->type(), InternalType::kStringValue, + RSTATUS_DCHECK_EQ(source->value_case(), InternalType::kStringValue, InvalidArgument, strings::Substitute("Invalid source type: ", QLType::ToCQLString(source_datatype))); RETURN_NOT_OK(d.FromString(source->string_value())); break; case ConvertDecimalVia::kVarint: - RSTATUS_DCHECK_EQ(source->type(), InternalType::kVarintValue, + RSTATUS_DCHECK_EQ(source->value_case(), InternalType::kVarintValue, InvalidArgument, strings::Substitute("Invalid source type: ", QLType::ToCQLString(source_datatype))); - RETURN_NOT_OK(d.FromVarInt(source->varint_value())); + RETURN_NOT_OK(d.FromVarInt(QLValue::varint_value(*source))); break; case ConvertDecimalVia::kDecimal: - RSTATUS_DCHECK_EQ(source->type(), InternalType::kDecimalValue, + RSTATUS_DCHECK_EQ(source->value_case(), InternalType::kDecimalValue, InvalidArgument, strings::Substitute("Invalid source type: ", QLType::ToCQLString(source_datatype))); RETURN_NOT_OK(d.DecodeFromComparable(source->decimal_value())); @@ -1447,8 +1444,8 @@ CHECKED_STATUS ConvertToDecimal(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertToString(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); return Status::OK(); } return SetStringResult(source, target); @@ -1456,8 +1453,8 @@ CHECKED_STATUS ConvertToString(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertToTimestamp(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); return Status::OK(); } return SetTimestampResult(source, target); @@ -1465,8 +1462,8 @@ CHECKED_STATUS ConvertToTimestamp(PTypePtr source, RTypePtr target) { template CHECKED_STATUS ConvertToDate(PTypePtr source, RTypePtr target) { - if (source->IsNull()) { - target->SetNull(); + if (IsNull(*source)) { + SetNull(&*target); return Status::OK(); } return SetDateResult(source, target); diff --git a/src/yb/bfql/bfunc_standard.h b/src/yb/bfql/bfunc_standard.h index e70b8281dfbc..bcab71d20695 100644 --- a/src/yb/bfql/bfunc_standard.h +++ b/src/yb/bfql/bfunc_standard.h @@ -87,7 +87,7 @@ template uint16_t YBHash(const vector& params, RTypePtr result) { string encoded_key = ""; for (const PTypePtr& param : params) { - param->AppendToKeyBytes(&encoded_key); + AppendToKey(*param, &encoded_key); } return YBPartition::HashColumnCompoundValue(encoded_key); @@ -110,13 +110,13 @@ CHECKED_STATUS PartitionHash(const vector& params, RTypePtr result) { template CHECKED_STATUS ToJson(PTypePtr col, RTypePtr result) { common::Jsonb jsonb; - Status s = jsonb.FromQLValuePB(col->value()); + Status s = jsonb.FromQLValue(*col); if (!s.ok()) { - return s.CloneAndPrepend(strings::Substitute( + return s.CloneAndPrepend(Format( "Cannot convert $0 value $1 to $2", - QLType::ToCQLString(InternalToDataType(col->type())), - col->ToString(), + QLType::ToCQLString(InternalToDataType(col->value_case())), + *col, QLType::ToCQLString(DataType::JSONB))); } @@ -139,7 +139,7 @@ CHECKED_STATUS writetime(PTypePtr col, RTypePtr result) { template CHECKED_STATUS IncCounter(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull()) { + if (IsNull(*x)) { result->set_int64_value(y->int64_value()); } else { result->set_int64_value(x->int64_value() + y->int64_value()); @@ -149,7 +149,7 @@ CHECKED_STATUS IncCounter(PTypePtr x, PTypePtr y, RTypePtr result) { template CHECKED_STATUS DecCounter(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull()) { + if (IsNull(*x)) { result->set_int64_value(-y->int64_value()); } else { result->set_int64_value(x->int64_value() - y->int64_value()); @@ -162,8 +162,8 @@ CHECKED_STATUS DecCounter(PTypePtr x, PTypePtr y, RTypePtr result) { template CHECKED_STATUS AddI64I64(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { result->set_int64_value(x->int64_value() + y->int64_value()); } @@ -172,8 +172,8 @@ CHECKED_STATUS AddI64I64(PTypePtr x, PTypePtr y, RTypePtr result) { template CHECKED_STATUS AddDoubleDouble(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { result->set_double_value(x->double_value() + y->double_value()); } @@ -182,8 +182,8 @@ CHECKED_STATUS AddDoubleDouble(PTypePtr x, PTypePtr y, RTypePtr result) { template CHECKED_STATUS AddStringString(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { result->set_string_value(x->string_value() + y->string_value()); } @@ -192,8 +192,8 @@ CHECKED_STATUS AddStringString(PTypePtr x, PTypePtr y, RTypePtr result) { template CHECKED_STATUS AddStringDouble(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { result->set_string_value(x->string_value() + std::to_string(y->double_value())); } @@ -202,8 +202,8 @@ CHECKED_STATUS AddStringDouble(PTypePtr x, PTypePtr y, RTypePtr result) { template CHECKED_STATUS AddDoubleString(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { result->set_string_value(std::to_string(x->double_value()) + y->string_value()); } @@ -230,8 +230,8 @@ CHECKED_STATUS AddListList(PTypePtr x, PTypePtr y, RTypePtr result) { template CHECKED_STATUS SubI64I64(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { result->set_int64_value(x->int64_value() - y->int64_value()); } @@ -240,8 +240,8 @@ CHECKED_STATUS SubI64I64(PTypePtr x, PTypePtr y, RTypePtr result) { template CHECKED_STATUS SubDoubleDouble(PTypePtr x, PTypePtr y, RTypePtr result) { - if (x->IsNull() || y->IsNull()) { - result->SetNull(); + if (IsNull(*x) || IsNull(*y)) { + SetNull(&*result); } else { result->set_double_value(x->double_value() - y->double_value()); } @@ -267,7 +267,7 @@ CHECKED_STATUS SubListList(PTypePtr x, PTypePtr y, RTypePtr result) { // For clarity, this implementation should be removed (see e.g. SubSetSet above) as soon as // RemoveFromList is implemented in DocDB. result->set_list_value(); - if (x->IsNull() || y->IsNull()) { + if (IsNull(*x) || IsNull(*y)) { return Status::OK(); } @@ -304,7 +304,7 @@ CHECKED_STATUS NowTime(RTypePtr result) { template CHECKED_STATUS NowTimestamp(RTypePtr result) { - result->set_timestamp_value(DateTime::TimestampNow()); + result->set_timestamp_value(DateTime::TimestampNow().ToInt64()); return Status::OK(); } @@ -315,7 +315,7 @@ CHECKED_STATUS NowTimeUuid(RTypePtr result) { Uuid time_uuid(linux_time_uuid); CHECK_OK(time_uuid.IsTimeUuid()); CHECK_OK(time_uuid.HashMACAddress()); - result->set_timeuuid_value(time_uuid); + QLValue::set_timeuuid_value(time_uuid, &*result); return Status::OK(); } @@ -330,7 +330,7 @@ CHECKED_STATUS GetUuid(RTypePtr result) { return STATUS_FORMAT(IllegalState, "Unexpected UUID type $0, expected $1.", uuid.version(), kUUIDType); } - result->set_uuid_value(uuid); + QLValue::set_uuid_value(uuid, &*result); return Status::OK(); } @@ -341,8 +341,8 @@ CHECKED_STATUS MapConstructor(const vector& params, RTypePtr result) { auto *qlmap = result->mutable_map_value(); RSTATUS_DCHECK(params.size()%2 == 0, RuntimeError, "Unexpected argument count for map::map"); for (size_t i = 0; i < params.size(); i++) { - *qlmap->add_keys() = params[i]->value(); - *qlmap->add_values() = params[++i]->value(); + QLValue::set_value(*params[i], qlmap->add_keys()); + QLValue::set_value(*params[++i], qlmap->add_values()); } return Status::OK(); } @@ -352,7 +352,7 @@ template CHECKED_STATUS SetConstructor(const vector& params, RTypePtr result) { auto *qlset = result->mutable_set_value(); for (const auto& param : params) { - *qlset->add_elems() = param->value(); + QLValue::set_value(*param, qlset->add_elems()); } return Status::OK(); } @@ -362,7 +362,7 @@ template CHECKED_STATUS ListConstructor(const vector& params, RTypePtr result) { auto *qllist = result->mutable_list_value(); for (const auto& param : params) { - *qllist->add_elems() = param->value(); + QLValue::set_value(*param, qllist->add_elems()); } return Status::OK(); } @@ -394,8 +394,8 @@ CHECKED_STATUS MapFrozen(const vector& params, RTypePtr result) { auto *frozen_value = result->mutable_frozen_value(); for (auto &elem : map_elems) { - *frozen_value->add_elems() = elem.first.value(); - *frozen_value->add_elems() = elem.second.value(); + QLValue::set_value(elem.first, frozen_value->add_elems()); + QLValue::set_value(elem.second, frozen_value->add_elems()); } return Status::OK(); } @@ -425,7 +425,7 @@ CHECKED_STATUS SetFrozen(const vector& params, RTypePtr result) { auto *frozen_value = result->mutable_frozen_value(); for (auto &elem : set_elems) { - *frozen_value->add_elems() = elem.value(); + QLValue::set_value(elem, frozen_value->add_elems()); } return Status::OK(); } @@ -435,7 +435,7 @@ template CHECKED_STATUS ListFrozen(const vector& params, RTypePtr result) { auto *frozen_value = result->mutable_frozen_value(); for (const auto& param : params) { - *frozen_value->add_elems() = param->value(); + QLValue::set_value(*param, frozen_value->add_elems()); } return Status::OK(); } diff --git a/src/yb/common/CMakeLists.txt b/src/yb/common/CMakeLists.txt index 9cbfeddfa5c7..1e2d4d81c747 100644 --- a/src/yb/common/CMakeLists.txt +++ b/src/yb/common/CMakeLists.txt @@ -48,7 +48,11 @@ ADD_YB_LIBRARY(yb_common_proto NONLINK_DEPS ${COMMON_PROTO_TGTS}) set(COMMON_BASE_SRCS + json_util.cc + jsonb.cc + ql_datatype.cc ql_type.cc + ql_value.cc types.cc ) @@ -71,22 +75,18 @@ set(COMMON_SRCS doc_hybrid_time.cc # must be after hybrid_time.cc id_mapping.cc index.cc - json_util.cc - jsonb.cc key_encoder.cc partial_row.cc pgsql_error.cc placement_info.cc ql_bfunc.cc - ql_datatype.cc ql_expr.cc ql_name.cc ql_protocol_util.cc ql_resultset.cc ql_rowblock.cc + ql_serialization.cc ql_scanspec.cc - ql_type.cc - ql_value.cc pg_types.cc retryable_request.cc roles_permissions.cc @@ -96,7 +96,6 @@ set(COMMON_SRCS snapshot.cc transaction.cc transaction_error.cc - types.cc wire_protocol.cc ybc_util.cc ybc-internal.cc diff --git a/src/yb/common/jsonb.cc b/src/yb/common/jsonb.cc index 3d8465d8f94e..9cf178bb6f60 100644 --- a/src/yb/common/jsonb.cc +++ b/src/yb/common/jsonb.cc @@ -90,12 +90,16 @@ Status Jsonb::FromRapidJson(const rapidjson::Value& value) { return FromRapidJson(document); } -Status Jsonb::FromQLValuePB(const QLValuePB& value_pb) { +Status Jsonb::FromQLValue(const QLValuePB& value_pb) { rapidjson::Document document; RETURN_NOT_OK(ConvertQLValuePBToRapidJson(value_pb, &document)); return FromRapidJson(document); } +Status Jsonb::FromQLValue(const QLValue& value) { + return FromQLValue(value.value()); +} + std::pair Jsonb::ComputeOffsetsAndJsonbHeader(size_t num_entries, uint32_t container_type, std::string* jsonb) { @@ -719,7 +723,8 @@ Status Jsonb::ApplyJsonbOperatorToObject(const Slice& jsonb, const QLJsonOperati return STATUS_SUBSTITUTE(NotFound, "Couldn't find key $0 in json document", search_key); } -Status Jsonb::ApplyJsonbOperators(const QLJsonColumnOperationsPB& json_ops, QLValue* result) const { +Status Jsonb::ApplyJsonbOperators( + const QLJsonColumnOperationsPB& json_ops, QLValuePB* result) const { const int num_ops = json_ops.json_operations().size(); Slice jsonop_result; @@ -731,7 +736,7 @@ Status Jsonb::ApplyJsonbOperators(const QLJsonColumnOperationsPB& json_ops, QLVa &element_metadata); if (s.IsNotFound()) { // We couldn't apply the operator to the operand and hence return null as the result. - result->SetNull(); + SetNull(result); return Status::OK(); } RETURN_NOT_OK(s); @@ -739,7 +744,7 @@ Status Jsonb::ApplyJsonbOperators(const QLJsonColumnOperationsPB& json_ops, QLVa if (IsScalar(element_metadata) && i != num_ops - 1) { // We have to apply another operation after this, but we received a scalar intermediate // result. - result->SetNull(); + SetNull(result); return Status::OK(); } operand = jsonop_result; diff --git a/src/yb/common/jsonb.h b/src/yb/common/jsonb.h index 4bef7f8b76e3..a6d125718cb7 100644 --- a/src/yb/common/jsonb.h +++ b/src/yb/common/jsonb.h @@ -78,7 +78,8 @@ class Jsonb { CHECKED_STATUS FromRapidJson(const rapidjson::Value& value); // Creates a serialized jsonb string from QLValuePB. - CHECKED_STATUS FromQLValuePB(const QLValuePB& value_pb); + CHECKED_STATUS FromQLValue(const QLValuePB& value_pb); + CHECKED_STATUS FromQLValue(const QLValue& value); // Builds a json document from serialized jsonb. CHECKED_STATUS ToRapidJson(rapidjson::Document* document) const; @@ -87,7 +88,7 @@ class Jsonb { CHECKED_STATUS ToJsonString(std::string* json) const; CHECKED_STATUS ApplyJsonbOperators(const QLJsonColumnOperationsPB& json_ops, - QLValue* result) const; + QLValuePB* result) const; const std::string& SerializedJsonb() const; diff --git a/src/yb/common/ql_bfunc.cc b/src/yb/common/ql_bfunc.cc index 0cda7da1b76c..5d8a409a9c4e 100644 --- a/src/yb/common/ql_bfunc.cc +++ b/src/yb/common/ql_bfunc.cc @@ -27,47 +27,22 @@ using std::vector; //-------------------------------------------------------------------------------------------------- // CQL support -using QLBfuncExecApi = yb::bfql::BFExecApi; - -Status QLBfunc::Exec(bfql::BFOpcode opcode, - const vector>& params, - const shared_ptr& result) { - return QLBfuncExecApi::ExecQLOpcode(opcode, params, result); -} - -Status QLBfunc::Exec(bfql::BFOpcode opcode, - const vector& params, - QLValue *result) { - return QLBfuncExecApi::ExecQLOpcode(opcode, params, result); -} - -Status QLBfunc::Exec(bfql::BFOpcode opcode, - vector *params, - QLValue *result) { - return QLBfuncExecApi::ExecQLOpcode(opcode, params, result); +CHECKED_STATUS ExecBfunc( + bfql::BFOpcode opcode, std::vector* params, QLValuePB* result) { + return bfql::BFExecApi::ExecQLOpcode(opcode, params, result); } //-------------------------------------------------------------------------------------------------- // PGSQL support -using PgsqlBfuncExecApi = yb::bfpg::BFExecApi; - -Status PgsqlBfunc::Exec(bfpg::BFOpcode opcode, - const vector>& params, - const shared_ptr& result) { - return PgsqlBfuncExecApi::ExecPgsqlOpcode(opcode, params, result); -} - -Status PgsqlBfunc::Exec(bfpg::BFOpcode opcode, - const vector& params, - QLValue *result) { - return PgsqlBfuncExecApi::ExecPgsqlOpcode(opcode, params, result); +CHECKED_STATUS ExecBfunc( + bfpg::BFOpcode opcode, std::vector* params, QLValuePB *result) { + return bfpg::BFExecApi::ExecPgsqlOpcode(opcode, params, result); } -Status PgsqlBfunc::Exec(bfpg::BFOpcode opcode, - vector *params, - QLValue *result) { - return PgsqlBfuncExecApi::ExecPgsqlOpcode(opcode, params, result); +CHECKED_STATUS ExecBfunc( + bfpg::BFOpcode opcode, std::vector* params, LWQLValuePB *result) { + return bfpg::BFExecApi::ExecPgsqlOpcode(opcode, params, result); } } // namespace yb diff --git a/src/yb/common/ql_bfunc.h b/src/yb/common/ql_bfunc.h index a72ff4db51ab..8ec0aea4cb96 100644 --- a/src/yb/common/ql_bfunc.h +++ b/src/yb/common/ql_bfunc.h @@ -50,38 +50,16 @@ namespace yb { // - Do not add non-static members to this class as QLBfunc is not meant for creating different // objects with different behaviors. For compability reason, all builtin calls must be processed // the same way across all processes and all releases in YugaByte. -class QLBfunc { - public: - static Status Exec(bfql::BFOpcode opcode, - const std::vector>& params, - const std::shared_ptr& result); - - static Status Exec(bfql::BFOpcode opcode, - const std::vector& params, - QLValue *result); - - static Status Exec(bfql::BFOpcode opcode, - std::vector *params, - QLValue *result); -}; +CHECKED_STATUS ExecBfunc( + bfql::BFOpcode opcode, std::vector* params, QLValuePB* result); //-------------------------------------------------------------------------------------------------- // PGSQL support -class PgsqlBfunc { - public: - static Status Exec(bfpg::BFOpcode opcode, - const std::vector>& params, - const std::shared_ptr& result); - - static Status Exec(bfpg::BFOpcode opcode, - const std::vector& params, - QLValue *result); - - static Status Exec(bfpg::BFOpcode opcode, - std::vector *params, - QLValue *result); -}; +CHECKED_STATUS ExecBfunc( + bfpg::BFOpcode opcode, std::vector* params, QLValuePB *result); +CHECKED_STATUS ExecBfunc( + bfpg::BFOpcode opcode, std::vector* params, LWQLValuePB *result); } // namespace yb diff --git a/src/yb/common/ql_expr.cc b/src/yb/common/ql_expr.cc index ce0a0baf72d9..20e95b3c4b92 100644 --- a/src/yb/common/ql_expr.cc +++ b/src/yb/common/ql_expr.cc @@ -20,6 +20,51 @@ constexpr size_t kInvalidIndex = std::numeric_limits::max(); } +template <> +QLExprResultWriter::ExprResultWriter(QLExprResult* result) : result_(result) { + result_->existing_value_ = nullptr; +} + +template <> +void QLExprResultWriter::SetNull() { + yb::SetNull(&result_->value_); +} + +template <> +void QLExprResultWriter::SetExisting(const QLValuePB* existing_value) { + result_->existing_value_ = existing_value; +} + +template <> +QLValuePB& QLExprResultWriter::NewValue() { + return result_->value_; +} + +template <> +LWExprResultWriter::ExprResultWriter(LWExprResult* result) : result_(result) { + result_->value_ = nullptr; +} + +template <> +void LWExprResultWriter::SetExisting(const LWQLValuePB* existing_value) { + if (&existing_value->arena() == result_->arena_) { + result_->value_ = const_cast(existing_value); + } else { + result_->value_ = result_->arena_->NewObject(result_->arena_, *existing_value); + } +} + +template <> +LWQLValuePB& LWExprResultWriter::NewValue() { + result_->value_ = result_->arena_->NewObject(result_->arena_); + return *result_->value_; +} + +template <> +void LWExprResultWriter::SetNull() { + yb::SetNull(&NewValue()); +} + bfql::TSOpcode QLExprExecutor::GetTSWriteInstruction(const QLExpressionPB& ql_expr) const { // "kSubDocInsert" instructs the tablet server to insert a new value or replace an existing value. if (ql_expr.has_tscall()) { @@ -47,7 +92,7 @@ CHECKED_STATUS QLExprExecutor::EvalExpr(const QLExpressionPB& ql_expr, QLExprResult temp; const QLJsonColumnOperationsPB& json_ops = ql_expr.json_column(); RETURN_NOT_OK(table_row.ReadColumn(json_ops.column_id(), temp.Writer())); - if (temp.IsNull()) { + if (IsNull(temp.Value())) { result_writer.SetNull(); } else { common::Jsonb jsonb; @@ -69,7 +114,7 @@ CHECKED_STATUS QLExprExecutor::EvalExpr(const QLExpressionPB& ql_expr, break; case QLExpressionPB::ExprCase::kBfcall: - return EvalBFCall(ql_expr.bfcall(), table_row, &result_writer.NewValue()); + return EvalBFCall(ql_expr.bfcall(), table_row, &result_writer.NewValue()); case QLExpressionPB::ExprCase::kTscall: return EvalTSCall(ql_expr.tscall(), table_row, &result_writer.NewValue(), schema); @@ -98,13 +143,6 @@ CHECKED_STATUS QLExprExecutor::EvalExpr(QLExpressionPB* ql_expr, return Status::OK(); } -CHECKED_STATUS QLExprExecutor::EvalExpr(const PgsqlExpressionPB& ql_expr, - const QLTableRow& table_row, - QLExprResultWriter result_writer, - const Schema *schema) { - return EvalExpr(ql_expr, &table_row, result_writer, schema); -} - //-------------------------------------------------------------------------------------------------- CHECKED_STATUS QLExprExecutor::ReadExprValue(const QLExpressionPB& ql_expr, @@ -119,9 +157,17 @@ CHECKED_STATUS QLExprExecutor::ReadExprValue(const QLExpressionPB& ql_expr, //-------------------------------------------------------------------------------------------------- -CHECKED_STATUS QLExprExecutor::EvalBFCall(const QLBCallPB& bfcall, - const QLTableRow& table_row, - QLValue *result) { +void AddArgs(QLValuePB* result, std::vector* args) { + args->emplace_back(); +} + +void AddArgs(LWQLValuePB* result, std::vector* args) { + args->emplace_back(&result->arena()); +} + +template +CHECKED_STATUS QLExprExecutor::EvalBFCall( + const Expr& bfcall, const QLTableRow& table_row, Value* result) { // TODO(neil) // - Use TSOpode for collection expression if only TabletServer can execute. // OR @@ -137,27 +183,27 @@ CHECKED_STATUS QLExprExecutor::EvalBFCall(const QLBCallPB& bfcall, // "AddListList" // "SubListList" - const bfql::BFOpcode bf_opcode = static_cast(bfcall.opcode()); // First evaluate the arguments. - vector args(bfcall.operands().size()); - int arg_index = 0; - QLExprResult temp; - for (auto operand : bfcall.operands()) { + std::vector args; + args.reserve(bfcall.operands().size()); + ExprResult temp(result); + for (const auto& operand : bfcall.operands()) { RETURN_NOT_OK(EvalExpr(operand, table_row, temp.Writer())); - temp.MoveTo(args[arg_index++].mutable_value()); + AddArgs(result, &args); + temp.MoveTo(&args.back()); } // Execute the builtin call associated with the given opcode. - return QLBfunc::Exec(bf_opcode, &args, result); + return ExecBfunc(static_cast(bfcall.opcode()), &args, result); } //-------------------------------------------------------------------------------------------------- CHECKED_STATUS QLExprExecutor::EvalTSCall(const QLBCallPB& ql_expr, const QLTableRow& table_row, - QLValue *result, + QLValuePB *result, const Schema *schema) { - result->SetNull(); + SetNull(result); return STATUS(RuntimeError, "Only tablet server can execute this operator"); } @@ -173,23 +219,23 @@ CHECKED_STATUS QLExprExecutor::ReadTSCallValue(const QLBCallPB& ql_expr, CHECKED_STATUS QLExprExecutor::EvalCondition(const QLConditionPB& condition, const QLTableRow& table_row, bool* result) { - QLValue result_pb; + QLValuePB result_pb; RETURN_NOT_OK(EvalCondition(condition, table_row, &result_pb)); *result = result_pb.bool_value(); return Status::OK(); } -template +template Result In( - QLExprExecutor* executor, const Operands& operands, const QLTableRow& table_row) { - QLExprResult left, right; - RETURN_NOT_OK(EvalOperands(executor, operands, table_row, left.Writer(), right.Writer())); + QLExprExecutor* executor, const Operands& operands, const QLTableRow& table_row, Res* lhs) { + Res rhs(lhs); + RETURN_NOT_OK(EvalOperands(executor, operands, table_row, lhs->Writer(), rhs.Writer())); - for (const QLValuePB& elem : right.Value().list_value().elems()) { - if (!Comparable(elem, left.Value())) { + for (const auto& elem : rhs.Value().list_value().elems()) { + if (!Comparable(elem, lhs->Value())) { return STATUS(RuntimeError, "values not comparable"); } - if (elem == left.Value()) { + if (elem == lhs->Value()) { return true; } } @@ -197,46 +243,46 @@ Result In( return false; } -template +template Result EvalRelationalOp( - QLExprExecutor* executor, const Operands& operands, const QLTableRow& table_row, const Op& op) { - QLExprResult left, right; - RETURN_NOT_OK(EvalOperands(executor, operands, table_row, left.Writer(), right.Writer())); - if (!Comparable(left.Value(), right.Value())) { + QLExprExecutor* executor, const Operands& operands, const QLTableRow& table_row, const Op& op, + Res* lhs) { + Res rhs(lhs); + RETURN_NOT_OK(EvalOperands(executor, operands, table_row, lhs->Writer(), rhs.Writer())); + if (!Comparable(lhs->Value(), rhs.Value())) { return STATUS(RuntimeError, "values not comparable"); } - return op(left.Value(), right.Value()); + return op(lhs->Value(), rhs.Value()); } -template +template Result Is( - QLExprExecutor* executor, const Operands& operands, const QLTableRow& table_row) { - QLExprResult temp; - RETURN_NOT_OK(EvalOperands(executor, operands, table_row, temp.Writer())); - if (temp.Value().value_case() != InternalType::kBoolValue) { + QLExprExecutor* executor, const Operands& operands, const QLTableRow& table_row, Res* result) { + RETURN_NOT_OK(EvalOperands(executor, operands, table_row, result->Writer())); + if (result->Value().value_case() != InternalType::kBoolValue) { return STATUS(RuntimeError, "not a bool value"); } - return !IsNull(temp.Value()) && temp.Value().bool_value() == Value; + return !IsNull(result->Value()) && result->Value().bool_value() == Value; } -template +template Result Between( - QLExprExecutor* executor, const Operands& operands, const QLTableRow& table_row) { + QLExprExecutor* executor, const Operands& operands, const QLTableRow& table_row, Res* temp) { CHECK_EQ(operands.size(), 3); - QLExprResult temp, lower, upper; + Res lower(temp), upper(temp); RETURN_NOT_OK(EvalOperands( - executor, operands, table_row, temp.Writer(), lower.Writer(), upper.Writer())); - if (!Comparable(temp.Value(), lower.Value()) || !Comparable(temp.Value(), upper.Value())) { + executor, operands, table_row, temp->Writer(), lower.Writer(), upper.Writer())); + if (!Comparable(temp->Value(), lower.Value()) || !Comparable(temp->Value(), upper.Value())) { return STATUS(RuntimeError, "values not comparable"); } - return temp.Value() >= lower.Value() && temp.Value() <= upper.Value(); + return temp->Value() >= lower.Value() && temp->Value() <= upper.Value(); } CHECKED_STATUS QLExprExecutor::EvalCondition(const QLConditionPB& condition, const QLTableRow& table_row, - QLValue *result) { + QLValuePB *result) { #define QL_EVALUATE_RELATIONAL_OP(op) \ - result->set_bool_value(VERIFY_RESULT(EvalRelationalOp(this, operands, table_row, op))); \ + result->set_bool_value(VERIFY_RESULT(EvalRelationalOp(this, operands, table_row, op, &temp))); \ return Status::OK(); QLExprResult temp; @@ -245,7 +291,7 @@ CHECKED_STATUS QLExprExecutor::EvalCondition(const QLConditionPB& condition, case QL_OP_NOT: { CHECK_EQ(operands.size(), 1); CHECK_EQ(operands.Get(0).expr_case(), QLExpressionPB::ExprCase::kCondition); - QLValue sub_result; + QLValuePB sub_result; RETURN_NOT_OK(EvalCondition(operands.Get(0).condition(), table_row, &sub_result)); result->set_bool_value(!sub_result.bool_value()); return Status::OK(); @@ -264,11 +310,11 @@ CHECKED_STATUS QLExprExecutor::EvalCondition(const QLConditionPB& condition, return Status::OK(); case QL_OP_IS_TRUE: - result->set_bool_value(VERIFY_RESULT(Is(this, operands, table_row))); + result->set_bool_value(VERIFY_RESULT(Is(this, operands, table_row, &temp))); return Status::OK(); case QL_OP_IS_FALSE: - result->set_bool_value(VERIFY_RESULT(Is(this, operands, table_row))); + result->set_bool_value(VERIFY_RESULT(Is(this, operands, table_row, &temp))); return Status::OK(); case QL_OP_EQUAL: @@ -312,11 +358,11 @@ CHECKED_STATUS QLExprExecutor::EvalCondition(const QLConditionPB& condition, return Status::OK(); case QL_OP_BETWEEN: - result->set_bool_value(VERIFY_RESULT(Between(this, operands, table_row))); + result->set_bool_value(VERIFY_RESULT(Between(this, operands, table_row, &temp))); return Status::OK(); case QL_OP_NOT_BETWEEN: - result->set_bool_value(!VERIFY_RESULT(Between(this, operands, table_row))); + result->set_bool_value(!VERIFY_RESULT(Between(this, operands, table_row, &temp))); return Status::OK(); // When a row exists, the primary key columns are always populated in the row (value-map) by @@ -332,12 +378,12 @@ CHECKED_STATUS QLExprExecutor::EvalCondition(const QLConditionPB& condition, case QL_OP_IN: CHECK_EQ(operands.size(), 2); - result->set_bool_value(VERIFY_RESULT(In(this, operands, table_row))); + result->set_bool_value(VERIFY_RESULT(In(this, operands, table_row, &temp))); return Status::OK(); case QL_OP_NOT_IN: CHECK_EQ(operands.size(), 2); - result->set_bool_value(!VERIFY_RESULT(In(this, operands, table_row))); + result->set_bool_value(!VERIFY_RESULT(In(this, operands, table_row, &temp))); return Status::OK(); case QL_OP_LIKE: FALLTHROUGH_INTENDED; @@ -349,7 +395,7 @@ CHECKED_STATUS QLExprExecutor::EvalCondition(const QLConditionPB& condition, break; } - result->SetNull(); + SetNull(result); return STATUS(RuntimeError, "Internal error: illegal or unknown operator"); #undef QL_EVALUATE_RELATIONAL_OP @@ -371,6 +417,21 @@ CHECKED_STATUS QLExprExecutor::EvalExpr(const PgsqlExpressionPB& ql_expr, const QLTableRow* table_row, QLExprResultWriter result_writer, const Schema *schema) { + return DoEvalExpr(ql_expr, table_row, result_writer, schema); +} + +CHECKED_STATUS QLExprExecutor::EvalExpr(const LWPgsqlExpressionPB& ql_expr, + const QLTableRow* table_row, + LWExprResultWriter result_writer, + const Schema *schema) { + return DoEvalExpr(ql_expr, table_row, result_writer, schema); +} + +template +CHECKED_STATUS QLExprExecutor::DoEvalExpr(const PB& ql_expr, + const QLTableRow* table_row, + Writer result_writer, + const Schema *schema) { switch (ql_expr.expr_case()) { case PgsqlExpressionPB::ExprCase::kValue: result_writer.SetExisting(&ql_expr.value()); @@ -380,7 +441,7 @@ CHECKED_STATUS QLExprExecutor::EvalExpr(const PgsqlExpressionPB& ql_expr, return EvalColumnRef(ql_expr.column_id(), table_row, result_writer); case PgsqlExpressionPB::ExprCase::kBfcall: - return EvalBFCall(ql_expr.bfcall(), *table_row, &result_writer.NewValue()); + return EvalBFCall(ql_expr.bfcall(), *table_row, &result_writer.NewValue()); case PgsqlExpressionPB::ExprCase::kTscall: return EvalTSCall(ql_expr.tscall(), *table_row, &result_writer.NewValue(), schema); @@ -414,6 +475,18 @@ CHECKED_STATUS QLExprExecutor::ReadExprValue(const PgsqlExpressionPB& ql_expr, CHECKED_STATUS QLExprExecutor::EvalColumnRef(ColumnIdRep col_id, const QLTableRow* table_row, QLExprResultWriter result_writer) { + return DoEvalColumnRef(col_id, table_row, result_writer); +} + +CHECKED_STATUS QLExprExecutor::EvalColumnRef(ColumnIdRep col_id, + const QLTableRow* table_row, + LWExprResultWriter result_writer) { + return DoEvalColumnRef(col_id, table_row, result_writer); +} + +template +CHECKED_STATUS QLExprExecutor::DoEvalColumnRef( + ColumnIdRep col_id, const QLTableRow* table_row, Writer result_writer) { if (table_row == nullptr) { result_writer.SetNull(); } else { @@ -424,35 +497,19 @@ CHECKED_STATUS QLExprExecutor::EvalColumnRef(ColumnIdRep col_id, //-------------------------------------------------------------------------------------------------- -CHECKED_STATUS QLExprExecutor::EvalBFCall(const PgsqlBCallPB& bfcall, +CHECKED_STATUS QLExprExecutor::EvalTSCall(const PgsqlBCallPB& ql_expr, const QLTableRow& table_row, - QLValue *result) { - // TODO(neil) - // - Use TSOpode for collection expression if only TabletServer can execute. - // OR - // - Introduce BuiltinOperator in addition to builtin function. Use builtin operators for all - // special operations including collection operations. That way, we don't need special cases. - - // First, evaluate the arguments. - vector args(bfcall.operands().size()); - int arg_index = 0; - QLExprResult temp; - for (auto operand : bfcall.operands()) { - RETURN_NOT_OK(EvalExpr(operand, &table_row, temp.Writer())); - temp.MoveTo(args[arg_index++].mutable_value()); - } - - // Now, execute the builtin call associated with the given opcode. - return PgsqlBfunc::Exec(static_cast(bfcall.opcode()), &args, result); + QLValuePB *result, + const Schema *schema) { + SetNull(result); + return STATUS(RuntimeError, "Only tablet server can execute this operator"); } -//-------------------------------------------------------------------------------------------------- - -CHECKED_STATUS QLExprExecutor::EvalTSCall(const PgsqlBCallPB& ql_expr, +CHECKED_STATUS QLExprExecutor::EvalTSCall(const LWPgsqlBCallPB& ql_expr, const QLTableRow& table_row, - QLValue *result, + LWQLValuePB *result, const Schema *schema) { - result->SetNull(); + SetNull(result); return STATUS(RuntimeError, "Only tablet server can execute this operator"); } @@ -468,49 +525,48 @@ CHECKED_STATUS QLExprExecutor::ReadTSCallValue(const PgsqlBCallPB& ql_expr, CHECKED_STATUS QLExprExecutor::EvalCondition(const PgsqlConditionPB& condition, const QLTableRow& table_row, bool* result) { - QLValue result_pb; + QLValuePB result_pb; RETURN_NOT_OK(EvalCondition(condition, table_row, &result_pb)); *result = result_pb.bool_value(); return Status::OK(); } -CHECKED_STATUS QLExprExecutor::EvalCondition(const PgsqlConditionPB& condition, - const QLTableRow& table_row, - QLValue *result) { -#define QL_EVALUATE_RELATIONAL_OP(op) \ - result->set_bool_value(VERIFY_RESULT(EvalRelationalOp(this, operands, table_row, op))); \ +template +CHECKED_STATUS QLExprExecutor::EvalCondition( + const PB& condition, const QLTableRow& table_row, Value* result) { +#define QL_EVALUATE_RELATIONAL_OP(op) \ + result->set_bool_value(VERIFY_RESULT(EvalRelationalOp(this, operands, table_row, op, &temp))); \ return Status::OK(); - QLExprResult temp; + ExprResult temp(result); const auto& operands = condition.operands(); switch (condition.op()) { case QL_OP_NOT: { CHECK_EQ(operands.size(), 1); - CHECK_EQ(operands.Get(0).expr_case(), PgsqlExpressionPB::ExprCase::kCondition); - QLValue sub_result; - RETURN_NOT_OK(EvalCondition(operands.Get(0).condition(), table_row, &sub_result)); - result->set_bool_value(!sub_result.bool_value()); + CHECK_EQ(operands.begin()->expr_case(), PgsqlExpressionPB::ExprCase::kCondition); + RETURN_NOT_OK(EvalCondition(operands.begin()->condition(), table_row, &temp.ForceNewValue())); + result->set_bool_value(!temp.Value().bool_value()); return Status::OK(); } case QL_OP_IS_NULL: CHECK_EQ(operands.size(), 1); - RETURN_NOT_OK(EvalExpr(operands.Get(0), table_row, temp.Writer())); + RETURN_NOT_OK(EvalExpr(*operands.begin(), table_row, temp.Writer())); result->set_bool_value(IsNull(temp.Value())); return Status::OK(); case QL_OP_IS_NOT_NULL: CHECK_EQ(operands.size(), 1); - RETURN_NOT_OK(EvalExpr(operands.Get(0), table_row, temp.Writer())); + RETURN_NOT_OK(EvalExpr(*operands.begin(), table_row, temp.Writer())); result->set_bool_value(!IsNull(temp.Value())); return Status::OK(); case QL_OP_IS_TRUE: - result->set_bool_value(VERIFY_RESULT(Is(this, operands, table_row))); + result->set_bool_value(VERIFY_RESULT(Is(this, operands, table_row, &temp))); return Status::OK(); case QL_OP_IS_FALSE: { - result->set_bool_value(VERIFY_RESULT(Is(this, operands, table_row))); + result->set_bool_value(VERIFY_RESULT(Is(this, operands, table_row, &temp))); return Status::OK(); } @@ -555,11 +611,11 @@ CHECKED_STATUS QLExprExecutor::EvalCondition(const PgsqlConditionPB& condition, return Status::OK(); case QL_OP_BETWEEN: - result->set_bool_value(VERIFY_RESULT(Between(this, operands, table_row))); + result->set_bool_value(VERIFY_RESULT(Between(this, operands, table_row, &temp))); return Status::OK(); case QL_OP_NOT_BETWEEN: - result->set_bool_value(!VERIFY_RESULT(Between(this, operands, table_row))); + result->set_bool_value(!VERIFY_RESULT(Between(this, operands, table_row, &temp))); return Status::OK(); // When a row exists, the primary key columns are always populated in the row (value-map) by @@ -575,12 +631,12 @@ CHECKED_STATUS QLExprExecutor::EvalCondition(const PgsqlConditionPB& condition, case QL_OP_IN: CHECK_EQ(operands.size(), 2); - result->set_bool_value(VERIFY_RESULT(In(this, operands, table_row))); + result->set_bool_value(VERIFY_RESULT(In(this, operands, table_row, &temp))); break; case QL_OP_NOT_IN: CHECK_EQ(operands.size(), 2); - result->set_bool_value(!VERIFY_RESULT(In(this, operands, table_row))); + result->set_bool_value(!VERIFY_RESULT(In(this, operands, table_row, &temp))); break; case QL_OP_LIKE: FALLTHROUGH_INTENDED; @@ -592,7 +648,7 @@ CHECKED_STATUS QLExprExecutor::EvalCondition(const PgsqlConditionPB& condition, break; } - result->SetNull(); + SetNull(result); return STATUS(RuntimeError, "Internal error: illegal or unknown operator"); #undef QL_EVALUATE_RELATIONAL_OP @@ -649,17 +705,34 @@ const QLValuePB* QLTableRow::GetColumn(ColumnIdRep col_id) const { return column ? &column->value : nullptr; } -CHECKED_STATUS QLTableRow::ReadColumn(ColumnIdRep col_id, QLExprResultWriter result_writer) const { +void SetColumnValue(const QLValuePB& value, QLExprResultWriter writer) { + writer.SetExisting(&value); +} + +void SetColumnValue(const QLValuePB& value, LWExprResultWriter writer) { + writer.NewValue() = value; +} + +template +CHECKED_STATUS QLTableRow::DoReadColumn(ColumnIdRep col_id, Writer result_writer) const { auto value = GetColumn(col_id); if (value == nullptr) { result_writer.SetNull(); return Status::OK(); } - result_writer.SetExisting(value); + SetColumnValue(*value, result_writer); return Status::OK(); } +CHECKED_STATUS QLTableRow::ReadColumn(ColumnIdRep col_id, QLExprResultWriter result_writer) const { + return DoReadColumn(col_id, result_writer); +} + +CHECKED_STATUS QLTableRow::ReadColumn(ColumnIdRep col_id, LWExprResultWriter result_writer) const { + return DoReadColumn(col_id, result_writer); +} + CHECKED_STATUS QLTableRow::ReadSubscriptedColumn(const QLSubscriptedColPB& subcol, const QLValuePB& index_arg, QLExprResultWriter result_writer) const { @@ -879,24 +952,16 @@ void QLExprResult::MoveToJsonb(common::Jsonb* out) { out->Assign(existing_value_->jsonb_value()); existing_value_ = nullptr; } else { - out->Assign(std::move(*value_.mutable_value()->mutable_jsonb_value())); + out->Assign(std::move(*value_.mutable_jsonb_value())); } } -const QLValuePB& QLExprResult::Value() const { +const QLValuePB& QLExprResult::Value() { if (existing_value_) { return *existing_value_; } - return value_.value(); -} - -bool QLExprResult::IsNull() const { - if (existing_value_) { - return yb::IsNull(*existing_value_); - } - - return value_.IsNull(); + return value_; } void QLExprResult::MoveTo(QLValuePB* out) { @@ -904,11 +969,11 @@ void QLExprResult::MoveTo(QLValuePB* out) { *out = *existing_value_; existing_value_ = nullptr; } else { - value_.mutable_value()->Swap(out); + value_.Swap(out); } } -QLValue& QLExprResult::ForceNewValue() { +QLValuePB& QLExprResult::ForceNewValue() { if (existing_value_) { value_ = *existing_value_; existing_value_ = nullptr; @@ -921,16 +986,34 @@ QLExprResultWriter QLExprResult::Writer() { return QLExprResultWriter(this); } -void QLExprResultWriter::SetNull() { - result_->value_.SetNull(); +void LWExprResult::MoveToJsonb(common::Jsonb* out) { + if (value_) { + out->Assign(value_->jsonb_value().ToBuffer()); + value_ = nullptr; + } } -void QLExprResultWriter::SetExisting(const QLValuePB* existing_value) { - result_->existing_value_ = existing_value; +void LWExprResult::MoveTo(LWQLValuePB* out) { + if (value_) { + *out = *value_; // TODO(LW_PERFORM) + } else { + yb::SetNull(out); + } } -QLValue& QLExprResultWriter::NewValue() { - return result_->value_; +LWQLValuePB& LWExprResult::ForceNewValue() { + return *(value_ = arena_->NewObject(arena_)); +} + +const LWQLValuePB& LWExprResult::Value() { + if (!value_) { + return ForceNewValue(); + } + return *value_; +} + +LWExprResultWriter LWExprResult::Writer() { + return LWExprResultWriter(this); } std::string QLTableColumn::ToString() const { diff --git a/src/yb/common/ql_expr.h b/src/yb/common/ql_expr.h index 1dbe0b74e25f..6b0b7ff5b21a 100644 --- a/src/yb/common/ql_expr.h +++ b/src/yb/common/ql_expr.h @@ -17,6 +17,7 @@ #include "yb/common/common_fwd.h" #include "yb/common/column_id.h" #include "yb/common/ql_value.h" +#include "yb/common/value.messages.h" #include "yb/gutil/casts.h" @@ -48,44 +49,82 @@ struct QLTableColumn { std::string ToString() const; }; -class QLExprResultWriter; +template +class ExprResultWriter; -class QLExprResult { +template +class ExprResult; + +template <> +class ExprResult { public: - const QLValuePB& Value() const; + ExprResult() = default; + explicit ExprResult(QLValuePB* template_value) {} + explicit ExprResult(ExprResult* template_result) {} + + const QLValuePB& Value(); void MoveToJsonb(common::Jsonb* out); void MoveTo(QLValuePB* out); - QLValue& ForceNewValue(); - - QLExprResultWriter Writer(); + QLValuePB& ForceNewValue(); - bool IsNull() const; + ExprResultWriter Writer(); private: - friend class QLExprResultWriter; + friend class ExprResultWriter; - QLValue value_; + QLValuePB value_; const QLValuePB* existing_value_ = nullptr; }; -class QLExprResultWriter { +template <> +class ExprResult { public: - explicit QLExprResultWriter(QLExprResult* result) : result_(result) { - result_->existing_value_ = nullptr; - } + explicit ExprResult(Arena* arena) : arena_(arena) {} + explicit ExprResult(LWQLValuePB* template_value) : arena_(&template_value->arena()) {} + explicit ExprResult(ExprResult* template_result) + : arena_(template_result->arena_) {} + + const LWQLValuePB& Value(); + + void MoveToJsonb(common::Jsonb* out); + + void MoveTo(LWQLValuePB* out); + + LWQLValuePB& ForceNewValue(); + + ExprResultWriter Writer(); + + private: + friend class ExprResultWriter; + + Arena* arena_; + LWQLValuePB* value_ = nullptr; +}; + +template +class ExprResultWriter { + public: + explicit ExprResultWriter(ExprResult* result); void SetNull(); - void SetExisting(const QLValuePB* existing_value); + void SetExisting(const Val* existing_value); + + Val& NewValue(); - QLValue& NewValue(); private: - QLExprResult* result_; + ExprResult* result_; }; +using QLExprResult = ExprResult; +using LWExprResult = ExprResult; + +using QLExprResultWriter = ExprResultWriter; +using LWExprResultWriter = ExprResultWriter; + class QLTableRow { public: // Public types. @@ -159,6 +198,7 @@ class QLTableRow { // Get the column value in PB format. CHECKED_STATUS ReadColumn(ColumnIdRep col_id, QLExprResultWriter result_writer) const; + CHECKED_STATUS ReadColumn(ColumnIdRep col_id, LWExprResultWriter result_writer) const; const QLValuePB* GetColumn(ColumnIdRep col_id) const; CHECKED_STATUS ReadSubscriptedColumn(const QLSubscriptedColPB& subcol, const QLValuePB& index, @@ -183,6 +223,9 @@ class QLTableRow { // Appends new entry to values_ and assigned_ fields. QLTableColumn& AppendColumn(); + template + CHECKED_STATUS DoReadColumn(ColumnIdRep col_id, Writer result_writer) const; + // Map from column id to index in values_ and assigned_ vectors. // For columns from [kFirstColumnId; kFirstColumnId + kPreallocatedSize) we don't use // this field and map them directly. @@ -245,15 +288,14 @@ class QLExprExecutor { const QLTableRow* table_row, QLExprResultWriter result_writer); - // Evaluate call to regular builtin operator. - virtual CHECKED_STATUS EvalBFCall(const QLBCallPB& ql_expr, - const QLTableRow& table_row, - QLValue *result); + virtual CHECKED_STATUS EvalColumnRef(ColumnIdRep col_id, + const QLTableRow* table_row, + LWExprResultWriter result_writer); // Evaluate call to tablet-server builtin operator. virtual CHECKED_STATUS EvalTSCall(const QLBCallPB& ql_expr, const QLTableRow& table_row, - QLValue *result, + QLValuePB *result, const Schema *schema = nullptr); virtual CHECKED_STATUS ReadTSCallValue(const QLBCallPB& ql_expr, @@ -261,18 +303,18 @@ class QLExprExecutor { QLExprResultWriter result_writer); // Evaluate a boolean condition for the given row. - virtual CHECKED_STATUS EvalCondition(const QLConditionPB& condition, - const QLTableRow& table_row, - bool* result); - virtual CHECKED_STATUS EvalCondition(const QLConditionPB& condition, - const QLTableRow& table_row, - QLValue *result); + CHECKED_STATUS EvalCondition(const QLConditionPB& condition, + const QLTableRow& table_row, + bool* result); + CHECKED_STATUS EvalCondition(const QLConditionPB& condition, + const QLTableRow& table_row, + QLValuePB *result); //------------------------------------------------------------------------------------------------ // PGSQL Support. // Get TServer opcode. - yb::bfpg::TSOpcode GetTSWriteInstruction(const PgsqlExpressionPB& ql_expr) const; + bfpg::TSOpcode GetTSWriteInstruction(const PgsqlExpressionPB& ql_expr) const; // Evaluate the given QLExpressionPB. CHECKED_STATUS EvalExpr(const PgsqlExpressionPB& ql_expr, @@ -283,27 +325,35 @@ class QLExprExecutor { CHECKED_STATUS EvalExpr(const PgsqlExpressionPB& ql_expr, const QLTableRow& table_row, QLExprResultWriter result_writer, - const Schema *schema = nullptr); + const Schema *schema = nullptr) { + return EvalExpr(ql_expr, &table_row, result_writer, schema); + } - CHECKED_STATUS EvalExpr(const PgsqlExpressionPB& ql_expr, + CHECKED_STATUS EvalExpr(const LWPgsqlExpressionPB& ql_expr, + const QLTableRow* table_row, + LWExprResultWriter result_writer, + const Schema* schema = nullptr); + + CHECKED_STATUS EvalExpr(const LWPgsqlExpressionPB& ql_expr, const QLTableRow& table_row, - QLValuePB* result, - const Schema *schema = nullptr); + LWExprResultWriter result_writer) { + return EvalExpr(ql_expr, &table_row, result_writer); + } // Read evaluated value from an expression. This is only useful for aggregate function. CHECKED_STATUS ReadExprValue(const PgsqlExpressionPB& ql_expr, const QLTableRow& table_row, QLExprResultWriter result_writer); - // Evaluate call to regular builtin operator. - virtual CHECKED_STATUS EvalBFCall(const PgsqlBCallPB& ql_expr, - const QLTableRow& table_row, - QLValue *result); - // Evaluate call to tablet-server builtin operator. virtual CHECKED_STATUS EvalTSCall(const PgsqlBCallPB& ql_expr, const QLTableRow& table_row, - QLValue *result, + QLValuePB *result, + const Schema *schema = nullptr); + + virtual CHECKED_STATUS EvalTSCall(const LWPgsqlBCallPB& ql_expr, + const QLTableRow& table_row, + LWQLValuePB *result, const Schema *schema = nullptr); virtual CHECKED_STATUS ReadTSCallValue(const PgsqlBCallPB& ql_expr, @@ -311,26 +361,41 @@ class QLExprExecutor { QLExprResultWriter result_writer); // Evaluate a boolean condition for the given row. - virtual CHECKED_STATUS EvalCondition(const PgsqlConditionPB& condition, - const QLTableRow& table_row, - bool* result); - virtual CHECKED_STATUS EvalCondition(const PgsqlConditionPB& condition, - const QLTableRow& table_row, - QLValue *result); + CHECKED_STATUS EvalCondition(const PgsqlConditionPB& condition, + const QLTableRow& table_row, + bool* result); + + template + CHECKED_STATUS EvalCondition( + const PB& condition, const QLTableRow& table_row, Value* result); + + private: + template + CHECKED_STATUS DoEvalColumnRef( + ColumnIdRep col_id, const QLTableRow* table_row, Writer result_writer); + + template + CHECKED_STATUS DoEvalExpr( + const PB& ql_expr, const QLTableRow* table_row, Writer result_writer, const Schema* schema); + + // Evaluate call to regular builtin operator. + template + CHECKED_STATUS EvalBFCall( + const Expr& ql_expr, const QLTableRow& table_row, Value* result); }; -template +template CHECKED_STATUS EvalOperandsHelper( - QLExprExecutor* executor, const Operands& operands, const QLTableRow& table_row, int index) { + QLExprExecutor* executor, It it, const QLTableRow& table_row) { return Status::OK(); } -template +template CHECKED_STATUS EvalOperandsHelper( - QLExprExecutor* executor, const Operands& operands, const QLTableRow& table_row, int index, - QLExprResultWriter arg0, Args&&... args) { - RETURN_NOT_OK(executor->EvalExpr(operands[index], table_row, arg0)); - return EvalOperandsHelper(executor, operands, table_row, index + 1, std::forward(args)...); + QLExprExecutor* executor, It it, const QLTableRow& table_row, + Writer writer, Args&&... args) { + RETURN_NOT_OK(executor->EvalExpr(*it, table_row, writer)); + return EvalOperandsHelper(executor, ++it, table_row, std::forward(args)...); } template @@ -342,7 +407,7 @@ CHECKED_STATUS EvalOperands( sizeof...(Args), operands.size()); } - return EvalOperandsHelper(executor, operands, table_row, 0, std::forward(args)...); + return EvalOperandsHelper(executor, operands.begin(), table_row, std::forward(args)...); } } // namespace yb diff --git a/src/yb/common/ql_resultset.cc b/src/yb/common/ql_resultset.cc index 66ca317c47d5..42e11b50f4c1 100644 --- a/src/yb/common/ql_resultset.cc +++ b/src/yb/common/ql_resultset.cc @@ -5,6 +5,7 @@ #include "yb/common/ql_protocol.pb.h" #include "yb/common/ql_protocol_util.h" +#include "yb/common/ql_serialization.h" #include "yb/common/ql_value.h" namespace yb { @@ -42,12 +43,12 @@ void QLResultSet::AllocateRow() { } void QLResultSet::AppendColumn(const size_t index, const QLValue& value) { - value.Serialize(rsrow_desc_->rscol_descs()[index].ql_type(), YQL_CLIENT_CQL, rows_data_); + SerializeValue( + rsrow_desc_->rscol_descs()[index].ql_type(), YQL_CLIENT_CQL, value.value(), rows_data_); } void QLResultSet::AppendColumn(const size_t index, const QLValuePB& value) { - QLValue::Serialize( - rsrow_desc_->rscol_descs()[index].ql_type(), YQL_CLIENT_CQL, value, rows_data_); + SerializeValue(rsrow_desc_->rscol_descs()[index].ql_type(), YQL_CLIENT_CQL, value, rows_data_); } size_t QLResultSet::rsrow_count() const { diff --git a/src/yb/common/ql_rowblock.cc b/src/yb/common/ql_rowblock.cc index 1eb025cbd51b..8b2d8f321314 100644 --- a/src/yb/common/ql_rowblock.cc +++ b/src/yb/common/ql_rowblock.cc @@ -18,6 +18,7 @@ #include "yb/bfql/bfql.h" #include "yb/common/ql_protocol_util.h" +#include "yb/common/ql_serialization.h" #include "yb/common/ql_value.h" #include "yb/common/schema.h" @@ -54,7 +55,7 @@ const std::shared_ptr& QLRow::column_type(const size_t col_idx) const { void QLRow::Serialize(const QLClient client, faststring* buffer) const { for (size_t col_idx = 0; col_idx < schema_->num_columns(); ++col_idx) { - values_[col_idx].Serialize(column_type(col_idx), client, buffer); + SerializeValue(column_type(col_idx), client, values_[col_idx].value(), buffer); } } diff --git a/src/yb/common/ql_serialization.cc b/src/yb/common/ql_serialization.cc new file mode 100644 index 000000000000..2f3889ad82d6 --- /dev/null +++ b/src/yb/common/ql_serialization.cc @@ -0,0 +1,236 @@ +// Copyright (c) YugaByte, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under the License +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions and limitations +// under the License. +// + +#include "yb/common/ql_serialization.h" + +#include "yb/common/jsonb.h" +#include "yb/common/ql_protocol_util.h" +#include "yb/common/ql_type.h" +#include "yb/common/ql_value.h" + +#include "yb/gutil/casts.h" + +#include "yb/util/date_time.h" +#include "yb/util/decimal.h" + +namespace yb { + +void SerializeValue( + const std::shared_ptr& ql_type, const QLClient& client, const QLValuePB& pb, + faststring* buffer) { + CHECK_EQ(client, YQL_CLIENT_CQL); + if (IsNull(pb)) { + CQLEncodeLength(-1, buffer); + return; + } + + switch (ql_type->main()) { + case INT8: + CQLEncodeNum(Store8, static_cast(pb.int8_value()), buffer); + return; + case INT16: + CQLEncodeNum(NetworkByteOrder::Store16, static_cast(pb.int16_value()), buffer); + return; + case INT32: + CQLEncodeNum(NetworkByteOrder::Store32, pb.int32_value(), buffer); + return; + case INT64: + CQLEncodeNum(NetworkByteOrder::Store64, pb.int64_value(), buffer); + return; + case FLOAT: + CQLEncodeFloat(NetworkByteOrder::Store32, pb.float_value(), buffer); + return; + case DOUBLE: + CQLEncodeFloat(NetworkByteOrder::Store64, pb.double_value(), buffer); + return; + case DECIMAL: { + auto decimal = util::DecimalFromComparable(pb.decimal_value()); + bool is_out_of_range = false; + CQLEncodeBytes(decimal.EncodeToSerializedBigDecimal(&is_out_of_range), buffer); + if(is_out_of_range) { + LOG(ERROR) << "Out of range: Unable to encode decimal " << decimal.ToString() + << " into a BigDecimal serialized representation"; + } + return; + } + case VARINT: { + CQLEncodeBytes(QLValue::varint_value(pb).EncodeToTwosComplement(), buffer); + return; + } + case STRING: + CQLEncodeBytes(pb.string_value(), buffer); + return; + case BOOL: + CQLEncodeNum(Store8, static_cast(pb.bool_value() ? 1 : 0), buffer); + return; + case BINARY: + CQLEncodeBytes(pb.binary_value(), buffer); + return; + case TIMESTAMP: { + int64_t val = DateTime::AdjustPrecision(QLValue::timestamp_value_pb(pb), + DateTime::kInternalPrecision, + DateTime::CqlInputFormat.input_precision); + CQLEncodeNum(NetworkByteOrder::Store64, val, buffer); + return; + } + case DATE: { + CQLEncodeNum(NetworkByteOrder::Store32, pb.date_value(), buffer); + return; + } + case TIME: { + CQLEncodeNum(NetworkByteOrder::Store64, pb.time_value(), buffer); + return; + } + case INET: { + CQLEncodeBytes(QLValue::inetaddress_value(pb).ToBytes(), buffer); + return; + } + case JSONB: { + std::string json; + common::Jsonb jsonb(pb.jsonb_value()); + CHECK_OK(jsonb.ToJsonString(&json)); + CQLEncodeBytes(json, buffer); + return; + } + case UUID: { + std::string bytes; + QLValue::uuid_value(pb).ToBytes(&bytes); + CQLEncodeBytes(bytes, buffer); + return; + } + case TIMEUUID: { + std::string bytes; + Uuid uuid = QLValue::timeuuid_value(pb); + CHECK_OK(uuid.IsTimeUuid()); + uuid.ToBytes(&bytes); + CQLEncodeBytes(bytes, buffer); + return; + } + case MAP: { + const QLMapValuePB& map = pb.map_value(); + DCHECK_EQ(map.keys_size(), map.values_size()); + int32_t start_pos = CQLStartCollection(buffer); + int32_t length = static_cast(map.keys_size()); + CQLEncodeLength(length, buffer); + const auto& keys_type = ql_type->params()[0]; + const auto& values_type = ql_type->params()[1]; + for (int i = 0; i < length; i++) { + SerializeValue(keys_type, client, map.keys(i), buffer); + SerializeValue(values_type, client, map.values(i), buffer); + } + CQLFinishCollection(start_pos, buffer); + return; + } + case SET: { + const QLSeqValuePB& set = pb.set_value(); + int32_t start_pos = CQLStartCollection(buffer); + int32_t length = static_cast(set.elems_size()); + CQLEncodeLength(length, buffer); // number of elements in collection + const auto& elems_type = ql_type->param_type(0); + for (auto& elem : set.elems()) { + SerializeValue(elems_type, client, elem, buffer); + } + CQLFinishCollection(start_pos, buffer); + return; + } + case LIST: { + const QLSeqValuePB& list = pb.list_value(); + int32_t start_pos = CQLStartCollection(buffer); + int32_t length = static_cast(list.elems_size()); + CQLEncodeLength(length, buffer); + const auto& elems_type = ql_type->param_type(0); + for (auto& elem : list.elems()) { + SerializeValue(elems_type, client, elem, buffer); + } + CQLFinishCollection(start_pos, buffer); + return; + } + + case USER_DEFINED_TYPE: { + const QLMapValuePB& map = pb.map_value(); + DCHECK_EQ(map.keys_size(), map.values_size()); + int32_t start_pos = CQLStartCollection(buffer); + + // For every field the UDT has, we try to find a corresponding map entry. If found we + // serialize the value, else null. Map keys should always be in ascending order. + int key_idx = 0; + for (size_t i = 0; i < ql_type->udtype_field_names().size(); i++) { + if (key_idx < map.keys_size() && + implicit_cast(map.keys(key_idx).int16_value()) == i) { + SerializeValue(ql_type->param_type(i), client, map.values(key_idx), buffer); + key_idx++; + } else { // entry not found -> writing null + CQLEncodeLength(-1, buffer); + } + } + + CQLFinishCollection(start_pos, buffer); + return; + } + case FROZEN: { + const QLSeqValuePB& frozen = pb.frozen_value(); + const auto& type = ql_type->param_type(0); + switch (type->main()) { + case MAP: { + DCHECK_EQ(frozen.elems_size() % 2, 0); + int32_t start_pos = CQLStartCollection(buffer); + int32_t length = static_cast(frozen.elems_size() / 2); + CQLEncodeLength(length, buffer); + const auto& keys_type = type->params()[0]; + const auto& values_type = type->params()[1]; + for (int i = 0; i < length; i++) { + SerializeValue(keys_type, client, frozen.elems(2 * i), buffer); + SerializeValue(values_type, client, frozen.elems(2 * i + 1), buffer); + } + CQLFinishCollection(start_pos, buffer); + return; + } + case SET: FALLTHROUGH_INTENDED; + case LIST: { + int32_t start_pos = CQLStartCollection(buffer); + int32_t length = static_cast(frozen.elems_size()); + CQLEncodeLength(length, buffer); // number of elements in collection + const auto& elems_type = type->param_type(0); + for (auto &elem : frozen.elems()) { + SerializeValue(elems_type, client, elem, buffer); + } + CQLFinishCollection(start_pos, buffer); + return; + } + case USER_DEFINED_TYPE: { + int32_t start_pos = CQLStartCollection(buffer); + for (int i = 0; i < frozen.elems_size(); i++) { + SerializeValue(type->param_type(i), client, frozen.elems(i), buffer); + } + CQLFinishCollection(start_pos, buffer); + return; + } + + default: + break; + } + break; + } + + QL_UNSUPPORTED_TYPES_IN_SWITCH: + break; + + QL_INVALID_TYPES_IN_SWITCH: + break; + // default: fall through + } + + LOG(FATAL) << "Internal error: unsupported type " << ql_type->ToString(); +} + +} // namespace yb diff --git a/src/yb/common/ql_serialization.h b/src/yb/common/ql_serialization.h new file mode 100644 index 000000000000..bfde901b1529 --- /dev/null +++ b/src/yb/common/ql_serialization.h @@ -0,0 +1,30 @@ +// Copyright (c) YugaByte, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software distributed under the License +// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions and limitations +// under the License. +// + +#ifndef YB_COMMON_QL_SERIALIZATION_H +#define YB_COMMON_QL_SERIALIZATION_H + +#include "yb/common/common_fwd.h" +#include "yb/common/common_types.pb.h" + +#include "yb/util/faststring.h" + +namespace yb { + +void SerializeValue( + const std::shared_ptr& ql_type, const QLClient& client, const QLValuePB& pb, + faststring* buffer); + +} // namespace yb + +#endif // YB_COMMON_QL_SERIALIZATION_H diff --git a/src/yb/common/ql_value.cc b/src/yb/common/ql_value.cc index 0f5e8fb94153..81d2d0d7f79c 100644 --- a/src/yb/common/ql_value.cc +++ b/src/yb/common/ql_value.cc @@ -55,8 +55,6 @@ static int GenericCompare(const T& lhs, const T& rhs) { return 0; } -QLValue::~QLValue() {} - //------------------------- instance methods for abstract QLValue class ----------------------- int QLValue::CompareTo(const QLValue& other) const { @@ -266,219 +264,6 @@ void AppendToKey(const LWQLValuePB &value_pb, std::string *bytes) { DoAppendToKey(value_pb, bytes); } -void QLValue::Serialize( - const std::shared_ptr& ql_type, const QLClient& client, const QLValuePB& pb, - faststring* buffer) { - CHECK_EQ(client, YQL_CLIENT_CQL); - if (IsNull(pb)) { - CQLEncodeLength(-1, buffer); - return; - } - - switch (ql_type->main()) { - case INT8: - CQLEncodeNum(Store8, static_cast(int8_value(pb)), buffer); - return; - case INT16: - CQLEncodeNum(NetworkByteOrder::Store16, static_cast(int16_value(pb)), buffer); - return; - case INT32: - CQLEncodeNum(NetworkByteOrder::Store32, int32_value(pb), buffer); - return; - case INT64: - CQLEncodeNum(NetworkByteOrder::Store64, int64_value(pb), buffer); - return; - case FLOAT: - CQLEncodeFloat(NetworkByteOrder::Store32, float_value(pb), buffer); - return; - case DOUBLE: - CQLEncodeFloat(NetworkByteOrder::Store64, double_value(pb), buffer); - return; - case DECIMAL: { - auto decimal = util::DecimalFromComparable(decimal_value(pb)); - bool is_out_of_range = false; - CQLEncodeBytes(decimal.EncodeToSerializedBigDecimal(&is_out_of_range), buffer); - if(is_out_of_range) { - LOG(ERROR) << "Out of range: Unable to encode decimal " << decimal.ToString() - << " into a BigDecimal serialized representation"; - } - return; - } - case VARINT: { - CQLEncodeBytes(varint_value(pb).EncodeToTwosComplement(), buffer); - return; - } - case STRING: - CQLEncodeBytes(string_value(pb), buffer); - return; - case BOOL: - CQLEncodeNum(Store8, static_cast(bool_value(pb) ? 1 : 0), buffer); - return; - case BINARY: - CQLEncodeBytes(binary_value(pb), buffer); - return; - case TIMESTAMP: { - int64_t val = DateTime::AdjustPrecision(timestamp_value_pb(pb), - DateTime::kInternalPrecision, - DateTime::CqlInputFormat.input_precision); - CQLEncodeNum(NetworkByteOrder::Store64, val, buffer); - return; - } - case DATE: { - CQLEncodeNum(NetworkByteOrder::Store32, date_value(pb), buffer); - return; - } - case TIME: { - CQLEncodeNum(NetworkByteOrder::Store64, time_value(pb), buffer); - return; - } - case INET: { - CQLEncodeBytes(inetaddress_value(pb).ToBytes(), buffer); - return; - } - case JSONB: { - std::string json; - Jsonb jsonb(jsonb_value(pb)); - CHECK_OK(jsonb.ToJsonString(&json)); - CQLEncodeBytes(json, buffer); - return; - } - case UUID: { - std::string bytes; - uuid_value(pb).ToBytes(&bytes); - CQLEncodeBytes(bytes, buffer); - return; - } - case TIMEUUID: { - std::string bytes; - Uuid uuid = timeuuid_value(pb); - CHECK_OK(uuid.IsTimeUuid()); - uuid.ToBytes(&bytes); - CQLEncodeBytes(bytes, buffer); - return; - } - case MAP: { - const QLMapValuePB& map = map_value(pb); - DCHECK_EQ(map.keys_size(), map.values_size()); - int32_t start_pos = CQLStartCollection(buffer); - int32_t length = static_cast(map.keys_size()); - CQLEncodeLength(length, buffer); - const shared_ptr& keys_type = ql_type->params()[0]; - const shared_ptr& values_type = ql_type->params()[1]; - for (int i = 0; i < length; i++) { - QLValue::Serialize(keys_type, client, map.keys(i), buffer); - QLValue::Serialize(values_type, client, map.values(i), buffer); - } - CQLFinishCollection(start_pos, buffer); - return; - } - case SET: { - const QLSeqValuePB& set = set_value(pb); - int32_t start_pos = CQLStartCollection(buffer); - int32_t length = static_cast(set.elems_size()); - CQLEncodeLength(length, buffer); // number of elements in collection - const shared_ptr& elems_type = ql_type->param_type(0); - for (auto& elem : set.elems()) { - QLValue::Serialize(elems_type, client, elem, buffer); - } - CQLFinishCollection(start_pos, buffer); - return; - } - case LIST: { - const QLSeqValuePB& list = list_value(pb); - int32_t start_pos = CQLStartCollection(buffer); - int32_t length = static_cast(list.elems_size()); - CQLEncodeLength(length, buffer); - const shared_ptr& elems_type = ql_type->param_type(0); - for (auto& elem : list.elems()) { - QLValue::Serialize(elems_type, client, elem, buffer); - } - CQLFinishCollection(start_pos, buffer); - return; - } - - case USER_DEFINED_TYPE: { - const QLMapValuePB& map = map_value(pb); - DCHECK_EQ(map.keys_size(), map.values_size()); - int32_t start_pos = CQLStartCollection(buffer); - - // For every field the UDT has, we try to find a corresponding map entry. If found we - // serialize the value, else null. Map keys should always be in ascending order. - int key_idx = 0; - for (size_t i = 0; i < ql_type->udtype_field_names().size(); i++) { - if (key_idx < map.keys_size() && - implicit_cast(map.keys(key_idx).int16_value()) == i) { - QLValue::Serialize(ql_type->param_type(i), client, map.values(key_idx), buffer); - key_idx++; - } else { // entry not found -> writing null - CQLEncodeLength(-1, buffer); - } - } - - CQLFinishCollection(start_pos, buffer); - return; - } - case FROZEN: { - const QLSeqValuePB& frozen = frozen_value(pb); - const auto& type = ql_type->param_type(0); - switch (type->main()) { - case MAP: { - DCHECK_EQ(frozen.elems_size() % 2, 0); - int32_t start_pos = CQLStartCollection(buffer); - int32_t length = static_cast(frozen.elems_size() / 2); - CQLEncodeLength(length, buffer); - const shared_ptr &keys_type = type->params()[0]; - const shared_ptr &values_type = type->params()[1]; - for (int i = 0; i < length; i++) { - QLValue::Serialize(keys_type, client, frozen.elems(2 * i), buffer); - QLValue::Serialize(values_type, client, frozen.elems(2 * i + 1), buffer); - } - CQLFinishCollection(start_pos, buffer); - return; - } - case SET: FALLTHROUGH_INTENDED; - case LIST: { - int32_t start_pos = CQLStartCollection(buffer); - int32_t length = static_cast(frozen.elems_size()); - CQLEncodeLength(length, buffer); // number of elements in collection - const shared_ptr &elems_type = type->param_type(0); - for (auto &elem : frozen.elems()) { - QLValue::Serialize(elems_type, client, elem, buffer); - } - CQLFinishCollection(start_pos, buffer); - return; - } - case USER_DEFINED_TYPE: { - int32_t start_pos = CQLStartCollection(buffer); - for (int i = 0; i < frozen.elems_size(); i++) { - QLValue::Serialize(type->param_type(i), client, frozen.elems(i), buffer); - } - CQLFinishCollection(start_pos, buffer); - return; - } - - default: - break; - } - break; - } - - QL_UNSUPPORTED_TYPES_IN_SWITCH: - break; - - QL_INVALID_TYPES_IN_SWITCH: - break; - // default: fall through - } - - LOG(FATAL) << "Internal error: unsupported type " << ql_type->ToString(); -} - -void QLValue::Serialize( - const std::shared_ptr& ql_type, const QLClient& client, faststring* buffer) const { - return Serialize(ql_type, client, pb_, buffer); -} - Status CheckForNull(const QLValue& val) { return val.IsNull() ? STATUS(InvalidArgument, "null is not supported inside collections") : Status::OK(); @@ -574,7 +359,7 @@ Status QLValue::Deserialize( string bytes; RETURN_NOT_OK(CQLDecodeBytes(len, data, &bytes)); InetAddress addr; - RETURN_NOT_OK(addr.FromBytes(bytes)); + RETURN_NOT_OK(addr.FromSlice(bytes)); set_inetaddress_value(addr); return Status::OK(); } @@ -952,14 +737,37 @@ util::VarInt QLValue::varint_value(const QLValuePB& pb) { return varint; } +util::VarInt QLValue::varint_value(const LWQLValuePB& pb) { + CHECK(pb.has_varint_value()) << "Value: " << pb.ShortDebugString(); + util::VarInt varint; + size_t num_decoded_bytes; + CHECK_OK(varint.DecodeFromComparable(pb.varint_value(), &num_decoded_bytes)); + return varint; +} + void QLValue::set_inetaddress_value(const InetAddress& val, QLValuePB* pb) { pb->mutable_inetaddress_value()->clear(); val.AppendToBytes(pb->mutable_inetaddress_value()); } -void QLValue::set_timeuuid_value(const Uuid& val) { +void QLValue::set_timeuuid_value(const Uuid& val, LWQLValuePB* out) { + CHECK_OK(val.IsTimeUuid()); + auto* dest = static_cast(out->arena().AllocateBytes(kUuidSize)); + val.ToBytes(dest); + out->ref_timeuuid_value(Slice(dest, kUuidSize)); +} + +void QLValue::set_timeuuid_value(const Uuid& val, QLValuePB* out) { CHECK_OK(val.IsTimeUuid()); - val.ToBytes(pb_.mutable_timeuuid_value()); + val.ToBytes(out->mutable_timeuuid_value()); +} + +void QLValue::set_timeuuid_value(const Uuid& val, QLValue* out) { + set_timeuuid_value(val, out->mutable_value()); +} + +void QLValue::set_timeuuid_value(const Uuid& val) { + set_timeuuid_value(val, this); } template @@ -1034,47 +842,115 @@ bool IsNull(const LWQLValuePB& v) { void SetNull(QLValuePB* v) { v->Clear(); } + +void SetNull(LWQLValuePB* v) { + v->Clear(); +} + bool EitherIsNull(const QLValuePB& lhs, const QLValuePB& rhs) { return IsNull(lhs) || IsNull(rhs); } + +bool EitherIsNull(const LWQLValuePB& lhs, const LWQLValuePB& rhs) { + return IsNull(lhs) || IsNull(rhs); +} + bool BothNotNull(const QLValuePB& lhs, const QLValuePB& rhs) { return !IsNull(lhs) && !IsNull(rhs); } + bool BothNull(const QLValuePB& lhs, const QLValuePB& rhs) { return IsNull(lhs) && IsNull(rhs); } + +bool BothNull(const LWQLValuePB& lhs, const LWQLValuePB& rhs) { + return IsNull(lhs) && IsNull(rhs); +} + bool EitherIsVirtual(const QLValuePB& lhs, const QLValuePB& rhs) { return lhs.value_case() == QLValuePB::kVirtualValue || rhs.value_case() == QLValuePB::kVirtualValue; } -bool Comparable(const QLValuePB& lhs, const QLValuePB& rhs) { + +bool EitherIsVirtual(const LWQLValuePB& lhs, const LWQLValuePB& rhs) { + return lhs.value_case() == QLValuePB::kVirtualValue || + rhs.value_case() == QLValuePB::kVirtualValue; +} + +template +bool DoComparable(const PB& lhs, const PB& rhs) { return (lhs.value_case() == rhs.value_case() || EitherIsNull(lhs, rhs) || EitherIsVirtual(lhs, rhs)); } + +bool Comparable(const QLValuePB& lhs, const QLValuePB& rhs) { + return DoComparable(lhs, rhs); +} + +bool Comparable(const LWQLValuePB& lhs, const LWQLValuePB& rhs) { + return DoComparable(lhs, rhs); +} + bool EitherIsNull(const QLValuePB& lhs, const QLValue& rhs) { return IsNull(lhs) || rhs.IsNull(); } + bool EitherIsVirtual(const QLValuePB& lhs, const QLValue& rhs) { return lhs.value_case() == QLValuePB::kVirtualValue || rhs.IsVirtual(); } + bool Comparable(const QLValuePB& lhs, const QLValue& rhs) { return (lhs.value_case() == rhs.type() || EitherIsNull(lhs, rhs) || EitherIsVirtual(lhs, rhs)); } + bool BothNotNull(const QLValuePB& lhs, const QLValue& rhs) { return !IsNull(lhs) && !rhs.IsNull(); } + +bool BothNotNull(const LWQLValuePB& lhs, const LWQLValuePB& rhs) { + return !IsNull(lhs) && !IsNull(rhs); +} + bool BothNull(const QLValuePB& lhs, const QLValue& rhs) { return IsNull(lhs) && rhs.IsNull(); } -int Compare(const QLValuePB& lhs, const QLValuePB& rhs) { + +template +int SeqCompare(const Seq& lhs, const Seq& rhs) { + // Compare elements one by one. + auto min_size = std::min(lhs.elems().size(), rhs.elems().size()); + auto li = lhs.elems().begin(); + auto ri = rhs.elems().begin(); + for (auto i = min_size; i > 0; --i, ++li, ++ri) { + if (IsNull(*li)) { + if (!IsNull(*ri)) { + return -1; + } + } else { + if (IsNull(*ri)) { + return 1; + } + int result = DoCompare(*li, *ri); + if (result != 0) { + return result; + } + } + } + + // If elements are equal, compare lengths. + return GenericCompare(lhs.elems().size(), rhs.elems().size()); +} + +template +int DoCompare(const PB& lhs, const PB& rhs) { if (rhs.value_case() == QLValuePB::kVirtualValue && lhs.value_case() != QLValuePB::kVirtualValue) { - return -Compare(rhs, lhs); + return -DoCompare(rhs, lhs); } - CHECK(Comparable(lhs, rhs)); + CHECK(DoComparable(lhs, rhs)); CHECK(BothNotNull(lhs, rhs)); switch (lhs.value_case()) { case QLValuePB::kInt8Value: return GenericCompare(lhs.int8_value(), rhs.int8_value()); @@ -1118,7 +994,7 @@ int Compare(const QLValuePB& lhs, const QLValuePB& rhs) { case QLValuePB::kTimeuuidValue: return GenericCompare(QLValue::timeuuid_value(lhs), QLValue::timeuuid_value(rhs)); case QLValuePB::kFrozenValue: - return Compare(lhs.frozen_value(), rhs.frozen_value()); + return SeqCompare(lhs.frozen_value(), rhs.frozen_value()); case QLValuePB::kMapValue: FALLTHROUGH_INTENDED; case QLValuePB::kSetValue: FALLTHROUGH_INTENDED; case QLValuePB::kListValue: @@ -1145,6 +1021,15 @@ int Compare(const QLValuePB& lhs, const QLValuePB& rhs) { return 0; } + +int Compare(const QLValuePB& lhs, const QLValuePB& rhs) { + return DoCompare(lhs, rhs); +} + +int Compare(const LWQLValuePB& lhs, const LWQLValuePB& rhs) { + return DoCompare(lhs, rhs); +} + int Compare(const QLValuePB& lhs, const QLValue& rhs) { if (rhs.IsVirtual() && lhs.value_case() != QLValuePB::kVirtualValue) { return -Compare(rhs.value(), lhs); @@ -1221,26 +1106,7 @@ int Compare(const QLValuePB& lhs, const QLValue& rhs) { } int Compare(const QLSeqValuePB& lhs, const QLSeqValuePB& rhs) { - // Compare elements one by one. - int result = 0; - int min_size = std::min(lhs.elems_size(), rhs.elems_size()); - for (int i = 0; i < min_size; i++) { - bool lhs_is_null = IsNull(lhs.elems(i)); - bool rhs_is_null = IsNull(rhs.elems(i)); - - if (lhs_is_null && rhs_is_null) result = 0; - else if (lhs_is_null) result = -1; - else if (rhs_is_null) result = 1; - else - result = Compare(lhs.elems(i), rhs.elems(i)); - - if (result != 0) { - return result; - } - } - - // If elements are equal, compare lengths. - return GenericCompare(lhs.elems_size(), rhs.elems_size()); + return SeqCompare(lhs, rhs); } int Compare(const bool lhs, const bool rhs) { @@ -1296,4 +1162,45 @@ bool operator !=(const QLValuePB& lhs, const QLValue& rhs) { return !(lhs == rhs); } +bool operator <(const LWQLValuePB& lhs, const LWQLValuePB& rhs) { + return BothNotNull(lhs, rhs) && Compare(lhs, rhs) < 0; +} +bool operator >(const LWQLValuePB& lhs, const LWQLValuePB& rhs) { + return BothNotNull(lhs, rhs) && Compare(lhs, rhs) > 0; +} + +// In YCQL equality holds for null values. +bool operator <=(const LWQLValuePB& lhs, const LWQLValuePB& rhs) { + return (BothNotNull(lhs, rhs) && Compare(lhs, rhs) <= 0) || BothNull(lhs, rhs); +} +bool operator >=(const LWQLValuePB& lhs, const LWQLValuePB& rhs) { + return (BothNotNull(lhs, rhs) && Compare(lhs, rhs) >= 0) || BothNull(lhs, rhs); +} + +bool operator ==(const LWQLValuePB& lhs, const LWQLValuePB& rhs) { + if (IsNull(lhs)) { + return IsNull(rhs); + } + return !IsNull(rhs) && DoCompare(lhs, rhs) == 0; +} + +bool operator !=(const LWQLValuePB& lhs, const LWQLValuePB& rhs) { + return !(lhs == rhs); +} + +void ConcatStrings(const std::string& lhs, const std::string& rhs, QLValuePB* result) { + result->set_string_value(lhs + rhs); +} + +void ConcatStrings(const std::string& lhs, const std::string& rhs, QLValue* result) { + ConcatStrings(lhs, rhs, result->mutable_value()); +} + +void ConcatStrings(const Slice& lhs, const Slice& rhs, LWQLValuePB* result) { + auto* data = static_cast(result->arena().AllocateBytes(lhs.size() + rhs.size())); + memcpy(data, lhs.cdata(), lhs.size()); + memcpy(data + lhs.size(), rhs.cdata(), rhs.size()); + result->ref_string_value(Slice(data, lhs.size() + rhs.size())); +} + } // namespace yb diff --git a/src/yb/common/ql_value.h b/src/yb/common/ql_value.h index 22cfb0e82208..6542a4d0cb93 100644 --- a/src/yb/common/ql_value.h +++ b/src/yb/common/ql_value.h @@ -62,11 +62,12 @@ class QLValue { QLValue() { } explicit QLValue(const QLValuePB& pb) : pb_(pb) { } explicit QLValue(QLValuePB&& pb) : pb_(std::move(pb)) { } - virtual ~QLValue(); //----------------------------------------------------------------------------------------- // Access functions to value and type. InternalType type() const { return pb_.value_case(); } + InternalType value_case() const { return pb_.value_case(); } + const QLValuePB& value() const { return pb_; } QLValuePB* mutable_value() { return &pb_; } @@ -495,14 +496,6 @@ class QLValue { } //----------------------------- serializer / deserializer --------------------------------- - static void Serialize(const std::shared_ptr& ql_type, - const QLClient& client, - const QLValuePB& pb, - faststring* buffer); - - void Serialize(const std::shared_ptr& ql_type, - const QLClient& client, - faststring* buffer) const; CHECKED_STATUS Deserialize(const std::shared_ptr& ql_type, const QLClient& client, Slice* data); @@ -561,12 +554,25 @@ bool operator ==(const LWQLValuePB& lhs, const LWQLValuePB& rhs); bool operator !=(const LWQLValuePB& lhs, const LWQLValuePB& rhs); InternalType type(const QLValuePB& v); + bool IsNull(const QLValuePB& v); + +inline bool IsNull(const QLValue& v) { + return IsNull(v.value()); +} + void SetNull(QLValuePB* v); +void SetNull(LWQLValuePB* v); + +inline void SetNull(QLValue* v) { + SetNull(v->mutable_value()); +} + bool EitherIsNull(const QLValuePB& lhs, const QLValuePB& rhs); bool BothNotNull(const QLValuePB& lhs, const QLValuePB& rhs); bool BothNull(const QLValuePB& lhs, const QLValuePB& rhs); bool Comparable(const QLValuePB& lhs, const QLValuePB& rhs); +bool Comparable(const LWQLValuePB& lhs, const LWQLValuePB& rhs); int Compare(const QLValuePB& lhs, const QLValuePB& rhs); bool EitherIsNull(const QLValuePB& lhs, const QLValue& rhs); bool Comparable(const QLValuePB& lhs, const QLValue& rhs); @@ -578,6 +584,14 @@ int Compare(const bool lhs, const bool rhs); bool IsNull(const LWQLValuePB& v); +inline void AppendToKey(const QLValue &value_pb, std::string *bytes) { + AppendToKey(value_pb.value(), bytes); +} + +void ConcatStrings(const std::string& lhs, const std::string& rhs, QLValuePB* result); +void ConcatStrings(const std::string& lhs, const std::string& rhs, QLValue* result); +void ConcatStrings(const Slice& lhs, const Slice& rhs, LWQLValuePB* result); + #define YB_SET_INT_VALUE(ql_valuepb, input, bits) \ case DataType::BOOST_PP_CAT(INT, bits): { \ auto value = CheckedStoInt(input); \ diff --git a/src/yb/docdb/CMakeLists.txt b/src/yb/docdb/CMakeLists.txt index dadd97daa4a2..3e5b3123d6aa 100644 --- a/src/yb/docdb/CMakeLists.txt +++ b/src/yb/docdb/CMakeLists.txt @@ -84,7 +84,6 @@ set(DOCDB_SRCS compaction_file_filter.cc intent_aware_iterator.cc lock_batch.cc - packed_row.cc pgsql_operation.cc ql_rocksdb_storage.cc ql_rowwise_iterator_interface.cc @@ -148,7 +147,6 @@ ADD_YB_TEST(doc_operation-test) ADD_YB_TEST(docdb_rocksdb_util-test) ADD_YB_TEST(docdb-test) ADD_YB_TEST(docrowwiseiterator-test) -ADD_YB_TEST(packed_row-test) ADD_YB_TEST(primitive_value-test) ADD_YB_TEST(randomized_docdb-test) ADD_YB_TEST(shared_lock_manager-test) diff --git a/src/yb/docdb/doc_expr.cc b/src/yb/docdb/doc_expr.cc index ec947555bf3e..d0512e16dc0c 100644 --- a/src/yb/docdb/doc_expr.cc +++ b/src/yb/docdb/doc_expr.cc @@ -11,7 +11,7 @@ #include "yb/common/jsonb.h" #include "yb/common/pg_system_attr.h" -#include "yb/common/pgsql_protocol.pb.h" +#include "yb/common/pgsql_protocol.messages.h" #include "yb/common/ql_datatype.h" #include "yb/common/ql_type.h" #include "yb/common/ql_value.h" @@ -64,8 +64,8 @@ CHECKED_STATUS DocExprExecutor::EvalColumnRef(ColumnIdRep col_id, return STATUS_SUBSTITUTE(InvalidArgument, "Invalid column ID: $0", col_id); } -CHECKED_STATUS DocExprExecutor::GetTupleId(QLValue *result) const { - result->SetNull(); +CHECKED_STATUS DocExprExecutor::GetTupleId(QLValuePB *result) const { + SetNull(result); return Status::OK(); } @@ -73,7 +73,7 @@ CHECKED_STATUS DocExprExecutor::GetTupleId(QLValue *result) const { CHECKED_STATUS DocExprExecutor::EvalTSCall(const QLBCallPB& tscall, const QLTableRow& table_row, - QLValue *result, + QLValuePB *result, const Schema *schema) { bfql::TSOpcode tsopcode = static_cast(tscall.opcode()); switch (tsopcode) { @@ -90,7 +90,7 @@ CHECKED_STATUS DocExprExecutor::EvalTSCall(const QLBCallPB& tscall, if (ttl_seconds != -1) { result->set_int64_value(ttl_seconds); } else { - result->SetNull(); + SetNull(result); } return Status::OK(); } @@ -146,14 +146,14 @@ CHECKED_STATUS DocExprExecutor::EvalTSCall(const QLBCallPB& tscall, // Return the value of the second operand. The first operand must be a column ID. QLExprResult temp; RETURN_NOT_OK(EvalExpr(tscall.operands(1), table_row, temp.Writer())); - temp.MoveTo(result->mutable_value()); + temp.MoveTo(result); return Status::OK(); } case bfql::TSOpcode::kListPrepend: { // Return the value of the first operand. The second operand is a column ID. QLExprResult temp; RETURN_NOT_OK(EvalExpr(tscall.operands(0), table_row, temp.Writer())); - temp.MoveTo(result->mutable_value()); + temp.MoveTo(result); return Status::OK(); } case bfql::TSOpcode::kListRemove: { @@ -166,7 +166,7 @@ CHECKED_STATUS DocExprExecutor::EvalTSCall(const QLBCallPB& tscall, org_list_result.MoveTo(org_list_value.mutable_value()); sub_list_result.MoveTo(sub_list_value.mutable_value()); - result->set_list_value(); + result->mutable_list_value(); if (!org_list_value.IsNull() && !sub_list_value.IsNull()) { QLSeqValuePB* org_list = org_list_value.mutable_list_value(); QLSeqValuePB* sub_list = sub_list_value.mutable_list_value(); @@ -179,7 +179,7 @@ CHECKED_STATUS DocExprExecutor::EvalTSCall(const QLBCallPB& tscall, } } if (!should_remove) { - *result->add_list_elem() = std::move(org_elem); + *result->mutable_list_value()->add_elems() = std::move(org_elem); } } } @@ -190,27 +190,42 @@ CHECKED_STATUS DocExprExecutor::EvalTSCall(const QLBCallPB& tscall, return EvalParametricToJson(tscall.operands(0), table_row, result, schema); } - result->SetNull(); + SetNull(result); return Status::OK(); } -CHECKED_STATUS DocExprExecutor::EvalTSCall(const PgsqlBCallPB& tscall, +CHECKED_STATUS DocExprExecutor::EvalTSCall(const PgsqlBCallPB& ql_expr, const QLTableRow& table_row, - QLValue *result, + QLValuePB *result, const Schema *schema) { + return DoEvalTSCall(ql_expr, table_row, result, schema); +} + +CHECKED_STATUS DocExprExecutor::EvalTSCall(const LWPgsqlBCallPB& ql_expr, + const QLTableRow& table_row, + LWQLValuePB *result, + const Schema *schema) { + return DoEvalTSCall(ql_expr, table_row, result, schema); +} + +template +CHECKED_STATUS DocExprExecutor::DoEvalTSCall(const Expr& tscall, + const QLTableRow& table_row, + Res *result, + const Schema *schema) { bfpg::TSOpcode tsopcode = static_cast(tscall.opcode()); switch (tsopcode) { case bfpg::TSOpcode::kCount: { - const auto& operand = tscall.operands(0); + const auto& operand = *tscall.operands().begin(); if (operand.has_column_id()) { // Check if column value is NULL. Postgres does not count NULL value of a column, unless // it's COUNT(*). - QLExprResult arg_result; + ExprResult arg_result(result); RETURN_NOT_OK(EvalExpr(operand, table_row, arg_result.Writer())); if (IsNull(arg_result.Value())) { return Status::OK(); } - } else if (operand.has_value() && QLValue::IsNull(operand.value())) { + } else if (operand.has_value() && IsNull(operand.value())) { // We've got COUNT(null) which is bound to return zero. return Status::OK(); } @@ -218,46 +233,46 @@ CHECKED_STATUS DocExprExecutor::EvalTSCall(const PgsqlBCallPB& tscall, } case bfpg::TSOpcode::kSumInt8: - return EvalSumInt(tscall.operands(0), table_row, result, [](const QLValuePB& value) { + return EvalSumInt(*tscall.operands().begin(), table_row, result, [](const Res& value) { return value.int8_value(); }); case bfpg::TSOpcode::kSumInt16: - return EvalSumInt(tscall.operands(0), table_row, result, [](const QLValuePB& value) { + return EvalSumInt(*tscall.operands().begin(), table_row, result, [](const Res& value) { return value.int16_value(); }); case bfpg::TSOpcode::kSumInt32: - return EvalSumInt(tscall.operands(0), table_row, result, [](const QLValuePB& value) { + return EvalSumInt(*tscall.operands().begin(), table_row, result, [](const Res& value) { return value.int32_value(); }); case bfpg::TSOpcode::kSumInt64: - return EvalSumInt(tscall.operands(0), table_row, result, [](const QLValuePB& value) { + return EvalSumInt(*tscall.operands().begin(), table_row, result, [](const Res& value) { return value.int64_value(); }); case bfpg::TSOpcode::kSumFloat: return EvalSumReal( - tscall.operands(0), table_row, result, - [](const QLValuePB& value) { return value.float_value(); }, - [](float value, QLValuePB* out) { return out->set_float_value(value); }); + *tscall.operands().begin(), table_row, result, + [](const Res& value) { return value.float_value(); }, + [](float value, Res* out) { return out->set_float_value(value); }); case bfpg::TSOpcode::kSumDouble: return EvalSumReal( - tscall.operands(0), table_row, result, - [](const QLValuePB& value) { return value.double_value(); }, - [](double value, QLValuePB* out) { return out->set_double_value(value); }); + *tscall.operands().begin(), table_row, result, + [](const Res& value) { return value.double_value(); }, + [](double value, Res* out) { return out->set_double_value(value); }); case bfpg::TSOpcode::kMin: { - QLExprResult arg_result; - RETURN_NOT_OK(EvalExpr(tscall.operands(0), table_row, arg_result.Writer())); + ExprResult arg_result(result); + RETURN_NOT_OK(EvalExpr(*tscall.operands().begin(), table_row, arg_result.Writer())); return EvalMin(arg_result.Value(), result); } case bfpg::TSOpcode::kMax: { - QLExprResult arg_result; - RETURN_NOT_OK(EvalExpr(tscall.operands(0), table_row, arg_result.Writer())); + ExprResult arg_result(result); + RETURN_NOT_OK(EvalExpr(*tscall.operands().begin(), table_row, arg_result.Writer())); return EvalMax(arg_result.Value(), result); } @@ -274,14 +289,15 @@ CHECKED_STATUS DocExprExecutor::EvalTSCall(const PgsqlBCallPB& tscall, break; } - result->SetNull(); + SetNull(result); return Status::OK(); } //-------------------------------------------------------------------------------------------------- -CHECKED_STATUS DocExprExecutor::EvalCount(QLValue *aggr_count) { - if (aggr_count->IsNull()) { +template +CHECKED_STATUS DocExprExecutor::EvalCount(Val *aggr_count) { + if (IsNull(*aggr_count)) { aggr_count->set_int64_value(1); } else { aggr_count->set_int64_value(aggr_count->int64_value() + 1); @@ -289,17 +305,18 @@ CHECKED_STATUS DocExprExecutor::EvalCount(QLValue *aggr_count) { return Status::OK(); } -CHECKED_STATUS DocExprExecutor::EvalSum(const QLValuePB& val, QLValue *aggr_sum) { +template +CHECKED_STATUS DocExprExecutor::EvalSum(const Val& val, Val *aggr_sum) { if (IsNull(val)) { return Status::OK(); } - if (aggr_sum->IsNull()) { + if (IsNull(*aggr_sum)) { *aggr_sum = val; return Status::OK(); } - switch (aggr_sum->type()) { + switch (aggr_sum->value_case()) { case InternalType::kInt8Value: aggr_sum->set_int8_value(aggr_sum->int8_value() + val.int8_value()); break; @@ -313,7 +330,8 @@ CHECKED_STATUS DocExprExecutor::EvalSum(const QLValuePB& val, QLValue *aggr_sum) aggr_sum->set_int64_value(aggr_sum->int64_value() + val.int64_value()); break; case InternalType::kVarintValue: - aggr_sum->set_varint_value(aggr_sum->varint_value() + QLValue::varint_value(val)); + aggr_sum->set_varint_value( + (QLValue::varint_value(*aggr_sum) + QLValue::varint_value(val)).EncodeToComparable()); break; case InternalType::kFloatValue: aggr_sum->set_float_value(aggr_sum->float_value() + val.float_value()); @@ -335,11 +353,11 @@ CHECKED_STATUS DocExprExecutor::EvalSum(const QLValuePB& val, QLValue *aggr_sum) return Status::OK(); } -template +template CHECKED_STATUS DocExprExecutor::EvalSumInt( - const PgsqlExpressionPB& operand, const QLTableRow& table_row, QLValue *aggr_sum, + const Expr& operand, const QLTableRow& table_row, Val *aggr_sum, const Extractor& extractor) { - QLExprResult arg_result; + ExprResult arg_result(aggr_sum); RETURN_NOT_OK(EvalExpr(operand, table_row, arg_result.Writer())); const auto& val = arg_result.Value(); @@ -347,7 +365,7 @@ CHECKED_STATUS DocExprExecutor::EvalSumInt( return Status::OK(); } - if (aggr_sum->IsNull()) { + if (IsNull(*aggr_sum)) { aggr_sum->set_int64_value(extractor(val)); } else { aggr_sum->set_int64_value(aggr_sum->int64_value() + extractor(val)); @@ -356,11 +374,11 @@ CHECKED_STATUS DocExprExecutor::EvalSumInt( return Status::OK(); } -template +template CHECKED_STATUS DocExprExecutor::EvalSumReal( - const PgsqlExpressionPB& operand, const QLTableRow& table_row, QLValue *aggr_sum, + const Expr& operand, const QLTableRow& table_row, Val *aggr_sum, const Extractor& extractor, const Setter& setter) { - QLExprResult arg_result; + ExprResult arg_result(aggr_sum); RETURN_NOT_OK(EvalExpr(operand, table_row, arg_result.Writer())); const auto& val = arg_result.Value(); @@ -368,52 +386,46 @@ CHECKED_STATUS DocExprExecutor::EvalSumReal( return Status::OK(); } - if (aggr_sum->IsNull()) { - setter(extractor(val), aggr_sum->mutable_value()); + if (IsNull(*aggr_sum)) { + setter(extractor(val), aggr_sum); } else { - setter(extractor(aggr_sum->value()) + extractor(val), aggr_sum->mutable_value()); + setter(extractor(*aggr_sum) + extractor(val), aggr_sum); } return Status::OK(); } -CHECKED_STATUS DocExprExecutor::EvalMax(const QLValuePB& val, QLValue *aggr_max) { - if (!IsNull(val) && (aggr_max->IsNull() || aggr_max->value() < val)) { +template +CHECKED_STATUS DocExprExecutor::EvalMax(const Val& val, Val *aggr_max) { + if (!IsNull(val) && (IsNull(*aggr_max) || *aggr_max < val)) { *aggr_max = val; } return Status::OK(); } -CHECKED_STATUS DocExprExecutor::EvalMin(const QLValuePB& val, QLValue *aggr_min) { - if (!IsNull(val) && (aggr_min->IsNull() || aggr_min->value() > val)) { +template +CHECKED_STATUS DocExprExecutor::EvalMin(const Val& val, Val *aggr_min) { + if (!IsNull(val) && (IsNull(*aggr_min) || *aggr_min > val)) { *aggr_min = val; } return Status::OK(); } -CHECKED_STATUS DocExprExecutor::EvalAvg(const QLValuePB& val, QLValue *aggr_avg) { +template +CHECKED_STATUS DocExprExecutor::EvalAvg(const Val& val, Val *aggr_avg) { if (IsNull(val)) { return Status::OK(); } - QLValue sum, count; - - if (aggr_avg->IsNull()) { - sum = val; - count.set_int64_value(1); - aggr_avg->set_map_value(); - *aggr_avg->add_map_key() = count.value(); - *aggr_avg->add_map_value() = sum.value(); + if (IsNull(*aggr_avg)) { + aggr_avg->mutable_map_value()->add_keys()->set_int64_value(1); + *aggr_avg->mutable_map_value()->add_values() = val; return Status::OK(); } QLMapValuePB* map = aggr_avg->mutable_map_value(); - sum = QLValue(map->values(0)); - RETURN_NOT_OK(EvalSum(val, &sum)); - count = QLValue(map->keys(0)); - count.set_int64_value(count.int64_value() + 1); - *map->mutable_keys(0) = count.value(); - *map->mutable_values(0) = sum.value(); + RETURN_NOT_OK(EvalSum(val, map->mutable_values(0))); + map->mutable_keys(0)->set_int64_value(map->keys(0).int64_value() + 1); return Status::OK(); } @@ -452,11 +464,11 @@ void UnpackUDTAndFrozen(const QLType::SharedPtr& type, QLValuePB* value) { QLMapValuePB* map = value->mutable_map_value(); for (int i = 0; i < seq.elems_size();) { - QLValuePB* const key = map->add_keys(); + auto* const key = map->add_keys(); *key = seq.elems(i++); UnpackUDTAndFrozen(type->param_type()->keys_type(), key); - QLValuePB* const value = map->add_values(); + auto* const value = map->add_values(); *value = seq.elems(i++); UnpackUDTAndFrozen(type->param_type()->values_type(), value); } @@ -495,7 +507,7 @@ void UnpackUDTAndFrozen(const QLType::SharedPtr& type, QLValuePB* value) { CHECKED_STATUS DocExprExecutor::EvalParametricToJson(const QLExpressionPB& operand, const QLTableRow& table_row, - QLValue *result, + QLValuePB *result, const Schema *schema) { QLExprResult val; RETURN_NOT_OK(EvalExpr(operand, table_row, val.Writer(), schema)); @@ -506,7 +518,7 @@ CHECKED_STATUS DocExprExecutor::EvalParametricToJson(const QLExpressionPB& opera DCHECK(col.ok()); if (col.ok()) { - UnpackUDTAndFrozen(col->type(), val.ForceNewValue().mutable_value()); + UnpackUDTAndFrozen(col->type(), &val.ForceNewValue()); } } diff --git a/src/yb/docdb/doc_expr.h b/src/yb/docdb/doc_expr.h index 822630acdf3a..3eea95684c5b 100644 --- a/src/yb/docdb/doc_expr.h +++ b/src/yb/docdb/doc_expr.h @@ -31,36 +31,57 @@ class DocExprExecutor : public QLExprExecutor { // Evaluate call to tablet-server builtin operator. CHECKED_STATUS EvalTSCall(const QLBCallPB& ql_expr, const QLTableRow& table_row, - QLValue *result, + QLValuePB *result, const Schema *schema = nullptr) override; CHECKED_STATUS EvalTSCall(const PgsqlBCallPB& ql_expr, const QLTableRow& table_row, - QLValue *result, + QLValuePB *result, const Schema *schema) override; + CHECKED_STATUS EvalTSCall(const LWPgsqlBCallPB& ql_expr, + const QLTableRow& table_row, + LWQLValuePB *result, + const Schema *schema) override; + + protected: // Evaluate aggregate functions for each row. - CHECKED_STATUS EvalCount(QLValue *aggr_count); - CHECKED_STATUS EvalSum(const QLValuePB& val, QLValue *aggr_sum); - template + template + CHECKED_STATUS EvalCount(Val *aggr_count); + + template + CHECKED_STATUS EvalSum(const Val& val, Val *aggr_sum); + + template CHECKED_STATUS EvalSumInt( - const PgsqlExpressionPB& expr, const QLTableRow& table_row, QLValue *aggr_sum, - const Extractor& extractor); - template + const Expr& expr, const QLTableRow& table_row, Val *aggr_sum, const Extractor& extractor); + + template CHECKED_STATUS EvalSumReal( - const PgsqlExpressionPB& expr, const QLTableRow& table_row, QLValue *aggr_sum, + const Expr& expr, const QLTableRow& table_row, Val *aggr_sum, const Extractor& extractor, const Setter& setter); - CHECKED_STATUS EvalMax(const QLValuePB& val, QLValue *aggr_max); - CHECKED_STATUS EvalMin(const QLValuePB& val, QLValue *aggr_min); - CHECKED_STATUS EvalAvg(const QLValuePB& val, QLValue *aggr_avg); + + template + CHECKED_STATUS EvalMax(const Val& val, Val *aggr_max); + + template + CHECKED_STATUS EvalMin(const Val& val, Val *aggr_min); + + template + CHECKED_STATUS EvalAvg(const Val& val, Val *aggr_avg); CHECKED_STATUS EvalParametricToJson(const QLExpressionPB& operand, const QLTableRow& table_row, - QLValue *result, + QLValuePB *result, const Schema *schema); - protected: - virtual CHECKED_STATUS GetTupleId(QLValue *result) const; + template + CHECKED_STATUS DoEvalTSCall(const Expr& ql_expr, + const QLTableRow& table_row, + Val *result, + const Schema *schema); + + virtual CHECKED_STATUS GetTupleId(QLValuePB *result) const; std::vector aggr_result_; }; diff --git a/src/yb/docdb/docdb-test.cc b/src/yb/docdb/docdb-test.cc index 480da3eed2b3..21a4087e34f5 100644 --- a/src/yb/docdb/docdb-test.cc +++ b/src/yb/docdb/docdb-test.cc @@ -3665,9 +3665,9 @@ SubDocKey(DocKey([], ["c"]), ["k5"; HT{ physical: 1100 }]) -> "vv5"; ttl: 25.000 } std::string EncodeValue(const QLValuePB& value) { - ValueBuffer result; + std::string result; AppendEncodedValue(value, SortingType::kNotSpecified, &result); - return result.ToStringBuffer(); + return result; } TEST_P(DocDBTestWrapper, CompactionWithTransactions) { diff --git a/src/yb/docdb/pgsql_operation.cc b/src/yb/docdb/pgsql_operation.cc index ce60d3c6a24b..477f2cb146e3 100644 --- a/src/yb/docdb/pgsql_operation.cc +++ b/src/yb/docdb/pgsql_operation.cc @@ -1145,7 +1145,7 @@ Status PgsqlReadOperation::PopulateResultSet(const QLTableRow& table_row, return Status::OK(); } -Status PgsqlReadOperation::GetTupleId(QLValue *result) const { +Status PgsqlReadOperation::GetTupleId(QLValuePB *result) const { // Get row key and save to QLValue. // TODO(neil) Check if we need to append a table_id and other info to TupleID. For example, we // might need info to make sure the TupleId by itself is a valid reference to a specific row of diff --git a/src/yb/docdb/pgsql_operation.h b/src/yb/docdb/pgsql_operation.h index 2379614c404a..bfa57bc89af6 100644 --- a/src/yb/docdb/pgsql_operation.h +++ b/src/yb/docdb/pgsql_operation.h @@ -153,7 +153,7 @@ class PgsqlReadOperation : public DocExprExecutor { faststring *result_buffer, HybridTime *restart_read_ht); - CHECKED_STATUS GetTupleId(QLValue *result) const override; + CHECKED_STATUS GetTupleId(QLValuePB *result) const override; CHECKED_STATUS GetIntents(const Schema& schema, KeyValueWriteBatchPB* out); diff --git a/src/yb/docdb/primitive_value-test.cc b/src/yb/docdb/primitive_value-test.cc index 32e8767191e0..8bb1a81b7efa 100644 --- a/src/yb/docdb/primitive_value-test.cc +++ b/src/yb/docdb/primitive_value-test.cc @@ -392,8 +392,8 @@ TEST(PrimitiveValueTest, TestAllTypesComparisons) { InetAddress addr1; InetAddress addr2; - ASSERT_OK(addr1.FromBytes(RandomHumanReadableString(4))); - ASSERT_OK(addr2.FromBytes(RandomHumanReadableString(4))); + ASSERT_OK(addr1.FromSlice(RandomHumanReadableString(4))); + ASSERT_OK(addr2.FromSlice(RandomHumanReadableString(4))); ComparePrimitiveValues(PrimitiveValue(addr1), PrimitiveValue(addr2)); ComparePrimitiveValues(PrimitiveValue(Uuid(Uuid::Generate())), diff --git a/src/yb/docdb/primitive_value.cc b/src/yb/docdb/primitive_value.cc index b83d90ac6f8c..fed061a2f1b6 100644 --- a/src/yb/docdb/primitive_value.cc +++ b/src/yb/docdb/primitive_value.cc @@ -917,7 +917,7 @@ Status PrimitiveValue::DecodeKey(rocksdb::Slice* slice, PrimitiveValue* out) { string bytes; RETURN_NOT_OK(DecodeZeroEncodedStr(slice, &bytes)); out->inetaddress_val_ = new InetAddress(); - RETURN_NOT_OK(out->inetaddress_val_->FromBytes(bytes)); + RETURN_NOT_OK(out->inetaddress_val_->FromSlice(bytes)); } else { RETURN_NOT_OK(DecodeZeroEncodedStr(slice, nullptr)); } @@ -930,7 +930,7 @@ Status PrimitiveValue::DecodeKey(rocksdb::Slice* slice, PrimitiveValue* out) { string bytes; RETURN_NOT_OK(DecodeComplementZeroEncodedStr(slice, &bytes)); out->inetaddress_val_ = new InetAddress(); - RETURN_NOT_OK(out->inetaddress_val_->FromBytes(bytes)); + RETURN_NOT_OK(out->inetaddress_val_->FromSlice(bytes)); } else { RETURN_NOT_OK(DecodeComplementZeroEncodedStr(slice, nullptr)); } diff --git a/src/yb/util/memory/arena_list.h b/src/yb/util/memory/arena_list.h index 0a5db8724a63..657784b16ce2 100644 --- a/src/yb/util/memory/arena_list.h +++ b/src/yb/util/memory/arena_list.h @@ -24,7 +24,8 @@ namespace yb { template -struct ArenaListNode : public boost::intrusive::list_base_hook<> { +struct ArenaListNode : public boost::intrusive::list_base_hook> { Entry* value_ptr = nullptr; }; diff --git a/src/yb/util/net/inetaddress-test.cc b/src/yb/util/net/inetaddress-test.cc index 4526f89363d8..fa4b6f08e631 100644 --- a/src/yb/util/net/inetaddress-test.cc +++ b/src/yb/util/net/inetaddress-test.cc @@ -27,7 +27,7 @@ class InetAddressTest : public YBTest { InetAddress addr_orig(ASSERT_RESULT(ParseIpAddress(strval))); std::string bytes = addr_orig.ToBytes(); InetAddress addr_new; - ASSERT_OK(addr_new.FromBytes(bytes)); + ASSERT_OK(addr_new.FromSlice(bytes)); std::string strval_new; ASSERT_OK(addr_new.ToString(&strval_new)); ASSERT_EQ(strval, strval_new); @@ -86,13 +86,13 @@ TEST_F(InetAddressTest, TestErrors) { ASSERT_FALSE(ParseIpAddress("2607:g0d0:1002:51::4").ok()); std::string bytes; - ASSERT_FALSE(addr.FromBytes(bytes).ok()); + ASSERT_FALSE(addr.FromSlice(bytes).ok()); bytes = "0"; - ASSERT_FALSE(addr.FromBytes(bytes).ok()); + ASSERT_FALSE(addr.FromSlice(bytes).ok()); bytes = "012345"; - ASSERT_FALSE(addr.FromBytes(bytes).ok()); + ASSERT_FALSE(addr.FromSlice(bytes).ok()); bytes = "111111111111111111"; // 17 bytes. - ASSERT_FALSE(addr.FromBytes(bytes).ok()); + ASSERT_FALSE(addr.FromSlice(bytes).ok()); } TEST_F(InetAddressTest, FilterAddresses) { diff --git a/src/yb/util/net/inetaddress.cc b/src/yb/util/net/inetaddress.cc index 75ebc16b465e..2c7303bf18bc 100644 --- a/src/yb/util/net/inetaddress.cc +++ b/src/yb/util/net/inetaddress.cc @@ -62,10 +62,11 @@ std::string InetAddress::ToBytes() const { } CHECKED_STATUS InetAddress::FromSlice(const Slice& slice, size_t size_hint) { - size_t expected_size = (size_hint == 0) ? slice.size() : size_hint; + size_t expected_size = size_hint == 0 ? slice.size() : size_hint; if (expected_size > slice.size()) { - return STATUS_SUBSTITUTE(InvalidArgument, "Size of slice: $0 is smaller than provided " - "size_hint: $1", slice.size(), expected_size); + return STATUS_FORMAT( + InvalidArgument, "Size of slice: $0 is smaller than provided size_hint: $1", + slice.size(), expected_size); } if (expected_size == kInetAddressV4Size) { address_v4::bytes_type v4bytes; @@ -80,16 +81,11 @@ CHECKED_STATUS InetAddress::FromSlice(const Slice& slice, size_t size_hint) { address_v6 v6address(v6bytes); boost_addr_ = v6address; } else { - return STATUS_SUBSTITUTE(InvalidArgument, "Size of slice is invalid: $0", expected_size); + return STATUS_FORMAT(InvalidArgument, "Size of slice is invalid: $0", expected_size); } return Status::OK(); } -CHECKED_STATUS InetAddress::FromBytes(const std::string& bytes) { - Slice slice (bytes.data(), bytes.size()); - return FromSlice(slice); -} - bool IsIPv6NonLinkLocal(const IpAddress& address) { if (!address.is_v6() || address.is_unspecified()) { return false; diff --git a/src/yb/util/net/inetaddress.h b/src/yb/util/net/inetaddress.h index a565b306409c..772219513657 100644 --- a/src/yb/util/net/inetaddress.h +++ b/src/yb/util/net/inetaddress.h @@ -65,10 +65,6 @@ class InetAddress { std::string ToBytes() const; - // Given a string holding the raw bytes in network byte order, it builds the appropriate - // InetAddress object. - CHECKED_STATUS FromBytes(const std::string& bytes); - // Give a slice holding raw bytes in network byte order, build the appropriate InetAddress // object. If size_hint is specified, it indicates the number of bytes to decode from the slice. CHECKED_STATUS FromSlice(const Slice& slice, size_t size_hint = 0); diff --git a/src/yb/util/uuid.cc b/src/yb/util/uuid.cc index 20f956487fd1..eb29da337575 100644 --- a/src/yb/util/uuid.cc +++ b/src/yb/util/uuid.cc @@ -90,6 +90,10 @@ void Uuid::ToBytes(std::array* out) const { memcpy(out->data(), boost_uuid_.data, kUuidSize); } +void Uuid::ToBytes(void* out) const { + memcpy(out, boost_uuid_.data, kUuidSize); +} + Slice Uuid::AsSlice() const { return Slice(boost_uuid_.data, boost_uuid_.size()); } diff --git a/src/yb/util/uuid.h b/src/yb/util/uuid.h index 72b209e4afd6..5fe9774da13a 100644 --- a/src/yb/util/uuid.h +++ b/src/yb/util/uuid.h @@ -75,6 +75,7 @@ class Uuid { // Fills in the given string with the raw bytes for the appropriate address in network byte order. void ToBytes(std::string* bytes) const; void ToBytes(std::array* out) const; + void ToBytes(void* buffer) const; Slice AsSlice() const; // Encodes the UUID into the time comparable uuid to be stored in RocksDB. diff --git a/src/yb/yql/cql/ql/exec/eval_aggr.cc b/src/yb/yql/cql/ql/exec/eval_aggr.cc index 535d21aa6feb..70845fd1763e 100644 --- a/src/yb/yql/cql/ql/exec/eval_aggr.cc +++ b/src/yb/yql/cql/ql/exec/eval_aggr.cc @@ -15,6 +15,7 @@ #include "yb/common/ql_protocol_util.h" #include "yb/common/ql_rowblock.h" +#include "yb/common/ql_serialization.h" #include "yb/common/ql_value.h" #include "yb/util/decimal.h" @@ -75,7 +76,7 @@ Status Executor::AggregateResultSets(const PTSelectStmt* pt_select, TnodeContext } // Serialize the return value. - ql_value.Serialize(expr_node->ql_type(), rows_result->client(), &buffer); + SerializeValue(expr_node->ql_type(), rows_result->client(), ql_value.value(), &buffer); column_index++; } diff --git a/src/yb/yql/cql/ql/test/ql-query-test.cc b/src/yb/yql/cql/ql/test/ql-query-test.cc index 2f178bc2d744..1d5d92910f0e 100644 --- a/src/yb/yql/cql/ql/test/ql-query-test.cc +++ b/src/yb/yql/cql/ql/test/ql-query-test.cc @@ -22,6 +22,7 @@ #include "yb/common/jsonb.h" #include "yb/common/partition.h" #include "yb/common/ql_protocol_util.h" +#include "yb/common/ql_serialization.h" #include "yb/common/ql_type.h" #include "yb/common/ql_value.h" @@ -1911,7 +1912,7 @@ void verifyJson(std::shared_ptr row_block) { ASSERT_OK(jsonb.ToJsonString(&json)); EXPECT_EQ("{\"a\":1,\"b\":2}", json); faststring buffer; - row.column(1).Serialize(QLType::Create(DataType::JSONB), YQL_CLIENT_CQL, &buffer); + SerializeValue(QLType::Create(DataType::JSONB), YQL_CLIENT_CQL, row.column(1).value(), &buffer); int32_t len = 0; Slice data(buffer); ASSERT_OK(CQLDecodeNum(sizeof(len), NetworkByteOrder::Load32, &data, &len)); diff --git a/src/yb/yql/cql/ql/test/ql-select-expr-test.cc b/src/yb/yql/cql/ql/test/ql-select-expr-test.cc index 751f6f138724..2232caef3b12 100644 --- a/src/yb/yql/cql/ql/test/ql-select-expr-test.cc +++ b/src/yb/yql/cql/ql/test/ql-select-expr-test.cc @@ -6,6 +6,7 @@ #include #include "yb/common/jsonb.h" +#include "yb/common/ql_serialization.h" #include "yb/common/ql_type.h" #include "yb/common/ql_value.h" #include "yb/common/schema.h" @@ -58,7 +59,7 @@ struct CQLQueryParameters : public CQLMessage::QueryParameters { void PushBack(const string& name, const QLValue& qv, const shared_ptr& type) { faststring buffer; - qv.Serialize(type, YQL_CLIENT_CQL, &buffer); + SerializeValue(type, YQL_CLIENT_CQL, qv.value(), &buffer); CQLMessage::Value msg_value; msg_value.name = name; diff --git a/src/yb/yql/pggate/pg_operation_buffer.cc b/src/yb/yql/pggate/pg_operation_buffer.cc index 0d2925486678..358fd8826df9 100644 --- a/src/yb/yql/pggate/pg_operation_buffer.cc +++ b/src/yb/yql/pggate/pg_operation_buffer.cc @@ -73,9 +73,8 @@ std::vector InitKeyColumnPrimitiveValues( // // Use regular executor for now. QLExprExecutor executor; - QLExprResult expr_result; - auto expr = column_value.ToGoogleProtobuf(); // TODO(LW_PERFORM) - auto s = executor.EvalExpr(expr, nullptr, expr_result.Writer()); + LWExprResult expr_result(&column_value.arena()); + auto s = executor.EvalExpr(column_value, nullptr, expr_result.Writer()); result.push_back(docdb::PrimitiveValue::FromQLValuePB(expr_result.Value(), sorting_type)); } diff --git a/src/yb/yql/pggate/pg_value.cc b/src/yb/yql/pggate/pg_value.cc index 7d265e7dd3b6..e744506a2476 100644 --- a/src/yb/yql/pggate/pg_value.cc +++ b/src/yb/yql/pggate/pg_value.cc @@ -162,9 +162,9 @@ Status PgValueFromPB(const YBCPgTypeEntity *type_entity, Status PgValueToPB(const YBCPgTypeEntity *type_entity, uint64_t datum, bool is_null, - QLValue* ql_value) { + QLValuePB* ql_value) { if (is_null) { - ql_value->SetNull(); + SetNull(ql_value); return Status::OK(); } diff --git a/src/yb/yql/pggate/pg_value.h b/src/yb/yql/pggate/pg_value.h index 8719f9f3dc8b..695ee0d41d47 100644 --- a/src/yb/yql/pggate/pg_value.h +++ b/src/yb/yql/pggate/pg_value.h @@ -39,7 +39,7 @@ Status PgValueFromPB(const YBCPgTypeEntity *type_entity, Status PgValueToPB(const YBCPgTypeEntity *type_entity, uint64_t datum, bool is_null, - QLValue* ql_value); + QLValuePB* ql_value); } // namespace pggate } // namespace yb diff --git a/src/yb/yql/pggate/ybc_pggate.cc b/src/yb/yql/pggate/ybc_pggate.cc index 50a7de445c7d..8e28a2c025a3 100644 --- a/src/yb/yql/pggate/ybc_pggate.cc +++ b/src/yb/yql/pggate/ybc_pggate.cc @@ -879,7 +879,7 @@ YBCStatus YBCGetDocDBKeySize(uint64_t data, const YBCPgTypeEntity *typeentity, } QLValue val; - Status status = pggate::PgValueToPB(typeentity, data, is_null, &val); + Status status = pggate::PgValueToPB(typeentity, data, is_null, val.mutable_value()); if (!status.IsOk()) { return ToYBCStatus(status); } @@ -896,7 +896,7 @@ YBCStatus YBCAppendDatumToKey(uint64_t data, const YBCPgTypeEntity *typeentity, size_t *bytes_written) { QLValue val; - Status status = pggate::PgValueToPB(typeentity, data, is_null, &val); + Status status = pggate::PgValueToPB(typeentity, data, is_null, val.mutable_value()); if (!status.IsOk()) { return ToYBCStatus(status); }