PragmaTwice commented on code in PR #2184:
URL: https://github.com/apache/kvrocks/pull/2184#discussion_r1536561267
##########
src/search/ir.h:
##########
@@ -20,87 +20,243 @@
#pragma once
+#include <fmt/format.h>
+
#include <limits>
#include <memory>
+#include <optional>
#include <string>
+#include <utility>
#include <variant>
#include <vector>
+#include "fmt/core.h"
+#include "string_util.h"
+
// kqir stands for Kvorcks Query Intermediate Representation
namespace kqir {
-struct FieldRef {
+struct Node {
+ virtual std::string Dump() const = 0;
+ virtual ~Node() = default;
+
+ template <typename T, typename U = Node, typename... Args>
+ static std::unique_ptr<U> Create(Args &&...args) {
+ return std::unique_ptr<U>(new T(std::forward<Args>(args)...));
+ }
+
+ template <typename T>
+ static std::unique_ptr<T> As(std::unique_ptr<Node> &&original) {
+ auto casted = dynamic_cast<T *>(original.release());
+ CHECK(casted);
+ return std::unique_ptr<T>(casted);
+ }
+};
+
+struct FieldRef : Node {
std::string name;
+
+ explicit FieldRef(std::string name) : name(std::move(name)) {}
+
+ std::string Dump() const override { return name; }
};
-struct StringLiteral {
+struct StringLiteral : Node {
std::string val;
+
+ explicit StringLiteral(std::string val) : val(std::move(val)) {}
+
+ std::string Dump() const override { return fmt::format("\"{}\"",
util::EscapeString(val)); }
};
-struct TagContainExpr {
- FieldRef field;
- StringLiteral tag;
+struct QueryExpr : Node {};
+
+struct BoolAtomExpr : QueryExpr {};
+
+struct TagContainExpr : BoolAtomExpr {
+ std::unique_ptr<FieldRef> field;
+ std::unique_ptr<StringLiteral> tag;
+
+ TagContainExpr(std::unique_ptr<FieldRef> &&field,
std::unique_ptr<StringLiteral> &&tag)
+ : field(std::move(field)), tag(std::move(tag)) {}
+
+ std::string Dump() const override { return fmt::format("{} hastag {}",
field->Dump(), tag->Dump()); }
};
-struct NumericLiteral {
+struct NumericLiteral : Node {
double val;
+
+ explicit NumericLiteral(double val) : val(val) {}
+
+ std::string Dump() const override { return fmt::format("{}", val); }
};
-struct NumericCompareExpr {
- enum { EQ, NE, LT, LET, GT, GET } op;
- FieldRef field;
- NumericLiteral num;
+// NOLINTNEXTLINE
+#define KQIR_NUMERIC_COMPARE_OPS(X) \
+ X(EQ, =, NE, EQ) X(NE, !=, EQ, NE) X(LT, <, GET, GT) X(LET, <=, GT, GET)
X(GT, >, LET, LT) X(GET, >=, LT, LET)
+
+struct NumericCompareExpr : BoolAtomExpr {
+ enum Op {
+#define X(n, s, o, f) n, // NOLINT
+ KQIR_NUMERIC_COMPARE_OPS(X)
+#undef X
+ } op;
+ std::unique_ptr<FieldRef> field;
+ std::unique_ptr<NumericLiteral> num;
+
+ NumericCompareExpr(Op op, std::unique_ptr<FieldRef> &&field,
std::unique_ptr<NumericLiteral> &&num)
+ : op(op), field(std::move(field)), num(std::move(num)) {}
+
+ static constexpr const char *ToOperator(Op op) {
+ switch (op) {
+// NOLINTNEXTLINE
+#define X(n, s, o, f) \
+ case n: \
+ return #s;
+ KQIR_NUMERIC_COMPARE_OPS(X)
+#undef X
+ }
+
+ return nullptr;
+ }
+
+ static constexpr std::optional<Op> FromOperator(std::string_view op) {
+// NOLINTNEXTLINE
+#define X(n, s, o, f) \
+ if (op == #s) return n;
+ KQIR_NUMERIC_COMPARE_OPS(X)
+#undef X
+
+ return std::nullopt;
+ }
+
+ static constexpr Op Negative(Op op) {
+ switch (op) {
+// NOLINTNEXTLINE
+#define X(n, s, o, f) \
+ case n: \
+ return o;
+ KQIR_NUMERIC_COMPARE_OPS(X)
+#undef X
+ }
+
+ __builtin_unreachable();
+ }
+
+ static constexpr Op Flip(Op op) {
+ switch (op) {
+// NOLINTNEXTLINE
+#define X(n, s, o, f) \
+ case n: \
+ return f;
+ KQIR_NUMERIC_COMPARE_OPS(X)
+#undef X
+ }
+
+ __builtin_unreachable();
+ }
+
+ std::string Dump() const override { return fmt::format("{} {} {}",
field->Dump(), ToOperator(op), num->Dump()); };
};
-struct BoolLiteral {
+struct BoolLiteral : BoolAtomExpr {
bool val;
-};
-struct BooleanExpr {
- std::variant<TagContainExpr, NumericCompareExpr, BoolLiteral> expr;
+ explicit BoolLiteral(bool val) : val(val) {}
+
+ std::string Dump() const override { return val ? "true" : "false"; }
};
struct QueryExpr;
-struct LogicalUnaryExpr {
- enum { NOT } op;
+struct NotExpr : QueryExpr {
std::unique_ptr<QueryExpr> inner;
+
+ explicit NotExpr(std::unique_ptr<QueryExpr> &&inner) :
inner(std::move(inner)) {}
+
+ std::string Dump() const override { return fmt::format("not {}",
inner->Dump()); }
};
-struct LogicalBinaryExpr {
- enum { AND, OR } op;
- std::unique_ptr<QueryExpr> lhs;
- std::unique_ptr<QueryExpr> rhs;
+struct AndExpr : QueryExpr {
+ std::vector<std::unique_ptr<QueryExpr>> inners;
+
+ explicit AndExpr(std::vector<std::unique_ptr<QueryExpr>> &&inners) :
inners(std::move(inners)) {}
+
+ std::string Dump() const override {
+ return fmt::format("(and {})", util::StringJoin(inners, [](const auto &v)
{ return v->Dump(); }));
+ }
};
-struct QueryExpr {
- std::variant<LogicalUnaryExpr, LogicalBinaryExpr, BooleanExpr> expr;
+struct OrExpr : QueryExpr {
+ std::vector<std::unique_ptr<QueryExpr>> inners;
+
+ explicit OrExpr(std::vector<std::unique_ptr<QueryExpr>> &&inners) :
inners(std::move(inners)) {}
+
+ std::string Dump() const override {
+ return fmt::format("(or {})", util::StringJoin(inners, [](const auto &v) {
return v->Dump(); }));
+ }
};
-struct Limit {
+struct Limit : Node {
size_t offset = 0;
size_t count = std::numeric_limits<size_t>::max();
+
+ Limit(size_t offset, size_t count) : offset(offset), count(count) {}
+
+ std::string Dump() const override { return fmt::format("limit {}, {}",
offset, count); }
};
-struct SortBy {
- enum { ASC, DESC } order;
- FieldRef field;
+struct SortBy : Node {
+ enum Order { ASC, DESC } order = ASC;
+ std::unique_ptr<FieldRef> field;
+
+ SortBy(Order order, std::unique_ptr<FieldRef> &&field) : order(order),
field(std::move(field)) {}
+
+ static constexpr const char *OrderToString(Order order) { return order ==
ASC ? "asc" : "desc"; }
Review Comment:
Hmm I see. I'll change it later.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]