Skip to content

Commit

Permalink
Merge a056f3b into b034800
Browse files Browse the repository at this point in the history
  • Loading branch information
agonist committed Nov 17, 2023
2 parents b034800 + a056f3b commit 0c13325
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 60 deletions.
7 changes: 6 additions & 1 deletion cmd/genji/doc/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package doc
type functionDocs map[string]string

var packageDocs = map[string]functionDocs{
"strings": stringsDocs,
"math": mathDocs,
"": builtinDocs,
}
Expand All @@ -16,7 +17,6 @@ var builtinDocs = functionDocs{
"avg": "The avg function returns the average of all values taken by the arg1 expression in a group.",
"typeof": "The typeof function returns the type of arg1.",
"len": "The len function returns length of the arg1 expression if arg1 evals to string, array or document, either returns NULL.",
"lower": "The lower function returns arg1 to lower-case if arg1 evals to string",
}

var mathDocs = functionDocs{
Expand All @@ -29,3 +29,8 @@ var mathDocs = functionDocs{
"atan2": "Returns the arctangent of arg1/arg2, using the signs of the two to determine the quadrant of the return value.",
"floor": "Returns the greatest integer value less than or equal to arg1.",
}

var stringsDocs = functionDocs{
"lower": "The lower function returns arg1 to lower-case if arg1 evals to string",
"upper": "The upper function returns arg1 to upper-case if arg1 evals to string",
}
48 changes: 0 additions & 48 deletions internal/expr/functions/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package functions

import (
"fmt"
"strings"

"github.com/cockroachdb/errors"
"github.com/genjidb/genji/document"
Expand Down Expand Up @@ -68,13 +67,6 @@ var builtinFunctions = Definitions{
return &Len{Expr: args[0]}, nil
},
},
"lower": &definition{
name: "lower",
arity: 1,
constructorFn: func(args ...expr.Expr) (expr.Function, error) {
return &Lower{Expr: args[0]}, nil
},
},
}

// BuiltinDefinitions returns a map of builtin functions.
Expand Down Expand Up @@ -724,44 +716,4 @@ func (s *Len) Params() []expr.Expr { return []expr.Expr{s.Expr} }
// String returns the literal representation of len.
func (s *Len) String() string {
return fmt.Sprintf("LEN(%v)", s.Expr)
}

// Lower is the LOWER function
// It returns the lower-case version of a string
type Lower struct {
Expr expr.Expr
}

func (s* Lower) Eval(env *environment.Environment) (types.Value, error) {
val, err := s.Expr.Eval(env)
if err != nil {
return nil, err
}

if val.Type() != types.TextValue {
return types.NewNullValue(), nil
}

lowerCaseString := strings.ToLower(types.As[string](val))

return types.NewTextValue(lowerCaseString), nil
}

func (s *Lower) IsEqual(other expr.Expr) bool {
if other == nil {
return false
}

o, ok := other.(*Lower)
if !ok {
return false
}

return expr.Equal(s.Expr, o.Expr)
}

func (s *Lower) Params() []expr.Expr { return []expr.Expr{s.Expr} }

func (s *Lower) String() string {
return fmt.Sprintf("LOWER(%v)", s.Expr)
}
1 change: 1 addition & 0 deletions internal/expr/functions/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func DefaultPackages() Packages {
return Packages{
"": BuiltinDefinitions(),
"math": MathFunctions(),
"strings": StringsDefinitions(),
}
}

Expand Down
111 changes: 111 additions & 0 deletions internal/expr/functions/strings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package functions

import (
"fmt"
"strings"

"github.com/genjidb/genji/internal/environment"
"github.com/genjidb/genji/internal/expr"
"github.com/genjidb/genji/types"
)

var stringsFunctions = Definitions{
"lower": &definition{
name: "lower",
arity: 1,
constructorFn: func(args ...expr.Expr) (expr.Function, error) {
return &Lower{Expr: args[0]}, nil
},
},
"upper": &definition{
name: "upper",
arity: 1,
constructorFn: func(args ...expr.Expr) (expr.Function, error) {
return &Upper{Expr: args[0]}, nil
},
},
}

func StringsDefinitions() Definitions {
return stringsFunctions
}

// Lower is the LOWER function
// It returns the lower-case version of a string
type Lower struct {
Expr expr.Expr
}

func (s *Lower) Eval(env *environment.Environment) (types.Value, error) {
val, err := s.Expr.Eval(env)
if err != nil {
return nil, err

Check warning on line 42 in internal/expr/functions/strings.go

View check run for this annotation

Codecov / codecov/patch

internal/expr/functions/strings.go#L42

Added line #L42 was not covered by tests
}

if val.Type() != types.TextValue {
return types.NewNullValue(), nil
}

lowerCaseString := strings.ToLower(types.As[string](val))

return types.NewTextValue(lowerCaseString), nil
}

func (s *Lower) IsEqual(other expr.Expr) bool {
if other == nil {
return false

Check warning on line 56 in internal/expr/functions/strings.go

View check run for this annotation

Codecov / codecov/patch

internal/expr/functions/strings.go#L54-L56

Added lines #L54 - L56 were not covered by tests
}

o, ok := other.(*Lower)
if !ok {
return false

Check warning on line 61 in internal/expr/functions/strings.go

View check run for this annotation

Codecov / codecov/patch

internal/expr/functions/strings.go#L59-L61

Added lines #L59 - L61 were not covered by tests
}

return expr.Equal(s.Expr, o.Expr)

Check warning on line 64 in internal/expr/functions/strings.go

View check run for this annotation

Codecov / codecov/patch

internal/expr/functions/strings.go#L64

Added line #L64 was not covered by tests
}

func (s *Lower) Params() []expr.Expr { return []expr.Expr{s.Expr} }

func (s *Lower) String() string {
return fmt.Sprintf("LOWER(%v)", s.Expr)
}

// Upper is the UPPER function
// It returns the upper-case version of a string
type Upper struct {
Expr expr.Expr
}

func (s *Upper) Eval(env *environment.Environment) (types.Value, error) {
val, err := s.Expr.Eval(env)
if err != nil {
return nil, err

Check warning on line 82 in internal/expr/functions/strings.go

View check run for this annotation

Codecov / codecov/patch

internal/expr/functions/strings.go#L82

Added line #L82 was not covered by tests
}

if val.Type() != types.TextValue {
return types.NewNullValue(), nil
}

upperCaseString := strings.ToUpper(types.As[string](val))

return types.NewTextValue(upperCaseString), nil
}

func (s *Upper) IsEqual(other expr.Expr) bool {
if other == nil {
return false

Check warning on line 96 in internal/expr/functions/strings.go

View check run for this annotation

Codecov / codecov/patch

internal/expr/functions/strings.go#L94-L96

Added lines #L94 - L96 were not covered by tests
}

o, ok := other.(*Lower)
if !ok {
return false

Check warning on line 101 in internal/expr/functions/strings.go

View check run for this annotation

Codecov / codecov/patch

internal/expr/functions/strings.go#L99-L101

Added lines #L99 - L101 were not covered by tests
}

return expr.Equal(s.Expr, o.Expr)

Check warning on line 104 in internal/expr/functions/strings.go

View check run for this annotation

Codecov / codecov/patch

internal/expr/functions/strings.go#L104

Added line #L104 was not covered by tests
}

func (s *Upper) Params() []expr.Expr { return []expr.Expr{s.Expr} }

func (s *Upper) String() string {
return fmt.Sprintf("UPPER(%v)", s.Expr)
}
22 changes: 11 additions & 11 deletions sqltests/SELECT/lower.sql → sqltests/SELECT/STRINGS/lower.sql
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ INSERT INTO test (a, b, c, d, e, f) VALUES (
);

-- test: TEXT value
SELECT LOWER(a) FROM test;
SELECT strings.LOWER(a) FROM test;
/* result:
{
"LOWER(a)": "foo"
Expand All @@ -32,7 +32,7 @@ SELECT LOWER(a) FROM test;


-- test: INT value
SELECT LOWER(b) FROM test;
SELECT strings.LOWER(b) FROM test;
/* result:
{
"LOWER(b)": NULL
Expand All @@ -41,71 +41,71 @@ SELECT LOWER(b) FROM test;


-- test: BOOL value
SELECT LOWER(c) FROM test;
SELECT strings.LOWER(c) FROM test;
/* result:
{
"LOWER(c)": NULL
}
*/

-- test: DOUBLE value
SELECT LOWER(d) FROM test;
SELECT strings.LOWER(d) FROM test;
/* result:
{
"LOWER(d)": NULL
}
*/

-- test: ARRAY value
SELECT LOWER(e) FROM test;
SELECT strings.LOWER(e) FROM test;
/* result:
{
"LOWER(e)": NULL
}
*/

-- test: DOCUMENT value
SELECT LOWER(f) FROM test;
SELECT strings.LOWER(f) FROM test;
/* result:
{
"LOWER(f)": NULL
}
*/

-- test: cast INT
SELECT LOWER(CAST(b as TEXT)) FROM test;
SELECT strings.LOWER(CAST(b as TEXT)) FROM test;
/* result:
{
"LOWER(CAST(b AS text))": "42"
}
*/

-- test: cast BOOL
SELECT LOWER(CAST(c as TEXT)) FROM test;
SELECT strings.LOWER(CAST(c as TEXT)) FROM test;
/* result:
{
"LOWER(CAST(c AS text))": "true"
}
*/

-- test: cast DOUBLE
SELECT LOWER(CAST(d as TEXT)) FROM test;
SELECT strings.LOWER(CAST(d as TEXT)) FROM test;
/* result:
{
"LOWER(CAST(d AS text))": "42.42"
}
*/

-- test: cast ARRAY
SELECT LOWER(CAST(e as TEXT)) FROM test;
SELECT strings.LOWER(CAST(e as TEXT)) FROM test;
/* result:
{
"LOWER(CAST(e AS text))": "[\"a\", \"b\", \"c\", \"d\", \"e\"]"
}
*/

-- test: cast DOCUMENT
SELECT LOWER(CAST(f as TEXT)) FROM test;
SELECT strings.LOWER(CAST(f as TEXT)) FROM test;
/* result:
{
"LOWER(CAST(f AS text))": "{\"a\": \"hello\", \"b\": \"world\"}"
Expand Down
Loading

0 comments on commit 0c13325

Please sign in to comment.