Pārlūkot izejas kodu

添加比较时类型检查

myuan 2 gadi atpakaļ
vecāks
revīzija
71ef1afed7
4 mainītis faili ar 50 papildinājumiem un 1 dzēšanām
  1. 20 0
      src/checker.cpp
  2. 14 0
      src/utils.cpp
  3. 9 0
      src/utils.h
  4. 7 1
      tests_config.py

+ 20 - 0
src/checker.cpp

@@ -45,7 +45,27 @@ void check_where_clause(const vector<string> table_names, const json& j) {
                     fmt::format("column `{}` not exists in `{}`\n",
                                 select_column_get_name(curr_branch),
                                 fmt::join(table_names, ", ")));
+            } else {
+                if (curr_branch_name == "right" &&
+                    op_type_of(j) == OpType::OP_COMPARE) {
+                    // 如果左右分支都是普通列, 并且当前节点操作符是比较,
+                    // 那么应当判断类型是否一致 如果能走到right,
+                    // 说明left也是普通列
+                    let curr_left_col_def =
+                        tables.get_select_column_define(table_names, left);
+                    if (curr_left_col_def.value().data_type !=
+                        col_def.value().data_type) {
+                        throw std::runtime_error(
+                            fmt::format("column `{}` type is `{}`, but `{}` "
+                                        "type is `{}`, cannot `{}` \n",
+                                        select_column_get_name(left),
+                                        curr_left_col_def.value().data_type,
+                                        select_column_get_name(curr_branch),
+                                        col_def.value().data_type, j["type"]));
+                    }
+                }
             }
+
         } else {
             check_where_clause(table_names, curr_branch);
         }

+ 14 - 0
src/utils.cpp

@@ -155,3 +155,17 @@ bool is_column(const json& j) {
            type == "float" || type == "select_all_column" ||
            type == "table_field";
 }
+
+OpType op_type_of(const nlohmann::json& j) {
+    // bin_contains_op, bin_logical_op, bin_cmp_op
+
+    let type = j.value("op_type", "none");
+    if (type == "bin_contains_op") {
+        return OpType::OP_CONTAINS;
+    } else if (type == "bin_logical_op") {
+        return OpType::OP_LOGIC;
+    } else if (type == "bin_cmp_op") {
+        return OpType::OP_COMPARE;
+    }
+    return OpType::OP_UNKNOWN;
+}

+ 9 - 0
src/utils.h

@@ -65,3 +65,12 @@ inline auto type_of(const nlohmann::json& j) { return j.value("type", "none"); }
 std::string select_column_get_name(const nlohmann::json& j);
 
 bool is_column(const nlohmann::json& j);
+
+enum OpType {
+    OP_COMPARE,
+    OP_LOGIC,
+    OP_CONTAINS,
+    OP_UNKNOWN,
+};
+
+OpType op_type_of(const nlohmann::json& j);

+ 7 - 1
tests_config.py

@@ -598,6 +598,12 @@ sql_checker_tests = [
         on class.id=person.classId and class.grade = 'zxc'
         where age=22;
         """,
-        True,
+        "column `class.grade` type is `int`, but `string:'zxc'` type is `string`, cannot `相等`",
+    ),
+    (
+        """select person.name 
+        from person where age>name;
+        """,
+        "column `age` type is `int`, but `name` type is `string`, cannot `大于`",
     ),
 ]