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 ec3d9032 fix(search): misidentify DESC token in SQL parser (#2439)
ec3d9032 is described below

commit ec3d9032deb7aef3e238570cfa9eeb607491e2e6
Author: Twice <[email protected]>
AuthorDate: Sun Jul 21 17:37:24 2024 +0900

    fix(search): misidentify DESC token in SQL parser (#2439)
---
 src/search/ir.h                  |  4 ++--
 src/search/passes/manager.h      | 14 ++++++++++++++
 src/search/passes/recorder.h     | 41 ++++++++++++++++++++++++++++++++++++++++
 src/search/sql_parser.h          |  4 ++--
 src/search/sql_transformer.h     |  3 +--
 tests/cppunit/sql_parser_test.cc |  1 +
 6 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/src/search/ir.h b/src/search/ir.h
index 72cb7351..116fe9a7 100644
--- a/src/search/ir.h
+++ b/src/search/ir.h
@@ -432,8 +432,8 @@ struct SearchExpr : Node {
   std::unique_ptr<Node> Clone() const override {
     return std::make_unique<SearchExpr>(
         Node::MustAs<IndexRef>(index->Clone()), 
Node::MustAs<QueryExpr>(query_expr->Clone()),
-        Node::MustAs<LimitClause>(limit->Clone()), 
Node::MustAs<SortByClause>(sort_by->Clone()),
-        Node::MustAs<SelectClause>(select->Clone()));
+        limit ? Node::MustAs<LimitClause>(limit->Clone()) : nullptr,
+        sort_by ? Node::MustAs<SortByClause>(sort_by->Clone()) : nullptr, 
Node::MustAs<SelectClause>(select->Clone()));
   }
 };
 
diff --git a/src/search/passes/manager.h b/src/search/passes/manager.h
index e94a12e9..57f317d2 100644
--- a/src/search/passes/manager.h
+++ b/src/search/passes/manager.h
@@ -31,6 +31,7 @@
 #include "search/passes/interval_analysis.h"
 #include "search/passes/lower_to_plan.h"
 #include "search/passes/push_down_not_expr.h"
+#include "search/passes/recorder.h"
 #include "search/passes/simplify_and_or_expr.h"
 #include "search/passes/simplify_boolean.h"
 #include "search/passes/sort_limit_fuse.h"
@@ -60,6 +61,18 @@ struct PassManager {
     return result;
   }
 
+  static PassSequence FullRecord(PassSequence &&seq, 
std::vector<std::unique_ptr<Node>> &results) {
+    PassSequence res_seq;
+    res_seq.push_back(std::make_unique<Recorder>(results));
+
+    for (auto &p : seq) {
+      res_seq.push_back(std::move(p));
+      res_seq.push_back(std::make_unique<Recorder>(results));
+    }
+
+    return res_seq;
+  }
+
   template <typename... PassSeqs>
   static PassSequence Merge(PassSeqs &&...seqs) {
     
static_assert(std::conjunction_v<std::negation<std::is_reference<PassSeqs>>...>);
@@ -79,6 +92,7 @@ struct PassManager {
   static PassSequence PlanPasses() { return Create(LowerToPlan{}, 
IndexSelection{}, SortLimitFuse{}); }
 
   static PassSequence Default() { return Merge(ExprPasses(), NumericPasses(), 
PlanPasses()); }
+  static PassSequence Debug(std::vector<std::unique_ptr<Node>> &recorded) { 
return FullRecord(Default(), recorded); }
 };
 
 }  // namespace kqir
diff --git a/src/search/passes/recorder.h b/src/search/passes/recorder.h
new file mode 100644
index 00000000..e68fa673
--- /dev/null
+++ b/src/search/passes/recorder.h
@@ -0,0 +1,41 @@
+/*
+ * 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 <memory>
+
+#include "search/ir.h"
+#include "search/ir_pass.h"
+
+namespace kqir {
+
+struct Recorder : Pass {
+  std::vector<std::unique_ptr<Node>> &results;
+
+  explicit Recorder(std::vector<std::unique_ptr<Node>> &results) : 
results(results) {}
+
+  std::unique_ptr<Node> Transform(std::unique_ptr<Node> node) override {
+    results.push_back(node->Clone());
+    return node;
+  }
+};
+
+}  // namespace kqir
diff --git a/src/search/sql_parser.h b/src/search/sql_parser.h
index 26e3da6d..9a611d9b 100644
--- a/src/search/sql_parser.h
+++ b/src/search/sql_parser.h
@@ -79,8 +79,8 @@ struct Desc : string<'d', 'e', 's', 'c'> {};
 struct Limit : string<'l', 'i', 'm', 'i', 't'> {};
 
 struct WhereClause : seq<Where, QueryExpr> {};
-struct AscOrDesc : WSPad<sor<Asc, Desc>> {};
-struct OrderByClause : seq<OrderBy, WSPad<Identifier>, opt<AscOrDesc>> {};
+struct AscOrDesc : sor<Asc, Desc> {};
+struct OrderByClause : seq<OrderBy, WSPad<Identifier>, opt<WSPad<AscOrDesc>>> 
{};
 struct LimitClause : seq<Limit, opt<seq<WSPad<UnsignedInteger>, one<','>>>, 
WSPad<UnsignedInteger>> {};
 
 struct SearchStmt
diff --git a/src/search/sql_transformer.h b/src/search/sql_transformer.h
index 972ae894..72aa0de7 100644
--- a/src/search/sql_transformer.h
+++ b/src/search/sql_transformer.h
@@ -133,8 +133,7 @@ struct Transformer : ir::TreeTransformer {
       }
 
       return Node::Create<ir::LimitClause>(offset, count);
-    }
-    if (Is<OrderByClause>(node)) {
+    } else if (Is<OrderByClause>(node)) {
       CHECK(node->children.size() == 1 || node->children.size() == 2);
 
       auto field = std::make_unique<FieldRef>(node->children[0]->string());
diff --git a/tests/cppunit/sql_parser_test.cc b/tests/cppunit/sql_parser_test.cc
index a566d965..c6fc96ba 100644
--- a/tests/cppunit/sql_parser_test.cc
+++ b/tests/cppunit/sql_parser_test.cc
@@ -125,6 +125,7 @@ TEST(SQLParserTest, Simple) {
   AssertIR(Parse("select a from b limit 2, 3"), "select a from b where true 
limit 2, 3");
   AssertIR(Parse("select a from b order by a"), "select a from b where true 
sortby a, asc");
   AssertIR(Parse("select a from b order by c desc"), "select a from b where 
true sortby c, desc");
+  AssertIR(Parse("select a from b order by c desc limit 10"), "select a from b 
where true sortby c, desc limit 0, 10");
   AssertIR(Parse("select a from b order by a limit 10"), "select a from b 
where true sortby a, asc limit 0, 10");
   AssertIR(Parse("select a from b where c = 1 limit 10"), "select a from b 
where c = 1 limit 0, 10");
   AssertIR(Parse("select a from b where c = 1 and d hastag \"x\" order by e"),

Reply via email to