コード例 #1
0
ファイル: semantic_test.go プロジェクト: sdayal/badwolf
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)
		}
	}
}
コード例 #2
0
ファイル: planner_test.go プロジェクト: opavader/badwolf
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)
	}
}
コード例 #3
0
ファイル: planner_test.go プロジェクト: opavader/badwolf
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)
	}
}
コード例 #4
0
ファイル: planner_test.go プロジェクト: msingle/badwolf
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)
	}
}
コード例 #5
0
ファイル: planner_test.go プロジェクト: google/badwolf
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)
	}
}
コード例 #6
0
ファイル: semantic_test.go プロジェクト: sdayal/badwolf
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)
		}
	}
}
コード例 #7
0
ファイル: planner_test.go プロジェクト: rossdakin/badwolf
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)
		}
	}
}
コード例 #8
0
ファイル: run.go プロジェクト: msingle/badwolf
// 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
}
コード例 #9
0
ファイル: semantic_test.go プロジェクト: sdayal/badwolf
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)
		}
	}
}
コード例 #10
0
ファイル: planner_test.go プロジェクト: rtu/badwolf
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)
		}
	}
}
コード例 #11
0
ファイル: planner_test.go プロジェクト: google/badwolf
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)
	}
}
コード例 #12
0
ファイル: runner.go プロジェクト: google/badwolf
// 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
}
コード例 #13
0
ファイル: planner_test.go プロジェクト: google/badwolf
// 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)
		}
	}
}
コード例 #14
0
ファイル: planner_test.go プロジェクト: opavader/badwolf
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)
		}
	}
}
コード例 #15
0
ファイル: planner_test.go プロジェクト: msingle/badwolf
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)
		}
	}
}