diff --git a/README.md b/README.md index 1d6eb66e4..b4880f11e 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ gitql exposes the following tables: gitql supports a subset of the SQL standard, currently including: -* `SELECT` (`*` not supported yet) +* `SELECT` * `WHERE` (`=` only) * `ORDER BY` (with `ASC` and `DESC`) * `LIMIT` diff --git a/cmd/gitql/query.go b/cmd/gitql/query.go index 85248bc1d..19914a1e2 100644 --- a/cmd/gitql/query.go +++ b/cmd/gitql/query.go @@ -95,7 +95,6 @@ func (c *CmdQuery) printQuery(schema sql.Schema, iter sql.RowIter) { w := tablewriter.NewWriter(os.Stdout) headers := []string{} for _, f := range schema { - fmt.Printf("HEADER: %s\n", f.Name) headers = append(headers, f.Name) } w.SetHeader(headers) diff --git a/sql/analyzer/analyzer_test.go b/sql/analyzer/analyzer_test.go index 5950b9e9c..915d674a5 100644 --- a/sql/analyzer/analyzer_test.go +++ b/sql/analyzer/analyzer_test.go @@ -50,6 +50,18 @@ func TestAnalyzer_Analyze(t *testing.T) { assert.Nil(err) assert.Equal(expected, analyzed) + notAnalyzed = plan.NewProject( + []sql.Expression{expression.NewStar()}, + plan.NewUnresolvedTable("mytable"), + ) + analyzed, err = a.Analyze(notAnalyzed) + expected = plan.NewProject( + []sql.Expression{expression.NewGetField(0, sql.Integer, "i")}, + table, + ) + assert.Nil(err) + assert.Equal(expected, analyzed) + notAnalyzed = plan.NewProject( []sql.Expression{ expression.NewAlias( diff --git a/sql/analyzer/rules.go b/sql/analyzer/rules.go index 24e8924fa..74c0d2d21 100644 --- a/sql/analyzer/rules.go +++ b/sql/analyzer/rules.go @@ -9,6 +9,7 @@ import ( var DefaultRules = []Rule{ {"resolve_tables", resolveTables}, {"resolve_columns", resolveColumns}, + {"resolve_star", resolveStar}, } func resolveTables(a *Analyzer, n sql.Node) sql.Node { @@ -28,6 +29,33 @@ func resolveTables(a *Analyzer, n sql.Node) sql.Node { }) } +func resolveStar(a *Analyzer, n sql.Node) sql.Node { + if n.Resolved() { + return n + } + + p, ok := n.(*plan.Project) + if !ok { + return n + } + + if len(p.Expressions) != 1 { + return n + } + + if _, ok := p.Expressions[0].(*expression.Star); !ok { + return n + } + + var exprs []sql.Expression + for i, e := range p.Child.Schema() { + gf := expression.NewGetField(i, e.Type, e.Name) + exprs = append(exprs, gf) + } + + return plan.NewProject(exprs, p.Child) +} + func resolveColumns(a *Analyzer, n sql.Node) sql.Node { if n.Resolved() { return n diff --git a/sql/plan/project.go b/sql/plan/project.go index 0b3d99382..bf78d8834 100644 --- a/sql/plan/project.go +++ b/sql/plan/project.go @@ -6,19 +6,19 @@ import ( type Project struct { UnaryNode - expressions []sql.Expression + Expressions []sql.Expression } func NewProject(expressions []sql.Expression, child sql.Node) *Project { return &Project{ UnaryNode: UnaryNode{child}, - expressions: expressions, + Expressions: expressions, } } func (p *Project) Schema() sql.Schema { var s sql.Schema - for _, e := range p.expressions { + for _, e := range p.Expressions { f := sql.Field{ Name: e.Name(), Type: e.Type(), @@ -33,7 +33,7 @@ func (p *Project) Resolved() bool { } func (p *Project) expressionsResolved() bool { - for _, e := range p.expressions { + for _, e := range p.Expressions { if !e.Resolved() { return false } @@ -51,7 +51,7 @@ func (p *Project) RowIter() (sql.RowIter, error) { func (p *Project) TransformUp(f func(sql.Node) sql.Node) sql.Node { c := p.UnaryNode.Child.TransformUp(f) - n := NewProject(p.expressions, c) + n := NewProject(p.Expressions, c) return f(n) } @@ -59,7 +59,7 @@ func (p *Project) TransformUp(f func(sql.Node) sql.Node) sql.Node { func (p *Project) TransformExpressionsUp(f func(sql.Expression) sql.Expression) sql.Node { c := p.UnaryNode.Child.TransformExpressionsUp(f) es := []sql.Expression{} - for _, e := range p.expressions { + for _, e := range p.Expressions { te := e.TransformUp(f) es = append(es, te) } @@ -78,7 +78,7 @@ func (i *iter) Next() (sql.Row, error) { if err != nil { return nil, err } - return filterRow(i.p.expressions, childRow), nil + return filterRow(i.p.Expressions, childRow), nil } func filterRow(expressions []sql.Expression, row sql.Row) sql.Row {