Skip to content

Commit

Permalink
Merge branch 'hotfix-0.1.6' into stable
Browse files Browse the repository at this point in the history
  • Loading branch information
hgouchet committed Jan 8, 2017
2 parents 5166417 + 23e96eb commit 0cc23b3
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 38 deletions.
39 changes: 26 additions & 13 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@ func (p *Parser) Parse() (statements []Stmt, err error) {
switch tk {
case DESC, DESCRIBE:
p.unscan()
stmt, err = p.parseDescribe()
stmt, err = p.ParseDescribe()
case CREATE:
p.unscan()
stmt, err = p.parseCreateView()
stmt, err = p.ParseCreateView()
case SELECT:
p.unscan()
stmt, err = p.parseSelect()
stmt, err = p.ParseSelect()
case SHOW:
p.unscan()
stmt, err = p.parseShow()
stmt, err = p.ParseShow()
default:
err = errors.New(ErrMsgBadStmt)
}
Expand All @@ -75,13 +75,24 @@ func (p *Parser) Parse() (statements []Stmt, err error) {
// If the next token is EOF, break the loop.
if tk, _ := p.scanIgnoreWhitespace(); tk == EOF {
break
} else {
p.unscan()
}
}
return
}

// parseDescribe parses a AWQL DESCRIBE statement.
func (p *Parser) parseDescribe() (*DescribeStatement, error) {
// ParseRow parses a AWQL statement and returns only the first.
func (p *Parser) ParseRow() (Stmt, error) {
stmts, err := p.Parse()
if err != nil {
return nil, err
}
return stmts[0], nil
}

// ParseDescribe parses a AWQL DESCRIBE statement.
func (p *Parser) ParseDescribe() (DescribeStmt, error) {
// First token should be a "DESC" keyword.
if tk, literal := p.scanIgnoreWhitespace(); tk != DESC && tk != DESCRIBE {
return nil, fmt.Errorf(ErrMsgBadMethod, literal)
Expand Down Expand Up @@ -118,8 +129,8 @@ func (p *Parser) parseDescribe() (*DescribeStatement, error) {
return stmt, nil
}

// parseCreateView parses a AWQL CREATE VIEW statement.
func (p *Parser) parseCreateView() (*CreateViewStatement, error) {
// ParseCreateView parses a AWQL CREATE VIEW statement.
func (p *Parser) ParseCreateView() (CreateViewStmt, error) {
// First token should be a "CREATE" keyword.
if tk, literal := p.scanIgnoreWhitespace(); tk != CREATE {
return nil, fmt.Errorf(ErrMsgBadMethod, literal)
Expand Down Expand Up @@ -172,16 +183,16 @@ func (p *Parser) parseCreateView() (*CreateViewStatement, error) {
}

// And finally, the query source of the view.
if selectStmt, err := p.parseSelect(); err != nil {
if selectStmt, err := p.ParseSelect(); err != nil {
return nil, err
} else {
stmt.View = selectStmt
stmt.View = selectStmt.(*SelectStatement)
}
return stmt, nil
}

// parseShow parses a AWQL SHOW statement.
func (p *Parser) parseShow() (*ShowStatement, error) {
// ParseShow parses a AWQL SHOW statement.
func (p *Parser) ParseShow() (ShowStmt, error) {
// First token should be a "SHOW" keyword.
if tk, literal := p.scanIgnoreWhitespace(); tk != SHOW {
return nil, fmt.Errorf(ErrMsgBadMethod, literal)
Expand Down Expand Up @@ -245,7 +256,7 @@ func (p *Parser) parseShow() (*ShowStatement, error) {
}

// Parse parses a AWQL SELECT statement.
func (p *Parser) parseSelect() (*SelectStatement, error) {
func (p *Parser) ParseSelect() (SelectStmt, error) {
// First token should be a "SELECT" keyword.
if tk, literal := p.scanIgnoreWhitespace(); tk != SELECT {
return nil, fmt.Errorf(ErrMsgBadMethod, literal)
Expand Down Expand Up @@ -640,6 +651,8 @@ func (p *Parser) scanQueryEnding() (bool, error) {
return true, nil
case SEMICOLON, EOF:
return false, nil
default:
p.unscan()
}
return false, fmt.Errorf(ErrMsgSyntax, literal)
}
Expand Down
16 changes: 8 additions & 8 deletions parser_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

// Ensure the parser can parse strings into CREATE VIEW Statement.
func TestParser_parseCreateView(t *testing.T) {
func TestParser_ParseCreateView(t *testing.T) {
var queryTests = []struct {
q string
stmt *CreateViewStatement
Expand Down Expand Up @@ -65,7 +65,7 @@ func TestParser_parseCreateView(t *testing.T) {
}

for i, qt := range queryTests {
stmt, err := NewParser(strings.NewReader(qt.q)).parseCreateView()
stmt, err := NewParser(strings.NewReader(qt.q)).ParseCreateView()
if err != nil {
if qt.err != err.Error() {
t.Errorf("%d. Expected the error message %v with %s, received %v", i, qt.err, qt.q, err.Error())
Expand All @@ -79,7 +79,7 @@ func TestParser_parseCreateView(t *testing.T) {
}

// Ensure the parser can parse strings into DESCRIBE Statement.
func TestParser_parseDescribe(t *testing.T) {
func TestParser_ParseDescribe(t *testing.T) {
var queryTests = []struct {
q string
stmt *DescribeStatement
Expand Down Expand Up @@ -126,7 +126,7 @@ func TestParser_parseDescribe(t *testing.T) {
}

for i, qt := range queryTests {
stmt, err := NewParser(strings.NewReader(qt.q)).parseDescribe()
stmt, err := NewParser(strings.NewReader(qt.q)).ParseDescribe()
if err != nil {
if qt.err != err.Error() {
t.Errorf("%d. Expected the error message %v with %s, received %v", i, qt.err, qt.q, err.Error())
Expand All @@ -140,7 +140,7 @@ func TestParser_parseDescribe(t *testing.T) {
}

// Ensure the parser can parse strings into SHOW Statement.
func TestParser_parseShow(t *testing.T) {
func TestParser_ParseShow(t *testing.T) {
var queryTests = []struct {
q string
stmt *ShowStatement
Expand Down Expand Up @@ -219,7 +219,7 @@ func TestParser_parseShow(t *testing.T) {
}

for i, qt := range queryTests {
stmt, err := NewParser(strings.NewReader(qt.q)).parseShow()
stmt, err := NewParser(strings.NewReader(qt.q)).ParseShow()
if err != nil {
if qt.err != err.Error() {
t.Errorf("%d. Expected the error message %v with %s, received %v", i, qt.err, qt.q, err.Error())
Expand All @@ -233,7 +233,7 @@ func TestParser_parseShow(t *testing.T) {
}

// Ensure the parser can parse strings into SELECT Statement.
func TestParser_parseSelect(t *testing.T) {
func TestParser_ParseSelect(t *testing.T) {
var queryTests = []struct {
q string
stmt *SelectStatement
Expand Down Expand Up @@ -396,7 +396,7 @@ func TestParser_parseSelect(t *testing.T) {
}

for i, qt := range queryTests {
stmt, err := NewParser(strings.NewReader(qt.q)).parseSelect()
stmt, err := NewParser(strings.NewReader(qt.q)).ParseSelect()
if err != nil {
if qt.err != err.Error() {
t.Errorf("%d. Expected the error message %v with %s, received %v", i, qt.err, qt.q, err.Error())
Expand Down
35 changes: 29 additions & 6 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,37 @@ import (
"strings"
)

// Ensure the scanner can scan tokens correctly.
// Ensure the parser can parse statements correctly.
func ExampleParser_Parse() {
q := `SELECT CampaignName FROM CAMPAIGN_PERFORMACE_REPORT ORDER BY 1 LIMIT 5\G`
q := `SELECT CampaignName FROM CAMPAIGN_PERFORMANCE_REPORT ORDER BY 1 LIMIT 5\GDESC ADGROUP_PERFORMANCE_REPORT AdGroupName;`
stmts, _ := NewParser(strings.NewReader(q)).Parse()
if stmt, ok := stmts[0].(SelectStmt); ok {
for _, stmt := range stmts {
switch stmt.(type) {
case SelectStmt:
fmt.Println(stmt.(SelectStmt).OrderList()[0].ColumnName)
case DescribeStmt:
fmt.Println(stmt.(DescribeStmt).SourceName())
}
}
// Output:
// CampaignName
// ADGROUP_PERFORMANCE_REPORT
}

// Ensure the parser can parse statements correctly and return only the first.
func ExampleParser_ParseRow() {
q := `SELECT CampaignName FROM CAMPAIGN_PERFORMANCE_REPORT;`
stmt, _ := NewParser(strings.NewReader(q)).ParseRow()
if stmt, ok := stmt.(SelectStmt); ok {
fmt.Println(stmt.SourceName())
fmt.Println(stmt.OrderList()[0].ColumnName)
// Output: CAMPAIGN_PERFORMACE_REPORT
// CampaignName
// Output: CAMPAIGN_PERFORMANCE_REPORT
}
}

// Ensure the parser can parse select statement.
func ExampleParser_ParseSelect() {
q := `SELECT AdGroupName FROM ADGROUP_PERFORMANCE_REPORT;`
stmt, _ := NewParser(strings.NewReader(q)).ParseSelect()
fmt.Println(stmt.SourceName())
// Output: ADGROUP_PERFORMANCE_REPORT
}
22 changes: 11 additions & 11 deletions statement.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,18 +234,24 @@ type FullStatement struct {
Full bool
}

// DescribeStatement represents a AWQL DESC statement.
// DESC...FULL
type DescribeStatement struct {
FullStatement
DataStatement
// FullMode returns true if the full display is required.
// It implements the DescribeStmt interface.
func (s FullStatement) FullMode() bool {
return s.Full
}

// FullStmt proposes the full statement mode.
type FullStmt interface {
FullMode() bool
}

// DescribeStatement represents a AWQL DESC statement.
// DESC...FULL
type DescribeStatement struct {
FullStatement
DataStatement
}

/*
DescribeStmt exposes the interface of AWQL Describe Statement
Expand All @@ -259,12 +265,6 @@ type DescribeStmt interface {
FullStmt
}

// FullMode returns true if the full display is required.
// It implements the DescribeStmt interface.
func (s DescribeStatement) FullMode() bool {
return s.Full
}

// ShowStatement represents a AWQL SHOW statement.
// SHOW...FULL...TABLES...LIKE...WITH
type ShowStatement struct {
Expand Down

0 comments on commit 0cc23b3

Please sign in to comment.