This repository was archived by the owner on Jan 28, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 109
/
Copy pathcoalesce.go
106 lines (89 loc) · 2.31 KB
/
coalesce.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package function
import (
"fmt"
"strings"
"github.com/src-d/go-mysql-server/sql"
)
// Coalesce returns the first non-NULL value in the list, or NULL if there are no non-NULL values.
type Coalesce struct {
args []sql.Expression
}
// NewCoalesce creates a new Coalesce sql.Expression.
func NewCoalesce(args ...sql.Expression) (sql.Expression, error) {
if len(args) == 0 {
return nil, sql.ErrInvalidArgumentNumber.New("COALESCE", "1 or more", 0)
}
return &Coalesce{args}, nil
}
// Type implements the sql.Expression interface.
// The return type of Type() is the aggregated type of the argument types.
func (c *Coalesce) Type() sql.Type {
for _, arg := range c.args {
if arg == nil {
continue
}
t := arg.Type()
if t == nil {
continue
}
return t
}
return nil
}
// IsNullable implements the sql.Expression interface.
// Returns true if all arguments are nil
// or of the first non-nil argument is nullable, otherwise false.
func (c *Coalesce) IsNullable() bool {
for _, arg := range c.args {
if arg == nil {
continue
}
return arg.IsNullable()
}
return true
}
func (c *Coalesce) String() string {
var args = make([]string, len(c.args))
for i, arg := range c.args {
args[i] = arg.String()
}
return fmt.Sprintf("coalesce(%s)", strings.Join(args, ", "))
}
// WithChildren implements the Expression interface.
func (*Coalesce) WithChildren(children ...sql.Expression) (sql.Expression, error) {
return NewCoalesce(children...)
}
// Resolved implements the sql.Expression interface.
// The function checks if first non-nil argument is resolved.
func (c *Coalesce) Resolved() bool {
for _, arg := range c.args {
if arg == nil {
continue
}
if !arg.Resolved() {
return false
}
}
return true
}
// Children implements the sql.Expression interface.
func (c *Coalesce) Children() []sql.Expression { return c.args }
// Eval implements the sql.Expression interface.
// The function evaluates the first non-nil argument. If the value is nil,
// then we keep going, otherwise we return the first non-nil value.
func (c *Coalesce) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
for _, arg := range c.args {
if arg == nil {
continue
}
val, err := arg.Eval(ctx, row)
if err != nil {
return nil, err
}
if val == nil {
continue
}
return val, nil
}
return nil, nil
}