diff --git a/engine/sql/engine/parse.go b/engine/sql/engine/parse.go index 0720383..b5c3f96 100644 --- a/engine/sql/engine/parse.go +++ b/engine/sql/engine/parse.go @@ -1,15 +1,15 @@ package engine -import "fmt" +import ( + "fmt" + "github.com/xwb1989/sqlparser" +) // ASTNode is the abstract syntax tree node. type ASTNode interface { - // NodeType returns node type. - NodeType() string - // Children returns child nodes. - Children() []ASTNode // String returns the string representation of the node. String() string + Only() bool } type SQLParser interface { @@ -22,8 +22,23 @@ type SelectStatement struct { Where Condition } -func (s *SelectStatement) String() string { - panic("implement me") +type InsertStatement struct { + Columns []string + From string +} + +func (s SelectStatement) String() string { + return fmt.Sprintf("select %v from %s where %s", s.Columns, s.From, s.Where) +} + +func (s SelectStatement) Only() bool { + return true +} + +func NewSQLParser(sql string) SQLParser { + return &parser{ + sql: sql, + } } type Condition struct { @@ -36,8 +51,68 @@ func (c *Condition) String() string { return fmt.Sprintf("%s %s %v", c.Column, c.Operator, c.Value) } -type SimpleSQLParser struct{} +type parser struct { + sql string +} + +func (p *parser) Parse(query string) (ASTNode, error) { + statement, err := sqlparser.Parse(query) + if err != nil { + return nil, err + } + switch statement := statement.(type) { + case *sqlparser.Select: + return p.parseSelect(statement) + case *sqlparser.Insert: + return p.parseInsert(statement) + default: + return nil, fmt.Errorf("unsupported statement type: %T", statement) + } +} + +func (p *parser) parseSelect(statement *sqlparser.Select) (*SelectStatement, error) { + var columns []string + for _, column := range statement.SelectExprs { + switch column := column.(type) { + case *sqlparser.AliasedExpr: + columns = append(columns, column.Expr.(*sqlparser.ColName).Name.String()) + default: + return nil, fmt.Errorf("unsupported select expression type: %T", column) + } + } + table := statement.From[0].(*sqlparser.AliasedTableExpr).Expr.(*sqlparser.TableName).Name.String() + var condition Condition + if statement.Where != nil { + condition = p.parseCondition(statement.Where.Expr) + } + return &SelectStatement{ + Columns: columns, + From: table, + Where: condition, + }, nil +} + +func (p *parser) parseInsert(statement *sqlparser.Insert) (*SelectStatement, error) { + var columns []string + for _, column := range statement.Columns { + columns = append(columns, column.String()) + } + table := statement.Table.Name.String() + return &SelectStatement{ + Columns: columns, + From: table, + }, nil +} -func (p *SimpleSQLParser) Parse(query string) (ASTNode, error) { - panic("implement me") +func (p *parser) parseCondition(expr sqlparser.Expr) Condition { + switch expr := expr.(type) { + case *sqlparser.ComparisonExpr: + return Condition{ + Column: expr.Left.(*sqlparser.ColName).Name.String(), + Operator: expr.Operator, + Value: expr.Right, + } + default: + panic(fmt.Sprintf("unsupported expression type: %T", expr)) + } } diff --git a/engine/sql/sql.go b/engine/sql/sql.go new file mode 100644 index 0000000..5916131 --- /dev/null +++ b/engine/sql/sql.go @@ -0,0 +1,30 @@ +package sql + +import v1 "github.com/ByteStorage/FlyDB/engine/sql/engine" + +type Engine interface { + Execute(sql string, args ...interface{}) (int64, error) +} + +type engine struct { +} + +func NewEngine() Engine { + return &engine{} +} + +func (e *engine) Execute(sql string, args ...interface{}) (int64, error) { + // sql parse + parser := v1.NewSQLParser(sql) + _, err := parser.Parse(sql) + if err != nil { + return 0, err + } + // sql optimize + + // sql execute plan + + // sql execute + + return 0, nil +} diff --git a/go.mod b/go.mod index 8f28b68..0befb66 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,7 @@ require ( github.com/spaolacci/murmur3 v1.1.0 github.com/stretchr/testify v1.8.2 github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c + github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 go.etcd.io/bbolt v1.3.7 go.uber.org/zap v1.24.0 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 @@ -47,7 +48,6 @@ require ( github.com/kr/pretty v0.3.0 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.16 // indirect - github.com/panjf2000/ants v1.3.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect go.uber.org/atomic v1.7.0 // indirect diff --git a/go.sum b/go.sum index 8c568fd..f693ba9 100644 --- a/go.sum +++ b/go.sum @@ -140,8 +140,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU= -github.com/panjf2000/ants v1.3.0 h1:8pQ+8leaLc9lys2viEEr8md0U4RN6uOSUCE9bOYjQ9M= -github.com/panjf2000/ants v1.3.0/go.mod h1:AaACblRPzq35m1g3enqYcxspbbiOJJYaxU2wMpm1cXY= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -191,6 +189,8 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 h1:zzrxE1FKn5ryBNl9eKOeqQ58Y/Qpo3Q9QNxKHX5uzzQ= +github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2/go.mod h1:hzfGeIUDq/j97IG+FhNqkowIyEcD88LrW6fyU3K3WqY= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=