Prechádzať zdrojové kódy

允许 select in select

myuan 2 rokov pred
rodič
commit
ff3322a5bd
2 zmenil súbory, kde vykonal 56 pridanie a 26 odobranie
  1. 37 7
      run_test.py
  2. 19 19
      src/calc.y

+ 37 - 7
run_test.py

@@ -398,13 +398,43 @@ async def assert_sqls():
 
     await assert_sql(
         """SELECT Sname
-FROM Student
-WHERE Sno IN (
-    SELECT Sno
-    FROM SC 
-    WHERE Cno='81003'
-);""",
-        [],
+            FROM Student
+            WHERE Sno IN (
+                SELECT Sno
+                FROM SC 
+                WHERE Cno='81003'
+        );""",
+        [
+            {
+                "type": "select",
+                "select_cols": [
+                    {
+                        "type": "select_column",
+                        "target": {"type": "identifier", "value": "Sname"},
+                    }
+                ],
+                "table_name": "Student",
+                "where": {
+                    "type": "包含于",
+                    "left": {"type": "identifier", "value": "Sno"},
+                    "right": {
+                        "type": "select",
+                        "select_cols": [
+                            {
+                                "type": "select_column",
+                                "target": {"type": "identifier", "value": "Sno"},
+                            }
+                        ],
+                        "table_name": "SC",
+                        "where": {
+                            "type": "相等",
+                            "left": {"type": "identifier", "value": "Cno"},
+                            "right": {"type": "string", "value": "'81003'"},
+                        },
+                    },
+                },
+            }
+        ],
     )
 
 

+ 19 - 19
src/calc.y

@@ -46,6 +46,8 @@ cJSON* jroot;
 #define MEET_VAR(msg, msg2) fprintf(stderr, "MEET %s %s\n", #msg, msg2);
 #define MEET_JSON(msg, msg2) MEET_VAR(msg, cJSON_Print(msg2));
 
+#define ADD_TO_ROOT(node) cJSON_AddItemToArray(jroot, node);
+
 %}
 
 %union {
@@ -98,28 +100,28 @@ statement: NEWLINE
 	| sql_statement 
 ;
 
-sql_statement: create_table_stmt
-	| insert_stmt
-	| update_stmt
-	| delete_stmt
-	| select_stmt
+sql_statement: 
+create_table_stmt NEWLINE {cJSON_AddItemToArray(jroot, $1);}
+	| insert_stmt NEWLINE {cJSON_AddItemToArray(jroot, $1);}
+	| update_stmt NEWLINE {cJSON_AddItemToArray(jroot, $1);}
+	| delete_stmt NEWLINE {cJSON_AddItemToArray(jroot, $1);}
+	| select_stmt NEWLINE {cJSON_AddItemToArray(jroot, $1);}
 ;
 
-create_table_stmt: CREATE TABLE IDENTIFIER NEWLINE
+create_table_stmt: CREATE TABLE IDENTIFIER
 	{
 		cJSON* node = cJSON_CreateObject();
 		cJSON_AddStringToObject(node, "type", "create_table");
 		cJSON_AddStringToObject(node, "table_name", $3);
 		cJSON_AddItemToObject(node, "cols", cJSON_CreateArray());
-		cJSON_AddItemToArray(jroot, node);
+		$$=node;
 	}
 
-create_table_stmt: CREATE TABLE IDENTIFIER '(' create_col_list ')' NEWLINE {
+create_table_stmt: CREATE TABLE IDENTIFIER '(' create_col_list ')' {
 		cJSON* node = cJSON_CreateObject();
 		cJSON_AddStringToObject(node, "type", "create_table");
 		cJSON_AddStringToObject(node, "table_name", $3);
 		cJSON_AddItemToObject(node, "cols", $5);
-		cJSON_AddItemToArray(jroot, node);
 		$$=node;
 };
 
@@ -165,12 +167,11 @@ data_type: INT_T
 	| STRING_T
 ;
 
-insert_stmt: INSERT INTO IDENTIFIER VALUES '(' insert_list ')' NEWLINE {
+insert_stmt: INSERT INTO IDENTIFIER VALUES '(' insert_list ')' {
 		cJSON* node = cJSON_CreateObject();
 		cJSON_AddStringToObject(node, "type", "insert");
 		cJSON_AddStringToObject(node, "table_name", $3);
 		cJSON_AddItemToObject(node, "values", $6);
-		cJSON_AddItemToArray(jroot, node);
 		$$=node;
 };
 
@@ -195,13 +196,12 @@ data_value: INT_V {SIMPLE_TYPE_VALUE_OBJECT($$, int, Number, $1);}
 	| STRING_V {SIMPLE_TYPE_VALUE_OBJECT($$, string, String, $1);}
 ;
 
-update_stmt: UPDATE IDENTIFIER SET update_list WHERE where_expr NEWLINE {
+update_stmt: UPDATE IDENTIFIER SET update_list WHERE where_expr {
 		cJSON* node = cJSON_CreateObject();
 		cJSON_AddStringToObject(node, "type", "update");
 		cJSON_AddStringToObject(node, "table_name", $2);
 		cJSON_AddItemToObject(node, "set", $4);
 		cJSON_AddItemToObject(node, "where", $6);
-		cJSON_AddItemToArray(jroot, node);
 		$$=node;
 };
 update_list: single_assign_item {
@@ -243,6 +243,7 @@ where_expr: logical_expr {
 ;
 op_where_expr: {$$=cJSON_CreateObject();} 
 	| WHERE where_expr {$$=$2;}
+;
 
 compare_expr: compare_expr bin_cmp_op compare_expr {
 	fprintf(stderr, "compare_expr %s\n", $2);
@@ -257,15 +258,16 @@ negative_expr: NOT negative_expr {
 	| compare_expr {MEET_JSON(compare_expr from negative_expr, $1) $$=$1;}
 	| '(' negative_expr ')' {MEET_JSON(negative_expr from negative_expr, $2) $$=$2;}
 ;
-contains_expr: contains_expr bin_contains_op '(' select_stmt ')' {
+contains_expr: identifier bin_contains_op '(' select_stmt ')' {
 		MEET_JSON(logical_expr bin_contains_op select_stmt, $2);
 		SIMPLE_OP_NODE($$, $2, $1, $4)
 	}
-	| contains_expr bin_contains_op '(' expr_list ')' {
+	| identifier bin_contains_op '(' expr_list ')' {
 		MEET_VAR(logical_expr bin_contains_op expr_list, $2);
 		SIMPLE_OP_NODE($$, $2, $1, $4)
 	}
 	| negative_expr {MEET_JSON(negative_expr from contains_expr, $1); $$=$1;}
+;
 
 logical_expr: logical_expr bin_logical_op contains_expr {
 		fprintf(stderr, "logical_expr %s\n", $2);
@@ -354,23 +356,21 @@ bin_logical_op: AND {MEET(and from bin_log) $$ = "且";}
 bin_contains_op: IN {$$ = "包含于";}
 	| NOT IN {$$ = "不包含于";}
 ;
-delete_stmt: DELETE FROM IDENTIFIER op_where_expr NEWLINE {
+delete_stmt: DELETE FROM IDENTIFIER op_where_expr {
 		cJSON* node = cJSON_CreateObject();
 		cJSON_AddStringToObject(node, "type", "delete");
 		cJSON_AddStringToObject(node, "table_name", $3);
 		cJSON_AddItemToObject(node, "where", $4);
-		cJSON_AddItemToArray(jroot, node);
 		$$=node;
 };
 
-select_stmt: SELECT select_items FROM IDENTIFIER op_where_expr NEWLINE {
+select_stmt: SELECT select_items FROM IDENTIFIER 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);
 		$$=node;
-		cJSON_AddItemToArray(jroot, node);
 };
 select_items: select_item {
 		cJSON* node = cJSON_CreateArray();