Beispiel #1
0
// newQueryPlan returns a new query plan ready to be excecuted.
func newQueryPlan(store storage.Store, stm *semantic.Statement) (*queryPlan, error) {
	bs := []string{}
	for _, b := range stm.Bindings() {
		bs = append(bs, b)
	}
	t, err := table.New([]string{})
	if err != nil {
		return nil, err
	}
	var gs []storage.Graph
	for _, g := range stm.Graphs() {
		ng, err := store.Graph(g)
		if err != nil {
			return nil, err
		}
		gs = append(gs, ng)
	}
	return &queryPlan{
		stm:       stm,
		store:     store,
		bndgs:     bs,
		grfs:      gs,
		grfsNames: stm.Graphs(),
		cls:       stm.SortedGraphPatternClauses(),
		tbl:       t,
	}, nil
}
Beispiel #2
0
// Execute queries the indicated graphs.
func (p *queryPlan) Execute(ctx context.Context) (*table.Table, error) {
	// Retrieve the data.
	lo := p.stm.GlobalLookupOptions()
	if err := p.processGraphPattern(ctx, lo); err != nil {
		return nil, err
	}
	if err := p.projectAndGroupBy(); err != nil {
		return nil, err
	}
	p.orderBy()
	err := p.having()
	if err != nil {
		return nil, err
	}
	p.limit()
	if p.tbl.NumRows() == 0 {
		// Correct the bindings.
		t, err := table.New(p.stm.OutputBindings())
		if err != nil {
			return nil, err
		}
		p.tbl = t
	}
	return p.tbl, nil
}
func TestAddTriples(t *testing.T) {
	testBindings := []string{"?s", "?p", "?o"}
	cls := &semantic.GraphClause{
		SBinding: "?s",
		PBinding: "?p",
		OBinding: "?o",
	}
	g, err := getTestStore(t).Graph("?test")
	if err != nil {
		t.Fatal(err)
	}
	ts, err := g.Triples()
	if err != nil {
		t.Fatal(err)
	}
	tbl, err := table.New([]string{})
	if err != nil {
		t.Fatal(err)
	}
	if err := addTriples(ts, cls, tbl); err != nil {
		t.Errorf("addTriple failed with errorf %v", err)
	}
	if got, want := tbl.NumRows(), len(testTextTriples); got != want {
		t.Errorf("addTriples returned the wrong number of rows; got %d, want %d", got, want)
	}
	for _, r := range tbl.Rows() {
		if got, want := len(r), len(testBindings); got != want {
			t.Errorf("addTriples returned row %v with the incorrect number of bindings; got %d, want %d", r, got, want)
		}
	}
}
Beispiel #4
0
// Execute deletes the provided data into the indicated graphs.
func (p *deletePlan) Excecute() (*table.Table, error) {
	t, err := table.New([]string{})
	if err != nil {
		return nil, err
	}
	return t, update(p.stm, p.store, func(g storage.Graph, d []*triple.Triple) error {
		return g.RemoveTriples(d)
	})
}
Beispiel #5
0
// Execute inserts the provided data into the indicated graphs.
func (p *insertPlan) Execute(ctx context.Context) (*table.Table, error) {
	t, err := table.New([]string{})
	if err != nil {
		return nil, err
	}
	return t, update(ctx, p.stm, p.store, func(g storage.Graph, d []*triple.Triple) error {
		return g.AddTriples(ctx, d)
	})
}
Beispiel #6
0
// simpleFetch returns a table containing the data specified by the graph
// clause by querying the provided stora. Will return an error if it had poblems
// retrieveing the data.
func simpleFetch(gs []storage.Graph, cls *semantic.GraphClause) (*table.Table, error) {
	tbl, err := table.New(cls.Bindings())
	if err != nil {
		return nil, err
	}
	if cls.S != nil && cls.P != nil && cls.O != nil {
		// Fully qualified triple.
		// TODO(xllora): Implement.
		return nil, nil
	}
	if cls.S != nil && cls.P != nil && cls.O == nil {
		// SP request.
		// TODO(xllora): Implement.
		return nil, nil
	}
	if cls.S != nil && cls.P == nil && cls.O != nil {
		// SO request.
		// TODO(xllora): Implement.
		return nil, nil
	}
	if cls.S == nil && cls.P != nil && cls.O != nil {
		// PO request.
		// TODO(xllora): Implement.
		return nil, nil
	}
	if cls.S != nil && cls.P == nil && cls.O == nil {
		// S request.
		// TODO(xllora): Implement.
		return nil, nil
	}
	if cls.S == nil && cls.P != nil && cls.O == nil {
		// P request.
		// TODO(xllora): Implement.
		return nil, nil
	}
	if cls.S == nil && cls.P == nil && cls.O != nil {
		// O request.
		// TODO(xllora): Implement.
		return nil, nil
	}
	if cls.S == nil && cls.P == nil && cls.O == nil {
		// Full data request.
		for _, g := range gs {
			ts, err := g.Triples()
			if err != nil {
				return nil, err
			}
			if err := addTriples(ts, cls, tbl); err != nil {
				return nil, err
			}
		}
		return tbl, nil
	}

	return nil, fmt.Errorf("planner.simpleFetch could not recognize request in clause %v", cls)
}
Beispiel #7
0
// OutputTable returns the expected result table for the must result table
// provided by the story.
func (a *Assertion) OutputTable(bo []string) (*table.Table, error) {
	// Return the already computed output table.
	if a.table != nil {
		return a.table, nil
	}
	// Compute the output table.
	var (
		first  bool
		mBdngs map[string]bool
		data   []table.Row
		bs     []string
	)
	mBdngs, first = make(map[string]bool), true
	for _, row := range a.MustReturn {
		nr := table.Row{}
		for k, v := range row {
			_, ok := mBdngs[k]
			if first && !ok {
				bs = append(bs, k)
			}
			if !first && !ok {
				return nil, fmt.Errorf("unknow binding %q; available ones are %v", k, mBdngs)
			}
			mBdngs[k], nr[k] = true, inferCell(v)
		}
		data = append(data, nr)
		first = false
	}
	if first {
		// No data was provided. This will create the empty table with the right
		// bindings.
		bs = bo
	}
	// Build the table.
	if len(bo) != len(bs) {
		return nil, fmt.Errorf("incompatible bindings; got %v, want %v", bs, bo)
	}
	for _, b := range bo {
		if _, ok := mBdngs[b]; !first && !ok {
			return nil, fmt.Errorf("missing binding %q; want bining in %v", b, bo)
		}
	}
	t, err := table.New(bo)
	if err != nil {
		return nil, err
	}
	for _, r := range data {
		t.AddRow(r)
	}
	return t, nil
}
Beispiel #8
0
// Execute drops the indicated graphs.
func (p *dropPlan) Excecute() (*table.Table, error) {
	t, err := table.New([]string{})
	if err != nil {
		return nil, err
	}
	errs := []string{}
	for _, g := range p.stm.Graphs() {
		if err := p.store.DeleteGraph(g); err != nil {
			errs = append(errs, err.Error())
		}
	}
	if len(errs) > 0 {
		return nil, errors.New(strings.Join(errs, "; "))
	}
	return t, nil
}
Beispiel #9
0
// Execute creates the indicated graphs.
func (p *createPlan) Execute(ctx context.Context) (*table.Table, error) {
	t, err := table.New([]string{})
	if err != nil {
		return nil, err
	}
	errs := []string{}
	for _, g := range p.stm.Graphs() {
		if _, err := p.store.NewGraph(ctx, g); err != nil {
			errs = append(errs, err.Error())
		}
	}
	if len(errs) > 0 {
		return nil, errors.New(strings.Join(errs, "; "))
	}
	return t, nil
}
Beispiel #10
0
func TestDataAccessAddTriples(t *testing.T) {
	ctx := context.Background()
	testBindings := []string{"?s", "?p", "?o"}
	cls := &semantic.GraphClause{
		SBinding: "?s",
		PBinding: "?p",
		OBinding: "?o",
	}
	g, err := getTestStore(t, testImmutatbleTriples).Graph(ctx, "?test")
	if err != nil {
		t.Fatal(err)
	}
	tbl, err := table.New([]string{})
	if err != nil {
		t.Fatal(err)
	}
	var wg sync.WaitGroup
	wg.Add(2)
	ts := make(chan *triple.Triple)
	go func() {
		defer wg.Done()
		if err := g.Triples(ctx, ts); err != nil {
			t.Fatal(err)
		}
	}()
	go func() {
		defer wg.Done()
		if err := addTriples(ts, cls, tbl); err != nil {
			t.Errorf("addTriple failed with errorf %v", err)
		}
	}()
	wg.Wait()
	if got, want := tbl.NumRows(), len(testImmutatbleTriples); got != want {
		t.Errorf("addTriples returned the wrong number of rows; got %d, want %d", got, want)
	}
	for _, r := range tbl.Rows() {
		if got, want := len(r), len(testBindings); got != want {
			t.Errorf("addTriples returned row %v with the incorrect number of bindings; got %d, want %d", r, got, want)
		}
	}
}
Beispiel #11
0
// simpleExist returns true if the triple exist. Return the unfeasible state,
// the table and the error if present.
func simpleExist(gs []storage.Graph, cls *semantic.GraphClause, t *triple.Triple) (bool, *table.Table, error) {
	unfeasible := true
	tbl, err := table.New(cls.Bindings())
	if err != nil {
		return true, nil, err
	}
	for _, g := range gs {
		b, err := g.Exist(t)
		if err != nil {
			return true, nil, err
		}
		if b {
			unfeasible = false
			ts := make(chan *triple.Triple, 1)
			ts <- t
			close(ts)
			if err := addTriples(ts, cls, tbl); err != nil {
				return true, nil, err
			}
		}
	}
	return unfeasible, tbl, nil
}
Beispiel #12
0
// simpleFetch returns a table containing the data specified by the graph
// clause by querying the provided stora. Will return an error if it had poblems
// retrieveing the data.
func simpleFetch(gs []storage.Graph, cls *semantic.GraphClause, lo *storage.LookupOptions) (*table.Table, error) {
	s, p, o := cls.S, cls.P, cls.O
	lo = updateTimeBounds(lo, cls)
	tbl, err := table.New(cls.Bindings())
	if err != nil {
		return nil, err
	}
	if s != nil && p != nil && o != nil {
		// Fully qualified triple.
		t, err := triple.New(s, p, o)
		if err != nil {
			return nil, err
		}
		for _, g := range gs {
			b, err := g.Exist(t)
			if err != nil {
				return nil, err
			}
			if b {
				ts := make(chan *triple.Triple, 1)
				ts <- t
				close(ts)
				if err := addTriples(ts, cls, tbl); err != nil {
					return nil, err
				}
			}
		}
		return tbl, nil
	}
	if s != nil && p != nil && o == nil {
		// SP request.
		for _, g := range gs {
			os, err := g.Objects(s, p, lo)
			if err != nil {
				return nil, err
			}
			var ros []*triple.Object
			for o := range os {
				ros = append(ros, o)
			}
			ts := make(chan *triple.Triple, len(ros))
			for _, o := range ros {
				t, err := triple.New(s, p, o)
				if err != nil {
					return nil, err
				}
				ts <- t
			}
			close(ts)
			if err := addTriples(ts, cls, tbl); err != nil {
				return nil, err
			}
		}
		return tbl, nil
	}
	if s != nil && p == nil && o != nil {
		// SO request.
		for _, g := range gs {
			ps, err := g.PredicatesForSubjectAndObject(s, o, lo)
			if err != nil {
				return nil, err
			}
			var rps []*predicate.Predicate
			for p := range ps {
				rps = append(rps, p)
			}
			ts := make(chan *triple.Triple, len(rps))
			for _, p := range rps {
				t, err := triple.New(s, p, o)
				if err != nil {
					return nil, err
				}
				ts <- t
			}
			close(ts)
			if err := addTriples(ts, cls, tbl); err != nil {
				return nil, err
			}
		}
		return tbl, nil
	}
	if s == nil && p != nil && o != nil {
		// PO request.
		for _, g := range gs {
			ss, err := g.Subjects(p, o, lo)
			if err != nil {
				return nil, err
			}
			var rss []*node.Node
			for s := range ss {
				rss = append(rss, s)
			}
			ts := make(chan *triple.Triple, len(rss))
			for _, s := range rss {
				t, err := triple.New(s, p, o)
				if err != nil {
					return nil, err
				}
				ts <- t
			}
			close(ts)
			if err := addTriples(ts, cls, tbl); err != nil {
				return nil, err
			}
		}
		return tbl, nil
	}
	if s != nil && p == nil && o == nil {
		// S request.
		for _, g := range gs {
			ts, err := g.TriplesForSubject(s, lo)
			if err != nil {
				return nil, err
			}
			if err := addTriples(ts, cls, tbl); err != nil {
				return nil, err
			}
		}
		return tbl, nil
	}
	if s == nil && p != nil && o == nil {
		// P request.
		for _, g := range gs {
			ts, err := g.TriplesForPredicate(p, lo)
			if err != nil {
				return nil, err
			}
			if err := addTriples(ts, cls, tbl); err != nil {
				return nil, err
			}
		}
		return tbl, nil
	}
	if s == nil && p == nil && o != nil {
		// O request.
		for _, g := range gs {
			ts, err := g.TriplesForObject(o, lo)
			if err != nil {
				return nil, err
			}
			if err := addTriples(ts, cls, tbl); err != nil {
				return nil, err
			}
		}
		return tbl, nil
	}
	if s == nil && p == nil && o == nil {
		// Full data request.
		for _, g := range gs {
			ts, err := g.Triples()
			if err != nil {
				return nil, err
			}
			if err := addTriples(ts, cls, tbl); err != nil {
				return nil, err
			}
		}
		return tbl, nil
	}

	return nil, fmt.Errorf("planner.simpleFetch could not recognize request in clause %v", cls)
}
Beispiel #13
0
// simpleFetch returns a table containing the data specified by the graph
// clause by querying the provided stora. Will return an error if it had poblems
// retrieveing the data.
func simpleFetch(ctx context.Context, gs []storage.Graph, cls *semantic.GraphClause, lo *storage.LookupOptions, chanSize int) (*table.Table, error) {
	s, p, o := cls.S, cls.P, cls.O
	lo = updateTimeBounds(lo, cls)
	tbl, err := table.New(cls.Bindings())
	if err != nil {
		return nil, err
	}
	if s != nil && p != nil && o != nil {
		// Fully qualified triple.
		t, err := triple.New(s, p, o)
		if err != nil {
			return nil, err
		}
		for _, g := range gs {
			b, err := g.Exist(ctx, t)
			if err != nil {
				return nil, err
			}
			if b {
				ts := make(chan *triple.Triple, 1)
				ts <- t
				close(ts)
				if err := addTriples(ts, cls, tbl); err != nil {
					return nil, err
				}
			}
		}
		return tbl, nil
	}
	if s != nil && p != nil && o == nil {
		// SP request.
		for _, g := range gs {
			var (
				oErr error
				aErr error
				lErr error
				wg   sync.WaitGroup
			)
			wg.Add(2)
			os := make(chan *triple.Object, chanSize)
			go func() {
				defer wg.Done()
				oErr = g.Objects(ctx, s, p, lo, os)
			}()
			ts := make(chan *triple.Triple, chanSize)
			go func() {
				defer wg.Done()
				aErr = addTriples(ts, cls, tbl)
			}()
			for o := range os {
				if lErr != nil {
					// Drain the channel to avoid leaking goroutines.
					continue
				}
				t, err := triple.New(s, p, o)
				if err != nil {
					lErr = err
					continue
				}
				ts <- t
			}
			close(ts)
			wg.Wait()
			if oErr != nil {
				return nil, oErr
			}
			if aErr != nil {
				return nil, aErr
			}
			if lErr != nil {
				return nil, lErr
			}
		}
		return tbl, nil
	}
	if s != nil && p == nil && o != nil {
		// SO request.
		for _, g := range gs {
			var (
				pErr error
				aErr error
				lErr error
				wg   sync.WaitGroup
			)
			wg.Add(2)
			ps := make(chan *predicate.Predicate, chanSize)
			go func() {
				defer wg.Done()
				pErr = g.PredicatesForSubjectAndObject(ctx, s, o, lo, ps)
			}()
			ts := make(chan *triple.Triple, chanSize)
			go func() {
				defer wg.Done()
				aErr = addTriples(ts, cls, tbl)
			}()
			for p := range ps {
				if lErr != nil {
					// Drain the channel to avoid leaking goroutines.
					continue
				}
				t, err := triple.New(s, p, o)
				if err != nil {
					lErr = err
					continue
				}
				ts <- t
			}
			close(ts)
			wg.Wait()
			if pErr != nil {
				return nil, pErr
			}
			if aErr != nil {
				return nil, aErr
			}
			if lErr != nil {
				return nil, lErr
			}
		}
		return tbl, nil
	}
	if s == nil && p != nil && o != nil {
		// PO request.
		for _, g := range gs {
			var (
				pErr error
				aErr error
				lErr error
				wg   sync.WaitGroup
			)
			wg.Add(2)
			ss := make(chan *node.Node, chanSize)
			go func() {
				defer wg.Done()
				pErr = g.Subjects(ctx, p, o, lo, ss)
			}()
			ts := make(chan *triple.Triple, chanSize)
			go func() {
				defer wg.Done()
				aErr = addTriples(ts, cls, tbl)
			}()
			for s := range ss {
				if lErr != nil {
					// Drain the channel to avoid leaking goroutines.
					continue
				}
				t, err := triple.New(s, p, o)
				if err != nil {
					lErr = err
					continue
				}
				ts <- t
			}
			close(ts)
			wg.Wait()
			if pErr != nil {
				return nil, pErr
			}
			if aErr != nil {
				return nil, aErr
			}
			if lErr != nil {
				return nil, lErr
			}
		}
		return tbl, nil
	}
	if s != nil && p == nil && o == nil {
		// S request.
		for _, g := range gs {
			var (
				tErr error
				aErr error
				wg   sync.WaitGroup
			)
			ts := make(chan *triple.Triple, chanSize)
			wg.Add(1)
			go func() {
				defer wg.Done()
				tErr = g.TriplesForSubject(ctx, s, lo, ts)
			}()
			aErr = addTriples(ts, cls, tbl)
			wg.Wait()
			if tErr != nil {
				return nil, tErr
			}
			if aErr != nil {
				return nil, aErr
			}
		}
		return tbl, nil
	}
	if s == nil && p != nil && o == nil {
		// P request.
		for _, g := range gs {
			var (
				tErr error
				aErr error
				wg   sync.WaitGroup
			)
			ts := make(chan *triple.Triple, chanSize)
			wg.Add(1)
			go func() {
				defer wg.Done()
				tErr = g.TriplesForPredicate(ctx, p, lo, ts)
			}()
			aErr = addTriples(ts, cls, tbl)
			wg.Wait()
			if tErr != nil {
				return nil, tErr
			}
			if aErr != nil {
				return nil, aErr
			}
		}
		return tbl, nil
	}
	if s == nil && p == nil && o != nil {
		// O request.
		for _, g := range gs {
			var (
				tErr error
				wg   sync.WaitGroup
			)
			ts := make(chan *triple.Triple, chanSize)
			wg.Add(1)
			go func() {
				defer wg.Done()
				tErr = g.TriplesForObject(ctx, o, lo, ts)
			}()
			aErr := addTriples(ts, cls, tbl)
			wg.Wait()
			if tErr != nil {
				return nil, tErr
			}
			if aErr != nil {
				return nil, aErr
			}
		}
		return tbl, nil
	}
	if s == nil && p == nil && o == nil {
		// Full data request.
		for _, g := range gs {
			var (
				tErr error
				aErr error
				wg   sync.WaitGroup
			)
			ts := make(chan *triple.Triple, chanSize)
			wg.Add(1)
			go func() {
				defer wg.Done()
				tErr = g.Triples(ctx, ts)
			}()
			aErr = addTriples(ts, cls, tbl)
			wg.Wait()
			if tErr != nil {
				return nil, tErr
			}
			if aErr != nil {
				return nil, aErr
			}
		}
		return tbl, nil
	}

	return nil, fmt.Errorf("planner.simpleFetch could not recognize request in clause %v", cls)
}