Repository: cayleygraph/cayley
Pull request #901 (2019-12-16 22:55:42)

LinkedQL: Refactor numeric operators to steps
I am not sure yet how to name `Like` and `Regex` as steps yet so I only refactored numeric operators.

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/cayleygraph/cayley/901)
<!-- Reviewable:end -->



Patch:
diff --git a/query/linkedql/operators.go b/query/linkedql/operators.go
index c17356e..c5e22e7 100644
--- a/query/linkedql/operators.go
+++ b/query/linkedql/operators.go
@@ -3,7 +3,6 @@ package linkedql
 import (
 	"regexp"
 
-	"github.com/cayleygraph/cayley/graph/iterator"
 	"github.com/cayleygraph/cayley/query/path"
 	"github.com/cayleygraph/cayley/query/shape"
 	"github.com/cayleygraph/quad"
@@ -15,94 +14,6 @@ type Operator interface {
 	Apply(p *path.Path) (*path.Path, error)
 }
 
-var _ Operator = (*LessThan)(nil)
-
-// LessThan corresponds to lt().
-type LessThan struct {
-	Value quad.Value `json:"value"`
-}
-
-// Type implements Operator.
-func (s *LessThan) Type() quad.IRI {
-	return Prefix + "LessThan"
-}
-
-// Description implements Operator.
-func (s *LessThan) Description() string {
-	return "Less than filters out values that are not less than given value"
-}
-
-// Apply implements Operator.
-func (s *LessThan) Apply(p *path.Path) (*path.Path, error) {
-	return p.Filter(iterator.CompareLT, s.Value), nil
-}
-
-var _ Operator = (*LessThanEquals)(nil)
-
-// LessThanEquals corresponds to lte().
-type LessThanEquals struct {
-	Value quad.Value `json:"value"`
-}
-
-// Type implements Operator.
-func (s *LessThanEquals) Type() quad.IRI {
-	return Prefix + "LessThanEquals"
-}
-
-// Description implements Operator.
-func (s *LessThanEquals) Description() string {
-	return "Less than equals filters out values that are not less than or equal given value"
-}
-
-// Apply implements Operator.
-func (s *LessThanEquals) Apply(p *path.Path) (*path.Path, error) {
-	return p.Filter(iterator.CompareLTE, s.Value), nil
-}
-
-var _ Operator = (*GreaterThan)(nil)
-
-// GreaterThan corresponds to gt().
-type GreaterThan struct {
-	Value quad.Value `json:"value"`
-}
-
-// Type implements Operator.
-func (s *GreaterThan) Type() quad.IRI {
-	return Prefix + "GreaterThan"
-}
-
-// Description implements Operator.
-func (s *GreaterThan) Description() string {
-	return "Greater than equals filters out values that are not greater than given value"
-}
-
-// Apply implements Operator.
-func (s *GreaterThan) Apply(p *path.Path) (*path.Path, error) {
-	return p.Filter(iterator.CompareGT, s.Value), nil
-}
-
-var _ Operator = (*GreaterThanEquals)(nil)
-
-// GreaterThanEquals corresponds to gte().
-type GreaterThanEquals struct {
-	Value quad.Value `json:"value"`
-}
-
-// Type implements Operator.
-func (s *GreaterThanEquals) Type() quad.IRI {
-	return Prefix + "GreaterThanEquals"
-}
-
-// Description implements Operator.
-func (s *GreaterThanEquals) Description() string {
-	return "Greater than equals filters out values that are not greater than or equal given value"
-}
-
-// Apply implements Operator.
-func (s *GreaterThanEquals) Apply(p *path.Path) (*path.Path, error) {
-	return p.Filter(iterator.CompareGTE, s.Value), nil
-}
-
 var _ Operator = (*RegExp)(nil)
 
 // RegExp corresponds to regex().
diff --git a/query/linkedql/steps.go b/query/linkedql/steps.go
index 45d6b7f..abcf5a2 100644
--- a/query/linkedql/steps.go
+++ b/query/linkedql/steps.go
@@ -2,6 +2,7 @@ package linkedql
 
 import (
 	"github.com/cayleygraph/cayley/graph"
+	"github.com/cayleygraph/cayley/graph/iterator"
 	"github.com/cayleygraph/cayley/query"
 	"github.com/cayleygraph/cayley/query/path"
 	"github.com/cayleygraph/quad"
@@ -1254,6 +1255,9 @@ func (s *Optional) BuildPath(qs graph.QuadStore) (*path.Path, error) {
 	return fromPath.Optional(p), nil
 }
 
+var _ IteratorStep = (*Where)(nil)
+var _ PathStep = (*Where)(nil)
+
 // Where corresponds to .where().
 type Where struct {
 	From  PathStep   `json:"from"`
@@ -1291,3 +1295,135 @@ func (s *Where) BuildPath(qs graph.QuadStore) (*path.Path, error) {
 	}
 	return p, nil
 }
+
+var _ IteratorStep = (*LessThan)(nil)
+var _ PathStep = (*LessThan)(nil)
+
+// LessThan corresponds to lt().
+type LessThan struct {
+	From  PathStep   `json:"from"`
+	Value quad.Value `json:"value"`
+}
+
+// Type implements Step.
+func (s *LessThan) Type() quad.IRI {
+	return Prefix + "LessThan"
+}
+
+// Description implements Step.
+func (s *LessThan) Description() string {
+	return "Less than filters out values that are not less than given value"
+}
+
+// BuildIterator implements IteratorStep.
+func (s *LessThan) BuildIterator(qs graph.QuadStore) (query.Iterator, error) {
+	return NewValueIteratorFromPathStep(s, qs)
+}
+
+// BuildPath implements Step.
+func (s *LessThan) BuildPath(qs graph.QuadStore) (*path.Path, error) {
+	fromPath, err := s.From.BuildPath(qs)
+	if err != nil {
+		return nil, err
+	}
+	return fromPath.Filter(iterator.CompareLT, s.Value), nil
+}
+
+var _ IteratorStep = (*LessThanEquals)(nil)
+var _ PathStep = (*LessThanEquals)(nil)
+
+// LessThanEquals corresponds to lte().
+type LessThanEquals struct {
+	From  PathStep   `json:"from"`
+	Value quad.Value `json:"value"`
+}
+
+// Type implements Step.
+func (s *LessThanEquals) Type() quad.IRI {
+	return Prefix + "LessThanEquals"
+}
+
+// Description implements Step.
+func (s *LessThanEquals) Description() string {
+	return "Less than equals filters out values that are not less than or equal given value"
+}
+
+// BuildIterator implements Step.
+func (s *LessThanEquals) BuildIterator(qs graph.QuadStore) (query.Iterator, error) {
+	return NewValueIteratorFromPathStep(s, qs)
+}
+
+// BuildPath implements Step.
+func (s *LessThanEquals) BuildPath(qs graph.QuadStore) (*path.Path, error) {
+	fromPath, err := s.From.BuildPath(qs)
+	if err != nil {
+		return nil, err
+	}
+	return fromPath.Filter(iterator.CompareLTE, s.Value), nil
+}
+
+var _ IteratorStep = (*GreaterThan)(nil)
+var _ PathStep = (*GreaterThan)(nil)
+
+// GreaterThan corresponds to gt().
+type GreaterThan struct {
+	From  PathStep   `json:"from"`
+	Value quad.Value `json:"value"`
+}
+
+// Type implements Step.
+func (s *GreaterThan) Type() quad.IRI {
+	return Prefix + "GreaterThan"
+}
+
+// Description implements Step.
+func (s *GreaterThan) Description() string {
+	return "Greater than equals filters out values that are not greater than given value"
+}
+
+// BuildIterator implements Step.
+func (s *GreaterThan) BuildIterator(qs graph.QuadStore) (query.Iterator, error) {
+	return NewValueIteratorFromPathStep(s, qs)
+}
+
+// BuildPath implements Step.
+func (s *GreaterThan) BuildPath(qs graph.QuadStore) (*path.Path, error) {
+	fromPath, err := s.From.BuildPath(qs)
+	if err != nil {
+		return nil, err
+	}
+	return fromPath.Filter(iterator.CompareGT, s.Value), nil
+}
+
+var _ IteratorStep = (*GreaterThanEquals)(nil)
+var _ PathStep = (*GreaterThanEquals)(nil)
+
+// GreaterThanEquals corresponds to gte().
+type GreaterThanEquals struct {
+	From  PathStep   `json:"from"`
+	Value quad.Value `json:"value"`
+}
+
+// Type implements Step.
+func (s *GreaterThanEquals) Type() quad.IRI {
+	return Prefix + "GreaterThanEquals"
+}
+
+// Description implements Step.
+func (s *GreaterThanEquals) Description() string {
+	return "Greater than equals filters out values that are not greater than or equal given value"
+}
+
+// BuildIterator implements Step.
+func (s *GreaterThanEquals) BuildIterator(qs graph.QuadStore) (query.Iterator, error) {
+	return NewValueIteratorFromPathStep(s, qs)
+}
+
+// BuildPath implements Step.
+func (s *GreaterThanEquals) BuildPath(qs graph.QuadStore) (*path.Path, error) {
+	fromPath, err := s.From.BuildPath(qs)
+	if err != nil {
+		return nil, err
+	}
+	return fromPath.Filter(iterator.CompareGTE, s.Value), nil
+}


Test patch:
diff --git a/query/linkedql/steps_test.go b/query/linkedql/steps_test.go
index 8cecea9..5a4e6fc 100644
--- a/query/linkedql/steps_test.go
+++ b/query/linkedql/steps_test.go
@@ -176,9 +176,9 @@ var testCases = []struct {
 			{Subject: quad.IRI("alice"), Predicate: quad.IRI("name"), Object: quad.Int(0), Label: nil},
 			{Subject: quad.IRI("alice"), Predicate: quad.IRI("name"), Object: quad.Int(1), Label: nil},
 		},
-		query: &Filter{
-			From:   &Vertex{Values: []quad.Value{}},
-			Filter: &LessThan{Value: quad.Int(1)},
+		query: &LessThan{
+			From:  &Vertex{Values: []quad.Value{}},
+			Value: quad.Int(1),
 		},
 		results: []interface{}{
 			quad.Int(0),
@@ -190,9 +190,9 @@ var testCases = []struct {
 			{Subject: quad.IRI("alice"), Predicate: quad.IRI("name"), Object: quad.Int(0), Label: nil},
 			{Subject: quad.IRI("alice"), Predicate: quad.IRI("name"), Object: quad.Int(1), Label: nil},
 		},
-		query: &Filter{
-			From:   &Vertex{Values: []quad.Value{}},
-			Filter: &GreaterThan{Value: quad.Int(0)},
+		query: &GreaterThan{
+			From:  &Vertex{Values: []quad.Value{}},
+			Value: quad.Int(0),
 		},
 		results: []interface{}{
 			quad.Int(1),
@@ -205,9 +205,9 @@ var testCases = []struct {
 			{Subject: quad.IRI("alice"), Predicate: quad.IRI("name"), Object: quad.Int(0), Label: nil},
 			{Subject: quad.IRI("alice"), Predicate: quad.IRI("name"), Object: quad.Int(1), Label: nil},
 		},
-		query: &Filter{
-			From:   &Vertex{Values: []quad.Value{}},
-			Filter: &LessThanEquals{Value: quad.Int(0)},
+		query: &LessThanEquals{
+			From:  &Vertex{Values: []quad.Value{}},
+			Value: quad.Int(0),
 		},
 		results: []interface{}{
 			quad.Int(-1),
@@ -221,9 +221,9 @@ var testCases = []struct {
 			{Subject: quad.IRI("alice"), Predicate: quad.IRI("name"), Object: quad.Int(1), Label: nil},
 			{Subject: quad.IRI("alice"), Predicate: quad.IRI("name"), Object: quad.Int(2), Label: nil},
 		},
-		query: &Filter{
-			From:   &Vertex{Values: []quad.Value{}},
-			Filter: &GreaterThanEquals{Value: quad.Int(1)},
+		query: &GreaterThanEquals{
+			From:  &Vertex{Values: []quad.Value{}},
+			Value: quad.Int(1),
 		},
 		results: []interface{}{
 			quad.Int(1),