mirror of
https://github.com/chaisql/chai.git
synced 2025-12-24 11:30:53 +08:00
187 lines
5.2 KiB
Go
187 lines
5.2 KiB
Go
package expr_test
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/chaisql/chai/internal/database"
|
|
"github.com/chaisql/chai/internal/environment"
|
|
"github.com/chaisql/chai/internal/row"
|
|
"github.com/chaisql/chai/internal/testutil"
|
|
"github.com/chaisql/chai/internal/types"
|
|
)
|
|
|
|
var envWithRow = environment.New(
|
|
nil,
|
|
nil,
|
|
nil,
|
|
database.NewBasicRow(row.NewColumnBuffer().Add("a", types.NewIntegerValue(1))),
|
|
)
|
|
|
|
func TestComparisonExpr(t *testing.T) {
|
|
tests := []struct {
|
|
expr string
|
|
res types.Value
|
|
fails bool
|
|
}{
|
|
{"1 = a", types.NewBooleanValue(true), false},
|
|
{"1 = NULL", nullLiteral, false},
|
|
{"1 = notFound", nullLiteral, true},
|
|
{"1 != a", types.NewBooleanValue(false), false},
|
|
{"1 != NULL", nullLiteral, false},
|
|
{"1 != notFound", nullLiteral, true},
|
|
{"1 > a", types.NewBooleanValue(false), false},
|
|
{"1 > NULL", nullLiteral, false},
|
|
{"1 > notFound", nullLiteral, true},
|
|
{"1 >= a", types.NewBooleanValue(true), false},
|
|
{"1 >= NULL", nullLiteral, false},
|
|
{"1 >= notFound", nullLiteral, true},
|
|
{"1 < a", types.NewBooleanValue(false), false},
|
|
{"1 < NULL", nullLiteral, false},
|
|
{"1 < notFound", nullLiteral, true},
|
|
{"1 <= a", types.NewBooleanValue(true), false},
|
|
{"1 <= NULL", nullLiteral, false},
|
|
{"1 <= notFound", nullLiteral, true},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.expr, func(t *testing.T) {
|
|
testutil.TestExpr(t, test.expr, envWithRow, test.res, test.fails)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestComparisonINExpr(t *testing.T) {
|
|
tests := []struct {
|
|
expr string
|
|
res types.Value
|
|
fails bool
|
|
}{
|
|
{"1 IN (2)", types.NewBooleanValue(false), false},
|
|
{"1 IN (1, 2, 3)", types.NewBooleanValue(true), false},
|
|
{"2 IN (2.1, 2.2, 2.0)", types.NewBooleanValue(true), false},
|
|
{"1 IN (2, 3)", types.NewBooleanValue(false), false},
|
|
{"(1) IN (1, 2, 3)", types.NewBooleanValue(true), false},
|
|
{"(1) IN (1), (2), (3)", types.NewBooleanValue(true), false},
|
|
{"NULL IN (1, 2, NULL)", nullLiteral, false},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.expr, func(t *testing.T) {
|
|
testutil.TestExpr(t, test.expr, envWithRow, test.res, test.fails)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestComparisonNOTINExpr(t *testing.T) {
|
|
tests := []struct {
|
|
expr string
|
|
res types.Value
|
|
fails bool
|
|
}{
|
|
{"1 NOT IN (1, 2, 3)", types.NewBooleanValue(false), false},
|
|
{"1 NOT IN (2, 3)", types.NewBooleanValue(true), false},
|
|
{"(1) NOT IN (1, 2, 3)", types.NewBooleanValue(false), false},
|
|
{"NULL NOT IN (1, 2, NULL)", nullLiteral, false},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.expr, func(t *testing.T) {
|
|
testutil.TestExpr(t, test.expr, envWithRow, test.res, test.fails)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestComparisonISExpr(t *testing.T) {
|
|
tests := []struct {
|
|
expr string
|
|
res types.Value
|
|
fails bool
|
|
}{
|
|
{"1 IS 1", types.NewBooleanValue(true), false},
|
|
{"1 IS 2", types.NewBooleanValue(false), false},
|
|
{"1 IS NULL", types.NewBooleanValue(false), false},
|
|
{"NULL IS NULL", types.NewBooleanValue(true), false},
|
|
{"NULL IS 1", types.NewBooleanValue(false), false},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.expr, func(t *testing.T) {
|
|
testutil.TestExpr(t, test.expr, envWithRow, test.res, test.fails)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestComparisonISNOTExpr(t *testing.T) {
|
|
tests := []struct {
|
|
expr string
|
|
res types.Value
|
|
fails bool
|
|
}{
|
|
{"1 IS NOT 1", types.NewBooleanValue(false), false},
|
|
{"1 IS NOT 2", types.NewBooleanValue(true), false},
|
|
{"1 IS NOT NULL", types.NewBooleanValue(true), false},
|
|
{"NULL IS NOT NULL", types.NewBooleanValue(false), false},
|
|
{"NULL IS NOT 1", types.NewBooleanValue(true), false},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.expr, func(t *testing.T) {
|
|
testutil.TestExpr(t, test.expr, envWithRow, test.res, test.fails)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestComparisonExprNoObject(t *testing.T) {
|
|
tests := []struct {
|
|
expr string
|
|
res types.Value
|
|
fails bool
|
|
}{
|
|
{"1 = a", nullLiteral, true},
|
|
{"1 != a", nullLiteral, true},
|
|
{"1 > a", nullLiteral, true},
|
|
{"1 >= a", nullLiteral, true},
|
|
{"1 < a", nullLiteral, true},
|
|
{"1 <= a", nullLiteral, true},
|
|
{"1 IN (a)", nullLiteral, true},
|
|
{"1 IS a", nullLiteral, true},
|
|
{"1 IS NOT a", nullLiteral, true},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.expr, func(t *testing.T) {
|
|
for _, test := range tests {
|
|
t.Run(test.expr, func(t *testing.T) {
|
|
var emptyenv environment.Environment
|
|
|
|
testutil.TestExpr(t, test.expr, &emptyenv, test.res, test.fails)
|
|
})
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestComparisonBetweenExpr(t *testing.T) {
|
|
tests := []struct {
|
|
expr string
|
|
res types.Value
|
|
fails bool
|
|
}{
|
|
{"1 BETWEEN 0 AND 2", types.NewBooleanValue(true), false},
|
|
{"1 BETWEEN 0 AND 1", types.NewBooleanValue(true), false},
|
|
{"1 BETWEEN 1 AND 2", types.NewBooleanValue(true), false},
|
|
{"1 BETWEEN NULL AND 2", types.NewNullValue(), false},
|
|
{"1 BETWEEN 0 AND 'foo'", types.NewBooleanValue(false), false},
|
|
{"1 BETWEEN 'foo' AND 2", types.NewBooleanValue(false), false},
|
|
{"1 BETWEEN '1' AND 2", types.NewBooleanValue(false), false},
|
|
{"1 BETWEEN CAST('1' AS int) AND 2", types.NewBooleanValue(true), false},
|
|
{"1 BETWEEN CAST('1' AS double precision) AND 2", types.NewBooleanValue(true), false},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.expr, func(t *testing.T) {
|
|
testutil.TestExpr(t, test.expr, envWithRow, test.res, test.fails)
|
|
})
|
|
}
|
|
}
|