Пример #1
0
// processClause retrives the triples for the provided triple given the
// information available.
func (p *queryPlan) processClause(cls *semantic.GraphClause, lo *storage.LookupOptions) error {
	// This method decides how to process the clause based on the current
	// list of bindings solved and data available.
	exist, total := 0, 0
	for _, b := range cls.Bindings() {
		total++
		if p.tbl.HasBinding(b) {
			exist++
		}
	}
	if exist == 0 {
		// Data is new.
		tbl, err := simpleFetch(p.grfs, cls, lo)
		if err != nil {
			return err
		}
		if len(p.tbl.Bindings()) > 0 {
			return p.tbl.DotProduct(tbl)
		}
		return p.tbl.AppendTable(tbl)
	}
	if exist > 0 && exist < total {
		// Data is partially binded, retrieve data either extends the row with the
		// new bindings or filters it out if now new bindings are available.
		return p.specifyClauseWithTable(cls, lo)
	}
	if exist > 0 && exist == total {
		// Since all bindings in the clause are already solved, the clause becomes a
		// fully specified triple. If the triple does not exist the row will be
		// deleted.
		return p.filterOnExistance(cls, lo)
	}
	// Somethign is wrong with the code.
	return fmt.Errorf("queryPlan.processClause(%v) should have never failed to resolve the clause", cls)
}
Пример #2
0
// processClause retrives the triples for the provided triple given the
// information available.
func (p *queryPlan) processClause(cls *semantic.GraphClause) error {
	// This method decides how to process the clause based on the current
	// list of bindings solved and data available.
	exist, total := 0, 0
	for _, b := range cls.Bindings() {
		total++
		if p.tbl.HasBinding(b) {
			exist++
		}
	}
	if exist == 0 {
		// Data is new.
		// TODO(xllora): Fetch the data.
		if len(p.tbl.Bindings()) > 0 {
			// TODO(xllora): The data should be added using the dot product.
			return nil
		}
		// TODO(xllora): Data should be added directly.
		return nil
	}
	if exist > 0 && exist < total {
		// TODO(xllora): Data is partially binded, retrieve data either extends
		// the row with the new bindings or filters it out if now new bindings
		// are available.
		return nil
	}
	if exist > 0 && exist == total {
		// TODO(xllora): Since all bindings in the clause are already solved,
		// the clause becomes a fully specified triple. If the triple does not
		// exist the row will be deleted.
		return nil
	}
	// Somethign is wrong with the code.
	return fmt.Errorf("queryPlan.processClause(%v) should have never failed to resolve the clause", cls)
}
Пример #3
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)
}
Пример #4
0
// addSpecifiedData specializes the clause given the row provided and attemp to
// retrieve the correspoinding clause data.
func (p *queryPlan) addSpecifiedData(r table.Row, cls *semantic.GraphClause, lo *storage.LookupOptions) error {
	if cls.S == nil {
		v := getBindedValueForComponent(r, []string{cls.SBinding, cls.SAlias})
		if v != nil {
			if v.N != nil {
				cls.S = v.N
			}
		}
	}
	if cls.P == nil {
		v := getBindedValueForComponent(r, []string{cls.PBinding, cls.PAlias})
		if v != nil {
			if v.N != nil {
				cls.P = v.P
			}
		}
		nlo, err := updateTimeBoundsForRow(lo, cls, r)
		if err != nil {
			return err
		}
		lo = nlo
	}
	if cls.O == nil {
		v := getBindedValueForComponent(r, []string{cls.PBinding, cls.PAlias})
		if v != nil {
			o, err := cellToObject(v)
			if err == nil {
				cls.O = o
			}
		}
		nlo, err := updateTimeBoundsForRow(lo, cls, r)
		if err != nil {
			return err
		}
		lo = nlo
	}
	tbl, err := simpleFetch(p.grfs, cls, lo)
	if err != nil {
		return err
	}
	p.tbl.AddBindings(tbl.Bindings())
	for _, nr := range tbl.Rows() {
		p.tbl.AddRow(table.MergeRows([]table.Row{r, nr}))
	}
	return nil
}
Пример #5
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
}
Пример #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, 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)
}
Пример #7
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)
}