Skip to content

Commit a2195f1

Browse files
committed
feat: add WithEnumsAsStrings transpiler option
1 parent be2b1a9 commit a2195f1

File tree

3 files changed

+40
-5
lines changed

3 files changed

+40
-5
lines changed

spanfiltering/transpile.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ import (
88
// TranspileFilter transpiles a parsed AIP filter expression to a spansql.BoolExpr, and
99
// parameters used in the expression.
1010
// The parameter map is nil if the expression does not contain any parameters.
11-
func TranspileFilter(filter filtering.Filter) (spansql.BoolExpr, map[string]interface{}, error) {
11+
func TranspileFilter(
12+
filter filtering.Filter,
13+
options ...TranspileOption,
14+
) (spansql.BoolExpr, map[string]interface{}, error) {
1215
var t Transpiler
13-
t.Init(filter)
16+
t.Init(filter, options...)
1417
return t.Transpile()
1518
}

spanfiltering/transpile_test.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ func TestTranspileFilter(t *testing.T) {
1818
expectedSQL string
1919
expectedParams map[string]interface{}
2020
errorContains string
21+
options []TranspileOption
2122
}{
2223
{
2324
name: "simple flag",
@@ -90,6 +91,19 @@ func TestTranspileFilter(t *testing.T) {
9091
},
9192
},
9293

94+
{
95+
name: "enum equality as strings",
96+
options: []TranspileOption{WithEnumValuesAsStrings()},
97+
filter: `example_enum = ENUM_ONE`,
98+
declarations: []filtering.DeclarationOption{
99+
filtering.DeclareEnumIdent("example_enum", syntaxv1.Enum(0).Type()),
100+
},
101+
expectedSQL: `(example_enum = @param_0)`,
102+
expectedParams: map[string]interface{}{
103+
"param_0": "ENUM_ONE",
104+
},
105+
},
106+
93107
{
94108
name: "enum negated equality",
95109
filter: `example_enum != ENUM_ONE`,
@@ -157,7 +171,7 @@ func TestTranspileFilter(t *testing.T) {
157171
return
158172
}
159173
assert.NilError(t, err)
160-
actual, params, err := TranspileFilter(filter)
174+
actual, params, err := TranspileFilter(filter, tt.options...)
161175
if err != nil && tt.errorContains != "" {
162176
assert.ErrorContains(t, err, tt.errorContains)
163177
return

spanfiltering/transpiler.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,29 @@ type Transpiler struct {
1717
filter filtering.Filter
1818
params map[string]interface{}
1919
paramCounter int
20+
options transpileOptions
2021
}
2122

22-
func (t *Transpiler) Init(filter filtering.Filter) {
23+
type TranspileOption func(options *transpileOptions)
24+
25+
func WithEnumValuesAsStrings() TranspileOption {
26+
return func(options *transpileOptions) {
27+
options.enumValuesAsStrings = true
28+
}
29+
}
30+
31+
type transpileOptions struct {
32+
enumValuesAsStrings bool
33+
}
34+
35+
func (t *Transpiler) Init(filter filtering.Filter, options ...TranspileOption) {
2336
*t = Transpiler{
2437
filter: filter,
2538
params: make(map[string]interface{}),
2639
}
40+
for _, option := range options {
41+
option(&t.options)
42+
}
2743
}
2844

2945
func (t *Transpiler) Transpile() (spansql.BoolExpr, map[string]interface{}, error) {
@@ -123,7 +139,9 @@ func (t *Transpiler) transpileIdentExpr(e *expr.Expr) (spansql.Expr, error) {
123139
if messageType := identType.GetMessageType(); messageType != "" {
124140
if enumType, err := protoregistry.GlobalTypes.FindEnumByName(protoreflect.FullName(messageType)); err == nil {
125141
if enumValue := enumType.Descriptor().Values().ByName(protoreflect.Name(identExpr.GetName())); enumValue != nil {
126-
// TODO: Configurable support for string literals.
142+
if t.options.enumValuesAsStrings {
143+
return t.param(string(enumValue.Name())), nil
144+
}
127145
// spanner does not support int32
128146
return t.param(int64(enumValue.Number())), nil
129147
}

0 commit comments

Comments
 (0)