diff --git a/Dockerfile b/Dockerfile index c8eed48b27de9024f98e8b977a656c457905530e..aef10e22666cc809da99a01d221ba4c13095fd1e 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 e26e66d1ac194992ff987453feb17733565741c8..ae511c2c1726c83ab092faaa757867498c1471a7 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 b9cf369d43c8be68458beddd2bd3198c86a9b3e5..e39775c660206792444f3de322d336b3da3ee89e 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 3f4e531c16aa81fe40f8cb8412ec27ef8945385d..9313671b021fc2f8ff01e63c7732f232a80c6226 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 91ff7e60601d3222b41314832dd0252c9d54765b..2b4b3cabd56b4b5e1f2df588a1f6a0f37da7bd03 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 }