func TestAcceptQueryBySemanticParse(t *testing.T) { table := []string{ // Test well type litterals are accepted. `select ?s from ?g where{?s ?p "1"^^type:int64};`, // Test predicates are accepted. // Test invalid predicate time anchor are rejected. `select ?s from ?b where{/_<foo> as ?s "id"@[2015] ?o};`, `select ?s from ?b where{/_<foo> as ?s "id"@[2015-07] ?o};`, `select ?s from ?b where{/_<foo> as ?s "id"@[2015-07-19] ?o};`, `select ?s from ?g where{/_<foo> as ?s "id"@[2015-07-19T13:12] ?o};`, `select ?s from ?g where{/_<foo> as ?s "id"@[2015-07-19T13:12:04] ?o};`, `select ?s from ?g where{/_<foo> as ?s "id"@[2015-07-19T13:12:04.669618843] ?o};`, `select ?s from ?g where{/_<foo> as ?s "id"@[2015-07-19T13:12:04.669618843-07:00] ?o};`, `select ?s from ?g where{/_<foo> as ?s "id"@[2015-07-19T13:12:04.669618843-07:00] as ?p ?o};`, `select ?s from ?g where{/_<foo> as ?s ?p "id"@[2015-07-19T13:12:04.669618843-07:00] as ?o};`, // Test predicates with bindings are accepted. `select ?s from ?g where{/_<foo> as ?s "id"@[?ta] ?o};`, `select ?s from ?g where{/_<foo> as ?s ?p "id"@[?ta] as ?o};`, // Test predicate bounds are accepted. `select ?s from ?g where{/_<foo> as ?s "id"@[2015-07-19T13:12:04.669618843-07:00, 2016-07-19T13:12:04.669618843-07:00] ?o};`, `select ?s from ?g where{/_<foo> as ?s ?p "id"@[2015-07-19T13:12:04.669618843-07:00, 2016-07-19T13:12:04.669618843-07:00] as ?o};`, // Test predicate bounds with bounds are accepted. `select ?s from ?g where{/_<foo> as ?s "id"@[?foo, 2016-07-19T13:12:04.669618843-07:00] ?o};`, `select ?s from ?g where{/_<foo> as ?s ?p "id"@[2015-07-19T13:12:04.669618843-07:00, ?bar] as ?o};`, `select ?s from ?g where{/_<foo> as ?s ?p "id"@[?foo, ?bar] as ?o};`} p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { t.Errorf("grammar.NewParser: should have produced a valid BQL parser") } for _, input := range table { if err := p.Parse(grammar.NewLLk(input, 1), &semantic.Statement{}); err != nil { t.Errorf("Parser.consume: failed to accept input %q with error %v", input, err) } } }
func deleteTest(t *testing.T) { bql := `delete data from ?a {/_<foo> "bar"@[] /_<foo> . /_<foo> "bar"@[] "bar"@[1975-01-01T00:01:01.999999999Z] . /_<foo> "bar"@[] "yeah"^^type:text};` p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { t.Errorf("grammar.NewParser: should have produced a valid BQL parser") } stm := &semantic.Statement{} if err := p.Parse(grammar.NewLLk(bql, 1), stm); err != nil { t.Errorf("Parser.consume: failed to accept BQL %q with error %v", bql, err) } pln, err := New(memory.DefaultStore, stm) if err != nil { t.Errorf("planner.New: should have not failed to create a plan using memory.DefaultStorage for statement %v", stm) } if _, err := pln.Excecute(); err != nil { t.Errorf("planner.Execute: failed to execute insert plan with error %v", err) } g, err := memory.DefaultStore.Graph("?a") if err != nil { t.Errorf("memory.DefaultStore.Graph(%q) should have not fail with error %v", "?a", err) } i := 0 ts, err := g.Triples() if err != nil { t.Error(err) } for _ = range ts { i++ } if i != 0 { t.Errorf("g.Triples should have returned 3 triples, returned %d instead", i) } }
func TestDropGraph(t *testing.T) { memory.DefaultStore.DeleteGraph("?foo") memory.DefaultStore.DeleteGraph("?bar") memory.DefaultStore.NewGraph("?foo") memory.DefaultStore.NewGraph("?bar") bql := `drop graph ?foo, ?bar;` p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { t.Errorf("grammar.NewParser: should have produced a valid BQL parser") } stm := &semantic.Statement{} if err := p.Parse(grammar.NewLLk(bql, 1), stm); err != nil { t.Errorf("Parser.consume: failed to accept BQL %q with error %v", bql, err) } pln, err := New(memory.DefaultStore, stm) if err != nil { t.Errorf("planner.New: should have not failed to create a plan using memory.DefaultStorage for statement %v", stm) } if _, err := pln.Excecute(); err != nil { t.Errorf("planner.Execute: failed to execute insert plan with error %v", err) } if g, err := memory.DefaultStore.Graph("?foo"); err == nil { t.Errorf("planner.Execute: failed to drop graph %q; returned %v", "?foo", g) } if g, err := memory.DefaultStore.Graph("?bar"); err == nil { t.Errorf("planner.Execute: failed to drop graph %q; returned %v", "?bar", g) } }
func TestCreateGraph(t *testing.T) { ctx := context.Background() memory.DefaultStore.DeleteGraph(ctx, "?foo") memory.DefaultStore.DeleteGraph(ctx, "?bar") bql := `create graph ?foo, ?bar;` p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { t.Errorf("grammar.NewParser: should have produced a valid BQL parser") } stm := &semantic.Statement{} if err := p.Parse(grammar.NewLLk(bql, 1), stm); err != nil { t.Errorf("Parser.consume: failed to accept BQL %q with error %v", bql, err) } pln, err := New(ctx, memory.DefaultStore, stm) if err != nil { t.Errorf("planner.New: should have not failed to create a plan using memory.DefaultStorage for statement %v with error %v", stm, err) } if _, err := pln.Excecute(ctx); err != nil { t.Errorf("planner.Execute: failed to execute insert plan with error %v", err) } if _, err := memory.DefaultStore.Graph(ctx, "?foo"); err != nil { t.Errorf("planner.Execute: failed to create graph %q with error %v", "?foo", err) } if _, err := memory.DefaultStore.Graph(ctx, "?bar"); err != nil { t.Errorf("planner.Execute: failed to create graph %q with error %v", "?bar", err) } }
func TestTreeTraversalToRoot(t *testing.T) { // Graph traversal data. traversalTriples := `/person<Gavin Belson> "born in"@[] /city<Springfield> /person<Gavin Belson> "parent of"@[] /person<Peter Belson> /person<Gavin Belson> "parent of"@[] /person<Mary Belson> /person<Mary Belson> "parent of"@[] /person<Amy Schumer> /person<Mary Belson> "parent of"@[] /person<Joe Schumer>` traversalQuery := `SELECT ?grandparent FROM ?test WHERE { ?s "parent of"@[] /person<Amy Schumer> . ?grandparent "parent of"@[] ?s };` // Load traversing data s, ctx := memory.NewStore(), context.Background() g, gErr := s.NewGraph(ctx, "?test") if gErr != nil { t.Fatalf("memory.NewGraph failed to create \"?test\" with error %v", gErr) } b := bytes.NewBufferString(traversalTriples) if _, err := io.ReadIntoGraph(ctx, g, b, literal.DefaultBuilder()); err != nil { t.Fatalf("io.ReadIntoGraph failed to read test graph with error %v", err) } p, pErr := grammar.NewParser(grammar.SemanticBQL()) if pErr != nil { t.Fatalf("grammar.NewParser: should have produced a valid BQL parser with error %v", pErr) } st := &semantic.Statement{} if err := p.Parse(grammar.NewLLk(traversalQuery, 1), st); err != nil { t.Errorf("Parser.consume: failed to parse query %q with error %v", traversalQuery, err) } plnr, err := New(ctx, s, st, 0) if err != nil { t.Errorf("planner.New failed to create a valid query plan with error %v", err) } tbl, err := plnr.Execute(ctx) if err != nil { t.Errorf("planner.Excecute failed for query %q with error %v", traversalQuery, err) } if got, want := len(tbl.Bindings()), 1; got != want { t.Errorf("tbl.Bindings returned the wrong number of bindings for %q; got %d, want %d", traversalQuery, got, want) } if got, want := len(tbl.Rows()), 1; got != want { t.Errorf("planner.Excecute failed to return the expected number of rows for query %q; got %d want %d\nGot:\n%v\n", traversalQuery, got, want, tbl) } }
func TestAcceptOpsByParseAndSemantic(t *testing.T) { table := []struct { query string graphs int triples int }{ // Insert data. {`insert data into ?a {/_<foo> "bar"@[1975-01-01T00:01:01.999999999Z] /_<foo>};`, 1, 1}, {`insert data into ?a {/_<foo> "bar"@[] "bar"@[1975-01-01T00:01:01.999999999Z]};`, 1, 1}, {`insert data into ?a {/_<foo> "bar"@[] "yeah"^^type:text};`, 1, 1}, // Insert into multiple graphs. {`insert data into ?a,?b,?c {/_<foo> "bar"@[] /_<foo>};`, 3, 1}, // Insert multiple data. {`insert data into ?a {/_<foo> "bar"@[] /_<foo> . /_<foo> "bar"@[] "bar"@[1975-01-01T00:01:01.999999999Z] . /_<foo> "bar"@[] "yeah"^^type:text};`, 1, 3}, // Delete data. {`delete data from ?a {/_<foo> "bar"@[] /_<foo>};`, 1, 1}, {`delete data from ?a {/_<foo> "bar"@[] "bar"@[1975-01-01T00:01:01.999999999Z]};`, 1, 1}, {`delete data from ?a {/_<foo> "bar"@[] "yeah"^^type:text};`, 1, 1}, // Delete from multiple graphs. {`delete data from ?a,?b,?c {/_<foo> "bar"@[1975-01-01T00:01:01.999999999Z] /_<foo>};`, 3, 1}, // Delete multiple data. {`delete data from ?a {/_<foo> "bar"@[] /_<foo> . /_<foo> "bar"@[] "bar"@[1975-01-01T00:01:01.999999999Z] . /_<foo> "bar"@[] "yeah"^^type:text};`, 1, 3}, // Create graphs. {`create graph ?foo;`, 1, 0}, // Drop graphs. {`drop graph ?foo, ?bar;`, 2, 0}, } p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { t.Errorf("grammar.NewParser: should have produced a valid BQL parser") } for _, entry := range table { st := &semantic.Statement{} if err := p.Parse(grammar.NewLLk(entry.query, 1), st); err != nil { t.Errorf("Parser.consume: failed to accept entry %q with error %v", entry, err) } if got, want := len(st.Graphs()), entry.graphs; got != want { t.Errorf("Parser.consume: failed to collect right number of graphs for case %v; got %d, want %d", entry, got, want) } if got, want := len(st.Data()), entry.triples; got != want { t.Errorf("Parser.consume: failed to collect right number of triples for case %v; got %d, want %d", entry, got, want) } } }
func TestQuery(t *testing.T) { testTable := []struct { q string nbs int nrws int }{ { q: `select ?s, ?p, ?o from ?test where {?s ?p ?o}`, nbs: 3, nrws: len(strings.Split(testTriples, "\n")), }, } s := populateTestStore(t) p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { t.Fatalf("grammar.NewParser: should have produced a valid BQL parser with error %v", err) } for _, entry := range testTable { st := &semantic.Statement{} if err := p.Parse(grammar.NewLLk(entry.q, 1), st); err == nil { t.Errorf("Parser.consume: failed to reject invalid semantic entry %q", entry) } plnr, err := New(s, st) if err != nil { t.Errorf("planner.New failed to create a valid query plan with error %v", err) } tbl, err := plnr.Excecute() if err != nil { t.Errorf("planner.Excecute failed for query %q with error %v", entry.q, err) } stbl, err := tbl.ToText(", ") if err != nil { t.Errorf("tbl.ToText failed to serialize table with error %v", err) } if got, want := len(tbl.Bindings()), entry.nbs; got != want { t.Errorf("tbl.Bindings returned the wrong number of bindings; got %d, want %d", got, want) } if got, want := len(strings.Split(stbl.String(), "\n")), entry.nrws; got != want { t.Errorf("planner.Excecute failed to return the expected number of rows for query %q; got %d want %d", entry.q, got, want) } } }
// runBQL attemps to excecute the provided query against the given store. func runBQL(ctx context.Context, bql string, s storage.Store) (*table.Table, error) { p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { return nil, fmt.Errorf("Failed to initilize a valid BQL parser") } stm := &semantic.Statement{} if err := p.Parse(grammar.NewLLk(bql, 1), stm); err != nil { return nil, fmt.Errorf("Failed to parse BQL statement with error %v", err) } pln, err := planner.New(ctx, s, stm) if err != nil { return nil, fmt.Errorf("Should have not failed to create a plan using memory.DefaultStorage for statement %v with error %v", stm, err) } res, err := pln.Excecute(ctx) if err != nil { return nil, fmt.Errorf("planner.Execute: failed to execute insert plan with error %v", err) } return res, nil }
func TestRejectByParseAndSemantic(t *testing.T) { table := []string{ // Test wront type litterals are rejected. `select ?s from ?g where{?s ?p "true"^^type:int64};`, // Test invalid predicate bounds are rejected. `select ?s from ?b where{/_<foo> as ?s "id"@[2018-07-19T13:12:04.669618843-07:00, 2015-07-19T13:12:04.669618843-07:00] ?o};`, `select ?s from ?b where{/_<foo> as ?s ?p "id"@[2019-07-19T13:12:04.669618843-07:00, 2015-07-19T13:12:04.669618843-07:00] as ?o};`, } p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { t.Errorf("grammar.NewParser: should have produced a valid BQL parser") } for _, entry := range table { st := &semantic.Statement{} if err := p.Parse(grammar.NewLLk(entry, 1), st); err == nil { t.Errorf("Parser.consume: failed to reject invalid semantic entry %q", entry) } } }
func TestQuery(t *testing.T) { testTable := []struct { q string r string }{ { q: `select ?o from ?test_graph where {/u<joe> "parent_of"@[] ?o}`, r: "\n", }, } s := populateTestStore(t) p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { t.Fatalf("grammar.NewParser: should have produced a valid BQL parser with error %v", err) } for _, entry := range testTable { st := &semantic.Statement{} if err := p.Parse(grammar.NewLLk(entry.q, 1), st); err == nil { t.Errorf("Parser.consume: failed to reject invalid semantic entry %q", entry) } plnr, err := New(s, st) if err != nil { t.Errorf("planner.New failed to create a valid query plan with error %v", err) } tbl, err := plnr.Excecute() if err != nil { t.Errorf("planner.Excecute failed for query %q with error %v", entry.q, err) } stbl, err := tbl.ToText(", ") if err != nil { t.Errorf("tbl.ToText failed to serialize table with error %v", err) } if got, want := stbl.String(), entry.r; got != want { t.Errorf("planner.Excecute failed to reture the expected output for query %q; got\n%q\nwant\n%q", entry.q, got, want) } } }
func insertTest(t *testing.T) { ctx := context.Background() bql := `insert data into ?a {/_<foo> "bar"@[] /_<foo> . /_<foo> "bar"@[] "bar"@[1975-01-01T00:01:01.999999999Z] . /_<foo> "bar"@[] "yeah"^^type:text};` p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { t.Errorf("grammar.NewParser: should have produced a valid BQL parser, %v", err) } stm := &semantic.Statement{} if err = p.Parse(grammar.NewLLk(bql, 1), stm); err != nil { t.Errorf("Parser.consume: failed to accept BQL %q with error %v", bql, err) } pln, err := New(ctx, memory.DefaultStore, stm, 0) if err != nil { t.Errorf("planner.New: should have not failed to create a plan using memory.DefaultStorage for statement %v with error %v", stm, err) } if _, err = pln.Execute(ctx); err != nil { t.Errorf("planner.Execute: failed to execute insert plan with error %v", err) } g, err := memory.DefaultStore.Graph(ctx, "?a") if err != nil { t.Errorf("memory.DefaultStore.Graph(%q) should have not fail with error %v", "?a", err) } i := 0 ts := make(chan *triple.Triple) go func() { if err := g.Triples(ctx, ts); err != nil { t.Error(err) } }() for _ = range ts { i++ } if i != 3 { t.Errorf("g.Triples should have returned 3 triples, returned %d instead", i) } }
// runAssertion runs the assertion and compares the outcome. Returns the outcome // of comparing the obtained result table with the assertion table if there is // no error during the assertion. func (a *Assertion) runAssertion(ctx context.Context, st storage.Store, chanSize int) (bool, *table.Table, *table.Table, error) { errorizer := func(e error) (bool, *table.Table, *table.Table, error) { if a.WillFail && e != nil { return true, nil, nil, nil } return false, nil, nil, e } // Run the query. p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { return errorizer(fmt.Errorf("Failed to initilize a valid BQL parser")) } stm := &semantic.Statement{} if err := p.Parse(grammar.NewLLk(a.Statement, 1), stm); err != nil { return errorizer(fmt.Errorf("Failed to parse BQL statement with error %v", err)) } pln, err := planner.New(ctx, st, stm, chanSize) if err != nil { return errorizer(fmt.Errorf("Should have not failed to create a plan using memory.DefaultStorage for statement %v with error %v", stm, err)) } tbl, err := pln.Execute(ctx) if err != nil { return errorizer(fmt.Errorf("planner.Execute: failed to execute assertion %q with error %v", a.Requires, err)) } // Check the output. want, err := a.OutputTable(stm.OutputBindings()) if err != nil { return errorizer(err) } // Cannot use reflect.DeepEqual, since projections only remove bindings from // the table but not the actual data. However, the serialized text version // of the tables will be equal regardless of the internal representation. return tbl.String() == want.String(), tbl, want, nil }
// benchmarkQuery is a helper function that runs a specified query on the testing data set for benchmarking purposes. func benchmarkQuery(query string, b *testing.B) { ctx := context.Background() s := populateBenchmarkStore(b) p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { b.Fatalf("grammar.NewParser: should have produced a valid BQL parser with error %v", err) } b.ResetTimer() for n := 0; n < b.N; n++ { st := &semantic.Statement{} if err := p.Parse(grammar.NewLLk(query, 1), st); err != nil { b.Errorf("Parser.consume: failed to parse query %q with error %v", query, err) } plnr, err := New(ctx, s, st, 0) if err != nil { b.Errorf("planner.New failed to create a valid query plan with error %v", err) } _, err = plnr.Execute(ctx) if err != nil { b.Errorf("planner.Excecute failed for query %q with error %v", query, err) } } }
func TestQuery(t *testing.T) { testTable := []struct { q string nbs int nrws int }{ { q: `select ?s, ?p, ?o from ?test where {?s ?p ?o};`, nbs: 3, nrws: len(strings.Split(testTriples, "\n")) - 2, }, { q: `select ?p, ?o from ?test where {/u<joe> ?p ?o};`, nbs: 2, nrws: 2, }, { q: `select ?s, ?o from ?test where {?s ?p /t<car>};`, nbs: 2, nrws: 4, }, { q: `select ?s, ?p from ?test where {?s "parent_of"@[] ?o};`, nbs: 2, nrws: 4, }, { q: `select ?s, ?p, ?o from ?test where {/u<joe> as ?s "parent_of"@[] as ?p /u<mary> as ?o};`, nbs: 3, nrws: 1, }, { q: `select ?s, ?p, ?o from ?test where {/u<unknown> as ?s "parent_of"@[] as ?p /u<mary> as ?o};`, nbs: 3, nrws: 0, }, { q: `select ?o from ?test where {/u<joe> "parent_of"@[] ?o};`, nbs: 1, nrws: 2, }, { q: `select ?p from ?test where {/u<joe> ?p /u<mary>};`, nbs: 1, nrws: 1, }, { q: `select ?s from ?test where {?s "is_a"@[] /t<car>};`, nbs: 1, nrws: 4, }, { q: `select ?s from ?test where {/u<joe> "parent_of"@[] ?o. ?o "parent_of"@[] /u<john>};`, nbs: 1, nrws: 1, }, { q: `select ?s, ?p, ?o, ?k, ?l, ?m from ?test where {?s ?p ?o. ?k ?l ?m};`, nbs: 6, nrws: (len(strings.Split(testTriples, "\n")) - 2) * (len(strings.Split(testTriples, "\n")) - 2), }, } s := populateTestStore(t) p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { t.Fatalf("grammar.NewParser: should have produced a valid BQL parser with error %v", err) } for _, entry := range testTable { st := &semantic.Statement{} if err := p.Parse(grammar.NewLLk(entry.q, 1), st); err != nil { t.Errorf("Parser.consume: failed to parse query %q with error %v", entry.q, err) } plnr, err := New(s, st) if err != nil { t.Errorf("planner.New failed to create a valid query plan with error %v", err) } tbl, err := plnr.Excecute() if err != nil { t.Errorf("planner.Excecute failed for query %q with error %v", entry.q, err) } if got, want := len(tbl.Bindings()), entry.nbs; got != want { t.Errorf("tbl.Bindings returned the wrong number of bindings for %q; got %d, want %d", entry.q, got, want) } if got, want := len(tbl.Rows()), entry.nrws; got != want { t.Errorf("planner.Excecute failed to return the expected number of rows for query %q; got %d want %d", entry.q, got, want) } } }
func TestQuery(t *testing.T) { ctx := context.Background() testTable := []struct { q string nbs int nrws int }{ { q: `select ?s, ?p, ?o from ?test where {?s ?p ?o};`, nbs: 3, nrws: len(strings.Split(testTriples, "\n")) - 2, }, { q: `select ?p, ?o from ?test where {/u<joe> ?p ?o};`, nbs: 2, nrws: 2, }, { q: `select ?s, ?p from ?test where {?s ?p /t<car>};`, nbs: 2, nrws: 4, }, { q: `select ?s, ?o from ?test where {?s "parent_of"@[] ?o};`, nbs: 2, nrws: 4, }, { q: `select ?s, ?p, ?o from ?test where {/u<joe> as ?s "parent_of"@[] as ?p /u<mary> as ?o};`, nbs: 3, nrws: 1, }, { q: `select ?s, ?p, ?o from ?test where {/u<unknown> as ?s "parent_of"@[] as ?p /u<mary> as ?o};`, nbs: 3, nrws: 0, }, { q: `select ?o from ?test where {/u<joe> "parent_of"@[] ?o};`, nbs: 1, nrws: 2, }, { q: `select ?p from ?test where {/u<joe> ?p /u<mary>};`, nbs: 1, nrws: 1, }, { q: `select ?s from ?test where {?s "is_a"@[] /t<car>};`, nbs: 1, nrws: 4, }, { q: `select ?o from ?test where {/u<joe> "parent_of"@[] ?o. ?o "parent_of"@[] /u<john>};`, nbs: 1, nrws: 1, }, { q: `select ?s, ?o from ?test where {/u<joe> "parent_of"@[] ?o. ?o "parent_of"@[] ?s};`, nbs: 2, nrws: 2, }, { q: `select ?s, ?p, ?o, ?k, ?l, ?m from ?test where {?s ?p ?o. ?k ?l ?m};`, nbs: 6, nrws: (len(strings.Split(testTriples, "\n")) - 2) * (len(strings.Split(testTriples, "\n")) - 2), }, { q: `select ?s, ?p, ?o, ?k, ?l from ?test where {?s ?p ?o. ?k ?l ?m};`, nbs: 5, nrws: (len(strings.Split(testTriples, "\n")) - 2) * (len(strings.Split(testTriples, "\n")) - 2), }, { q: `select ?s, ?p, ?o, ?k from ?test where {?s ?p ?o. ?k ?l ?m};`, nbs: 4, nrws: (len(strings.Split(testTriples, "\n")) - 2) * (len(strings.Split(testTriples, "\n")) - 2), }, { q: `select ?s, ?p, ?o from ?test where {?s ?p ?o. ?k ?l ?m};`, nbs: 3, nrws: (len(strings.Split(testTriples, "\n")) - 2) * (len(strings.Split(testTriples, "\n")) - 2), }, { q: `select ?s, ?p from ?test where {?s ?p ?o. ?k ?l ?m};`, nbs: 2, nrws: (len(strings.Split(testTriples, "\n")) - 2) * (len(strings.Split(testTriples, "\n")) - 2), }, { q: `select ?s from ?test where {?s ?p ?o. ?k ?l ?m};`, nbs: 1, nrws: (len(strings.Split(testTriples, "\n")) - 2) * (len(strings.Split(testTriples, "\n")) - 2), }, { q: `select ?o from ?test where {/u<peter> "bought"@[,] ?o};`, nbs: 1, nrws: 4, }, { q: `select ?o from ?test where {/u<peter> "bought"@[,2015-01-01T00:00:00-08:00] ?o};`, nbs: 1, nrws: 0, }, { q: `select ?o from ?test where {/u<peter> "bought"@[2017-01-01T00:00:00-08:00,] ?o};`, nbs: 1, nrws: 0, }, { q: `select ?o from ?test where {/u<peter> "bought"@[2015-01-01T00:00:00-08:00,2017-01-01T00:00:00-08:00] ?o};`, nbs: 1, nrws: 4, }, { q: `select ?o from ?test where {/l<barcelona> "predicate"@[] "turned"@[,] as ?o};`, nbs: 1, nrws: 4, }, { q: `select ?o from ?test where {/l<barcelona> "predicate"@[] "turned"@[,2015-01-01T00:00:00-08:00] as ?o};`, nbs: 1, nrws: 0, }, { q: `select ?o from ?test where {/l<barcelona> "predicate"@[] "turned"@[2017-01-01T00:00:00-08:00,] as ?o};`, nbs: 1, nrws: 0, }, { q: `select ?o from ?test where {/l<barcelona> "predicate"@[] "turned"@[2015-01-01T00:00:00-08:00,2017-01-01T00:00:00-08:00] as ?o};`, nbs: 1, nrws: 4, }, { q: `select ?grandparent, count(?name) as ?grandchildren from ?test where {/u<joe> as ?grandparent "parent_of"@[] ?offspring . ?offspring "parent_of"@[] ?name} group by ?grandparent;`, nbs: 2, nrws: 1, }, { q: `select ?grandparent, count(distinct ?name) as ?grandchildren from ?test where {/u<joe> as ?grandparent "parent_of"@[] ?offspring . ?offspring "parent_of"@[] ?name} group by ?grandparent;`, nbs: 2, nrws: 1, }, { q: `select ?s, ?p, ?o, ?k, ?l, ?m from ?test where {?s ?p ?o. ?k ?l ?m} order by ?s, ?p, ?o, ?k, ?l, ?m;`, nbs: 6, nrws: (len(strings.Split(testTriples, "\n")) - 2) * (len(strings.Split(testTriples, "\n")) - 2), }, { q: `select ?s, ?p, ?o, ?k, ?l, ?m from ?test where {?s ?p ?o. ?k ?l ?m} order by ?s, ?p, ?o, ?k, ?l, ?m having not(?s = ?s);`, nbs: 6, nrws: 0, }, { q: `select ?o from ?test where {/l<barcelona> "predicate"@[] "turned"@[2015-01-01T00:00:00-08:00,2017-01-01T00:00:00-08:00] as ?o} LIMIT "2"^^type:int64;`, nbs: 1, nrws: 2, }, { q: `select ?o from ?test where {/u<peter> "bought"@[2015-01-01T00:00:00-08:00,2017-01-01T00:00:00-08:00] ?o} before ""@[2014-01-01T00:00:00-08:00];`, nbs: 1, nrws: 0, }, { q: `select ?o from ?test where {/u<peter> "bought"@[2015-01-01T00:00:00-08:00,2017-01-01T00:00:00-08:00] ?o} after ""@[2017-01-01T00:00:00-08:00];`, nbs: 1, nrws: 0, }, { q: `select ?o from ?test where {/u<peter> "bought"@[2015-01-01T00:00:00-08:00,2017-01-01T00:00:00-08:00] ?o} between ""@[2014-01-01T00:00:00-08:00], ""@[2017-01-01T00:00:00-08:00];`, nbs: 1, nrws: 4, }, { q: `SELECT ?grandparent, COUNT(?grandparent) AS ?number_of_grandchildren FROM ?test WHERE{ ?gp ID ?grandparent "parent_of"@[] ?c . ?c "parent_of"@[] ?gc ID ?gc } GROUP BY ?grandparent;`, nbs: 2, nrws: 1, }, } s := populateTestStore(t) p, err := grammar.NewParser(grammar.SemanticBQL()) if err != nil { t.Fatalf("grammar.NewParser: should have produced a valid BQL parser with error %v", err) } for _, entry := range testTable { st := &semantic.Statement{} if err := p.Parse(grammar.NewLLk(entry.q, 1), st); err != nil { t.Errorf("Parser.consume: failed to parse query %q with error %v", entry.q, err) } plnr, err := New(ctx, s, st) if err != nil { t.Errorf("planner.New failed to create a valid query plan with error %v", err) } tbl, err := plnr.Excecute(ctx) if err != nil { t.Errorf("planner.Excecute failed for query %q with error %v", entry.q, err) } if got, want := len(tbl.Bindings()), entry.nbs; got != want { t.Errorf("tbl.Bindings returned the wrong number of bindings for %q; got %d, want %d", entry.q, got, want) } if got, want := len(tbl.Rows()), entry.nrws; got != want { t.Errorf("planner.Excecute failed to return the expected number of rows for query %q; got %d want %d\nGot:\n%v\n", entry.q, got, want, tbl) } } }