-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexpr.go
109 lines (90 loc) · 2.39 KB
/
expr.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
107
108
109
package squl
import (
stdfmt "fmt"
"strings"
fmt "golang.org/x/xerrors"
"github.com/trivigy/squl/internal/global"
)
// Expr describes the expression clause.
type Expr struct {
Type ExprType `json:"type"` /* see above */
// Wrap indicates whether or not to wrap the expression in parentheses.
Wrap bool
// Name represents possibly-qualified name of operator.
Name interface{} `json:"name"` /* possibly-qualified name of operator */
LHS Node `json:"lhs"` /* left argument, or NULL if none */
RHS Node `json:"rhs"` /* right argument, or NULL if none */
}
func (r *Expr) dump(counter *ordinalMarker) (string, error) {
switch r.Type {
case ExprTypeOp:
lhsDump, err := r.dumpOperand(counter, r.LHS)
if err != nil {
return "", err
}
opDump, err := r.dumpOperator(counter, r.Name)
if err != nil {
return "", err
}
rhsDump, err := r.dumpOperand(counter, r.RHS)
if err != nil {
return "", err
}
expr := stdfmt.Sprintf("%s %s %s", lhsDump, opDump, rhsDump)
if r.Wrap {
expr = "(" + expr + ")"
}
return expr, nil
case ExprTypeOf:
lhsDump, err := r.dumpOperand(counter, r.LHS)
if err != nil {
return "", err
}
var opDump string
switch r.Name {
case "=":
case "<>":
opDump = "NOT"
default:
return "", fmt.Errorf("unknown operator %q", r.Name)
}
rhsDump, err := r.dumpOperand(counter, r.RHS)
if err != nil {
return "", err
}
ops := []string{lhsDump, "IS"}
if opDump != "" {
ops = append(ops, opDump)
}
ops = append(ops, rhsDump)
expr := strings.Join(ops, " ")
if r.Wrap {
expr = "(" + expr + ")"
}
return expr, nil
default:
return "", fmt.Errorf(global.ErrFmt, pkg.Name(), fmt.Errorf("unknown type %q", r.Type))
}
}
func (r *Expr) dumpOperand(counter *ordinalMarker, op interface{}) (string, error) {
switch op := op.(type) {
case Node:
return op.dump(counter)
case string:
return stdfmt.Sprintf("%q", op), nil
case int:
return stdfmt.Sprintf("%d", op), nil
default:
return "", fmt.Errorf(global.ErrFmt, pkg.Name(), fmt.Errorf("unknown type (%T) for %q", op, op))
}
}
func (r *Expr) dumpOperator(_ *ordinalMarker, _ interface{}) (string, error) {
switch name := r.Name.(type) {
case string:
return name, nil
case []string:
return stdfmt.Sprintf("OPERATOR(%s)", strings.Join(name, ".")), nil
default:
return "", fmt.Errorf(global.ErrFmt, pkg.Name(), fmt.Errorf("unknown type (%T) for %q", name, name))
}
}