0304: 其他SQL语句
其他语句
仿照上一步的 parseSelect(),增加一些语句:
create table t (
a int64,
b string,
c string,
primary key (b, c)
);
insert into t values (1, 'x', 'y');
update t set a = 1 where b = 'x' and c = 'y';
delete from t where b = 'x' and c = 'y';对应的类型:
type StmtCreatTable struct {
table string
cols []Column
pkey []string
}
type StmtInsert struct {
table string
value []Cell
}
type StmtUpdate struct {
table string
keys []NamedCell
value []NamedCell
}
type StmtDelete struct {
table string
keys []NamedCell
}现在只实现了通过主键来操作单个 row,所以 WHERE 部分对应 keys。以后会增加范围查询、索引,相应的语法也会更复杂。
判断SQL语句
增加 parseStmt() 函数,用 interface{} 来返回不同的语句类型:
func (p *Parser) parseStmt() (out interface{}, err error) {
if p.tryKeyword("SELECT") {
stmt := &StmtSelect{}
err = p.parseSelect(stmt)
out = stmt
} else if p.tryKeyword("CREATE", "TABLE") {
stmt := &StmtCreatTable{}
err = p.parseCreateTable(stmt)
out = stmt
} else if p.tryKeyword("INSERT", "INTO") {
stmt := &StmtInsert{}
err = p.parseInsert(stmt)
out = stmt
} else if p.tryKeyword("UPDATE") {
stmt := &StmtUpdate{}
err = p.parseUpdate(stmt)
out = stmt
} else if p.tryKeyword("DELETE", "FROM") {
stmt := &StmtDelete{}
err = p.parseDelete(stmt)
out = stmt
} else {
err = errors.New("unknown statement")
}
if err != nil {
return nil, err
}
return out, nil
}其中 tryKeyword() 函数修改成了循环匹配多个 token:
func (p *Parser) tryKeyword(kws ...string) bool既然 parseStmt() 里已经把开头的 token 消耗掉了,所以之前的 parseSelect() 要修改。
这一步可以看到,解析SQL时,只要看当前的1~2个 token 就能决定下一步怎么做。很多计算机语言解析起来都是这么容易,并不需要编译原理里复杂的理论。即使以后增加了 select a+b*c 这样复杂的语法,也只要会用递归就行了。