Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented type casting #662

Merged
merged 4 commits into from
Aug 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
*.swp
*.so

build
_build
_build.log
_install
Expand Down
32 changes: 30 additions & 2 deletions src/common/filter/Expressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -715,13 +715,41 @@ std::string columnTypeToString(ColumnType type) {


std::string TypeCastingExpression::toString() const {
return "";
std::string buf;
buf.reserve(256);

buf += "(";
buf += columnTypeToString(type_);
buf += ")";
buf += operand_->toString();

return buf;
}


OptVariantType TypeCastingExpression::eval() const {
return OptVariantType(toString());
auto result = operand_->eval();
if (!result.ok()) {
return result;
}

switch (type_) {
case INT:
case TIMESTAMP:
return Expression::toInt(result.value());
case STRING:
return Expression::toString(result.value());
case DOUBLE:
return Expression::toDouble(result.value());
case BOOL:
return Expression::toBool(result.value());
case BIGINT:
return Status::Error("Type bigint not supported yet");
}
LOG(FATAL) << "casting to unknown type: " << static_cast<int>(type_);
}


Status TypeCastingExpression::prepare() {
return operand_->prepare();
}
Expand Down
52 changes: 52 additions & 0 deletions src/common/filter/Expressions.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ class Expression {
*/
static StatusOr<std::unique_ptr<Expression>> decode(folly::StringPiece buffer) noexcept;

// Procedures used to do type conversions only between compatible ones.
static int64_t asInt(const VariantType &value) {
return boost::get<int64_t>(value);
}
Expand Down Expand Up @@ -204,6 +205,57 @@ class Expression {
return std::abs(left - right) < EPSILON;
}

// Procedures used to do type casting
static std::string toString(const VariantType &value) {
char buf[1024];
switch (value.which()) {
case 0:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the macro from Base.h

return folly::to<std::string>(boost::get<int64_t>(value));
case 1:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use micro?

return folly::to<std::string>(boost::get<double>(value));
case 2:
snprintf(buf, sizeof(buf), "%s", boost::get<bool>(value) ? "true" : "false");
return buf;
case 3:
return boost::get<std::string>(value);
}
LOG(FATAL) << "unknown type: " << value.which();
}

static bool toBool(const VariantType &value) {
return asBool(value);
}

static double toDouble(const VariantType &value) {
switch (value.which()) {
case 0:
return static_cast<double>(boost::get<int64_t>(value));
case 1:
return boost::get<double>(value);
case 2:
return boost::get<bool>(value) ? 1.0 : 0.0;
case 3:
// TODO(dutor) error handling
return folly::to<double>(boost::get<std::string>(value));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think folly::tryTo would be better here, or exception would occur if an unparseable string is provided.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will address such problems after #669 is merged.

}
LOG(FATAL) << "unknown type: " << value.which();
}

static int64_t toInt(const VariantType &value) {
switch (value.which()) {
case 0:
return boost::get<int64_t>(value);
case 1:
return static_cast<int64_t>(boost::get<double>(value));
case 2:
return boost::get<bool>(value) ? 1.0 : 0.0;
case 3:
// TODO(dutor) error handling
return folly::to<int64_t>(boost::get<std::string>(value));
}
LOG(FATAL) << "unknown type: " << value.which();
}

static void print(const VariantType &value);

enum Kind : uint8_t {
Expand Down
6 changes: 3 additions & 3 deletions src/graph/test/YieldTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ TEST_F(YieldTest, Basic) {
}
{
cpp2::ExecutionResponse resp;
std::string query = "YIELD 1+1";
std::string query = "YIELD 1+1, '1+1', (int)3.14, (string)(1+1), (string)true";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1+1 < 3

auto code = client->execute(query, resp);
ASSERT_EQ(cpp2::ErrorCode::SUCCEEDED, code);
std::vector<std::tuple<int64_t>> expected{
{2}
std::vector<std::tuple<int64_t, std::string, int64_t, std::string, std::string>> expected{
{2, "1+1", 3, "2", "true"}
};
ASSERT_TRUE(verifyResult(resp, expected));
}
Expand Down