diff --git a/src/storage/context/StorageExpressionContext.cpp b/src/storage/context/StorageExpressionContext.cpp index 7253f2fdc55..025c2ca14a5 100644 --- a/src/storage/context/StorageExpressionContext.cpp +++ b/src/storage/context/StorageExpressionContext.cpp @@ -9,6 +9,7 @@ #include "common/utils/DefaultValueContext.h" #include "common/utils/IndexKeyUtils.h" #include "common/utils/NebulaKeyUtils.h" +#include "storage/exec/QueryUtils.h" namespace nebula { namespace storage { @@ -17,22 +18,13 @@ Value StorageExpressionContext::readValue(const std::string& propName) const { if (!schema_) { return Value::kNullValue; } - auto field = schema_->field(propName); - if (!field) { - return Value::kNullValue; - } - auto value = reader_->getValueByName(propName); - if (value.type() == Value::Type::NULLVALUE) { - // read null value - auto nullType = value.getNull(); - if (nullType == NullType::UNKNOWN_PROP && field->hasDefault()) { - DefaultValueContext expCtx; - auto expr = field->defaultValue()->clone(); - return Value(Expression::eval(expr, expCtx)); - } + + auto ret = QueryUtils::readValue(reader_, propName, schema_); + if (!ret.ok()) { return Value::kNullValue; } - return value; + + return std::move(ret).value(); } // Get the specified property from the tag, such as tag_name.prop_name @@ -120,12 +112,12 @@ Value StorageExpressionContext::getSrcProp(const std::string& tagName, } Value StorageExpressionContext::getIndexValue(const std::string& prop, bool isEdge) const { - // TODO (sky) : Handle string type values. - // when field type is FIXED_STRING type, - // actual length of the value is called "len" - // FIXED_STRING.type.len is called "fixed_len" - // if (len > fixed_len) : v = value.substr(0, fixed_len) - // if (len < fixed_len) : v.append(fixed_len - len, '\0') + // Handle string type values. + // when field type is FIXED_STRING type, + // actual length of the value is called "len" + // FIXED_STRING.type.len is called "fixed_len" + // if (len > fixed_len) : v = value.substr(0, fixed_len) + // if (len < fixed_len) : v.append(fixed_len - len, '\0') return IndexKeyUtils::getValueFromIndexKey(vIdLen_, key_, prop, fields_, isEdge, hasNullableCol_); } diff --git a/src/storage/exec/QueryUtils.h b/src/storage/exec/QueryUtils.h index 9450c7a080d..9b42303f841 100644 --- a/src/storage/exec/QueryUtils.h +++ b/src/storage/exec/QueryUtils.h @@ -71,6 +71,10 @@ class QueryUtils final { } return Status::Error(folly::stringPrintf("Fail to read prop %s ", propName.c_str())); } + if (field->type() == meta::cpp2::PropertyType::FIXED_STRING) { + const auto& fixedStr = value.getStr(); + return fixedStr.substr(0, fixedStr.find_first_of('\0')); + } return value; } diff --git a/tests/tck/features/expression/FixedString.feature b/tests/tck/features/expression/FixedString.feature new file mode 100644 index 00000000000..e857a78f357 --- /dev/null +++ b/tests/tck/features/expression/FixedString.feature @@ -0,0 +1,54 @@ +Feature: FixedString expression Eval + + Scenario: FixedString GO Expression + Given an empty graph + And create a space with following options: + | partition_num | 1 | + | replica_factor | 1 | + | vid_type | int64 | + | charset | utf8 | + | collate | utf8_bin | + And having executed: + """ + CREATE TAG IF NOT EXISTS fixed_string_tag_1(c1 fixed_string(30)); + CREATE EDGE IF NOT EXISTS fixed_string_edge_1(c1 fixed_string(30)); + """ + # insert vertex succeeded + When try to execute query: + """ + INSERT VERTEX fixed_string_tag_1(c1) VALUES 1:("row"), 2:("row"), 3:("row") + """ + Then the execution should be successful + # insert edge succeeded + When executing query: + """ + INSERT EDGE fixed_string_edge_1(c1) VALUES 1->2:("row"), 1->3:("row") + """ + Then the execution should be successful + # check fixed string expression with go + When executing query: + """ + GO from 1 over fixed_string_edge_1 where $$.fixed_string_tag_1.c1 == "row" yield $$.fixed_string_tag_1.c1 as c1 + """ + Then the result should be, in any order, with relax comparison: + | c1 | + | "row" | + | "row" | + # check fixed string expression with go + When executing query: + """ + GO from 1 over fixed_string_edge_1 where $^.fixed_string_tag_1.c1 == "row" yield $$.fixed_string_tag_1.c1 as c1 + """ + Then the result should be, in any order, with relax comparison: + | c1 | + | "row" | + | "row" | + # check fixed string expression with go + When executing query: + """ + GO from 1 over fixed_string_edge_1 where fixed_string_edge_1.c1 == "row" yield $$.fixed_string_tag_1.c1 as c1 + """ + Then the result should be, in any order, with relax comparison: + | c1 | + | "row" | + | "row" |