Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ sql_parse/clauses/__pycache__
sql_parse/clauses
sql_parse/test.py
sql_command/__pycache__/DB.cpython-310.pyc
pyrightconfig.json
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions .idea/sql_minibuilder.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

186 changes: 154 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
~~目前只需要改commands/DB.py就行了~~
~~目前只需要改command/DB.py就行了~~

commands中的执行功能都差不多写完了,tokenize已完成,AST写了一点

Expand Down Expand Up @@ -43,27 +43,38 @@ WHERE id = 1 AND this < 2.3;

完成情况:

- [x] 对SELECT的实现
- [x] 对SELECT的解析

- [X] 对FROM的实现
- [X] 对FROM的解析

- [x] 对WHERE的基础实现
- [x] 对WHERE的基础解析

- [ ] 对WHERE中AND、OR的正确顺序判断
- [x] 对WHERE中AND、OR的正确顺序判断

- [ ] 对CREATE的实现
- [x] 对SET的解析

- [ ] 对主键`PRIMARY`的实现
- [x] 对UPDATE的解析

- [ ] 对非空`NOT NULL`的实现
- [x] 对DELETE的解析

- [x] 对UPDATE的实现
##### 星期五添加

- [x] 对DELETE的实现
- [x] 对SELECT时`WILDCARD`的解析(就是选中所有列,详见输入输出5)

- [x] 对CREATE时主键`PRIMARY`的解析

- [x] 对CREATE时非空`NOT NULL`的解析

**目前已部分完成,只到能够解析查询命令(SELECT)、更新命令(UPDATE)与删除命令(DELETE)的地方**
- [ ] 对CREATE各种约束的解析(摆,不想做,因为外键有点麻烦)

- [x] 对SET赋值式右边的Binary Expression的解析(抱歉的是SET时的expression结构也换了,换成assignment了,详见输出2)

- [x] 对CREATE的解析

- [x] 对INSERT INTO的解析


**目前已部分完成,只到能够解析查询命令(SELECT)、更新命令(UPDATE)、删除命令(DELETE)与基础创建命令(CREATE)(不包含NOT NULL)的地方**

输入1:
```
Expand Down Expand Up @@ -133,36 +144,27 @@ WHERE level:AST_KEYWORDS.CLAUSE
输入2:
```
UPDATE table1
SET alexa = 50000, country='USA', salary = 14.5
SET alexa = 50000, country='USA', salary = salary * 14.5
WHERE id = 1 AND this < 2.3 OR name>1;
```

**实际输出2**:
```
UPDATE level:AST_KEYWORDS.CLAUSE

UPDATE level:AST_KEYWORDS.CLAUSE
-- table1
SET level:AST_KEYWORDS.CLAUSE

--SET level:AST_KEYWORDS.EXPRESSION

---- {'left': 'alexa', 'op': '=', 'right': 50000}
---- {'assignment': 'alexa', 'expression': {'left': 50000}}
--SET level:AST_KEYWORDS.EXPRESSION

---- {'left': 'country', 'op': '=', 'right': 'USA'}
---- {'assignment': 'country', 'expression': {'left': 'USA'}}
--SET level:AST_KEYWORDS.EXPRESSION

---- {'left': 'salary', 'op': '=', 'right': 14.5}
---- {'assignment': 'salary', 'expression': {'left': 'salary', 'op': '*', 'right': 14.5}}
WHERE level:AST_KEYWORDS.CLAUSE

--WHERE level:AST_KEYWORDS.EXPRESSION

---- {'left': 'id', 'op': '=', 'right': 1}
--AND level:AST_KEYWORDS.EXPRESSION

---- {'left': 'this', 'op': '<', 'right': 2.3}
--OR level:AST_KEYWORDS.EXPRESSION

---- {'left': 'name', 'op': '>', 'right': 1}
```

Expand All @@ -189,6 +191,106 @@ WHERE level:AST_KEYWORDS.
---- {'left': 'name', 'op': '>', 'right': 1}
```

输入4:
```
CREATE TABLE Persons
(
PersonID SERIAL int,
LastName PRIMARY varchar(255),
FirstName char(255) NOT NULL,
Address float,
City varchar(255)
);
```


**实际输出4**:
```
CREATE level:AST_KEYWORDS.CLAUSE
-- Persons
COLUMNS level:AST_KEYWORDS.CLAUSE
--COLUMN_DEFINITION level:AST_KEYWORDS.COLUMN_DEFINITION
---- {'PRIMARY': False, 'NOT NULL': False, 'name': 'PERSONID', 'type': 'int'}
--COLUMN_DEFINITION level:AST_KEYWORDS.COLUMN_DEFINITION
---- {'PRIMARY': True, 'NOT NULL': False, 'name': 'LASTNAME', 'type': 'varchar', 'length': 255}
--COLUMN_DEFINITION level:AST_KEYWORDS.COLUMN_DEFINITION
---- {'PRIMARY': False, 'NOT NULL': True, 'name': 'FIRSTNAME', 'type': 'char', 'length': 255}
--COLUMN_DEFINITION level:AST_KEYWORDS.COLUMN_DEFINITION
---- {'PRIMARY': False, 'NOT NULL': False, 'name': 'ADDRESS', 'type': 'float'}
--COLUMN_DEFINITION level:AST_KEYWORDS.COLUMN_DEFINITION
---- {'PRIMARY': False, 'NOT NULL': False, 'name': 'CITY', 'type': 'varchar', 'length': 255}
```

输入5:(与输入1相比,SELECT所有列):
```
SELECT *
FROM table1, table2
WHERE id = 1 AND "this" < 2.3;
```

**实际输出5**:
```
SELECT level:AST_KEYWORDS.CLAUSE
-- Token.Wildcard
FROM level:AST_KEYWORDS.CLAUSE
-- table1
-- table2
WHERE level:AST_KEYWORDS.CLAUSE
--WHERE level:AST_KEYWORDS.EXPRESSION
---- {'left': 'id', 'op': '=', 'right': 1}
--AND level:AST_KEYWORDS.EXPRESSION
---- {'left': 'this', 'op': '<', 'right': 2.3}
```

输入6:
```
INSERT INTO table1 (id, name, this)
VALUES (1, 'alex', 2.3);
```

**实际输出6**:
```
INSERT level:AST_KEYWORDS.CLAUSE
-- table1
COLUMNS level:AST_KEYWORDS.CLAUSE
-- id
-- name
-- this
VALUES level:AST_KEYWORDS.CLAUSE
-- 1
-- alex
-- 2.3
```

输入7:(与输入6的区别在于,INSERT INTO未指定表名,同时是多列)
```
INSERT INTO table1
VALUES(
(1, 'alex', 2.3),
(2, 'bob', 2.4),
(5, 'jjj', 2.5)
);
```

**实际输出7**
```
INSERT level:AST_KEYWORDS.CLAUSE
-- table1
COLUMNS level:AST_KEYWORDS.CLAUSE
VALUES level:AST_KEYWORDS.CLAUSE
-- 1
-- alex
-- 2.3
VALUES level:AST_KEYWORDS.CLAUSE
-- 2
-- bob
-- 2.4
VALUES level:AST_KEYWORDS.CLAUSE
-- 5
-- jjj
-- 2.5
```


**用语解释**:

Expand All @@ -201,19 +303,39 @@ WHERE level:AST_KEYWORDS.



#### 1.3 在AST基础上,实现对`sql_commands`的调用,完成语句
#### 1.3 在AST基础上,实现对`sql_command`的调用,完成语句

文件:`sql_control/main.py`(示例用,之后可能会改)

- [x] 完成示例文件,演示如何结合AST与实现的`sql_command`,通过FROM语句获得databse中的表

- [x] 完成AST与执行代码关于WHERE的结合

- [x] 完成AST与执行代码关于SELECT的结合

- [x] 完成AST与执行代码关于DELETE的结合

- [x] 完成AST与执行代码关于UPDATE的结合

##### 星期五添加的

- [ ] 一个小问题:所以什么时候在硬盘写入文件,读入文件?

- [x] 完成AST与执行代码关于SELECT的WILDCARD设置(也就是选中所有列,详见输入5,输出5)

- [x] 完成AST与执行代码关于SET的右侧赋值式结合

- [x] 完成AST与执行代码关于CREATE的基础结合,限制每一列的类型

文件:`sql_commands/main.py`(示例用,之后可能会改)
- [x] 完成AST与执行代码关于CREATE的主键设置,NOT NULL设置

- [x] 完成示例文件,演示如何结合AST与实现的`sql_commands`,通过FROM语句获得databse中的表
- [ ] 完成AST与执行代码关于CREATE中类型有SERIAL时,在INSERT时主键的自动更新并插入

- [ ] 完成AST与执行代码关于WHERE的结合

- [ ] 完成AST与执行代码关于SELECT的结合

- [ ] 完成AST与执行代码关于DELETE的结合
- [ ] 完成AST与执行代码关于INSERT的基础结合

- [ ] 完成AST与执行代码关于UPDATE的结合
- [ ] 完成AST与执行代码关于INSERT在表名未指定列时的正确处理(详见输入输出7)

- [ ] 更多……

Expand Down
16 changes: 13 additions & 3 deletions sql_command/DB.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@

class DB:
def __init__(self):
self.dbtypes=dict[dict['tablename':str,'tabledata':pd.DataFrame,'datatypes':dict]]
self.dbtypes=dict[dict['tablename':str,'tabledata':pd.DataFrame,'datatypes':dict,'not_null_flag':dict,'primary_key':str,'attri_len':dict]]
self.database = {}
#访问某个表用 database['表名']
#访问某个表中的数据用 database['表名']['tabledata'] 这是一个pd.DataFrame型的数据
#访问某个表中某个属性的数据类型用 database['表名']['datatypes']['属性名']
#查询某个表中某个属性是否是not null :database['表名']['not_null_flag']['属性名']
#访问某个表中某个(这里仅考虑char varchar类型)属性设定的长度 :database['表名']['attri_len']['属性名']
#primary: database['表名']['primary_key']['属性名']

def create(self,
table: str,
attributes: list[str],
types: list[str]) -> bool:
types: list[str],
not_null: list[bool],
primary_key: list[str],
char_attri: list[str],
char_attri_len: list[int]) -> bool:
#检查表是否已经存在
if table in self.database:
print(f"Table '{table}' already exists.")
Expand All @@ -21,7 +28,10 @@ def create(self,
newtable = {
'tablename': table,
'tabledata': pd.DataFrame(columns=attributes),
'datatypes': {attr: data_type for attr, data_type in zip(attributes, types)}
'datatypes': {attr: data_type for attr, data_type in zip(attributes, types)},
'not_null_flag': {attr: not_null for attr, not_null in zip(attributes, not_null)},
'primary_key': primary_key,
'attri_len': {ch: chlen for ch, chlen in zip(char_attri,char_attri_len)}
}
#数据库添加新表
self.database[table] = newtable
Expand Down
Loading