From c02a685d1f4dc20d6704ce1b5137999f55ebbcfe Mon Sep 17 00:00:00 2001 From: Manish R Jain <manishrjain@gmail.com> Date: Mon, 30 Nov 2015 13:04:30 +1100 Subject: [PATCH] Fix channel blocking issue during GQL parsing. Allow '-' to be part of predicate name. --- Dockerfile | 2 +- gql/parser.go | 46 ++++++++++++++++++++++++++++------------------ gql/parser_test.go | 21 +++++++++++++++++++++ gql/state.go | 4 ++-- lex/lexer.go | 4 ++-- 5 files changed, 54 insertions(+), 23 deletions(-) diff --git a/Dockerfile b/Dockerfile index c8eed48b..aef10e22 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,7 +21,7 @@ ENV LD_LIBRARY_PATH "/usr/local/lib" # Install DGraph and update dependencies to right versions. RUN go get -v github.com/robfig/glock && \ go get -v github.com/dgraph-io/dgraph/... && \ - glock sync github.com/dgraph-io/dgraph && echo "v0.1.0" + glock sync github.com/dgraph-io/dgraph && echo "v0.1.1" # Run some tests, don't build an image if we're failing tests. RUN go test github.com/dgraph-io/dgraph/... diff --git a/gql/parser.go b/gql/parser.go index e26e66d1..ae511c2c 100644 --- a/gql/parser.go +++ b/gql/parser.go @@ -57,7 +57,9 @@ func Parse(input string) (sg *query.SubGraph, rerr error) { return nil, rerr } } else { - godeep(l, sg) + if err := godeep(l, sg); err != nil { + return sg, err + } } } } @@ -114,29 +116,37 @@ func getRoot(l *lex.Lexer) (sg *query.SubGraph, rerr error) { return query.NewGraph(uid, xid) } -func godeep(l *lex.Lexer, sg *query.SubGraph) { - curp := sg // stores current pointer. - for { - switch item := <-l.Items; { - case item.Typ == itemName: +func godeep(l *lex.Lexer, sg *query.SubGraph) error { + curp := sg // Used to track current node, for nesting. + for item := range l.Items { + if item.Typ == lex.ItemError { + return errors.New(item.Val) + + } else if item.Typ == lex.ItemEOF { + return nil + + } else if item.Typ == itemName { child := new(query.SubGraph) child.Attr = item.Val sg.Children = append(sg.Children, child) curp = child - case item.Typ == itemLeftCurl: - godeep(l, curp) // recursive iteration - case item.Typ == itemRightCurl: - return - case item.Typ == itemLeftRound: - // absorb all these, we don't care right now. - for { - item = <-l.Items - if item.Typ == itemRightRound || item.Typ == lex.ItemEOF { - break + + } else if item.Typ == itemLeftCurl { + if err := godeep(l, curp); err != nil { + return err + } + + } else if item.Typ == itemRightCurl { + return nil + + } else if item.Typ == itemLeftRound { + // absorb all these, we don't use them right now. + for ti := range l.Items { + if ti.Typ == itemRightRound || ti.Typ == lex.ItemEOF { + return nil } } - default: - // continue } } + return nil } diff --git a/gql/parser_test.go b/gql/parser_test.go index b9cf369d..e39775c6 100644 --- a/gql/parser_test.go +++ b/gql/parser_test.go @@ -53,6 +53,7 @@ func TestParse(t *testing.T) { } if len(sg.Children) != 4 { t.Errorf("Expected 4 children. Got: %v", len(sg.Children)) + return } if err := checkAttr(sg.Children[0], "friends"); err != nil { t.Error(err) @@ -160,3 +161,23 @@ func TestParse_pass1(t *testing.T) { t.Errorf("Expected 0. Got: %v", len(sg.Children)) } } + +func TestParse_block(t *testing.T) { + query := ` + { + root(_uid_: 0x0a) { + type.object.name.es-419 + } + } + ` + sg, err := Parse(query) + if err != nil { + t.Error(err) + } + if len(sg.Children) != 1 { + t.Errorf("Expected 1. Got: %v", len(sg.Children)) + } + if err := checkAttr(sg.Children[0], "type.object.name.es-419"); err != nil { + t.Error(err) + } +} diff --git a/gql/state.go b/gql/state.go index 3f4e531c..9313671b 100644 --- a/gql/state.go +++ b/gql/state.go @@ -28,7 +28,7 @@ const ( itemLeftCurl // left curly bracket itemRightCurl // right curly bracket itemComment // comment - itemName // names + itemName // [9] names itemOpType // operation type itemString // quoted string itemLeftRound // left round bracket @@ -234,7 +234,7 @@ func isNameSuffix(r rune) bool { if r >= '0' && r <= '9' { return true } - if r == '.' { + if r == '.' || r == '-' { // Use by freebase. return true } return false diff --git a/lex/lexer.go b/lex/lexer.go index 91ff7e60..2b4b3cab 100644 --- a/lex/lexer.go +++ b/lex/lexer.go @@ -50,7 +50,7 @@ func (i item) String() string { case 0: return "EOF" } - return fmt.Sprintf("[%v] %q", i.Typ, i.Val) + return fmt.Sprintf("lex.Item [%v] %q", i.Typ, i.Val) } type Lexer struct { @@ -68,7 +68,7 @@ type Lexer struct { func NewLexer(input string) *Lexer { l := &Lexer{ Input: input, - Items: make(chan item), + Items: make(chan item, 100), } return l } -- GitLab