Skip to content

Commit

Permalink
Supported builtin functions in query language (vesoft-inc#264)
Browse files Browse the repository at this point in the history
  • Loading branch information
dutor authored Apr 15, 2019
1 parent e7e6afd commit ef32037
Show file tree
Hide file tree
Showing 9 changed files with 626 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/parser/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ add_library(
${FLEX_Scanner_OUTPUTS}
${BISON_Parser_OUTPUTS}
Expressions.cpp
FunctionManager.cpp
Clauses.cpp
SequentialSentences.cpp
MaintainSentences.cpp
Expand Down
85 changes: 85 additions & 0 deletions src/parser/Expressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "base/Base.h"
#include "base/Cord.h"
#include "parser/Expressions.h"
#include "parser/FunctionManager.h"


#define THROW_IF_NO_SPACE(POS, END, REQUIRE) \
Expand Down Expand Up @@ -71,6 +72,8 @@ std::unique_ptr<Expression> Expression::makeExpr(uint8_t kind) {
switch (intToKind(kind)) {
case kPrimary:
return std::make_unique<PrimaryExpression>();
case kFunctionCall:
return std::make_unique<FunctionCallExpression>();
case kUnary:
return std::make_unique<UnaryExpression>();
case kTypeCasting:
Expand Down Expand Up @@ -643,6 +646,88 @@ const char* PrimaryExpression::decode(const char *pos, const char *end) {
}


std::string FunctionCallExpression::toString() const {
std::string buf;
buf.reserve(256);
buf += *name_;
buf += "(";
for (auto &arg : args_) {
buf += arg->toString();
buf += ",";
}
if (!args_.empty()) {
buf.resize(buf.size() - 1);
}
return buf;
}


VariantType FunctionCallExpression::eval() const {
std::vector<VariantType> args;
args.resize(args_.size());
auto eval = [] (auto &expr) {
return expr->eval();
};
std::transform(args_.begin(), args_.end(), args.begin(), eval);
return function_(args);
}


Status FunctionCallExpression::prepare() {
auto result = FunctionManager::get(*name_, args_.size());
if (!result.ok()) {
return std::move(result).status();
}

function_ = std::move(result).value();

auto status = Status::OK();
for (auto &arg : args_) {
status = arg->prepare();
if (!status.ok()) {
break;
}
}
return status;
}


void FunctionCallExpression::encode(Cord &cord) const {
cord << kindToInt(kind());

cord << static_cast<uint16_t>(name_->size());
cord << *name_;

cord << static_cast<uint16_t>(args_.size());
for (auto &arg : args_) {
arg->encode(cord);
}
}


const char* FunctionCallExpression::decode(const char *pos, const char *end) {
THROW_IF_NO_SPACE(pos, end, 2UL);
auto size = *reinterpret_cast<const uint16_t*>(pos);
pos += 2;

THROW_IF_NO_SPACE(pos, end, size);
name_ = std::make_unique<std::string>(pos, size);
pos += size;

auto count = *reinterpret_cast<const uint16_t*>(pos);
pos += 2;

args_.reserve(count);
for (auto i = 0u; i < count; i++) {
THROW_IF_NO_SPACE(pos, end, 1UL);
auto arg = makeExpr(*reinterpret_cast<const uint8_t*>(pos++));
pos = arg->decode(pos, end);
args_.emplace_back(std::move(arg));
}
return pos;
}


std::string UnaryExpression::toString() const {
std::string buf;
buf.reserve(256);
Expand Down
57 changes: 57 additions & 0 deletions src/parser/Expressions.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ class Expression {
kUnknown = 0,

kPrimary,
kFunctionCall,
kUnary,
kTypeCasting,
kArithmetic,
Expand Down Expand Up @@ -251,6 +252,7 @@ class Expression {
// to allow them to call private encode/decode on each other.
friend class PrimaryExpression;
friend class UnaryExpression;
friend class FunctionCallExpression;
friend class TypeCastingExpression;
friend class ArithmeticExpression;
friend class RelationalExpression;
Expand Down Expand Up @@ -603,6 +605,61 @@ class PrimaryExpression final : public Expression {
};


class ArgumentList final {
public:
void addArgument(Expression *arg) {
args_.emplace_back(arg);
}

auto args() {
return std::move(args_);
}

private:
std::vector<std::unique_ptr<Expression>> args_;
};


class FunctionCallExpression final : public Expression {
public:
FunctionCallExpression() {
kind_ = kFunctionCall;
}

FunctionCallExpression(std::string *name, ArgumentList *args) {
kind_ = kFunctionCall;
name_.reset(name);
if (args != nullptr) {
args_ = args->args();
delete args;
}
}

std::string toString() const override;

VariantType eval() const override;

Status MUST_USE_RESULT prepare() override;

void setContext(ExpressionContext *ctx) {
context_ = ctx;
for (auto &arg : args_) {
arg->setContext(ctx);
}
}

private:
void encode(Cord &cord) const override;

const char* decode(const char *pos, const char *end) override;

private:
std::unique_ptr<std::string> name_;
std::vector<std::unique_ptr<Expression>> args_;
std::function<VariantType(const std::vector<VariantType>&)> function_;
};


// +expr, -expr, !expr
class UnaryExpression final : public Expression {
public:
Expand Down
Loading

0 comments on commit ef32037

Please sign in to comment.