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 66595db3 Initialize the query plan part of KQIR (#2232)
66595db3 is described below

commit 66595db3f89c3b4738703fe84e8d94ac51cb30e2
Author: Twice <[email protected]>
AuthorDate: Tue Apr 9 20:38:33 2024 +0900

    Initialize the query plan part of KQIR (#2232)
---
 src/search/ir.h              |  21 ++++----
 src/search/ir_pass.h         |  12 ++---
 src/search/ir_plan.h         | 113 +++++++++++++++++++++++++++++++++++++++++++
 src/search/ir_sema_checker.h |   4 +-
 src/search/sql_transformer.h |  16 +++---
 5 files changed, 140 insertions(+), 26 deletions(-)

diff --git a/src/search/ir.h b/src/search/ir.h
index 6e3dea28..af64588a 100644
--- a/src/search/ir.h
+++ b/src/search/ir.h
@@ -243,26 +243,26 @@ struct OrExpr : QueryExpr {
   NodeIterator ChildEnd() override { return NodeIterator(inners.end()); };
 };
 
-struct Limit : Node {
+struct LimitClause : 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) {}
+  LimitClause(size_t offset, size_t count) : offset(offset), count(count) {}
 
-  std::string_view Name() const override { return "Limit"; }
+  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); }
 };
 
-struct SortBy : Node {
+struct SortByClause : 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)) {}
+  SortByClause(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"; }
 
-  std::string_view Name() const override { return "SortBy"; }
+  std::string_view Name() const override { return "SortByClause"; }
   std::string Dump() const override { return fmt::format("sortby {}, {}", 
field->Dump(), OrderToString(order)); }
   std::string Content() const override { return OrderToString(order); }
 
@@ -299,11 +299,12 @@ struct SearchStmt : Node {
   std::unique_ptr<SelectExpr> select_expr;
   std::unique_ptr<IndexRef> index;
   std::unique_ptr<QueryExpr> query_expr;  // optional
-  std::unique_ptr<Limit> limit;           // optional
-  std::unique_ptr<SortBy> sort_by;        // optional
+  std::unique_ptr<LimitClause> limit;     // optional
+  std::unique_ptr<SortByClause> sort_by;  // optional
 
-  SearchStmt(std::unique_ptr<IndexRef> &&index, std::unique_ptr<QueryExpr> 
&&query_expr, std::unique_ptr<Limit> &&limit,
-             std::unique_ptr<SortBy> &&sort_by, std::unique_ptr<SelectExpr> 
&&select_expr)
+  SearchStmt(std::unique_ptr<IndexRef> &&index, std::unique_ptr<QueryExpr> 
&&query_expr,
+             std::unique_ptr<LimitClause> &&limit, 
std::unique_ptr<SortByClause> &&sort_by,
+             std::unique_ptr<SelectExpr> &&select_expr)
       : select_expr(std::move(select_expr)),
         index(std::move(index)),
         query_expr(std::move(query_expr)),
diff --git a/src/search/ir_pass.h b/src/search/ir_pass.h
index 9a67530a..a4db9a28 100644
--- a/src/search/ir_pass.h
+++ b/src/search/ir_pass.h
@@ -36,9 +36,9 @@ struct Visitor : Pass {
       return Visit(std::move(v));
     } else if (auto v = Node::As<IndexRef>(std::move(node))) {
       return Visit(std::move(v));
-    } else if (auto v = Node::As<Limit>(std::move(node))) {
+    } else if (auto v = Node::As<LimitClause>(std::move(node))) {
       return Visit(std::move(v));
-    } else if (auto v = Node::As<SortBy>(std::move(node))) {
+    } else if (auto v = Node::As<SortByClause>(std::move(node))) {
       return Visit(std::move(v));
     } else if (auto v = Node::As<AndExpr>(std::move(node))) {
       return Visit(std::move(v));
@@ -77,8 +77,8 @@ struct Visitor : Pass {
     node->index = VisitAs<IndexRef>(std::move(node->index));
     node->select_expr = VisitAs<SelectExpr>(std::move(node->select_expr));
     if (node->query_expr) node->query_expr = 
TransformAs<QueryExpr>(std::move(node->query_expr));
-    if (node->sort_by) node->sort_by = 
VisitAs<SortBy>(std::move(node->sort_by));
-    if (node->limit) node->limit = VisitAs<Limit>(std::move(node->limit));
+    if (node->sort_by) node->sort_by = 
VisitAs<SortByClause>(std::move(node->sort_by));
+    if (node->limit) node->limit = 
VisitAs<LimitClause>(std::move(node->limit));
     return node;
   }
 
@@ -133,9 +133,9 @@ struct Visitor : Pass {
     return node;
   }
 
-  virtual std::unique_ptr<Node> Visit(std::unique_ptr<Limit> node) { return 
node; }
+  virtual std::unique_ptr<Node> Visit(std::unique_ptr<LimitClause> node) { 
return node; }
 
-  virtual std::unique_ptr<Node> Visit(std::unique_ptr<SortBy> node) {
+  virtual std::unique_ptr<Node> Visit(std::unique_ptr<SortByClause> node) {
     node->field = VisitAs<FieldRef>(std::move(node->field));
     return node;
   }
diff --git a/src/search/ir_plan.h b/src/search/ir_plan.h
new file mode 100644
index 00000000..e718a33a
--- /dev/null
+++ b/src/search/ir_plan.h
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#pragma once
+
+#include <limits>
+#include <memory>
+
+#include "ir.h"
+#include "search/ir_sema_checker.h"
+#include "string_util.h"
+
+namespace kqir {
+
+struct PlanOperator : Node {};
+
+struct FullIndexScan : PlanOperator {
+  IndexInfo *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()); }
+};
+
+struct FieldScan : PlanOperator {
+  FieldInfo *field;
+};
+
+struct Interval {
+  double l, r;  // [l, r)
+
+  std::string ToString() const { return fmt::format("[{}, {})", l, r); }
+};
+
+struct NumericFieldScan : FieldScan {
+  Interval 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()); }
+};
+
+struct TagFieldScan : FieldScan {
+  std::string 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()); }
+};
+
+struct Filter : PlanOperator {
+  std::unique_ptr<PlanOperator> source;
+  std::unique_ptr<QueryExpr> 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 {}; }
+};
+
+struct Merge : PlanOperator {
+  std::vector<std::unique_ptr<PlanOperator>> 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(); }));
+  }
+
+  NodeIterator ChildBegin() override { return NodeIterator(ops.begin()); }
+  NodeIterator ChildEnd() override { return NodeIterator(ops.end()); }
+};
+
+struct Limit : PlanOperator {
+  std::unique_ptr<PlanOperator> op;
+  size_t offset = 0, count = std::numeric_limits<size_t>::max();
+
+  std::string_view Name() const override { return "Limit"; };
+  std::string Dump() const override { return fmt::format("(limit {}, {}: {})", 
offset, count, op->Dump()); }
+
+  NodeIterator ChildBegin() override { return NodeIterator{op.get()}; }
+  NodeIterator ChildEnd() override { return {}; }
+};
+
+struct Projection : PlanOperator {
+  std::unique_ptr<PlanOperator> source;
+  std::unique_ptr<SelectExpr> 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 {}; }
+};
+
+}  // namespace kqir
diff --git a/src/search/ir_sema_checker.h b/src/search/ir_sema_checker.h
index 77427c7c..1660d7f1 100644
--- a/src/search/ir_sema_checker.h
+++ b/src/search/ir_sema_checker.h
@@ -82,9 +82,9 @@ struct SemaChecker {
       } else {
         return {Status::NotOK, fmt::format("index `{}` not found", 
index_name)};
       }
-    } else if (auto v [[maybe_unused]] = dynamic_cast<Limit *>(node)) {
+    } else if (auto v [[maybe_unused]] = dynamic_cast<LimitClause *>(node)) {
       return Status::OK();
-    } else if (auto v = dynamic_cast<SortBy *>(node)) {
+    } else if (auto v = dynamic_cast<SortByClause *>(node)) {
       if (auto iter = current_index->fields.find(v->field->name); iter == 
current_index->fields.end()) {
         return {Status::NotOK, fmt::format("field `{}` not found in index 
`{}`", v->field->name, current_index->name)};
       } else {
diff --git a/src/search/sql_transformer.h b/src/search/sql_transformer.h
index 63397e40..eb3a1cd0 100644
--- a/src/search/sql_transformer.h
+++ b/src/search/sql_transformer.h
@@ -132,18 +132,18 @@ struct Transformer : ir::TreeTransformer {
         count = *ParseInt(node->children[1]->string());
       }
 
-      return Node::Create<ir::Limit>(offset, count);
+      return Node::Create<ir::LimitClause>(offset, count);
     }
     if (Is<OrderByClause>(node)) {
       CHECK(node->children.size() == 1 || node->children.size() == 2);
 
       auto field = std::make_unique<FieldRef>(node->children[0]->string());
-      auto order = SortBy::Order::ASC;
+      auto order = SortByClause::Order::ASC;
       if (node->children.size() == 2 && node->children[1]->string_view() == 
"desc") {
-        order = SortBy::Order::DESC;
+        order = SortByClause::Order::DESC;
       }
 
-      return Node::Create<SortBy>(order, std::move(field));
+      return Node::Create<SortByClause>(order, std::move(field));
     } else if (Is<SearchStmt>(node)) {  // root node
       CHECK(node->children.size() >= 2 && node->children.size() <= 5);
 
@@ -151,16 +151,16 @@ struct Transformer : ir::TreeTransformer {
       auto select = 
Node::MustAs<ir::SelectExpr>(GET_OR_RET(Transform(node->children[0])));
 
       std::unique_ptr<ir::QueryExpr> query_expr;
-      std::unique_ptr<ir::Limit> limit;
-      std::unique_ptr<ir::SortBy> sort_by;
+      std::unique_ptr<ir::LimitClause> limit;
+      std::unique_ptr<ir::SortByClause> sort_by;
 
       for (size_t i = 2; i < node->children.size(); ++i) {
         if (Is<WhereClause>(node->children[i])) {
           query_expr = 
Node::MustAs<ir::QueryExpr>(GET_OR_RET(Transform(node->children[i])));
         } else if (Is<LimitClause>(node->children[i])) {
-          limit = 
Node::MustAs<ir::Limit>(GET_OR_RET(Transform(node->children[i])));
+          limit = 
Node::MustAs<ir::LimitClause>(GET_OR_RET(Transform(node->children[i])));
         } else if (Is<OrderByClause>(node->children[i])) {
-          sort_by = 
Node::MustAs<ir::SortBy>(GET_OR_RET(Transform(node->children[i])));
+          sort_by = 
Node::MustAs<ir::SortByClause>(GET_OR_RET(Transform(node->children[i])));
         }
       }
 

Reply via email to