syncbase: query: Changes per kash comments on 10211, 10512, 10904.
Change-Id: I015f491811f6f682241591b65576d3950a74d746
diff --git a/v23/syncbase/nosql/internal/query/demo/demo.go b/v23/syncbase/nosql/internal/query/demo/demo.go
index 2cbb085..963a00d 100644
--- a/v23/syncbase/nosql/internal/query/demo/demo.go
+++ b/v23/syncbase/nosql/internal/query/demo/demo.go
@@ -2,50 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// This demo program exercises the syncbase query language.
-// The program's in-memory database implements the following
-// interfaces in query_db:
-// Database
-// Table
-// KeyValueStream
-//
-// The user can enter the following at the command line:
-// 1. dump - to get a dump of the database
-// 2. a syncbase select statement - which is executed and results printed to stdout
-// 3. exit (or empty line) - to exit the program
-//
-// To build example:
-// v23 go install v.io/syncbase/v23/syncbase/nosql/internal/query/demo
-//
-// To run example:
-// $V23_ROOT/roadmap/go/bin/demo
-//
-// Sample run:
-// > $V23_ROOT/roadmap/go/bin/demo
-// Enter query (or 'dump' or 'exit')? select v.Name, v.Address.State from Customer where t = "Customer"
-// John Smith,CA
-// Bat Masterson,IA
-// Enter query (or 'dump' or 'exit')? select v.CustID, v.InvoiceNum, v.ShipTo.Zip, v.Amount from Customer where t = "Invoice" and v.Amount > 100
-// 2,1001,50055,166
-// 2,1002,50055,243
-// 2,1004,50055,787
-// Enter query (or 'dump' or 'exit')? select k, v fro Customer
-// select k, v fro Customer
-// ^
-// Error: [Off:12] Expected 'from', found 'fro'
-// Enter query (or 'dump' or 'exit')? select k, v from Customer
-// 001,{John Smith 1 true 65 {1 Main St. Palo Alto CA 94303}
-// 001001,{1 1000 42 {1 Main St. Palo Alto CA 94303}}
-// 001002,{1 1003 7 {2 Main St. Palo Alto CA 94303}}
-// 001003,{1 1005 88 {3 Main St. Palo Alto CA 94303}}
-// 002,{Bat Masterson 2 true 66 {777 Any St. Collins IA 50055}
-// 002001,{2 1001 166 {777 Any St. collins IA 50055}}
-// 002002,{2 1002 243 {888 Any St. collins IA 50055}}
-// 002003,{2 1004 787 {999 Any St. collins IA 50055}}
-// 002004,{2 1006 88 {101010 Any St. collins IA 50055}}
-// exit
-// >
-//
package main
import (
diff --git a/v23/syncbase/nosql/internal/query/demo/doc.go b/v23/syncbase/nosql/internal/query/demo/doc.go
new file mode 100644
index 0000000..28c7fba
--- /dev/null
+++ b/v23/syncbase/nosql/internal/query/demo/doc.go
@@ -0,0 +1,48 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This demo program exercises the syncbase query language.
+// The program's in-memory database implements the following
+// interfaces in query_db:
+// Database
+// Table
+// KeyValueStream
+//
+// The user can enter the following at the command line:
+// 1. dump - to get a dump of the database
+// 2. a syncbase select statement - which is executed and results printed to stdout
+// 3. exit (or empty line) - to exit the program
+//
+// To build example:
+// v23 go install v.io/syncbase/v23/syncbase/nosql/internal/query/demo
+//
+// To run example:
+// $V23_ROOT/roadmap/go/bin/demo
+//
+// Sample run:
+// > $V23_ROOT/roadmap/go/bin/demo
+// Enter query (or 'dump' or 'exit')? select v.Name, v.Address.State from Customer where t = "Customer"
+// John Smith,CA
+// Bat Masterson,IA
+// Enter query (or 'dump' or 'exit')? select v.CustID, v.InvoiceNum, v.ShipTo.Zip, v.Amount from Customer where t = "Invoice" and v.Amount > 100
+// 2,1001,50055,166
+// 2,1002,50055,243
+// 2,1004,50055,787
+// Enter query (or 'dump' or 'exit')? select k, v fro Customer
+// select k, v fro Customer
+// ^
+// Error: [Off:12] Expected 'from', found 'fro'
+// Enter query (or 'dump' or 'exit')? select k, v from Customer
+// 001,{John Smith 1 true 65 {1 Main St. Palo Alto CA 94303}
+// 001001,{1 1000 42 {1 Main St. Palo Alto CA 94303}}
+// 001002,{1 1003 7 {2 Main St. Palo Alto CA 94303}}
+// 001003,{1 1005 88 {3 Main St. Palo Alto CA 94303}}
+// 002,{Bat Masterson 2 true 66 {777 Any St. Collins IA 50055}
+// 002001,{2 1001 166 {777 Any St. collins IA 50055}}
+// 002002,{2 1002 243 {888 Any St. collins IA 50055}}
+// 002003,{2 1004 787 {999 Any St. collins IA 50055}}
+// 002004,{2 1006 88 {101010 Any St. collins IA 50055}}
+// exit
+// >
+package main
diff --git a/v23/syncbase/nosql/internal/query/doc.go b/v23/syncbase/nosql/internal/query/doc.go
new file mode 100644
index 0000000..e4b73fa
--- /dev/null
+++ b/v23/syncbase/nosql/internal/query/doc.go
@@ -0,0 +1,6 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package query performs SQL-like select queries on the Syncbase NoSQL database.
+package query
diff --git a/v23/syncbase/nosql/internal/query/eval.go b/v23/syncbase/nosql/internal/query/eval.go
index 56b31ce..e14cee7 100644
--- a/v23/syncbase/nosql/internal/query/eval.go
+++ b/v23/syncbase/nosql/internal/query/eval.go
@@ -1,6 +1,7 @@
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+
package query
import (
@@ -26,8 +27,11 @@
switch e.Operator.Type {
case query_parser.And:
return Eval(k, v, e.Operand1.Expr) && Eval(k, v, e.Operand2.Expr)
- default: // query_parser.Or
+ case query_parser.Or:
return Eval(k, v, e.Operand1.Expr) || Eval(k, v, e.Operand2.Expr)
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return false
}
}
@@ -129,7 +133,7 @@
}
// Must be the same at this point.
if lhsValue.Type != rhsValue.Type {
- return nil, nil, errors.New(fmt.Sprintf("Logic error: expeced like types, got: %v, %v", lhsValue, rhsValue))
+ return nil, nil, errors.New(fmt.Sprintf("Logic error: expected like types, got: %v, %v", lhsValue, rhsValue))
}
return lhsValue, rhsValue, nil
@@ -158,8 +162,11 @@
c.CompRegex = o.CompRegex // non-nil for rhs of like expressions
case query_parser.TypUint:
c.Str = strconv.FormatUint(o.Uint, 10)
- default: // query_parser.TypObject
+ case query_parser.TypObject:
return nil, errors.New("Cannot convert object to string for comparison.")
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return nil, errors.New("Cannot convert operand to string for comparison.")
}
return &c, nil
}
@@ -186,8 +193,11 @@
bi.SetUint64(o.Uint)
var br big.Rat
c.BigRat = br.SetInt(&bi)
- default: // query_parser.TypObject
+ case query_parser.TypObject:
return nil, errors.New("Cannot convert object to big.Rat for comparison.")
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return nil, errors.New("Cannot convert operand to big.Rat for comparison.")
}
return &c, nil
}
@@ -205,8 +215,11 @@
c.Float = float64(o.Int)
case query_parser.TypUint:
c.Float = float64(o.Uint)
- default: // query_parser.TypObject
+ case query_parser.TypObject:
return nil, errors.New("Cannot convert object to float64 for comparison.")
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return nil, errors.New("Cannot convert operand to float64 for comparison.")
}
return &c, nil
}
@@ -226,8 +239,11 @@
var b big.Int
b.SetUint64(o.Uint)
c.BigInt = &b
- default: // case query_parser.TypObject
+ case query_parser.TypObject:
return nil, errors.New("Cannot convert object to big.Int for comparison.")
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return nil, errors.New("Cannot convert operand to big.Int for comparison.")
}
return &c, nil
}
@@ -241,8 +257,11 @@
return nil, errors.New("Cannot convert bool to int64 for comparison.")
case query_parser.TypInt:
c.Int = o.Int
- default: //case query_parser.TypObject
+ case query_parser.TypObject:
return nil, errors.New("Cannot convert object to int64 for comparison.")
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return nil, errors.New("Cannot convert operand to int64 for comparison.")
}
return &c, nil
}
@@ -256,8 +275,11 @@
return nil, errors.New("Cannot convert bool to int64 for comparison.")
case query_parser.TypUint:
c.Uint = o.Uint
- default: //case query_parser.TypObject
+ case query_parser.TypObject:
return nil, errors.New("Cannot convert object to int64 for comparison.")
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return nil, errors.New("Cannot convert operand to int64 for comparison.")
}
return &c, nil
}
@@ -266,8 +288,11 @@
switch oper.Type {
case query_parser.Equal:
return lhsValue.Bool == rhsValue.Bool
- default: // query_parser.NotEqual
+ case query_parser.NotEqual:
return lhsValue.Bool != rhsValue.Bool
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return false
}
}
@@ -283,8 +308,11 @@
return lhsValue.BigInt.Cmp(rhsValue.BigInt) <= 0
case query_parser.GreaterThan:
return lhsValue.BigInt.Cmp(rhsValue.BigInt) > 0
- default: // case query_parser.GreaterThanOrEqual
+ case query_parser.GreaterThanOrEqual:
return lhsValue.BigInt.Cmp(rhsValue.BigInt) >= 0
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return false
}
}
@@ -300,8 +328,11 @@
return lhsValue.BigRat.Cmp(rhsValue.BigRat) <= 0
case query_parser.GreaterThan:
return lhsValue.BigRat.Cmp(rhsValue.BigRat) > 0
- default: // case query_parser.GreaterThanOrEqual
+ case query_parser.GreaterThanOrEqual:
return lhsValue.BigRat.Cmp(rhsValue.BigRat) >= 0
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return false
}
}
@@ -317,8 +348,11 @@
return lhsValue.Float <= rhsValue.Float
case query_parser.GreaterThan:
return lhsValue.Float > rhsValue.Float
- default: // case query_parser.GreaterThanOrEqual
+ case query_parser.GreaterThanOrEqual:
return lhsValue.Float >= rhsValue.Float
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return false
}
}
@@ -334,8 +368,11 @@
return lhsValue.Int <= rhsValue.Int
case query_parser.GreaterThan:
return lhsValue.Int > rhsValue.Int
- default: // case query_parser.GreaterThanOrEqual
+ case query_parser.GreaterThanOrEqual:
return lhsValue.Int >= rhsValue.Int
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return false
}
}
@@ -351,8 +388,11 @@
return lhsValue.Uint <= rhsValue.Uint
case query_parser.GreaterThan:
return lhsValue.Uint > rhsValue.Uint
- default: // case query_parser.GreaterThanOrEqual
+ case query_parser.GreaterThanOrEqual:
return lhsValue.Uint >= rhsValue.Uint
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return false
}
}
@@ -378,8 +418,11 @@
return lhsValue.Str >= rhsValue.Str
case query_parser.Like:
return rhsValue.CompRegex.MatchString(lhsValue.Str)
- default: // query_parser.NotLike:
+ case query_parser.NotLike:
return !rhsValue.CompRegex.MatchString(lhsValue.Str)
+ default:
+ // TODO(jkline): Log this logic error and all other similar cases.
+ return false
}
}
@@ -487,8 +530,7 @@
return reflect.ValueOf(v).Type().PkgPath() + "." + name, true, name
}
}
- var object interface{}
- object = v
+ object := v
segments := f.Segments
// The first segment will always be v itself, skip it.
for i := 1; i < len(segments); i++ {
@@ -527,60 +569,66 @@
}
}
+// EvalWhereUsingOnlyKey return type. See that function for details.
+type EvalWithKeyResult int
+
+const (
+ INCLUDE EvalWithKeyResult = iota
+ EXCLUDE
+ FETCH_VALUE
+)
+
// Evaluate the where clause to determine if the row should be selected, but do so using only
// the key. Possible returns are:
-// true: the row should included in the results
-// false: the row should NOT be included
-// error: the value and/or type of the value are required to determine if row should be included.
+// INCLUDE: the row should included in the results
+// EXCLUDE: the row should NOT be included
+// FETCH_VALUE: the value and/or type of the value are required to determine if row should be included.
// The above decision is accomplished by evaluating all expressions which reference the key and
-// substituing false for all other expressions. If the result is true, true is returned.
-// If the result is false, but no other experssions (i.e., expressions which refer to the type
-// of the value or the value itself) were encountered, false is returned; else, an error is
+// substituing false for all other expressions. If the result is true, INCLUDE is returned.
+// If the result is false, but no other expressions (i.e., expressions which refer to the type
+// of the value or the value itself) were encountered, EXCLUDE is returned; else, FETCH_VALUE is
// returned indicating the value must be fetched in order to determine if the row should be included
// in the results.
-func EvalWhereUsingOnlyKey(s *query_parser.SelectStatement, k string) (bool, error) {
+func EvalWhereUsingOnlyKey(s *query_parser.SelectStatement, k string) EvalWithKeyResult {
if s.Where == nil { // all rows will be in result
- return true, nil
+ return INCLUDE
}
return evalExprUsingOnlyKey(s.Where.Expr, k)
}
-func evalExprUsingOnlyKey(e *query_parser.Expression, k string) (bool, error) {
+func evalExprUsingOnlyKey(e *query_parser.Expression, k string) EvalWithKeyResult {
switch e.Operator.Type {
case query_parser.And:
- op1Result, err1 := evalExprUsingOnlyKey(e.Operand1.Expr, k)
- op2Result, err2 := evalExprUsingOnlyKey(e.Operand2.Expr, k)
- if op1Result && op2Result {
- return true, nil
- } else if (op1Result == false && err1 == nil) || (op2Result == false && err2 == nil) {
- // One of the operands evaluated to false with no error.
+ op1Result := evalExprUsingOnlyKey(e.Operand1.Expr, k)
+ op2Result := evalExprUsingOnlyKey(e.Operand2.Expr, k)
+ if op1Result == INCLUDE && op2Result == INCLUDE {
+ return INCLUDE
+ } else if op1Result == EXCLUDE || op2Result == EXCLUDE {
+ // One of the operands evaluated to EXCLUDE.
// As such, the value is not needed to reject the row.
- return false, nil
+ return EXCLUDE
} else {
- if err1 != nil {
- return false, err1
- } else {
- return false, err2
- }
+ return FETCH_VALUE
}
case query_parser.Or:
- op1Result, err1 := evalExprUsingOnlyKey(e.Operand1.Expr, k)
- op2Result, err2 := evalExprUsingOnlyKey(e.Operand2.Expr, k)
- if op1Result || op2Result {
- return true, nil
+ op1Result := evalExprUsingOnlyKey(e.Operand1.Expr, k)
+ op2Result := evalExprUsingOnlyKey(e.Operand2.Expr, k)
+ if op1Result == INCLUDE || op2Result == INCLUDE {
+ return INCLUDE
+ } else if op1Result == EXCLUDE && op2Result == EXCLUDE {
+ return EXCLUDE
} else {
- if err1 != nil {
- return false, err1
- } else {
- return false, err2 // err2 may or may not be nil
- }
+ return FETCH_VALUE
}
default: // =, > >=, <, <=, Like, <>, NotLike
if !query_checker.IsKey(e.Operand1) {
- // Non-key expressions are evaluated as false.
- return false, errors.New("Value required for answer.") // err text not used
+ return FETCH_VALUE
} else {
- return evalComparisonOperators(k, nil, e), nil
+ if evalComparisonOperators(k, nil, e) {
+ return INCLUDE
+ } else {
+ return EXCLUDE
+ }
}
}
}
diff --git a/v23/syncbase/nosql/internal/query/query.go b/v23/syncbase/nosql/internal/query/query.go
index a4c563d..a6c1c99 100644
--- a/v23/syncbase/nosql/internal/query/query.go
+++ b/v23/syncbase/nosql/internal/query/query.go
@@ -1,11 +1,6 @@
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//
-// Package query performs SQL-like select queries on the Syncbase NoSQL database.
-//
-// Note: Presently, the query package is deliberately not depending on other parts of syncbase.
-// This will change at a future date.
package query
@@ -115,21 +110,19 @@
return false
}
for rs.keyValueStream.Advance() {
- if err := rs.keyValueStream.Err(); err != nil {
- rs.err = Error(rs.selectStatement.Off, err.Error())
- return false
- }
k, v := rs.keyValueStream.KeyValue()
- if err := rs.keyValueStream.Err(); err != nil {
- rs.err = Error(rs.selectStatement.Off, err.Error())
- return false
- }
// EvalWhereUsingOnlyKey
- // true: the row should included in the results
- // false: the row should NOT be included
- // error: the value and/or type of the value are required to determine...
- match, err := EvalWhereUsingOnlyKey(rs.selectStatement, k)
- if err != nil {
+ // INCLUDE: the row should be included in the results
+ // EXCLUDE: the row should NOT be included
+ // FETCH_VALUE: the value and/or type of the value are required to make determination.
+ rv := EvalWhereUsingOnlyKey(rs.selectStatement, k)
+ var match bool
+ switch rv {
+ case INCLUDE:
+ match = true
+ case EXCLUDE:
+ match = false
+ case FETCH_VALUE:
match = Eval(k, v, rs.selectStatement.Where.Expr)
}
if match {
@@ -143,6 +136,9 @@
}
}
}
+ if err := rs.keyValueStream.Err(); err != nil {
+ rs.err = Error(rs.selectStatement.Off, err.Error())
+ }
return false
}
diff --git a/v23/syncbase/nosql/internal/query/query_checker/doc.go b/v23/syncbase/nosql/internal/query/query_checker/doc.go
new file mode 100644
index 0000000..7dc7039
--- /dev/null
+++ b/v23/syncbase/nosql/internal/query/query_checker/doc.go
@@ -0,0 +1,15 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package query_checker performs a semantic check on an AST produced
+// by the query_parser package.
+//
+// For the foreseeasble future, only SelectStatements are supported.
+// The following clauses are checked sequentially,
+// SelectClause
+// FromClause
+// WhereClause (optional)
+// LimitClause (optional)
+// ResultsOffsetClause (optional)
+package query_checker
diff --git a/v23/syncbase/nosql/internal/query/query_checker/query_checker.go b/v23/syncbase/nosql/internal/query/query_checker/query_checker.go
index 3c7e4d5..fb1ba20 100644
--- a/v23/syncbase/nosql/internal/query/query_checker/query_checker.go
+++ b/v23/syncbase/nosql/internal/query/query_checker/query_checker.go
@@ -1,17 +1,7 @@
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//
-// Package query_checker performs a semantic check on an AST produced
-// by the query_parser package.
-//
-// For the foreseeasble future, only SelectStatements are supported.
-// The following clauses are checked sequentially,
-// SelectClause
-// FromClause
-// WhereClause (optional)
-// LimitClause (optional)
-// ResultsOffsetClause (optional)
+
package query_checker
import (
diff --git a/v23/syncbase/nosql/internal/query/query_checker/query_checker_test.go b/v23/syncbase/nosql/internal/query/query_checker/query_checker_test.go
index 8a1bcf5..b819c9d 100644
--- a/v23/syncbase/nosql/internal/query/query_checker/query_checker_test.go
+++ b/v23/syncbase/nosql/internal/query/query_checker/query_checker_test.go
@@ -1,6 +1,7 @@
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+
package query_checker_test
import (
@@ -44,9 +45,6 @@
var db mockDB
-func TestCreate(t *testing.T) {
-}
-
type checkSelectTest struct {
query string
}
diff --git a/v23/syncbase/nosql/internal/query/query_db/doc.go b/v23/syncbase/nosql/internal/query/query_db/doc.go
new file mode 100644
index 0000000..2c5b2ed
--- /dev/null
+++ b/v23/syncbase/nosql/internal/query/query_db/doc.go
@@ -0,0 +1,11 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package query_db defines the interfaces a consumer of the query package would need to
+// implement.
+//
+// The Database interface is used to get Table interfaces (by name).
+// The Table interface is used to get a KeyValueStream (by key prefixes).
+// The KeyValueStream is used to consume key value pairs that match the prefixes.
+package query_db
diff --git a/v23/syncbase/nosql/internal/query/query_db/query_db.go b/v23/syncbase/nosql/internal/query/query_db/query_db.go
index a019ad4..10e5ec0 100644
--- a/v23/syncbase/nosql/internal/query/query_db/query_db.go
+++ b/v23/syncbase/nosql/internal/query/query_db/query_db.go
@@ -1,14 +1,7 @@
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//
-// Package query_db defines the interfaces a consumer of the query package would need to
-// implement.
-//
-// The Database interface is used to get Table interfaces (by name).
-// The Table interface is used to get a KeyValueStream (by key prefixes).
-// The KeyValueStream is used to consume key value pairs that match the prefixes.
-//
+
package query_db
type Database interface {
@@ -23,13 +16,31 @@
Scan(prefixes []string) (KeyValueStream, error)
}
-// If Advance() returns true, KeyValue() will return the first/next
-// key value pair. If not advanced through the whole stream (i.e.,
-// until Advance() returns false), Cancel() should be called.
-// Err should be checked after every call to Advance().
type KeyValueStream interface {
+ // Advance stages an element so the client can retrieve it
+ // with KeyValue. Advance returns true iff there is an
+ // element to retrieve. The client must call Advance before
+ // calling KeyValue. The client must call Cancel if it does
+ // not iterate through all elements (i.e. until Advance
+ // returns false). Advance may block if an element is not
+ // immediately available.
Advance() bool
+
+ // KeyValue returns the element that was staged by Advance.
+ // KeyValue may panic if Advance returned false or was not
+ // called at all. KeyValue does not block.
KeyValue() (string, interface{})
+
+ // Err returns a non-nil error iff the stream encountered
+ // any errors. Err does not block.
Err() error
+
+ // Cancel notifies the stream provider that it can stop
+ // producing elements. The client must call Cancel if it does
+ // not iterate through all elements (i.e. until Advance
+ // returns false). Cancel is idempotent and can be called
+ // concurrently with a goroutine that is iterating via
+ // Advance/Value. Cancel causes Advance to subsequently
+ // return false. Cancel does not block.
Cancel()
}
diff --git a/v23/syncbase/nosql/internal/query/query_parser/doc.go b/v23/syncbase/nosql/internal/query/query_parser/doc.go
new file mode 100644
index 0000000..18f041f
--- /dev/null
+++ b/v23/syncbase/nosql/internal/query/query_parser/doc.go
@@ -0,0 +1,68 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package query_parser is a parser to parse a simplified select statement (a la SQL) for the
+// Vanadium key value store (a.k.a., syncbase).
+//
+// The select is of the form:
+//
+// <query_specification> ::=
+// SELECT <field_clause> <from_clause> [<where_clause>] [<limit_offset_clause>]
+//
+// <field_clause> ::= <field>[{<comma><field>}...]
+//
+// <field> ::= <segment>[{<period><segment>}...]
+//
+// <segment> ::= <identifier>
+//
+// <from_clause> ::= FROM <table>
+//
+// <table> ::= <identifier>
+//
+// <where_clause> ::= WHERE <expression>
+//
+// <limit_offset_clause> ::=
+// <limit_clause> [<offset_clause>]
+// | <offset_clause> [<limit_clause>]
+//
+// <limit_clause> ::= LIMIT <int_literal>
+//
+// <offset_clause> ::= OFFSET <int_literal>
+//
+// <expression> ::=
+// ( <expression> )
+// | <logical_expression>
+// | <binary_expression>
+//
+// <logical_expression> ::=
+// <expression> <logical_op> <expression>
+//
+// <logical_op> ::=
+// AND
+// | OR
+//
+// <binary_expression> ::=
+// <operand> <binary_op> <operand>
+//
+// <operand> ::=
+// <field>
+// | <literal>
+//
+// <binary_op> ::=
+// =
+// | <>
+// | <
+// | >
+// | <=
+// | >=
+// | EQUAL
+// | NOT EQUAL
+// | LIKE
+// | NOT LIKE
+//
+// <literal> ::= <string_literal> | <char_literal> | <int_literal> | <float_literal>
+//
+// Example:
+// select foo.bar, baz from foobarbaz where foo = 42 and bar not like "abc%"
+package query_parser
diff --git a/v23/syncbase/nosql/internal/query/query_parser/query_parser.go b/v23/syncbase/nosql/internal/query/query_parser/query_parser.go
index e9a77d5..61cce96 100644
--- a/v23/syncbase/nosql/internal/query/query_parser/query_parser.go
+++ b/v23/syncbase/nosql/internal/query/query_parser/query_parser.go
@@ -1,71 +1,7 @@
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-//
-// Package query_parser is a parser to parse a simplified select statement (a la SQL) for the
-// Vanadium key value store (a.k.a., syncbase).
-//
-// The select is of the form:
-//
-// <query_specification> ::=
-// SELECT <field_clause> <from_clause> [<where_clause>] [<limit_offset_clause>]
-//
-// <field_clause> ::= <field>[{<comma><field>}...]
-//
-// <field> ::= <segment>[{<period><segment>}...]
-//
-// <segment> ::= <identifier>
-//
-// <from_clause> ::= FROM <table>
-//
-// <table> ::= <identifier>
-//
-// <where_clause> ::= WHERE <expression>
-//
-// <limit_offset_clause> ::=
-// <limit_clause> [<offset_clause>]
-// | <offset_clause> [<limit_clause>]
-//
-// <limit_clause> ::= LIMIT <int_literal>
-//
-// <offset_clause> ::= OFFSET <int_literal>
-//
-// <expression> ::=
-// ( <expression> )
-// | <logical_expression>
-// | <binary_expression>
-//
-// <logical_expression> ::=
-// <expression> <logical_op> <expression>
-//
-// <logical_op> ::=
-// AND
-// | OR
-//
-// <binary_expression> ::=
-// <operand> <binary_op> <operand>
-//
-// <operand> ::=
-// <field>
-// | <literal>
-//
-// <binary_op> ::=
-// =
-// | <>
-// | <
-// | >
-// | <=
-// | >=
-// | EQUAL
-// | NOT EQUAL
-// | LIKE
-// | NOT LIKE
-//
-// <literal> ::= <string_literal> | <char_literal> | <int_literal> | <float_literal>
-//
-// Example:
-// select foo.bar, baz from foobarbaz where foo = 42 and bar not like "abc%"
-//
+
package query_parser
import (
diff --git a/v23/syncbase/nosql/internal/query/query_parser/query_parser_test.go b/v23/syncbase/nosql/internal/query/query_parser/query_parser_test.go
index c2ea1db..78a6075 100644
--- a/v23/syncbase/nosql/internal/query/query_parser/query_parser_test.go
+++ b/v23/syncbase/nosql/internal/query/query_parser/query_parser_test.go
@@ -1,6 +1,7 @@
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+
package query_parser_test
import (
diff --git a/v23/syncbase/nosql/internal/query/query_test.go b/v23/syncbase/nosql/internal/query/query_test.go
index e8bb006..dced5d7 100644
--- a/v23/syncbase/nosql/internal/query/query_test.go
+++ b/v23/syncbase/nosql/internal/query/query_test.go
@@ -1,6 +1,7 @@
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+
package query_test
import (
@@ -131,7 +132,7 @@
var customerRows []customerKV
-func TestCreate(t *testing.T) {
+func init() {
sampleRow = Customer{"John Smith", 123456, true, 'A', "1 Main St.", "Palo Alto", "CA", "94303", big.NewInt(1234567890), big.NewRat(123, 1), byte(12), uint16(1234), uint32(5678), uint64(999888777666), int16(9876), int32(876543), Nest1{Nest2{"foo", true, 42}}}
sampleRow123 = Customer{"John Smith", 123, true, 123, "1 Main St.", "Palo Alto", "CA", "94303", big.NewInt(123), big.NewRat(123, 1), byte(123), uint16(123), uint32(123), uint64(123), int16(123), int32(123), Nest1{Nest2{"foo", true, 123}}}
sampleRow = Customer{"John Smith", 123456, true, 'A', "1 Main St.", "Palo Alto", "CA", "94303", big.NewInt(1234567890), big.NewRat(123, 1), byte(12), uint16(1234), uint32(5678), uint64(999888777666), int16(9876), int32(876543), Nest1{Nest2{"foo", true, 42}}}
@@ -185,8 +186,7 @@
type evalWhereUsingOnlyKeyTest struct {
query string
key string
- result bool
- err error
+ result query.EvalWithKeyResult
}
type evalTest struct {
@@ -611,36 +611,31 @@
// Row will be selected using only the key.
"select k, v from Customer where k like \"abc%\"",
"abcdef",
- true,
- nil,
+ query.INCLUDE,
},
{
// Row will be rejected using only the key.
"select k, v from Customer where k like \"abc\"",
"abcd",
- false,
- nil,
+ query.EXCLUDE,
},
{
// Need value to determine if row should be selected.
"select k, v from Customer where k = \"abc\" or v.zip = \"94303\"",
"abcd",
- false,
- errors.New("Value required for answer."),
+ query.FETCH_VALUE,
},
{
// Need value (i.e., its type) to determine if row should be selected.
"select k, v from Customer where k = \"xyz\" or t = \"foo.Bar\"",
"wxyz",
- false,
- errors.New("Value required for answer."),
+ query.FETCH_VALUE,
},
{
// Although value is in where clause, it is not needed to reject row.
"select k, v from Customer where k = \"abcd\" and v.zip = \"94303\"",
"abcde",
- false,
- nil,
+ query.EXCLUDE,
},
}
@@ -657,13 +652,10 @@
if semErr == nil {
switch sel := (*s).(type) {
case query_parser.SelectStatement:
- result, err := query.EvalWhereUsingOnlyKey(&sel, test.key)
+ result := query.EvalWhereUsingOnlyKey(&sel, test.key)
if result != test.result {
t.Errorf("query: %s; got %v, want %v", test.query, result, test.result)
}
- if (err == nil && test.err != nil) || (err != nil && test.err == nil) {
- t.Errorf("query: %s; got %v, want %v", test.query, err, test.err)
- }
default:
t.Errorf("query: %s; got %v, want query_parser.SelectStatement", test.query, reflect.TypeOf(*s))
}