This is an automated email from the ASF dual-hosted git repository.

twice pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/kvrocks.git


The following commit(s) were added to refs/heads/unstable by this push:
     new fd5c376d Add clone method to KQIR Node (#2234)
fd5c376d is described below

commit fd5c376d2a18c57563435f15249b3b473712328b
Author: Twice <[email protected]>
AuthorDate: Wed Apr 10 22:32:15 2024 +0900

    Add clone method to KQIR Node (#2234)
---
 src/search/ir.h      | 82 ++++++++++++++++++++++++++++++++++++++++++++++++----
 src/search/ir_plan.h | 58 +++++++++++++++++++++++++++++++++++--
 2 files changed, 131 insertions(+), 9 deletions(-)

diff --git a/src/search/ir.h b/src/search/ir.h
index af64588a..6f96c406 100644
--- a/src/search/ir.h
+++ b/src/search/ir.h
@@ -48,6 +48,8 @@ struct Node {
   virtual NodeIterator ChildBegin() { return {}; };
   virtual NodeIterator ChildEnd() { return {}; };
 
+  virtual std::unique_ptr<Node> Clone() const = 0;
+
   virtual ~Node() = default;
 
   template <typename T, typename U = Node, typename... Args>
@@ -70,7 +72,9 @@ struct Node {
   }
 };
 
-struct FieldRef : Node {
+struct Ref : Node {};
+
+struct FieldRef : Ref {
   std::string name;
 
   explicit FieldRef(std::string name) : name(std::move(name)) {}
@@ -78,9 +82,13 @@ struct FieldRef : Node {
   std::string_view Name() const override { return "FieldRef"; }
   std::string Dump() const override { return name; }
   std::string Content() const override { return Dump(); }
+
+  std::unique_ptr<Node> Clone() const override { return 
std::make_unique<FieldRef>(*this); }
 };
 
-struct StringLiteral : Node {
+struct Literal : virtual Node {};
+
+struct StringLiteral : Literal {
   std::string val;
 
   explicit StringLiteral(std::string val) : val(std::move(val)) {}
@@ -88,9 +96,11 @@ struct StringLiteral : Node {
   std::string_view Name() const override { return "StringLiteral"; }
   std::string Dump() const override { return fmt::format("\"{}\"", 
util::EscapeString(val)); }
   std::string Content() const override { return Dump(); }
+
+  std::unique_ptr<Node> Clone() const override { return 
std::make_unique<StringLiteral>(*this); }
 };
 
-struct QueryExpr : Node {};
+struct QueryExpr : virtual Node {};
 
 struct BoolAtomExpr : QueryExpr {};
 
@@ -106,9 +116,14 @@ struct TagContainExpr : BoolAtomExpr {
 
   NodeIterator ChildBegin() override { return {field.get(), tag.get()}; };
   NodeIterator ChildEnd() override { return {}; };
+
+  std::unique_ptr<Node> Clone() const override {
+    return 
std::make_unique<TagContainExpr>(Node::MustAs<FieldRef>(field->Clone()),
+                                            
Node::MustAs<StringLiteral>(tag->Clone()));
+  }
 };
 
-struct NumericLiteral : Node {
+struct NumericLiteral : Literal {
   double val;
 
   explicit NumericLiteral(double val) : val(val) {}
@@ -116,6 +131,8 @@ struct NumericLiteral : Node {
   std::string_view Name() const override { return "NumericLiteral"; }
   std::string Dump() const override { return fmt::format("{}", val); }
   std::string Content() const override { return Dump(); }
+
+  std::unique_ptr<Node> Clone() const override { return 
std::make_unique<NumericLiteral>(*this); }
 };
 
 // NOLINTNEXTLINE
@@ -189,9 +206,14 @@ struct NumericCompareExpr : BoolAtomExpr {
 
   NodeIterator ChildBegin() override { return {field.get(), num.get()}; };
   NodeIterator ChildEnd() override { return {}; };
+
+  std::unique_ptr<Node> Clone() const override {
+    return std::make_unique<NumericCompareExpr>(op, 
Node::MustAs<FieldRef>(field->Clone()),
+                                                
Node::MustAs<NumericLiteral>(num->Clone()));
+  }
 };
 
-struct BoolLiteral : BoolAtomExpr {
+struct BoolLiteral : BoolAtomExpr, Literal {
   bool val;
 
   explicit BoolLiteral(bool val) : val(val) {}
@@ -199,6 +221,8 @@ struct BoolLiteral : BoolAtomExpr {
   std::string_view Name() const override { return "BoolLiteral"; }
   std::string Dump() const override { return val ? "true" : "false"; }
   std::string Content() const override { return Dump(); }
+
+  std::unique_ptr<Node> Clone() const override { return 
std::make_unique<BoolLiteral>(*this); }
 };
 
 struct QueryExpr;
@@ -213,6 +237,10 @@ struct NotExpr : QueryExpr {
 
   NodeIterator ChildBegin() override { return NodeIterator{inner.get()}; };
   NodeIterator ChildEnd() override { return {}; };
+
+  std::unique_ptr<Node> Clone() const override {
+    return std::make_unique<NotExpr>(Node::MustAs<QueryExpr>(inner->Clone()));
+  }
 };
 
 struct AndExpr : QueryExpr {
@@ -227,6 +255,15 @@ struct AndExpr : QueryExpr {
 
   NodeIterator ChildBegin() override { return NodeIterator(inners.begin()); };
   NodeIterator ChildEnd() override { return NodeIterator(inners.end()); };
+
+  std::unique_ptr<Node> Clone() const override {
+    std::vector<std::unique_ptr<QueryExpr>> res;
+    res.reserve(inners.size());
+    for (const auto &n : inners) {
+      res.push_back(Node::MustAs<QueryExpr>(n->Clone()));
+    }
+    return std::make_unique<AndExpr>(std::move(res));
+  }
 };
 
 struct OrExpr : QueryExpr {
@@ -241,6 +278,15 @@ struct OrExpr : QueryExpr {
 
   NodeIterator ChildBegin() override { return NodeIterator(inners.begin()); };
   NodeIterator ChildEnd() override { return NodeIterator(inners.end()); };
+
+  std::unique_ptr<Node> Clone() const override {
+    std::vector<std::unique_ptr<QueryExpr>> res;
+    res.reserve(inners.size());
+    for (const auto &n : inners) {
+      res.push_back(Node::MustAs<QueryExpr>(n->Clone()));
+    }
+    return std::make_unique<OrExpr>(std::move(res));
+  }
 };
 
 struct LimitClause : Node {
@@ -252,6 +298,8 @@ struct LimitClause : Node {
   std::string_view Name() const override { return "LimitClause"; }
   std::string Dump() const override { return fmt::format("limit {}, {}", 
offset, count); }
   std::string Content() const override { return fmt::format("{}, {}", offset, 
count); }
+
+  std::unique_ptr<Node> Clone() const override { return 
std::make_unique<LimitClause>(*this); }
 };
 
 struct SortByClause : Node {
@@ -268,6 +316,10 @@ struct SortByClause : Node {
 
   NodeIterator ChildBegin() override { return NodeIterator(field.get()); };
   NodeIterator ChildEnd() override { return {}; };
+
+  std::unique_ptr<Node> Clone() const override {
+    return std::make_unique<SortByClause>(order, 
Node::MustAs<FieldRef>(field->Clone()));
+  }
 };
 
 struct SelectExpr : Node {
@@ -283,9 +335,18 @@ struct SelectExpr : Node {
 
   NodeIterator ChildBegin() override { return NodeIterator(fields.begin()); };
   NodeIterator ChildEnd() override { return NodeIterator(fields.end()); };
+
+  std::unique_ptr<Node> Clone() const override {
+    std::vector<std::unique_ptr<FieldRef>> res;
+    res.reserve(fields.size());
+    for (const auto &f : fields) {
+      res.push_back(Node::MustAs<FieldRef>(f->Clone()));
+    }
+    return std::make_unique<SelectExpr>(std::move(res));
+  }
 };
 
-struct IndexRef : Node {
+struct IndexRef : Ref {
   std::string name;
 
   explicit IndexRef(std::string name) : name(std::move(name)) {}
@@ -293,6 +354,8 @@ struct IndexRef : Node {
   std::string_view Name() const override { return "IndexRef"; }
   std::string Dump() const override { return name; }
   std::string Content() const override { return Dump(); }
+
+  std::unique_ptr<Node> Clone() const override { return 
std::make_unique<IndexRef>(*this); }
 };
 
 struct SearchStmt : Node {
@@ -328,6 +391,13 @@ struct SearchStmt : Node {
 
   NodeIterator ChildBegin() override { return NodeIterator(this, 
ChildMap.begin()); };
   NodeIterator ChildEnd() override { return NodeIterator(this, 
ChildMap.end()); };
+
+  std::unique_ptr<Node> Clone() const override {
+    return std::make_unique<SearchStmt>(
+        Node::MustAs<IndexRef>(index->Clone()), 
Node::MustAs<QueryExpr>(query_expr->Clone()),
+        Node::MustAs<LimitClause>(limit->Clone()), 
Node::MustAs<SortByClause>(sort_by->Clone()),
+        Node::MustAs<SelectExpr>(select_expr->Clone()));
+  }
 };
 
 }  // namespace kqir
diff --git a/src/search/ir_plan.h b/src/search/ir_plan.h
index e718a33a..ebe2d668 100644
--- a/src/search/ir_plan.h
+++ b/src/search/ir_plan.h
@@ -34,51 +34,77 @@ struct PlanOperator : Node {};
 struct FullIndexScan : PlanOperator {
   IndexInfo *index;
 
+  explicit FullIndexScan(IndexInfo *index) : index(index) {}
+
   std::string_view Name() const override { return "FullIndexScan"; };
   std::string Content() const override { return index->name; };
   std::string Dump() const override { return fmt::format("full-scan {}", 
Content()); }
+
+  std::unique_ptr<Node> Clone() const override { return 
std::make_unique<FullIndexScan>(*this); }
 };
 
 struct FieldScan : PlanOperator {
   FieldInfo *field;
+
+  explicit FieldScan(FieldInfo *field) : field(field) {}
 };
 
 struct Interval {
   double l, r;  // [l, r)
 
+  explicit Interval(double l, double r) : l(l), r(r) {}
+
   std::string ToString() const { return fmt::format("[{}, {})", l, r); }
 };
 
 struct NumericFieldScan : FieldScan {
   Interval range;
 
+  NumericFieldScan(FieldInfo *field, Interval range) : FieldScan(field), 
range(range) {}
+
   std::string_view Name() const override { return "NumericFieldScan"; };
   std::string Content() const override { return fmt::format("{}, {}", 
field->name, range.ToString()); };
   std::string Dump() const override { return fmt::format("numeric-scan {}", 
Content()); }
+
+  std::unique_ptr<Node> Clone() const override { return 
std::make_unique<NumericFieldScan>(*this); }
 };
 
 struct TagFieldScan : FieldScan {
   std::string tag;
 
+  TagFieldScan(FieldInfo *field, std::string tag) : FieldScan(field), 
tag(std::move(tag)) {}
+
   std::string_view Name() const override { return "TagFieldScan"; };
   std::string Content() const override { return fmt::format("{}, {}", 
field->name, tag); };
   std::string Dump() const override { return fmt::format("tag-scan {}", 
Content()); }
+
+  std::unique_ptr<Node> Clone() const override { return 
std::make_unique<TagFieldScan>(*this); }
 };
 
 struct Filter : PlanOperator {
   std::unique_ptr<PlanOperator> source;
   std::unique_ptr<QueryExpr> filter_expr;
 
+  Filter(std::unique_ptr<PlanOperator> &&source, std::unique_ptr<QueryExpr> 
&&filter_expr)
+      : source(std::move(source)), filter_expr(std::move(filter_expr)) {}
+
   std::string_view Name() const override { return "Filter"; };
   std::string Dump() const override { return fmt::format("(filter {}, {})", 
source->Dump(), Content()); }
 
   NodeIterator ChildBegin() override { return {source.get(), 
filter_expr.get()}; }
   NodeIterator ChildEnd() override { return {}; }
+
+  std::unique_ptr<Node> Clone() const override {
+    return 
std::make_unique<Filter>(Node::MustAs<PlanOperator>(source->Clone()),
+                                    
Node::MustAs<QueryExpr>(filter_expr->Clone()));
+  }
 };
 
 struct Merge : PlanOperator {
   std::vector<std::unique_ptr<PlanOperator>> ops;
 
+  explicit Merge(std::vector<std::unique_ptr<PlanOperator>> &&ops) : 
ops(std::move(ops)) {}
+
   std::string_view Name() const override { return "Merge"; };
   std::string Dump() const override {
     return fmt::format("(merge {})", util::StringJoin(ops, [](const auto &v) { 
return v->Dump(); }));
@@ -86,28 +112,54 @@ struct Merge : PlanOperator {
 
   NodeIterator ChildBegin() override { return NodeIterator(ops.begin()); }
   NodeIterator ChildEnd() override { return NodeIterator(ops.end()); }
+
+  std::unique_ptr<Node> Clone() const override {
+    std::vector<std::unique_ptr<PlanOperator>> res;
+    res.reserve(ops.size());
+    for (const auto &op : ops) {
+      res.push_back(Node::MustAs<PlanOperator>(op->Clone()));
+    }
+    return std::make_unique<Merge>(std::move(res));
+  }
 };
 
 struct Limit : PlanOperator {
   std::unique_ptr<PlanOperator> op;
-  size_t offset = 0, count = std::numeric_limits<size_t>::max();
+  std::unique_ptr<LimitClause> limit;
+
+  Limit(std::unique_ptr<PlanOperator> &&op, std::unique_ptr<LimitClause> 
&&limit)
+      : op(std::move(op)), limit(std::move(limit)) {}
 
   std::string_view Name() const override { return "Limit"; };
-  std::string Dump() const override { return fmt::format("(limit {}, {}: {})", 
offset, count, op->Dump()); }
+  std::string Dump() const override {
+    return fmt::format("(limit {}, {}: {})", limit->offset, limit->count, 
op->Dump());
+  }
 
-  NodeIterator ChildBegin() override { return NodeIterator{op.get()}; }
+  NodeIterator ChildBegin() override { return NodeIterator{op.get(), 
limit.get()}; }
   NodeIterator ChildEnd() override { return {}; }
+
+  std::unique_ptr<Node> Clone() const override {
+    return std::make_unique<Limit>(Node::MustAs<PlanOperator>(op->Clone()), 
Node::MustAs<LimitClause>(limit->Clone()));
+  }
 };
 
 struct Projection : PlanOperator {
   std::unique_ptr<PlanOperator> source;
   std::unique_ptr<SelectExpr> select;
 
+  Projection(std::unique_ptr<PlanOperator> &&source, 
std::unique_ptr<SelectExpr> &&select)
+      : source(std::move(source)), select(std::move(select)) {}
+
   std::string_view Name() const override { return "Projection"; };
   std::string Dump() const override { return fmt::format("(project {}: {})", 
select, source); }
 
   NodeIterator ChildBegin() override { return {source.get(), select.get()}; }
   NodeIterator ChildEnd() override { return {}; }
+
+  std::unique_ptr<Node> Clone() const override {
+    return 
std::make_unique<Projection>(Node::MustAs<PlanOperator>(source->Clone()),
+                                        
Node::MustAs<SelectExpr>(select->Clone()));
+  }
 };
 
 }  // namespace kqir

Reply via email to