Skip to content

Commit

Permalink
Make cel2sql generic using View abstraction
Browse files Browse the repository at this point in the history
  • Loading branch information
RafaeLeal committed Jul 7, 2023
1 parent e857941 commit 5e0dfce
Show file tree
Hide file tree
Showing 18 changed files with 540 additions and 269 deletions.
40 changes: 40 additions & 0 deletions pkg/api/server/cel/view/records.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package view

import (
"github.com/google/cel-go/cel"
"github.com/tektoncd/results/pkg/api/server/cel2sql"
)

// NewRecordsView return the set of variables and constants available for CEL
// filters
func NewRecordsView() (*cel2sql.View, error) {
view := &cel2sql.View{
Constants: map[string]cel2sql.Constant{},
Fields: map[string]cel2sql.Field{
"parent": {
CELType: cel.StringType,
SQL: `parent`,
},
"result_name": {
CELType: cel.StringType,
SQL: `result_name`,
},
"name": {
CELType: cel.StringType,
SQL: `name`,
},
"data_type": {
CELType: cel.StringType,
SQL: `type`,
},
"data": {
CELType: cel.AnyType,
SQL: `data`,
},
},
}
for typeName, value := range typeConstants {
view.Constants[typeName] = value
}
return view, nil
}
24 changes: 24 additions & 0 deletions pkg/api/server/cel/view/records_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package view

import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/tektoncd/results/pkg/api/server/cel2sql"
"k8s.io/utils/pointer"
)

func TestNewRecordsViewConstants(t *testing.T) {
view, err := NewRecordsView()
if err != nil {
t.Fatal(err)
}

expectedConstants := map[string]cel2sql.Constant{
"PIPELINE_RUN": {StringVal: pointer.String("tekton.dev/v1beta1.PipelineRun")},
"TASK_RUN": {StringVal: pointer.String("tekton.dev/v1beta1.TaskRun")},
}
if diff := cmp.Diff(expectedConstants, view.Constants); diff != "" {
t.Errorf("Invalid constants (-want, +got):\n%s", diff)
}
}
66 changes: 66 additions & 0 deletions pkg/api/server/cel/view/results.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package view

import (
"github.com/google/cel-go/cel"
"github.com/tektoncd/results/pkg/api/server/cel2sql"
resultspb "github.com/tektoncd/results/proto/v1alpha2/results_go_proto"
)

var (
typePipelineRun = "tekton.dev/v1beta1.PipelineRun"
typeTaskRun = "tekton.dev/v1beta1.TaskRun"

typeConstants = map[string]cel2sql.Constant{
"PIPELINE_RUN": {
StringVal: &typePipelineRun,
},
"TASK_RUN": {
StringVal: &typeTaskRun,
},
}
)

// NewResultsView return the set of variables and constants available for CEL
// filters
func NewResultsView() (*cel2sql.View, error) {
view := &cel2sql.View{
Constants: map[string]cel2sql.Constant{},
Fields: map[string]cel2sql.Field{
"parent": {
CELType: cel.StringType,
SQL: `parent`,
},
"uid": {
CELType: cel.StringType,
SQL: `id`,
},
"create_time": {
CELType: cel2sql.CELTypeTimestamp,
SQL: `created_time`,
},
"update_time": {
CELType: cel2sql.CELTypeTimestamp,
SQL: `updated_time`,
},
"annotations": {
CELType: cel.MapType(cel.StringType, cel.StringType),
SQL: `annotations`,
},
"summary": {
CELType: cel.ObjectType("tekton.results.v1alpha2.RecordSummary"),
ObjectType: &resultspb.RecordSummary{},
SQL: `recordsummary_{{.Field}}`,
},
},
}
for typeName, value := range typeConstants {
view.Constants[typeName] = value
}
for name, value := range resultspb.RecordSummary_Status_value {
v := value
view.Constants[name] = cel2sql.Constant{
Int32Val: &v,
}
}
return view, nil
}
29 changes: 29 additions & 0 deletions pkg/api/server/cel/view/results_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package view

import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/tektoncd/results/pkg/api/server/cel2sql"
"k8s.io/utils/pointer"
)

func TestNewResultsViewConstants(t *testing.T) {
view, err := NewResultsView()
if err != nil {
t.Fatal(err)
}

expectedConstants := map[string]cel2sql.Constant{
"PIPELINE_RUN": {StringVal: pointer.String("tekton.dev/v1beta1.PipelineRun")},
"TASK_RUN": {StringVal: pointer.String("tekton.dev/v1beta1.TaskRun")},
"UNKNOWN": {Int32Val: pointer.Int32(0)},
"SUCCESS": {Int32Val: pointer.Int32(1)},
"FAILURE": {Int32Val: pointer.Int32(2)},
"TIMEOUT": {Int32Val: pointer.Int32(3)},
"CANCELLED": {Int32Val: pointer.Int32(4)},
}
if diff := cmp.Diff(expectedConstants, view.Constants); diff != "" {
t.Errorf("Invalid constants (-want, +got):\n%s", diff)
}
}
20 changes: 15 additions & 5 deletions pkg/api/server/cel2sql/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@ import (
"github.com/google/cel-go/cel"
)

// Convert takes CEL expressions and attempt to convert them into Postgres SQL
// filters.
func Convert(env *cel.Env, filters string) (string, error) {
// Convert takes a View and CEL expressions and attempt to convert them into
// Postgres SQL filters.
func Convert(view *View, filters string) (string, error) {
env, err := view.GetEnv()
if err != nil {
return "", fmt.Errorf("invalid view: %w", err)
}

ast, issues := env.Compile(filters)
if issues != nil && issues.Err() != nil {
return "", fmt.Errorf("error compiling CEL filters: %w", issues.Err())
Expand All @@ -32,10 +37,15 @@ func Convert(env *cel.Env, filters string) (string, error) {
return "", fmt.Errorf("expected boolean expression, but got %s", outputType.String())
}

interpreter, err := newInterpreter(ast)
interpreter, err := newInterpreter(ast, view)
if err != nil {
return "", fmt.Errorf("error creating cel2sql interpreter: %w", err)
}

return interpreter.interpret()
sql, err := interpreter.interpret()
if err != nil {
return "", err
}

return sql, nil
}
Loading

0 comments on commit 5e0dfce

Please sign in to comment.