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 1834ce81 Fix plan operator child iterator in KQIR (#2282)
1834ce81 is described below

commit 1834ce81823fb5fa1442c24b9d7a84f950438124
Author: Twice <[email protected]>
AuthorDate: Tue Apr 30 01:02:25 2024 +0900

    Fix plan operator child iterator in KQIR (#2282)
---
 src/search/ir_plan.h                | 16 ++++++----
 tests/cppunit/ir_dot_dumper_test.cc | 59 +++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+), 5 deletions(-)

diff --git a/src/search/ir_plan.h b/src/search/ir_plan.h
index 9a81a94a..f93199b5 100644
--- a/src/search/ir_plan.h
+++ b/src/search/ir_plan.h
@@ -44,9 +44,12 @@ struct FullIndexScan : PlanOperator {
 
   explicit FullIndexScan(std::unique_ptr<IndexRef> index) : 
index(std::move(index)) {}
 
-  std::string_view Name() const override { return "FullIndexScan"; };
+  std::string_view Name() const override { return "FullIndexScan"; }
   std::string Dump() const override { return fmt::format("full-scan {}", 
index->name); }
 
+  NodeIterator ChildBegin() override { return NodeIterator{index.get()}; }
+  NodeIterator ChildEnd() override { return {}; }
+
   std::unique_ptr<Node> Clone() const override {
     return 
std::make_unique<FullIndexScan>(Node::MustAs<IndexRef>(index->Clone()));
   }
@@ -56,6 +59,9 @@ struct FieldScan : PlanOperator {
   std::unique_ptr<FieldRef> field;
 
   explicit FieldScan(std::unique_ptr<FieldRef> field) : 
field(std::move(field)) {}
+
+  NodeIterator ChildBegin() override { return NodeIterator{field.get()}; }
+  NodeIterator ChildEnd() override { return {}; }
 };
 
 struct NumericFieldScan : FieldScan {
@@ -67,9 +73,9 @@ struct NumericFieldScan : FieldScan {
 
   std::string_view Name() const override { return "NumericFieldScan"; };
   std::string Content() const override {
-    return fmt::format("{}, {}, {}", field->name, range.ToString(), 
SortByClause::OrderToString(order));
+    return fmt::format("{}, {}", range.ToString(), 
SortByClause::OrderToString(order));
   };
-  std::string Dump() const override { return fmt::format("numeric-scan {}", 
Content()); }
+  std::string Dump() const override { return fmt::format("numeric-scan {}, 
{}", field->name, Content()); }
 
   std::unique_ptr<Node> Clone() const override {
     return std::make_unique<NumericFieldScan>(field->CloneAs<FieldRef>(), 
range, order);
@@ -82,8 +88,8 @@ struct TagFieldScan : FieldScan {
   TagFieldScan(std::unique_ptr<FieldRef> field, std::string tag) : 
FieldScan(std::move(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::string Content() const override { return tag; };
+  std::string Dump() const override { return fmt::format("tag-scan {}, {}", 
field->name, tag); }
 
   std::unique_ptr<Node> Clone() const override {
     return std::make_unique<TagFieldScan>(field->CloneAs<FieldRef>(), tag);
diff --git a/tests/cppunit/ir_dot_dumper_test.cc 
b/tests/cppunit/ir_dot_dumper_test.cc
index 0310eb21..66a588d9 100644
--- a/tests/cppunit/ir_dot_dumper_test.cc
+++ b/tests/cppunit/ir_dot_dumper_test.cc
@@ -24,6 +24,9 @@
 #include <sstream>
 
 #include "gtest/gtest.h"
+#include "search/ir_plan.h"
+#include "search/ir_sema_checker.h"
+#include "search/passes/manager.h"
 #include "search/sql_transformer.h"
 
 using namespace kqir;
@@ -53,3 +56,59 @@ TEST(DotDumperTest, Simple) {
   ASSERT_NE(dot.find(fmt::format("{} -> {}", search_stmt, or_expr)), 
std::string::npos);
   ASSERT_NE(dot.find(fmt::format("{} -> {}", or_expr, and_expr)), 
std::string::npos);
 }
+
+static auto ParseS(SemaChecker& sc, const std::string& in) {
+  auto ir = *Parse(in);
+  EXPECT_EQ(sc.Check(ir.get()).Msg(), Status::ok_msg);
+  return ir;
+}
+
+static IndexMap MakeIndexMap() {
+  auto f1 = FieldInfo("t1", std::make_unique<redis::SearchTagFieldMetadata>());
+  auto f2 = FieldInfo("t2", std::make_unique<redis::SearchTagFieldMetadata>());
+  f2.metadata->noindex = true;
+  auto f3 = FieldInfo("n1", 
std::make_unique<redis::SearchNumericFieldMetadata>());
+  auto f4 = FieldInfo("n2", 
std::make_unique<redis::SearchNumericFieldMetadata>());
+  auto f5 = FieldInfo("n3", 
std::make_unique<redis::SearchNumericFieldMetadata>());
+  f5.metadata->noindex = true;
+  auto ia = IndexInfo("ia", SearchMetadata());
+  ia.Add(std::move(f1));
+  ia.Add(std::move(f2));
+  ia.Add(std::move(f3));
+  ia.Add(std::move(f4));
+  ia.Add(std::move(f5));
+
+  auto& name = ia.name;
+  IndexMap res;
+  res.emplace(name, std::move(ia));
+  return res;
+}
+
+TEST(DotDumperTest, Plan) {
+  auto index_map = MakeIndexMap();
+  SemaChecker sc(index_map);
+  auto plan = PassManager::Execute(
+      PassManager::Default(),
+      ParseS(
+          sc,
+          "select * from ia where (n1 < 2 or n1 >= 3) and (n1 >= 1 and n1 < 4) 
and not n3 != 1 and t2 hastag \"a\""));
+
+  std::stringstream ss;
+  DotDumper dd(ss);
+  dd.Dump(plan.get());
+
+  std::string dot = ss.str();
+  std::smatch matches;
+
+  std::regex_search(dot, matches, std::regex(R"((\w+) \[ label = "Filter)"));
+  auto filter = matches[1].str();
+
+  std::regex_search(dot, matches, std::regex(R"((\w+) \[ label = "Merge)"));
+  auto merge = matches[1].str();
+
+  std::regex_search(dot, matches, std::regex(R"((\w+) \[ label = 
"NumericFieldScan)"));
+  auto scan = matches[1].str();
+
+  ASSERT_NE(dot.find(fmt::format("{} -> {}", filter, merge)), 
std::string::npos);
+  ASSERT_NE(dot.find(fmt::format("{} -> {}", merge, scan)), std::string::npos);
+}

Reply via email to