Rand() function added
Reviewers: mislav.bradac, buda Reviewed By: mislav.bradac Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D690
This commit is contained in:
parent
ff3bd2011a
commit
1a619c54e9
@ -5,6 +5,7 @@
|
|||||||
### Major Features and Improvements
|
### Major Features and Improvements
|
||||||
|
|
||||||
* CASE construct (without aggregations)
|
* CASE construct (without aggregations)
|
||||||
|
* rand() function added
|
||||||
|
|
||||||
### Bug Fixes and Other Changes
|
### Bug Fixes and Other Changes
|
||||||
|
|
||||||
|
@ -440,6 +440,7 @@ functions.
|
|||||||
`sign` | Applies the signum function to a given number and returns the result. The signum of positive numbers is 1, of negative -1 and for 0 returns 0.
|
`sign` | Applies the signum function to a given number and returns the result. The signum of positive numbers is 1, of negative -1 and for 0 returns 0.
|
||||||
`e` | Returns the base of the natural logarithm.
|
`e` | Returns the base of the natural logarithm.
|
||||||
`pi` | Returns the constant *pi*.
|
`pi` | Returns the constant *pi*.
|
||||||
|
`rand` | Returns a random floating point number between 0 (inclusive) and 1 (exclusive).
|
||||||
`startsWith` | Check if the first argument starts with the second.
|
`startsWith` | Check if the first argument starts with the second.
|
||||||
`endsWith` | Check if the first argument ends with the second.
|
`endsWith` | Check if the first argument ends with the second.
|
||||||
`contains` | Check if the first argument has an element which is equal to the second argument.
|
`contains` | Check if the first argument has an element which is equal to the second argument.
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
#include "utils/on_scope_exit.hpp"
|
#include "utils/on_scope_exit.hpp"
|
||||||
|
|
||||||
GraphDbAccessor::GraphDbAccessor(GraphDb &db)
|
GraphDbAccessor::GraphDbAccessor(GraphDb &db)
|
||||||
: db_(db), transaction_(db.tx_engine_.Begin()) {}
|
: db_(db), transaction_(db.tx_engine_.Begin()) {
|
||||||
|
pseudo_rand_gen_.seed(std::random_device()());
|
||||||
|
}
|
||||||
|
|
||||||
GraphDbAccessor::~GraphDbAccessor() {
|
GraphDbAccessor::~GraphDbAccessor() {
|
||||||
if (!commited_ && !aborted_) {
|
if (!commited_ && !aborted_) {
|
||||||
@ -332,3 +334,5 @@ const std::string &GraphDbAccessor::PropertyName(
|
|||||||
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted");
|
debug_assert(!commited_ && !aborted_, "Accessor committed or aborted");
|
||||||
return *property;
|
return *property;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double GraphDbAccessor::Rand() { return rand_dist_(pseudo_rand_gen_); }
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <experimental/optional>
|
#include <experimental/optional>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
#include "cppitertools/filter.hpp"
|
#include "cppitertools/filter.hpp"
|
||||||
#include "cppitertools/imap.hpp"
|
#include "cppitertools/imap.hpp"
|
||||||
@ -552,6 +553,11 @@ class GraphDbAccessor {
|
|||||||
if (!accessor.new_) accessor.new_ = accessor.vlist_->update(*transaction_);
|
if (!accessor.new_) accessor.new_ = accessor.vlist_->update(*transaction_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a uniformly random-generated number from the [0, 1) interval.
|
||||||
|
*/
|
||||||
|
double Rand();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Insert this vertex into corresponding label and label+property (if it
|
* Insert this vertex into corresponding label and label+property (if it
|
||||||
@ -584,6 +590,7 @@ class GraphDbAccessor {
|
|||||||
void UpdatePropertyIndex(const GraphDbTypes::Property &property,
|
void UpdatePropertyIndex(const GraphDbTypes::Property &property,
|
||||||
const RecordAccessor<Vertex> &record_accessor,
|
const RecordAccessor<Vertex> &record_accessor,
|
||||||
const Vertex *const vertex);
|
const Vertex *const vertex);
|
||||||
|
|
||||||
GraphDb &db_;
|
GraphDb &db_;
|
||||||
|
|
||||||
/** The current transaction */
|
/** The current transaction */
|
||||||
@ -591,4 +598,8 @@ class GraphDbAccessor {
|
|||||||
|
|
||||||
bool commited_{false};
|
bool commited_{false};
|
||||||
bool aborted_{false};
|
bool aborted_{false};
|
||||||
|
|
||||||
|
// Random number generation stuff.
|
||||||
|
std::mt19937 pseudo_rand_gen_;
|
||||||
|
std::uniform_real_distribution<> rand_dist_{0, 1};
|
||||||
};
|
};
|
||||||
|
@ -453,6 +453,13 @@ TypedValue Pi(const std::vector<TypedValue> &args, GraphDbAccessor &) {
|
|||||||
return M_PI;
|
return M_PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypedValue Rand(const std::vector<TypedValue> &args, GraphDbAccessor &dba) {
|
||||||
|
if (args.size() != 0U) {
|
||||||
|
throw QueryRuntimeException("rand shouldn't be called with arguments");
|
||||||
|
}
|
||||||
|
return dba.Rand();
|
||||||
|
}
|
||||||
|
|
||||||
template <bool (*Predicate)(const std::string &s1, const std::string &s2)>
|
template <bool (*Predicate)(const std::string &s1, const std::string &s2)>
|
||||||
TypedValue StringMatchOperator(const std::vector<TypedValue> &args,
|
TypedValue StringMatchOperator(const std::vector<TypedValue> &args,
|
||||||
GraphDbAccessor &) {
|
GraphDbAccessor &) {
|
||||||
@ -534,6 +541,7 @@ NameToFunction(const std::string &function_name) {
|
|||||||
if (function_name == "SIGN") return Sign;
|
if (function_name == "SIGN") return Sign;
|
||||||
if (function_name == "E") return E;
|
if (function_name == "E") return E;
|
||||||
if (function_name == "PI") return Pi;
|
if (function_name == "PI") return Pi;
|
||||||
|
if (function_name == "RAND") return Rand;
|
||||||
if (function_name == kStartsWith) return StartsWith;
|
if (function_name == kStartsWith) return StartsWith;
|
||||||
if (function_name == kEndsWith) return EndsWith;
|
if (function_name == kEndsWith) return EndsWith;
|
||||||
if (function_name == kContains) return Contains;
|
if (function_name == kContains) return Contains;
|
||||||
|
@ -616,6 +616,15 @@ Feature: Functions
|
|||||||
| n |
|
| n |
|
||||||
| 3.141592653589793 |
|
| 3.141592653589793 |
|
||||||
|
|
||||||
|
Scenario: Rand test:
|
||||||
|
When executing query:
|
||||||
|
"""
|
||||||
|
WITH rand() as r RETURN r >= 0.0 AND r < 1.0 as result
|
||||||
|
"""
|
||||||
|
Then the result should be:
|
||||||
|
| result |
|
||||||
|
| true |
|
||||||
|
|
||||||
Scenario: All test 01:
|
Scenario: All test 01:
|
||||||
When executing query:
|
When executing query:
|
||||||
"""
|
"""
|
||||||
|
@ -352,6 +352,19 @@ TEST(GraphDbAccessorTest, Transfer) {
|
|||||||
EXPECT_EQ(dba3->Transfer(e12)->PropsAt(prop).Value<int64_t>(), 12);
|
EXPECT_EQ(dba3->Transfer(e12)->PropsAt(prop).Value<int64_t>(), 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(GraphDbAccessorTest, Rand) {
|
||||||
|
Dbms dbms;
|
||||||
|
auto dba = dbms.active();
|
||||||
|
|
||||||
|
double a = dba->Rand();
|
||||||
|
EXPECT_GE(a, 0.0);
|
||||||
|
EXPECT_LT(a, 1.0);
|
||||||
|
double b = dba->Rand();
|
||||||
|
EXPECT_GE(b, 0.0);
|
||||||
|
EXPECT_LT(b, 1.0);
|
||||||
|
EXPECT_NE(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
// ::testing::GTEST_FLAG(filter) = "*.DetachRemoveVertex";
|
// ::testing::GTEST_FLAG(filter) = "*.DetachRemoveVertex";
|
||||||
|
@ -1047,6 +1047,12 @@ TEST(ExpressionEvaluator, FunctionPi) {
|
|||||||
ASSERT_DOUBLE_EQ(EvaluateFunction("PI", {}).Value<double>(), M_PI);
|
ASSERT_DOUBLE_EQ(EvaluateFunction("PI", {}).Value<double>(), M_PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ExpressionEvaluator, FunctionRand) {
|
||||||
|
ASSERT_THROW(EvaluateFunction("RAND", {1}), QueryRuntimeException);
|
||||||
|
ASSERT_GE(EvaluateFunction("RAND", {}).Value<double>(), 0.0);
|
||||||
|
ASSERT_LT(EvaluateFunction("RAND", {}).Value<double>(), 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ExpressionEvaluator, FunctionStartsWith) {
|
TEST(ExpressionEvaluator, FunctionStartsWith) {
|
||||||
EXPECT_THROW(EvaluateFunction(kStartsWith, {}), QueryRuntimeException);
|
EXPECT_THROW(EvaluateFunction(kStartsWith, {}), QueryRuntimeException);
|
||||||
EXPECT_TRUE(EvaluateFunction(kStartsWith, {"a", TypedValue::Null}).IsNull());
|
EXPECT_TRUE(EvaluateFunction(kStartsWith, {"a", TypedValue::Null}).IsNull());
|
||||||
|
Loading…
Reference in New Issue
Block a user