Skip to content

Commit d8351df

Browse files
Modify cost updates to be more extension friendly (#1113)
* Revert scalar designation for type and null values * Revert type size estimation to defer to caller first
1 parent 2f7606a commit d8351df

File tree

2 files changed

+96
-8
lines changed

2 files changed

+96
-8
lines changed

checker/cost.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,14 @@ func (c *coster) computeSize(e ast.Expr) *SizeEstimate {
930930
if size, ok := c.computedSizes[e.ID()]; ok {
931931
return &size
932932
}
933+
// Ensure size estimates are computed first as users may choose to override the costs that
934+
// CEL would otherwise ascribe to the type.
935+
node := astNode{expr: e, path: c.getPath(e), t: c.getType(e)}
936+
if size := c.estimator.EstimateSize(node); size != nil {
937+
// storing the computed size should reduce calls to EstimateSize()
938+
c.computedSizes[e.ID()] = *size
939+
return size
940+
}
933941
if size := computeExprSize(e); size != nil {
934942
return size
935943
}
@@ -942,12 +950,6 @@ func (c *coster) computeSize(e ast.Expr) *SizeEstimate {
942950
return v.size
943951
}
944952
}
945-
node := astNode{expr: e, path: c.getPath(e), t: c.getType(e)}
946-
if size := c.estimator.EstimateSize(node); size != nil {
947-
// storing the computed size should reduce calls to EstimateSize()
948-
c.computedSizes[e.ID()] = *size
949-
return size
950-
}
951953
return nil
952954
}
953955

@@ -1014,8 +1016,7 @@ func computeTypeSize(t *types.Type) *SizeEstimate {
10141016
// in addition to protobuf.Any and protobuf.Value (their size is not knowable at compile time).
10151017
func isScalar(t *types.Type) bool {
10161018
switch t.Kind() {
1017-
case types.BoolKind, types.DoubleKind, types.DurationKind, types.IntKind,
1018-
types.NullTypeKind, types.TimestampKind, types.TypeKind, types.UintKind:
1019+
case types.BoolKind, types.DoubleKind, types.DurationKind, types.IntKind, types.TimestampKind, types.UintKind:
10191020
return true
10201021
case types.OpaqueKind:
10211022
if t.TypeName() == "optional_type" {

checker/cost_test.go

+87
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,93 @@ func TestCost(t *testing.T) {
628628
expr: `['hello', 'hi'][0] != ['hello', 'bye'][1]`,
629629
wanted: CostEstimate{Min: 23, Max: 23},
630630
},
631+
{
632+
name: "type call",
633+
expr: `type(1)`,
634+
wanted: CostEstimate{Min: 1, Max: 1},
635+
},
636+
{
637+
name: "type call variable",
638+
expr: `type(self.val1)`,
639+
vars: []*decls.VariableDecl{
640+
decls.NewVariable("self", types.NewMapType(types.StringType, types.IntType)),
641+
},
642+
wanted: CostEstimate{Min: 3, Max: 3},
643+
},
644+
{
645+
name: "type call variable equality",
646+
expr: `type(self.val1) == int`,
647+
vars: []*decls.VariableDecl{
648+
decls.NewVariable("self", types.NewMapType(types.StringType, types.IntType)),
649+
},
650+
wanted: CostEstimate{Min: 5, Max: 1844674407370955268},
651+
},
652+
{
653+
name: "type literal equality cost",
654+
expr: `type(1) == int`,
655+
wanted: CostEstimate{Min: 3, Max: 1844674407370955266},
656+
},
657+
{
658+
name: "type variable equality cost",
659+
expr: `type(1) == int`,
660+
wanted: CostEstimate{Min: 3, Max: 1844674407370955266},
661+
},
662+
{
663+
name: "namespace variable equality",
664+
expr: `self.val1 == 1.0`,
665+
vars: []*decls.VariableDecl{
666+
decls.NewVariable("self.val1", types.DoubleType),
667+
},
668+
wanted: CostEstimate{Min: 2, Max: 2},
669+
},
670+
{
671+
name: "simple map variable equality",
672+
expr: `self.val1 == 1.0`,
673+
vars: []*decls.VariableDecl{
674+
decls.NewVariable("self", types.NewMapType(types.StringType, types.DoubleType)),
675+
},
676+
wanted: CostEstimate{Min: 3, Max: 3},
677+
},
678+
{
679+
name: "date-time math",
680+
vars: []*decls.VariableDecl{
681+
decls.NewVariable("self", types.NewMapType(types.StringType, types.TimestampType)),
682+
},
683+
expr: `self.val1 == timestamp('2011-08-18T00:00:00.000+01:00') + duration('19h3m37s10ms')`,
684+
wanted: FixedCostEstimate(6),
685+
},
686+
{
687+
name: "date-time math self-conversion",
688+
vars: []*decls.VariableDecl{
689+
decls.NewVariable("self", types.NewMapType(types.StringType, types.TimestampType)),
690+
},
691+
expr: `timestamp(self.val1) == timestamp('2011-08-18T00:00:00.000+01:00') + duration('19h3m37s10ms')`,
692+
wanted: FixedCostEstimate(7),
693+
},
694+
{
695+
name: "boolean vars equal",
696+
vars: []*decls.VariableDecl{
697+
decls.NewVariable("self", types.NewMapType(types.StringType, types.BoolType)),
698+
},
699+
expr: `self.val1 != self.val2`,
700+
wanted: FixedCostEstimate(5),
701+
},
702+
{
703+
name: "boolean var equals literal",
704+
vars: []*decls.VariableDecl{
705+
decls.NewVariable("self", types.NewMapType(types.StringType, types.BoolType)),
706+
},
707+
expr: `self.val1 != true`,
708+
wanted: FixedCostEstimate(3),
709+
},
710+
{
711+
name: "double var equals literal",
712+
vars: []*decls.VariableDecl{
713+
decls.NewVariable("self", types.NewMapType(types.StringType, types.DoubleType)),
714+
},
715+
expr: `self.val1 == 1.0`,
716+
wanted: FixedCostEstimate(3),
717+
},
631718
}
632719

633720
for _, tst := range cases {

0 commit comments

Comments
 (0)