myuan 2 år sedan
förälder
incheckning
f5b70d02b2
2 ändrade filer med 119 tillägg och 4 borttagningar
  1. 96 0
      run_test.py
  2. 23 4
      src/calc.y

+ 96 - 0
run_test.py

@@ -445,6 +445,102 @@ async def assert_sqls():
             }
         ],
     )
+    await assert_sql(
+        """
+        select Student.Sname 
+        from Student join SC 
+        on Student.Sno=SC.Sno 
+        where SC.Cno='81003';
+        """,
+        [
+            {
+                "type": "select",
+                "select_cols": [
+                    {
+                        "type": "select_column",
+                        "target": {
+                            "type": "table_field",
+                            "table": "Student",
+                            "field": "Sname",
+                        },
+                    }
+                ],
+                "table_name": "Student",
+                "join_options": {
+                    "type": "join_options",
+                    "join_with": {"type": "identifier", "value": "SC"},
+                    "on": {
+                        "type": "相等",
+                        "left": {
+                            "type": "table_field",
+                            "table": "Student",
+                            "field": "Sno",
+                        },
+                        "right": {"type": "table_field", "table": "SC", "field": "Sno"},
+                    },
+                },
+                "where": {
+                    "type": "相等",
+                    "left": {"type": "table_field", "table": "SC", "field": "Cno"},
+                    "right": {"type": "string", "value": "'81003'"},
+                },
+            }
+        ],
+    )
+    await assert_sql(
+        """
+        select Student.Sname 
+        from   Student join SC 
+        on     Student.Sno=SC.Sno 
+        and    SC.Cno='81003';
+        """,
+        [
+            {
+                "type": "select",
+                "select_cols": [
+                    {
+                        "type": "select_column",
+                        "target": {
+                            "type": "table_field",
+                            "table": "Student",
+                            "field": "Sname",
+                        },
+                    }
+                ],
+                "table_name": "Student",
+                "join_options": {
+                    "type": "join_options",
+                    "join_with": {"type": "identifier", "value": "SC"},
+                    "on": {
+                        "type": "且",
+                        "left": {
+                            "type": "相等",
+                            "left": {
+                                "type": "table_field",
+                                "table": "Student",
+                                "field": "Sno",
+                            },
+                            "right": {
+                                "type": "table_field",
+                                "table": "SC",
+                                "field": "Sno",
+                            },
+                        },
+                        "right": {
+                            "type": "相等",
+                            "left": {
+                                "type": "table_field",
+                                "table": "SC",
+                                "field": "Cno",
+                            },
+                            "right": {"type": "string", "value": "'81003'"},
+                        },
+                    },
+                },
+                "where": {},
+            }
+        ],
+    )
 
 
 async def on_modified(event):

+ 23 - 4
src/calc.y

@@ -81,6 +81,7 @@ cJSON* jroot;
 %type <jv> delete_stmt select_stmt select_item select_items 
 %type <jv> data_value_list identifier_or_const_value_or_const_value_list
 %type <jv> search_expr compare_expr single_expr expr where_expr logical_expr negative_expr op_where_expr expr_list contains_expr
+%type <jv> op_join table_field column_name
 
 
 %left OR
@@ -221,14 +222,19 @@ single_assign_item: identifier '=' identifier_or_const_value {
 	}
 ;
 
-single_expr: identifier {$$=$1;}
-	| IDENTIFIER '.' IDENTIFIER {
+table_field: IDENTIFIER '.' IDENTIFIER {
 		cJSON* node = cJSON_CreateObject();
 		cJSON_AddStringToObject(node, "type", "table_field");
 		cJSON_AddStringToObject(node, "table", $1);
 		cJSON_AddStringToObject(node, "field", $3);
 		$$=node;
 	}
+;
+
+column_name: table_field {$$=$1;} | identifier {$$=$1;};
+
+single_expr: identifier {$$=$1;}
+	| table_field {$$=$1;}
 	| data_value {$$=$1;}
 	// | '(' single_expr ')' {$$=$2;}
 ;
@@ -364,12 +370,25 @@ delete_stmt: DELETE FROM IDENTIFIER op_where_expr {
 	}
 ;
 
-select_stmt: SELECT select_items FROM IDENTIFIER op_where_expr {
+op_join: {$$ = NULL;}
+	| JOIN column_name ON where_expr {
+		cJSON* node = cJSON_CreateObject();
+		cJSON_AddStringToObject(node, "type", "join_options");
+		cJSON_AddItemToObject(node, "join_with", $2);
+		cJSON_AddItemToObject(node, "on", $4);
+		$$=node;
+	}
+;
+
+select_stmt: SELECT select_items FROM IDENTIFIER op_join op_where_expr {
 		cJSON* node = cJSON_CreateObject();
 		cJSON_AddStringToObject(node, "type", "select");
 		cJSON_AddItemToObject(node, "select_cols", $2);
 		cJSON_AddStringToObject(node, "table_name", $4);
-		cJSON_AddItemToObject(node, "where", $5);
+		if ($5 != NULL) {
+			cJSON_AddItemToObject(node, "join_options", $5);
+		}
+		cJSON_AddItemToObject(node, "where", $6);
 		$$=node;
 	}
 ;