Improve binary condition comparison checks
This commit is contained in:
parent
cc8f4ec29e
commit
4e81a5633c
4 changed files with 1076 additions and 237 deletions
21
db/check.go
21
db/check.go
|
@ -24,12 +24,25 @@ import (
|
||||||
|
|
||||||
func (d *document) check(ctx context.Context, cond sql.Expr) (ok bool, err error) {
|
func (d *document) check(ctx context.Context, cond sql.Expr) (ok bool, err error) {
|
||||||
|
|
||||||
val, err := d.i.e.fetch(ctx, cond, d.current)
|
// If no condition expression has been
|
||||||
if val, ok := val.(bool); ok {
|
// defined then we can ignore this, and
|
||||||
return val, err
|
// process the current document.
|
||||||
|
|
||||||
|
if cond == nil {
|
||||||
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, err
|
// If a condition expression has been
|
||||||
|
// defined then let's process it to see
|
||||||
|
// what value it returns or error.
|
||||||
|
|
||||||
|
val, err := d.i.e.fetch(ctx, cond, d.current)
|
||||||
|
|
||||||
|
// If the condition expression result is
|
||||||
|
// not a boolean value, then let's see
|
||||||
|
// if the value can be equated to a bool.
|
||||||
|
|
||||||
|
return calcAsBool(val), err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
300
db/fetch.go
300
db/fetch.go
|
@ -20,6 +20,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/abcum/surreal/cnf"
|
"github.com/abcum/surreal/cnf"
|
||||||
|
@ -36,6 +37,8 @@ func (e *executor) fetch(ctx context.Context, val interface{}, doc *data.Doc) (o
|
||||||
switch val := val.(type) {
|
switch val := val.(type) {
|
||||||
default:
|
default:
|
||||||
return val, nil
|
return val, nil
|
||||||
|
case *sql.Null:
|
||||||
|
return nil, nil
|
||||||
case *sql.Thing:
|
case *sql.Thing:
|
||||||
return val, nil
|
return val, nil
|
||||||
case *sql.Value:
|
case *sql.Value:
|
||||||
|
@ -202,7 +205,13 @@ func (e *executor) fetch(ctx context.Context, val interface{}, doc *data.Doc) (o
|
||||||
return binaryBool(val.Op, l, r), nil
|
return binaryBool(val.Op, l, r), nil
|
||||||
case sql.ADD, sql.SUB, sql.MUL, sql.DIV, sql.INC, sql.DEC:
|
case sql.ADD, sql.SUB, sql.MUL, sql.DIV, sql.INC, sql.DEC:
|
||||||
return binaryMath(val.Op, l, r), nil
|
return binaryMath(val.Op, l, r), nil
|
||||||
case sql.EQ, sql.NEQ, sql.ANY, sql.LT, sql.LTE, sql.GT, sql.GTE, sql.SIN, sql.SNI, sql.INS, sql.NIS:
|
case sql.EQ, sql.NEQ, sql.ANY, sql.LT, sql.LTE, sql.GT, sql.GTE:
|
||||||
|
return binaryCheck(val.Op, l, r, val.LHS, val.RHS, doc), nil
|
||||||
|
case sql.SIN, sql.SNI, sql.INS, sql.NIS:
|
||||||
|
return binaryCheck(val.Op, l, r, val.LHS, val.RHS, doc), nil
|
||||||
|
case sql.CONTAINSALL, sql.CONTAINSSOME, sql.CONTAINSNONE:
|
||||||
|
return binaryCheck(val.Op, l, r, val.LHS, val.RHS, doc), nil
|
||||||
|
case sql.ALLCONTAINEDIN, sql.SOMECONTAINEDIN, sql.NONECONTAINEDIN:
|
||||||
return binaryCheck(val.Op, l, r, val.LHS, val.RHS, doc), nil
|
return binaryCheck(val.Op, l, r, val.LHS, val.RHS, doc), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,8 +237,11 @@ func (e *executor) fetchPaths(ctx context.Context, doc *data.Doc, exprs ...sql.E
|
||||||
case sql.DOT:
|
case sql.DOT:
|
||||||
return e.fetchPaths(ctx, doc, exprs...)
|
return e.fetchPaths(ctx, doc, exprs...)
|
||||||
case sql.OEDGE:
|
case sql.OEDGE:
|
||||||
|
return nil, featureNotImplemented
|
||||||
case sql.IEDGE:
|
case sql.IEDGE:
|
||||||
|
return nil, featureNotImplemented
|
||||||
case sql.BEDGE:
|
case sql.BEDGE:
|
||||||
|
return nil, featureNotImplemented
|
||||||
}
|
}
|
||||||
case *sql.PartExpression:
|
case *sql.PartExpression:
|
||||||
switch val := val.Part.(type) {
|
switch val := val.Part.(type) {
|
||||||
|
@ -443,62 +455,42 @@ func binaryCheck(op sql.Token, l, r, lo, ro interface{}, d *data.Doc) interface{
|
||||||
switch lo.(type) {
|
switch lo.(type) {
|
||||||
case *sql.Void:
|
case *sql.Void:
|
||||||
switch ro.(type) {
|
switch ro.(type) {
|
||||||
default:
|
case *sql.Null:
|
||||||
return op == sql.NEQ
|
|
||||||
case nil:
|
|
||||||
return op == sql.NEQ
|
return op == sql.NEQ
|
||||||
case *sql.Void:
|
case *sql.Void:
|
||||||
return op == sql.EQ
|
return op == sql.EQ
|
||||||
case *sql.Empty:
|
case *sql.Empty:
|
||||||
return op == sql.EQ
|
return op == sql.EQ
|
||||||
case *sql.Ident:
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
case *sql.Empty:
|
case *sql.Empty:
|
||||||
switch ro.(type) {
|
switch ro.(type) {
|
||||||
default:
|
case *sql.Null:
|
||||||
return op == sql.NEQ
|
|
||||||
case nil:
|
|
||||||
return op == sql.EQ
|
return op == sql.EQ
|
||||||
case *sql.Void:
|
case *sql.Void:
|
||||||
return op == sql.EQ
|
return op == sql.EQ
|
||||||
case *sql.Empty:
|
case *sql.Empty:
|
||||||
return op == sql.EQ
|
return op == sql.EQ
|
||||||
case *sql.Param:
|
|
||||||
break
|
|
||||||
case *sql.Ident:
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ro.(type) {
|
switch ro.(type) {
|
||||||
case *sql.Void:
|
case *sql.Void:
|
||||||
switch lo.(type) {
|
switch lo.(type) {
|
||||||
default:
|
case *sql.Null:
|
||||||
return op == sql.NEQ
|
|
||||||
case nil:
|
|
||||||
return op == sql.NEQ
|
return op == sql.NEQ
|
||||||
case *sql.Void:
|
case *sql.Void:
|
||||||
return op == sql.EQ
|
return op == sql.EQ
|
||||||
case *sql.Empty:
|
case *sql.Empty:
|
||||||
return op == sql.EQ
|
return op == sql.EQ
|
||||||
case *sql.Ident:
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
case *sql.Empty:
|
case *sql.Empty:
|
||||||
switch lo.(type) {
|
switch lo.(type) {
|
||||||
default:
|
case *sql.Null:
|
||||||
return op == sql.NEQ
|
|
||||||
case nil:
|
|
||||||
return op == sql.EQ
|
return op == sql.EQ
|
||||||
case *sql.Void:
|
case *sql.Void:
|
||||||
return op == sql.EQ
|
return op == sql.EQ
|
||||||
case *sql.Empty:
|
case *sql.Empty:
|
||||||
return op == sql.EQ
|
return op == sql.EQ
|
||||||
case *sql.Param:
|
|
||||||
break
|
|
||||||
case *sql.Ident:
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,7 +515,7 @@ func binaryCheck(op sql.Token, l, r, lo, ro interface{}, d *data.Doc) interface{
|
||||||
return d.Exists(r.ID) == true && d.Get(r.ID).Data() != nil
|
return d.Exists(r.ID) == true && d.Get(r.ID).Data() != nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case nil:
|
case *sql.Null:
|
||||||
switch r := ro.(type) {
|
switch r := ro.(type) {
|
||||||
case *sql.Ident:
|
case *sql.Ident:
|
||||||
if op == sql.EQ {
|
if op == sql.EQ {
|
||||||
|
@ -553,7 +545,7 @@ func binaryCheck(op sql.Token, l, r, lo, ro interface{}, d *data.Doc) interface{
|
||||||
return d.Exists(l.ID) == true && d.Get(l.ID).Data() != nil
|
return d.Exists(l.ID) == true && d.Get(l.ID).Data() != nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case nil:
|
case *sql.Null:
|
||||||
switch l := lo.(type) {
|
switch l := lo.(type) {
|
||||||
case *sql.Ident:
|
case *sql.Ident:
|
||||||
if op == sql.EQ {
|
if op == sql.EQ {
|
||||||
|
@ -568,20 +560,36 @@ func binaryCheck(op sql.Token, l, r, lo, ro interface{}, d *data.Doc) interface{
|
||||||
|
|
||||||
switch l := l.(type) {
|
switch l := l.(type) {
|
||||||
|
|
||||||
case *sql.Empty:
|
|
||||||
switch r.(type) {
|
|
||||||
default:
|
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case nil:
|
|
||||||
return op == sql.EQ
|
|
||||||
}
|
|
||||||
|
|
||||||
case nil:
|
case nil:
|
||||||
switch r := r.(type) {
|
switch r := r.(type) {
|
||||||
default:
|
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case nil:
|
case nil:
|
||||||
return op == sql.EQ
|
return op == sql.EQ
|
||||||
|
case *sql.Null:
|
||||||
|
return op == sql.EQ
|
||||||
|
case *sql.Empty:
|
||||||
|
return op == sql.EQ
|
||||||
|
case []interface{}:
|
||||||
|
return chkArrayR(op, l, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *sql.Null:
|
||||||
|
switch r := r.(type) {
|
||||||
|
case nil:
|
||||||
|
return op == sql.EQ
|
||||||
|
case *sql.Null:
|
||||||
|
return op == sql.EQ
|
||||||
|
case *sql.Empty:
|
||||||
|
return op == sql.EQ
|
||||||
|
case []interface{}:
|
||||||
|
return chkArrayR(op, l, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
case *sql.Empty:
|
||||||
|
switch r := r.(type) {
|
||||||
|
case nil:
|
||||||
|
return op == sql.EQ
|
||||||
|
case *sql.Null:
|
||||||
|
return op == sql.EQ
|
||||||
case *sql.Empty:
|
case *sql.Empty:
|
||||||
return op == sql.EQ
|
return op == sql.EQ
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
|
@ -592,8 +600,6 @@ func binaryCheck(op sql.Token, l, r, lo, ro interface{}, d *data.Doc) interface{
|
||||||
|
|
||||||
case *sql.Thing:
|
case *sql.Thing:
|
||||||
switch r := r.(type) {
|
switch r := r.(type) {
|
||||||
default:
|
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case *sql.Thing:
|
case *sql.Thing:
|
||||||
return chkThing(op, l, r)
|
return chkThing(op, l, r)
|
||||||
case string:
|
case string:
|
||||||
|
@ -604,44 +610,34 @@ func binaryCheck(op sql.Token, l, r, lo, ro interface{}, d *data.Doc) interface{
|
||||||
|
|
||||||
case bool:
|
case bool:
|
||||||
switch r := r.(type) {
|
switch r := r.(type) {
|
||||||
default:
|
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case bool:
|
case bool:
|
||||||
return chkBool(op, l, r)
|
return chkBool(op, l, r)
|
||||||
case string:
|
case string:
|
||||||
if b, err := strconv.ParseBool(r); err == nil {
|
if b, err := strconv.ParseBool(r); err == nil {
|
||||||
return chkBool(op, l, b)
|
return chkBool(op, l, b)
|
||||||
}
|
}
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case *regexp.Regexp:
|
case *regexp.Regexp:
|
||||||
return chkRegex(op, strconv.FormatBool(l), r)
|
return chkRegex(op, strconv.FormatBool(l), r)
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
return chkArrayR(op, l, r)
|
return chkArrayR(op, l, r)
|
||||||
case map[string]interface{}:
|
|
||||||
return chkObject(op, r, l)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case string:
|
case string:
|
||||||
switch r := r.(type) {
|
switch r := r.(type) {
|
||||||
default:
|
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case bool:
|
case bool:
|
||||||
if b, err := strconv.ParseBool(l); err == nil {
|
if b, err := strconv.ParseBool(l); err == nil {
|
||||||
return chkBool(op, r, b)
|
return chkBool(op, r, b)
|
||||||
}
|
}
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case string:
|
case string:
|
||||||
return chkString(op, l, r)
|
return chkString(op, l, r)
|
||||||
case int64:
|
case int64:
|
||||||
if n, err := strconv.ParseInt(l, 10, 64); err == nil {
|
if n, err := strconv.ParseInt(l, 10, 64); err == nil {
|
||||||
return chkInt(op, r, n)
|
return chkInt(op, r, n)
|
||||||
}
|
}
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case float64:
|
case float64:
|
||||||
if n, err := strconv.ParseFloat(l, 64); err == nil {
|
if n, err := strconv.ParseFloat(l, 64); err == nil {
|
||||||
return chkFloat(op, r, n)
|
return chkFloat(op, r, n)
|
||||||
}
|
}
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case time.Time:
|
case time.Time:
|
||||||
return chkString(op, l, r.String())
|
return chkString(op, l, r.String())
|
||||||
case *sql.Thing:
|
case *sql.Thing:
|
||||||
|
@ -650,19 +646,14 @@ func binaryCheck(op sql.Token, l, r, lo, ro interface{}, d *data.Doc) interface{
|
||||||
return chkRegex(op, l, r)
|
return chkRegex(op, l, r)
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
return chkArrayR(op, l, r)
|
return chkArrayR(op, l, r)
|
||||||
case map[string]interface{}:
|
|
||||||
return chkObject(op, r, l)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case int64:
|
case int64:
|
||||||
switch r := r.(type) {
|
switch r := r.(type) {
|
||||||
default:
|
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case string:
|
case string:
|
||||||
if n, err := strconv.ParseInt(r, 10, 64); err == nil {
|
if n, err := strconv.ParseInt(r, 10, 64); err == nil {
|
||||||
return chkInt(op, l, n)
|
return chkInt(op, l, n)
|
||||||
}
|
}
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case int64:
|
case int64:
|
||||||
return chkInt(op, l, r)
|
return chkInt(op, l, r)
|
||||||
case float64:
|
case float64:
|
||||||
|
@ -673,19 +664,14 @@ func binaryCheck(op sql.Token, l, r, lo, ro interface{}, d *data.Doc) interface{
|
||||||
return chkRegex(op, strconv.FormatInt(l, 10), r)
|
return chkRegex(op, strconv.FormatInt(l, 10), r)
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
return chkArrayR(op, l, r)
|
return chkArrayR(op, l, r)
|
||||||
case map[string]interface{}:
|
|
||||||
return chkObject(op, r, l)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case float64:
|
case float64:
|
||||||
switch r := r.(type) {
|
switch r := r.(type) {
|
||||||
default:
|
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case string:
|
case string:
|
||||||
if n, err := strconv.ParseFloat(r, 64); err == nil {
|
if n, err := strconv.ParseFloat(r, 64); err == nil {
|
||||||
return chkFloat(op, l, n)
|
return chkFloat(op, l, n)
|
||||||
}
|
}
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case int64:
|
case int64:
|
||||||
return chkFloat(op, l, float64(r))
|
return chkFloat(op, l, float64(r))
|
||||||
case float64:
|
case float64:
|
||||||
|
@ -696,14 +682,10 @@ func binaryCheck(op sql.Token, l, r, lo, ro interface{}, d *data.Doc) interface{
|
||||||
return chkRegex(op, strconv.FormatFloat(l, 'g', -1, 64), r)
|
return chkRegex(op, strconv.FormatFloat(l, 'g', -1, 64), r)
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
return chkArrayR(op, l, r)
|
return chkArrayR(op, l, r)
|
||||||
case map[string]interface{}:
|
|
||||||
return chkObject(op, r, l)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case time.Time:
|
case time.Time:
|
||||||
switch r := r.(type) {
|
switch r := r.(type) {
|
||||||
default:
|
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
|
||||||
case string:
|
case string:
|
||||||
return chkString(op, l.String(), r)
|
return chkString(op, l.String(), r)
|
||||||
case int64:
|
case int64:
|
||||||
|
@ -716,8 +698,6 @@ func binaryCheck(op sql.Token, l, r, lo, ro interface{}, d *data.Doc) interface{
|
||||||
return chkRegex(op, l.String(), r)
|
return chkRegex(op, l.String(), r)
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
return chkArrayR(op, l, r)
|
return chkArrayR(op, l, r)
|
||||||
case map[string]interface{}:
|
|
||||||
return chkObject(op, r, l)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
|
@ -745,7 +725,7 @@ func binaryCheck(op sql.Token, l, r, lo, ro interface{}, d *data.Doc) interface{
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
switch r := r.(type) {
|
switch r := r.(type) {
|
||||||
default:
|
default:
|
||||||
return op == sql.NEQ || op == sql.SNI || op == sql.NIS || op == sql.CONTAINSNONE
|
return chkObject(op, l, r)
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
return chkArrayR(op, l, r)
|
return chkArrayR(op, l, r)
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
|
@ -754,16 +734,39 @@ func binaryCheck(op sql.Token, l, r, lo, ro interface{}, d *data.Doc) interface{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return negOp(op)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func chkVoid(op sql.Token, a, b bool) (val bool) {
|
func posOp(op sql.Token) bool {
|
||||||
return
|
return chkOp(op) > 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func chkNull(op sql.Token, a, b bool) (val bool) {
|
func negOp(op sql.Token) bool {
|
||||||
return
|
return chkOp(op) < 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func chkOp(op sql.Token) int8 {
|
||||||
|
switch op {
|
||||||
|
case sql.EQ, sql.SIN, sql.INS:
|
||||||
|
return +1
|
||||||
|
case sql.NEQ, sql.SNI, sql.NIS:
|
||||||
|
return -1
|
||||||
|
case sql.CONTAINSALL:
|
||||||
|
return +1
|
||||||
|
case sql.CONTAINSSOME:
|
||||||
|
return +1
|
||||||
|
case sql.CONTAINSNONE:
|
||||||
|
return -1
|
||||||
|
case sql.ALLCONTAINEDIN:
|
||||||
|
return +1
|
||||||
|
case sql.SOMECONTAINEDIN:
|
||||||
|
return +1
|
||||||
|
case sql.NONECONTAINEDIN:
|
||||||
|
return -1
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func chkBool(op sql.Token, a, b bool) (val bool) {
|
func chkBool(op sql.Token, a, b bool) (val bool) {
|
||||||
|
@ -772,14 +775,8 @@ func chkBool(op sql.Token, a, b bool) (val bool) {
|
||||||
return a == b
|
return a == b
|
||||||
case sql.NEQ:
|
case sql.NEQ:
|
||||||
return a != b
|
return a != b
|
||||||
case sql.SNI:
|
|
||||||
return true
|
|
||||||
case sql.NIS:
|
|
||||||
return true
|
|
||||||
case sql.CONTAINSNONE:
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return
|
return negOp(op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func chkString(op sql.Token, a, b string) (val bool) {
|
func chkString(op sql.Token, a, b string) (val bool) {
|
||||||
|
@ -796,14 +793,16 @@ func chkString(op sql.Token, a, b string) (val bool) {
|
||||||
return a > b
|
return a > b
|
||||||
case sql.GTE:
|
case sql.GTE:
|
||||||
return a >= b
|
return a >= b
|
||||||
case sql.SNI:
|
case sql.INS:
|
||||||
return true
|
return strings.Contains(b, a) == true
|
||||||
case sql.NIS:
|
case sql.NIS:
|
||||||
return true
|
return strings.Contains(b, a) == false
|
||||||
case sql.CONTAINSNONE:
|
case sql.SIN:
|
||||||
return true
|
return strings.Contains(a, b) == true
|
||||||
|
case sql.SNI:
|
||||||
|
return strings.Contains(a, b) == false
|
||||||
}
|
}
|
||||||
return
|
return negOp(op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func chkInt(op sql.Token, a, b int64) (val bool) {
|
func chkInt(op sql.Token, a, b int64) (val bool) {
|
||||||
|
@ -820,14 +819,8 @@ func chkInt(op sql.Token, a, b int64) (val bool) {
|
||||||
return a > b
|
return a > b
|
||||||
case sql.GTE:
|
case sql.GTE:
|
||||||
return a >= b
|
return a >= b
|
||||||
case sql.SNI:
|
|
||||||
return true
|
|
||||||
case sql.NIS:
|
|
||||||
return true
|
|
||||||
case sql.CONTAINSNONE:
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return
|
return negOp(op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func chkFloat(op sql.Token, a, b float64) (val bool) {
|
func chkFloat(op sql.Token, a, b float64) (val bool) {
|
||||||
|
@ -844,14 +837,8 @@ func chkFloat(op sql.Token, a, b float64) (val bool) {
|
||||||
return a > b
|
return a > b
|
||||||
case sql.GTE:
|
case sql.GTE:
|
||||||
return a >= b
|
return a >= b
|
||||||
case sql.SNI:
|
|
||||||
return true
|
|
||||||
case sql.NIS:
|
|
||||||
return true
|
|
||||||
case sql.CONTAINSNONE:
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return
|
return negOp(op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func chkThing(op sql.Token, a, b *sql.Thing) (val bool) {
|
func chkThing(op sql.Token, a, b *sql.Thing) (val bool) {
|
||||||
|
@ -860,14 +847,8 @@ func chkThing(op sql.Token, a, b *sql.Thing) (val bool) {
|
||||||
return a.TB == b.TB && a.ID == b.ID
|
return a.TB == b.TB && a.ID == b.ID
|
||||||
case sql.NEQ:
|
case sql.NEQ:
|
||||||
return a.TB != b.TB || a.ID != b.ID
|
return a.TB != b.TB || a.ID != b.ID
|
||||||
case sql.SNI:
|
|
||||||
return true
|
|
||||||
case sql.NIS:
|
|
||||||
return true
|
|
||||||
case sql.CONTAINSNONE:
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return
|
return negOp(op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func chkRegex(op sql.Token, a string, r *regexp.Regexp) (val bool) {
|
func chkRegex(op sql.Token, a string, r *regexp.Regexp) (val bool) {
|
||||||
|
@ -879,83 +860,95 @@ func chkRegex(op sql.Token, a string, r *regexp.Regexp) (val bool) {
|
||||||
case sql.ANY:
|
case sql.ANY:
|
||||||
return r.MatchString(a) == true
|
return r.MatchString(a) == true
|
||||||
}
|
}
|
||||||
return
|
return negOp(op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func chkObject(op sql.Token, m map[string]interface{}, i interface{}) (val bool) {
|
func chkObject(op sql.Token, m map[string]interface{}, i interface{}) (val bool) {
|
||||||
switch op {
|
switch op {
|
||||||
case sql.EQ:
|
case sql.EQ:
|
||||||
if reflect.TypeOf(m) == reflect.TypeOf(i) && reflect.DeepEqual(m, i) == true {
|
switch i.(type) {
|
||||||
return true
|
case *sql.Empty:
|
||||||
|
return len(m) == 0
|
||||||
|
default:
|
||||||
|
return reflect.TypeOf(m) == reflect.TypeOf(i) && reflect.DeepEqual(m, i) == true
|
||||||
}
|
}
|
||||||
case sql.NEQ:
|
case sql.NEQ:
|
||||||
if reflect.TypeOf(m) != reflect.TypeOf(i) || reflect.DeepEqual(m, i) == false {
|
switch i.(type) {
|
||||||
return true
|
case *sql.Empty:
|
||||||
|
return len(m) != 0
|
||||||
|
default:
|
||||||
|
return reflect.TypeOf(m) != reflect.TypeOf(i) || reflect.DeepEqual(m, i) == false
|
||||||
}
|
}
|
||||||
case sql.SNI:
|
|
||||||
return true
|
|
||||||
case sql.NIS:
|
|
||||||
return true
|
|
||||||
case sql.CONTAINSNONE:
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return
|
return negOp(op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func chkArrayL(op sql.Token, a []interface{}, i interface{}) (val bool) {
|
func chkArrayL(op sql.Token, a []interface{}, i interface{}) (val bool) {
|
||||||
switch op {
|
switch op {
|
||||||
case sql.EQ:
|
case sql.EQ:
|
||||||
return false
|
switch i.(type) {
|
||||||
|
case *sql.Empty:
|
||||||
|
return len(a) == 0
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
case sql.NEQ:
|
case sql.NEQ:
|
||||||
return true
|
switch i.(type) {
|
||||||
|
case *sql.Empty:
|
||||||
|
return len(a) != 0
|
||||||
|
default:
|
||||||
|
return true
|
||||||
|
}
|
||||||
case sql.SIN:
|
case sql.SIN:
|
||||||
if i == nil {
|
switch i.(type) {
|
||||||
|
case nil, *sql.Null:
|
||||||
return data.Consume(a).Contains(nil) == true
|
return data.Consume(a).Contains(nil) == true
|
||||||
} else {
|
default:
|
||||||
return data.Consume(a).Contains(i) == true
|
return data.Consume(a).Contains(i) == true
|
||||||
}
|
}
|
||||||
case sql.SNI:
|
case sql.SNI:
|
||||||
if i == nil {
|
switch i.(type) {
|
||||||
|
case nil, *sql.Null:
|
||||||
return data.Consume(a).Contains(nil) == false
|
return data.Consume(a).Contains(nil) == false
|
||||||
} else {
|
default:
|
||||||
return data.Consume(a).Contains(i) == false
|
return data.Consume(a).Contains(i) == false
|
||||||
}
|
}
|
||||||
case sql.INS:
|
|
||||||
return false
|
|
||||||
case sql.NIS:
|
|
||||||
return true
|
|
||||||
case sql.CONTAINSNONE:
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return
|
return negOp(op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func chkArrayR(op sql.Token, i interface{}, a []interface{}) (val bool) {
|
func chkArrayR(op sql.Token, i interface{}, a []interface{}) (val bool) {
|
||||||
switch op {
|
switch op {
|
||||||
case sql.EQ:
|
case sql.EQ:
|
||||||
return false
|
switch i.(type) {
|
||||||
|
case *sql.Empty:
|
||||||
|
return len(a) == 0
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
case sql.NEQ:
|
case sql.NEQ:
|
||||||
return true
|
switch i.(type) {
|
||||||
case sql.SIN:
|
case *sql.Empty:
|
||||||
return false
|
return len(a) != 0
|
||||||
case sql.SNI:
|
default:
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
case sql.INS:
|
case sql.INS:
|
||||||
if i == nil {
|
switch i.(type) {
|
||||||
|
case nil, *sql.Null:
|
||||||
return data.Consume(a).Contains(nil) == true
|
return data.Consume(a).Contains(nil) == true
|
||||||
} else {
|
default:
|
||||||
return data.Consume(a).Contains(i) == true
|
return data.Consume(a).Contains(i) == true
|
||||||
}
|
}
|
||||||
case sql.NIS:
|
case sql.NIS:
|
||||||
if i == nil {
|
switch i.(type) {
|
||||||
|
case nil, *sql.Null:
|
||||||
return data.Consume(a).Contains(nil) == false
|
return data.Consume(a).Contains(nil) == false
|
||||||
} else {
|
default:
|
||||||
return data.Consume(a).Contains(i) == false
|
return data.Consume(a).Contains(i) == false
|
||||||
}
|
}
|
||||||
case sql.CONTAINSNONE:
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return
|
return negOp(op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func chkArray(op sql.Token, a []interface{}, b []interface{}) (val bool) {
|
func chkArray(op sql.Token, a []interface{}, b []interface{}) (val bool) {
|
||||||
|
@ -997,6 +990,27 @@ func chkArray(op sql.Token, a []interface{}, b []interface{}) (val bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
case sql.ALLCONTAINEDIN:
|
||||||
|
for _, v := range a {
|
||||||
|
if data.Consume(b).Contains(v) == false {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
case sql.SOMECONTAINEDIN:
|
||||||
|
for _, v := range a {
|
||||||
|
if data.Consume(b).Contains(v) == true {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
case sql.NONECONTAINEDIN:
|
||||||
|
for _, v := range a {
|
||||||
|
if data.Consume(b).Contains(v) == true {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
902
db/fetch_test.go
Normal file
902
db/fetch_test.go
Normal file
|
@ -0,0 +1,902 @@
|
||||||
|
// Copyright © 2016 Abcum Ltd
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFetch(t *testing.T) {
|
||||||
|
|
||||||
|
Convey("Check calc-as-bool expressions", t, func() {
|
||||||
|
|
||||||
|
setupDB()
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
|
||||||
|
USE NS test DB test;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE gone;
|
||||||
|
SELECT * FROM "test" WHERE true;
|
||||||
|
SELECT * FROM "test" WHERE 0;
|
||||||
|
SELECT * FROM "test" WHERE -1;
|
||||||
|
SELECT * FROM "test" WHERE +1;
|
||||||
|
SELECT * FROM "test" WHERE "test";
|
||||||
|
SELECT * FROM "test" WHERE time.now();
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [];
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3];
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE {};
|
||||||
|
SELECT * FROM "test" WHERE {test:true};
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE gone OR gone;
|
||||||
|
SELECT * FROM "test" WHERE true OR true;
|
||||||
|
SELECT * FROM "test" WHERE gone OR true;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE gone AND gone;
|
||||||
|
SELECT * FROM "test" WHERE true AND true;
|
||||||
|
SELECT * FROM "test" WHERE gone AND true;
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 18)
|
||||||
|
|
||||||
|
So(res[1].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[2].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[3].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[4].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[5].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[6].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[7].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[8].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[9].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[10].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[11].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[12].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[13].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[14].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[15].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[16].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[17].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Check calc-as-math expressions", t, func() {
|
||||||
|
|
||||||
|
setupDB()
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
|
||||||
|
USE NS test DB test;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE 0 + false;
|
||||||
|
SELECT * FROM "test" WHERE 1 + false;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE 0 + true;
|
||||||
|
SELECT * FROM "test" WHERE 1 + true;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE time.now() + 1;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [] + [];
|
||||||
|
SELECT * FROM "test" WHERE {} + {};
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 8)
|
||||||
|
|
||||||
|
So(res[1].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[2].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[3].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[4].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[5].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[6].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[7].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Check binary math comparisons", t, func() {
|
||||||
|
|
||||||
|
setupDB()
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
|
||||||
|
USE NS test DB test;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE 1 = 1;
|
||||||
|
SELECT * FROM "test" WHERE 1 != 1;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE 1 < 2;
|
||||||
|
SELECT * FROM "test" WHERE 1 > 2;
|
||||||
|
SELECT * FROM "test" WHERE 1 <= 2;
|
||||||
|
SELECT * FROM "test" WHERE 1 >= 2;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE 10-10 = 0;
|
||||||
|
SELECT * FROM "test" WHERE 10+10 = 20;
|
||||||
|
SELECT * FROM "test" WHERE 10*10 = 100;
|
||||||
|
SELECT * FROM "test" WHERE 10/10 = 1;
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 11)
|
||||||
|
|
||||||
|
So(res[1].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[2].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[3].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[4].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[5].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[6].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[7].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[8].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[9].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[10].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Check binary NULL comparisons", t, func() {
|
||||||
|
|
||||||
|
setupDB()
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
|
||||||
|
USE NS test DB test;
|
||||||
|
|
||||||
|
LET var = NULL;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE NULL = "";
|
||||||
|
SELECT * FROM "test" WHERE NULL = [];
|
||||||
|
SELECT * FROM "test" WHERE NULL = {};
|
||||||
|
SELECT * FROM "test" WHERE NULL = $var;
|
||||||
|
SELECT * FROM "test" WHERE NULL = VOID;
|
||||||
|
SELECT * FROM "test" WHERE NULL = NULL;
|
||||||
|
SELECT * FROM "test" WHERE NULL = EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE NULL = something;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE "" = NULL;
|
||||||
|
SELECT * FROM "test" WHERE [] = NULL;
|
||||||
|
SELECT * FROM "test" WHERE {} = NULL;
|
||||||
|
SELECT * FROM "test" WHERE $var = NULL;
|
||||||
|
SELECT * FROM "test" WHERE VOID = NULL;
|
||||||
|
SELECT * FROM "test" WHERE NULL = NULL;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY = NULL;
|
||||||
|
SELECT * FROM "test" WHERE something = NULL;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE NULL != "";
|
||||||
|
SELECT * FROM "test" WHERE NULL != [];
|
||||||
|
SELECT * FROM "test" WHERE NULL != {};
|
||||||
|
SELECT * FROM "test" WHERE NULL != $var;
|
||||||
|
SELECT * FROM "test" WHERE NULL != VOID;
|
||||||
|
SELECT * FROM "test" WHERE NULL != NULL;
|
||||||
|
SELECT * FROM "test" WHERE NULL != EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE NULL != something;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE "" != NULL;
|
||||||
|
SELECT * FROM "test" WHERE [] != NULL;
|
||||||
|
SELECT * FROM "test" WHERE {} != NULL;
|
||||||
|
SELECT * FROM "test" WHERE $var != NULL;
|
||||||
|
SELECT * FROM "test" WHERE VOID != NULL;
|
||||||
|
SELECT * FROM "test" WHERE NULL != NULL;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY != NULL;
|
||||||
|
SELECT * FROM "test" WHERE something != NULL;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE NULL ∈ [];
|
||||||
|
SELECT * FROM "test" WHERE NULL ∉ [];
|
||||||
|
SELECT * FROM "test" WHERE NULL ∋ [];
|
||||||
|
SELECT * FROM "test" WHERE NULL ∌ [];
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [] ∈ NULL;
|
||||||
|
SELECT * FROM "test" WHERE [] ∉ NULL;
|
||||||
|
SELECT * FROM "test" WHERE [] ∋ NULL;
|
||||||
|
SELECT * FROM "test" WHERE [] ∌ NULL;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE NULL ∈ [null];
|
||||||
|
SELECT * FROM "test" WHERE NULL ∉ [null];
|
||||||
|
SELECT * FROM "test" WHERE [null] ∋ NULL;
|
||||||
|
SELECT * FROM "test" WHERE [null] ∌ NULL;
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 46)
|
||||||
|
|
||||||
|
So(res[2].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[3].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[4].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[5].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[6].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[7].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[8].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[9].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[10].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[11].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[12].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[13].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[14].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[15].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[16].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[17].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[18].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[19].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[20].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[21].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[22].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[23].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[24].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[25].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[26].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[27].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[28].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[29].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[30].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[31].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[32].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[33].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[34].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[35].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[36].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[37].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[38].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[39].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[40].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[41].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[42].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[43].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[44].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[45].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Check binary VOID comparisons", t, func() {
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
|
||||||
|
USE NS test DB test;
|
||||||
|
|
||||||
|
LET var = NULL;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE VOID = "";
|
||||||
|
SELECT * FROM "test" WHERE VOID = [];
|
||||||
|
SELECT * FROM "test" WHERE VOID = {};
|
||||||
|
SELECT * FROM "test" WHERE VOID = $var;
|
||||||
|
SELECT * FROM "test" WHERE VOID = NULL;
|
||||||
|
SELECT * FROM "test" WHERE VOID = VOID;
|
||||||
|
SELECT * FROM "test" WHERE VOID = EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE VOID = something;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE "" = VOID;
|
||||||
|
SELECT * FROM "test" WHERE [] = VOID;
|
||||||
|
SELECT * FROM "test" WHERE {} = VOID;
|
||||||
|
SELECT * FROM "test" WHERE $var = VOID;
|
||||||
|
SELECT * FROM "test" WHERE NULL = VOID;
|
||||||
|
SELECT * FROM "test" WHERE VOID = VOID;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY = VOID;
|
||||||
|
SELECT * FROM "test" WHERE something = VOID;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE VOID != "";
|
||||||
|
SELECT * FROM "test" WHERE VOID != [];
|
||||||
|
SELECT * FROM "test" WHERE VOID != {};
|
||||||
|
SELECT * FROM "test" WHERE VOID != $var;
|
||||||
|
SELECT * FROM "test" WHERE VOID != NULL;
|
||||||
|
SELECT * FROM "test" WHERE VOID != VOID;
|
||||||
|
SELECT * FROM "test" WHERE VOID != EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE VOID != something;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE "" != VOID;
|
||||||
|
SELECT * FROM "test" WHERE [] != VOID;
|
||||||
|
SELECT * FROM "test" WHERE {} != VOID;
|
||||||
|
SELECT * FROM "test" WHERE $var != VOID;
|
||||||
|
SELECT * FROM "test" WHERE NULL != VOID;
|
||||||
|
SELECT * FROM "test" WHERE VOID != VOID;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY != VOID;
|
||||||
|
SELECT * FROM "test" WHERE something != VOID;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE VOID ∈ [];
|
||||||
|
SELECT * FROM "test" WHERE VOID ∉ [];
|
||||||
|
SELECT * FROM "test" WHERE VOID ∋ [];
|
||||||
|
SELECT * FROM "test" WHERE VOID ∌ [];
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [] ∈ VOID;
|
||||||
|
SELECT * FROM "test" WHERE [] ∉ VOID;
|
||||||
|
SELECT * FROM "test" WHERE [] ∋ VOID;
|
||||||
|
SELECT * FROM "test" WHERE [] ∌ VOID;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE VOID ∈ [null];
|
||||||
|
SELECT * FROM "test" WHERE VOID ∉ [null];
|
||||||
|
SELECT * FROM "test" WHERE [null] ∋ VOID;
|
||||||
|
SELECT * FROM "test" WHERE [null] ∌ VOID;
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 46)
|
||||||
|
|
||||||
|
So(res[2].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[3].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[4].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[5].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[6].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[7].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[8].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[9].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[10].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[11].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[12].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[13].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[14].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[15].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[16].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[17].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[18].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[19].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[20].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[21].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[22].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[23].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[24].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[25].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[26].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[27].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[28].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[29].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[30].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[31].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[32].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[33].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[34].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[35].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[36].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[37].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[38].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[39].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[40].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[41].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[42].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[43].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[44].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[45].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Check binary EMPTY comparisons", t, func() {
|
||||||
|
|
||||||
|
setupDB()
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
|
||||||
|
USE NS test DB test;
|
||||||
|
|
||||||
|
LET var = NULL;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE EMPTY = "";
|
||||||
|
SELECT * FROM "test" WHERE EMPTY = [];
|
||||||
|
SELECT * FROM "test" WHERE EMPTY = {};
|
||||||
|
SELECT * FROM "test" WHERE EMPTY = $var;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY = NULL;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY = VOID;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY = EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY = something;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE "" = EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE [] = EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE {} = EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE $var = EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE NULL = EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE VOID = EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY = EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE something = EMPTY;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE EMPTY != "";
|
||||||
|
SELECT * FROM "test" WHERE EMPTY != [];
|
||||||
|
SELECT * FROM "test" WHERE EMPTY != {};
|
||||||
|
SELECT * FROM "test" WHERE EMPTY != $var;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY != NULL;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY != VOID;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY != EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY != something;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE "" != EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE [] != EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE {} != EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE $var != EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE NULL != EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE VOID != EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE EMPTY != EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE something != EMPTY;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE EMPTY ∈ [];
|
||||||
|
SELECT * FROM "test" WHERE EMPTY ∉ [];
|
||||||
|
SELECT * FROM "test" WHERE EMPTY ∋ [];
|
||||||
|
SELECT * FROM "test" WHERE EMPTY ∌ [];
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [] ∈ EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE [] ∉ EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE [] ∋ EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE [] ∌ EMPTY;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE EMPTY ∈ [null];
|
||||||
|
SELECT * FROM "test" WHERE EMPTY ∉ [null];
|
||||||
|
SELECT * FROM "test" WHERE [null] ∋ EMPTY;
|
||||||
|
SELECT * FROM "test" WHERE [null] ∌ EMPTY;
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 46)
|
||||||
|
|
||||||
|
So(res[2].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[3].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[4].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[5].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[6].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[7].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[8].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[9].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[10].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[11].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[12].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[13].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[14].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[15].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[16].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[17].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[18].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[19].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[20].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[21].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[22].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[23].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[24].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[25].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[26].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[27].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[28].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[29].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[30].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[31].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[32].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[33].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[34].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[35].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[36].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[37].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[38].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[39].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[40].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[41].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[42].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[43].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[44].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[45].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Check binary thing comparisons", t, func() {
|
||||||
|
|
||||||
|
setupDB()
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
|
||||||
|
USE NS test DB test;
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE person:test = person:test;
|
||||||
|
SELECT * FROM "test" WHERE person:test = "person:test";
|
||||||
|
SELECT * FROM "test" WHERE person:test ∈ array(person:test);
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE person:test = person:test;
|
||||||
|
SELECT * FROM "test" WHERE person:test != person:test;
|
||||||
|
SELECT * FROM "test" WHERE person:test = user:test;
|
||||||
|
SELECT * FROM "test" WHERE person:test != user:test;
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 8)
|
||||||
|
|
||||||
|
So(res[1].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[2].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[3].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[4].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[5].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[6].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[7].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Check binary bool comparisons", t, func() {
|
||||||
|
|
||||||
|
setupDB()
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
|
||||||
|
USE NS test DB test;
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE true = true;
|
||||||
|
SELECT * FROM "test" WHERE true = "true";
|
||||||
|
SELECT * FROM "test" WHERE true = /\w/;
|
||||||
|
SELECT * FROM "test" WHERE true ∈ [true,false];
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE true = true;
|
||||||
|
SELECT * FROM "test" WHERE true != true;
|
||||||
|
SELECT * FROM "test" WHERE false = false;
|
||||||
|
SELECT * FROM "test" WHERE false != false;
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 9)
|
||||||
|
|
||||||
|
So(res[1].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[2].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[3].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[4].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[5].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[6].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[7].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[8].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Check binary float comparisons", t, func() {
|
||||||
|
|
||||||
|
setupDB()
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
|
||||||
|
USE NS test DB test;
|
||||||
|
|
||||||
|
LET timer = "1987-06-22T08:30:30.511Z";
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE 1 = "1";
|
||||||
|
SELECT * FROM "test" WHERE 1 = /\d/;
|
||||||
|
SELECT * FROM "test" WHERE 1 ∈ [1,2,3];
|
||||||
|
SELECT * FROM "test" WHERE 551349030511000000 = $timer;
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE 1 = 1;
|
||||||
|
SELECT * FROM "test" WHERE 1.1 != 1.1;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE 1 < 2;
|
||||||
|
SELECT * FROM "test" WHERE 1 > 2;
|
||||||
|
SELECT * FROM "test" WHERE 1 <= 2;
|
||||||
|
SELECT * FROM "test" WHERE 1 >= 2;
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 12)
|
||||||
|
|
||||||
|
So(res[2].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[3].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[4].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[5].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[6].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[7].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[8].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[9].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[10].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[11].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Check binary string comparisons", t, func() {
|
||||||
|
|
||||||
|
setupDB()
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
|
||||||
|
USE NS test DB test;
|
||||||
|
|
||||||
|
LET timer = "1987-06-22T08:30:30.511Z";
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE "true" = true;
|
||||||
|
SELECT * FROM "test" WHERE "1.1" = 1.1;
|
||||||
|
SELECT * FROM "test" WHERE "person:test" = person:test;
|
||||||
|
SELECT * FROM "test" WHERE "test" = /\w/;
|
||||||
|
SELECT * FROM "test" WHERE "test" ∈ ["test","some"];
|
||||||
|
SELECT * FROM "test" WHERE "1987-06-22 08:30:30.511 +0000 UTC" = $timer;
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE "test" = "test";
|
||||||
|
SELECT * FROM "test" WHERE "test" != "test";
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE "abc" < "def";
|
||||||
|
SELECT * FROM "test" WHERE "abc" > "def";
|
||||||
|
SELECT * FROM "test" WHERE "abc" <= "def";
|
||||||
|
SELECT * FROM "test" WHERE "abc" >= "def";
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE "a true test string" ∋ "test";
|
||||||
|
SELECT * FROM "test" WHERE "a true test string" ∌ "test";
|
||||||
|
SELECT * FROM "test" WHERE "test" ∈ "a true test string";
|
||||||
|
SELECT * FROM "test" WHERE "test" ∉ "a true test string";
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE "a true test string" = /test/;
|
||||||
|
SELECT * FROM "test" WHERE "a true test string" != /test/;
|
||||||
|
SELECT * FROM "test" WHERE "a true test string" ?= /test/;
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 21)
|
||||||
|
|
||||||
|
So(res[2].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[3].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[4].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[5].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[6].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[7].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[8].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[9].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[10].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[11].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[12].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[13].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[14].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[15].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[16].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[17].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[18].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[19].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[20].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Check binary time.Time comparisons", t, func() {
|
||||||
|
|
||||||
|
setupDB()
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
|
||||||
|
USE NS test DB test;
|
||||||
|
|
||||||
|
LET timer = "1987-06-22T08:30:30.511Z";
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE $timer = "1987-06-22 08:30:30.511 +0000 UTC";
|
||||||
|
SELECT * FROM "test" WHERE $timer = 551349030511000000;
|
||||||
|
SELECT * FROM "test" WHERE $timer = $timer;
|
||||||
|
SELECT * FROM "test" WHERE $timer = /\d/;
|
||||||
|
SELECT * FROM "test" WHERE $timer ∈ array($timer);
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 7)
|
||||||
|
|
||||||
|
So(res[2].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[3].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[4].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[5].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[6].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Check binary array comparisons", t, func() {
|
||||||
|
|
||||||
|
setupDB()
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
|
||||||
|
USE NS test DB test;
|
||||||
|
|
||||||
|
LET timer = "1987-06-22T08:30:30.511Z";
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [true] ∋ true;
|
||||||
|
SELECT * FROM "test" WHERE ["test"] ∋ "test";
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3] ∋ 1;
|
||||||
|
SELECT * FROM "test" WHERE array($timer) ∋ $timer;
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3] = /\d/;
|
||||||
|
SELECT * FROM "test" WHERE [{test:true}] ∋ {test:true};
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [] = [];
|
||||||
|
SELECT * FROM "test" WHERE [] != [];
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3] = [1,2,3];
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3] = [4,5,6];
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3] != [1,2,3];
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3] != [4,5,6];
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3] ∈ [ [1,2,3] ];
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3] ∉ [ [1,2,3] ];
|
||||||
|
SELECT * FROM "test" WHERE [ [1,2,3] ] ∋ [1,2,3];
|
||||||
|
SELECT * FROM "test" WHERE [ [1,2,3] ] ∌ [1,2,3];
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3,4,5] ⊇ [1,3,5];
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3,4,5] ⊇ [2,4,6];
|
||||||
|
SELECT * FROM "test" WHERE [1,3,5,7,9] ⊃ [1,3,5];
|
||||||
|
SELECT * FROM "test" WHERE [1,3,5,7,9] ⊃ [2,4,6];
|
||||||
|
SELECT * FROM "test" WHERE [1,3,5,7,9] ⊅ [1,3,5];
|
||||||
|
SELECT * FROM "test" WHERE [1,3,5,7,9] ⊅ [2,4,6];
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [1,3,5] ⊆ [1,2,3,4,5];
|
||||||
|
SELECT * FROM "test" WHERE [2,4,6] ⊆ [1,2,3,4,5];
|
||||||
|
SELECT * FROM "test" WHERE [1,3,5] ⊂ [1,3,5,7,9];
|
||||||
|
SELECT * FROM "test" WHERE [2,4,6] ⊂ [1,3,5,7,9];
|
||||||
|
SELECT * FROM "test" WHERE [1,3,5] ⊄ [1,3,5,7,9];
|
||||||
|
SELECT * FROM "test" WHERE [2,4,6] ⊄ [1,3,5,7,9];
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3] = /[0-9]/;
|
||||||
|
SELECT * FROM "test" WHERE [1,"2",true] = /[0-9]/;
|
||||||
|
SELECT * FROM "test" WHERE ["a","b","c"] = /[0-9]/;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3] != /[0-9]/;
|
||||||
|
SELECT * FROM "test" WHERE [1,"2",true] != /[0-9]/;
|
||||||
|
SELECT * FROM "test" WHERE ["a","b","c"] != /[0-9]/;
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE [1,2,3] ?= /[0-9]/;
|
||||||
|
SELECT * FROM "test" WHERE [1,"2",true] ?= /[0-9]/;
|
||||||
|
SELECT * FROM "test" WHERE ["a","b","c"] ?= /[0-9]/;
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 39)
|
||||||
|
|
||||||
|
So(res[2].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[3].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[4].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[5].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[6].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[7].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[8].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[9].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[10].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[11].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[12].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[13].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[14].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[15].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[16].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[17].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
So(res[18].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[19].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[20].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[21].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[22].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[23].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[24].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[25].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[26].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[27].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[28].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[29].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[30].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[31].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[32].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[33].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[34].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[35].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[36].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[37].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[38].Result, ShouldHaveLength, 0)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
Convey("Check binary object comparisons", t, func() {
|
||||||
|
|
||||||
|
setupDB()
|
||||||
|
|
||||||
|
txt := `
|
||||||
|
|
||||||
|
USE NS test DB test;
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE {test:true} = {test:true};
|
||||||
|
SELECT * FROM "test" WHERE {test:true} ∈ [{test:true}];
|
||||||
|
|
||||||
|
-- ------------------------------
|
||||||
|
|
||||||
|
SELECT * FROM "test" WHERE {test:true} = {test:true};
|
||||||
|
SELECT * FROM "test" WHERE {test:true} != {test:true};
|
||||||
|
SELECT * FROM "test" WHERE {test:true} = {other:true};
|
||||||
|
SELECT * FROM "test" WHERE {test:true} != {other:true};
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
res, err := Execute(setupKV(), txt, nil)
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
So(res, ShouldHaveLength, 7)
|
||||||
|
|
||||||
|
So(res[1].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[2].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
So(res[3].Result, ShouldHaveLength, 1)
|
||||||
|
So(res[4].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[5].Result, ShouldHaveLength, 0)
|
||||||
|
So(res[6].Result, ShouldHaveLength, 1)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
|
@ -24,96 +24,6 @@ import (
|
||||||
|
|
||||||
func TestSelect(t *testing.T) {
|
func TestSelect(t *testing.T) {
|
||||||
|
|
||||||
Convey("Select temps", t, func() {
|
|
||||||
|
|
||||||
setupDB()
|
|
||||||
|
|
||||||
txt := `
|
|
||||||
|
|
||||||
USE NS test DB test;
|
|
||||||
|
|
||||||
LET var = NULL;
|
|
||||||
|
|
||||||
SELECT * FROM "test" WHERE NULL = "";
|
|
||||||
SELECT * FROM "test" WHERE NULL = $var;
|
|
||||||
SELECT * FROM "test" WHERE NULL = VOID;
|
|
||||||
SELECT * FROM "test" WHERE NULL = NULL;
|
|
||||||
SELECT * FROM "test" WHERE NULL = EMPTY;
|
|
||||||
|
|
||||||
SELECT * FROM "test" WHERE "" = NULL;
|
|
||||||
SELECT * FROM "test" WHERE $var = NULL;
|
|
||||||
SELECT * FROM "test" WHERE VOID = NULL;
|
|
||||||
SELECT * FROM "test" WHERE NULL = NULL;
|
|
||||||
SELECT * FROM "test" WHERE EMPTY = NULL;
|
|
||||||
|
|
||||||
SELECT * FROM "test" WHERE VOID = "";
|
|
||||||
SELECT * FROM "test" WHERE VOID = $var;
|
|
||||||
SELECT * FROM "test" WHERE VOID = NULL;
|
|
||||||
SELECT * FROM "test" WHERE VOID = VOID;
|
|
||||||
SELECT * FROM "test" WHERE VOID = EMPTY;
|
|
||||||
|
|
||||||
SELECT * FROM "test" WHERE "" = VOID;
|
|
||||||
SELECT * FROM "test" WHERE $var = VOID;
|
|
||||||
SELECT * FROM "test" WHERE NULL = VOID;
|
|
||||||
SELECT * FROM "test" WHERE VOID = VOID;
|
|
||||||
SELECT * FROM "test" WHERE EMPTY = VOID;
|
|
||||||
|
|
||||||
SELECT * FROM "test" WHERE EMPTY = "";
|
|
||||||
SELECT * FROM "test" WHERE EMPTY = $var;
|
|
||||||
SELECT * FROM "test" WHERE EMPTY = NULL;
|
|
||||||
SELECT * FROM "test" WHERE EMPTY = VOID;
|
|
||||||
SELECT * FROM "test" WHERE EMPTY = EMPTY;
|
|
||||||
|
|
||||||
SELECT * FROM "test" WHERE "" = EMPTY;
|
|
||||||
SELECT * FROM "test" WHERE $var = EMPTY;
|
|
||||||
SELECT * FROM "test" WHERE NULL = EMPTY;
|
|
||||||
SELECT * FROM "test" WHERE VOID = EMPTY;
|
|
||||||
SELECT * FROM "test" WHERE EMPTY = EMPTY;
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
res, err := Execute(setupKV(), txt, nil)
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
So(res, ShouldHaveLength, 32)
|
|
||||||
|
|
||||||
So(res[2].Result, ShouldHaveLength, 0)
|
|
||||||
So(res[3].Result, ShouldHaveLength, 1)
|
|
||||||
So(res[4].Result, ShouldHaveLength, 0)
|
|
||||||
So(res[5].Result, ShouldHaveLength, 1)
|
|
||||||
So(res[6].Result, ShouldHaveLength, 1)
|
|
||||||
|
|
||||||
So(res[7].Result, ShouldHaveLength, 0)
|
|
||||||
So(res[8].Result, ShouldHaveLength, 1)
|
|
||||||
So(res[9].Result, ShouldHaveLength, 0)
|
|
||||||
So(res[10].Result, ShouldHaveLength, 1)
|
|
||||||
So(res[11].Result, ShouldHaveLength, 1)
|
|
||||||
|
|
||||||
So(res[12].Result, ShouldHaveLength, 0)
|
|
||||||
So(res[13].Result, ShouldHaveLength, 0)
|
|
||||||
So(res[14].Result, ShouldHaveLength, 0)
|
|
||||||
So(res[15].Result, ShouldHaveLength, 1)
|
|
||||||
So(res[16].Result, ShouldHaveLength, 1)
|
|
||||||
|
|
||||||
So(res[17].Result, ShouldHaveLength, 0)
|
|
||||||
So(res[18].Result, ShouldHaveLength, 0)
|
|
||||||
So(res[19].Result, ShouldHaveLength, 0)
|
|
||||||
So(res[20].Result, ShouldHaveLength, 1)
|
|
||||||
So(res[21].Result, ShouldHaveLength, 1)
|
|
||||||
|
|
||||||
So(res[22].Result, ShouldHaveLength, 0)
|
|
||||||
So(res[23].Result, ShouldHaveLength, 1)
|
|
||||||
So(res[24].Result, ShouldHaveLength, 1)
|
|
||||||
So(res[25].Result, ShouldHaveLength, 1)
|
|
||||||
So(res[26].Result, ShouldHaveLength, 1)
|
|
||||||
|
|
||||||
So(res[27].Result, ShouldHaveLength, 0)
|
|
||||||
So(res[28].Result, ShouldHaveLength, 1)
|
|
||||||
So(res[29].Result, ShouldHaveLength, 1)
|
|
||||||
So(res[30].Result, ShouldHaveLength, 1)
|
|
||||||
So(res[31].Result, ShouldHaveLength, 1)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
Convey("Select records from one thing", t, func() {
|
Convey("Select records from one thing", t, func() {
|
||||||
|
|
||||||
setupDB()
|
setupDB()
|
||||||
|
|
Loading…
Reference in a new issue