Skip to content

Commit 1c2b4e0

Browse files
authored
Reformat count operator (#6432)
This commit reformats the count operator so the record expression is no longer required and the count alias in the record expression is now the last argument.
1 parent 1432e20 commit 1c2b4e0

File tree

9 files changed

+3466
-3391
lines changed

9 files changed

+3466
-3391
lines changed

compiler/parser/parser.go

Lines changed: 3386 additions & 3346 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

compiler/parser/parser.peg

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,13 @@ CountOp
485485
return &ast.CountOp{
486486
Kind: "CountOp",
487487
Expr: rec.(*ast.RecordExpr),
488+
Loc: loc(c),
489+
}, nil
490+
}
491+
/ COUNT &EndOfOp {
492+
return &ast.CountOp{
493+
Kind: "CountOp",
494+
Loc: loc(c),
488495
}, nil
489496
}
490497

compiler/semantic/checker.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,14 @@ func (c *checker) op(typ super.Type, op sem.Op) super.Type {
8888
case *sem.BadOp:
8989
return c.unknown
9090
case *sem.CountOp:
91-
elems := []sem.RecordElem{
92-
&sem.FieldElem{Name: op.Alias, Value: &sem.LiteralExpr{Value: "0(uint64)"}},
93-
}
91+
var elems []sem.RecordElem
9492
if op.Expr != nil {
9593
elems = append(elems, op.Expr.(*sem.RecordExpr).Elems...)
9694
}
95+
elems = append(elems, &sem.FieldElem{
96+
Name: op.Alias,
97+
Value: &sem.LiteralExpr{Value: "0(uint64)"},
98+
})
9799
return c.recordElems(typ, elems)
98100
case *sem.CutOp:
99101
return c.pathsToType(c.assignments(typ, op.Args))

compiler/semantic/op.go

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -652,23 +652,38 @@ func (t *translator) semOp(o ast.Op, seq sem.Seq) sem.Seq {
652652
Cases: cases,
653653
})
654654
case *ast.CountOp:
655-
if len(o.Expr.Elems) == 0 {
656-
t.error(o.Expr, errors.New("count record expression must not be empty"))
657-
return append(seq, badOp())
658-
}
659-
first, ok := o.Expr.Elems[0].(*ast.ExprElem)
660-
if !ok {
661-
t.error(o.Expr, errors.New("first element in record expression for count must be an identifier"))
662-
return append(seq, badOp())
663-
}
664-
alias := first.Expr.(*ast.IDExpr).Name
655+
var alias string
665656
var expr sem.Expr
666-
if len(o.Expr.Elems) > 1 {
667-
expr = t.expr(&ast.RecordExpr{
668-
Kind: "RecordExpr",
669-
Elems: o.Expr.Elems[1:],
670-
Loc: o.Expr.Loc,
671-
})
657+
if o.Expr == nil {
658+
alias = "count"
659+
expr = &sem.RecordExpr{
660+
Elems: []sem.RecordElem{
661+
&sem.FieldElem{Name: "that", Value: sem.NewThis(nil, nil)},
662+
},
663+
}
664+
} else {
665+
n := len(o.Expr.Elems)
666+
if n == 0 {
667+
t.error(o.Expr, errors.New("count record expression must not be empty"))
668+
return append(seq, badOp())
669+
}
670+
last := o.Expr.Elems[n-1]
671+
if exprElem, ok := last.(*ast.ExprElem); ok {
672+
if id, ok := exprElem.Expr.(*ast.IDExpr); ok {
673+
alias = id.Name
674+
}
675+
}
676+
if alias == "" {
677+
t.error(last, errors.New("last element in record expression for count must be an identifier"))
678+
return append(seq, badOp())
679+
}
680+
if len(o.Expr.Elems) > 1 {
681+
expr = t.expr(&ast.RecordExpr{
682+
Kind: "RecordExpr",
683+
Elems: o.Expr.Elems[:n-1],
684+
Loc: o.Expr.Loc,
685+
})
686+
}
672687
}
673688
return append(seq, &sem.CountOp{
674689
Node: o,

compiler/sfmt/dag.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,12 +411,12 @@ func (c *canonDAG) op(p dag.Op) {
411411
c.write("combine")
412412
case *dag.CountOp:
413413
c.next()
414-
c.write("count {%s", p.Alias)
414+
c.write("count {")
415415
if p.Expr != nil {
416-
c.write(",")
417416
c.recordElems(p.Expr.(*dag.RecordExpr).Elems)
417+
c.write(",")
418418
}
419-
c.write("}")
419+
c.write("%s}", p.Alias)
420420
case *dag.CutOp:
421421
c.next()
422422
c.write("cut ")

compiler/ztests/par-count.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# Test ensures that flowgraphs utilizing the count operator
22
# are not parallelized.
33
script: |
4-
SUPER_VAM=1 super compile -C -P 2 'from /dev/null | count {row_number,...this} | aggregate sum(x)'
4+
SUPER_VAM=1 super compile -C -P 2 'from /dev/null | count {...this,row_number} | aggregate sum(x)'
55
66
outputs:
77
- name: stdout
88
data: |
99
file /dev/null unordered
10-
| count {row_number,...this}
10+
| count {...this,row_number}
1111
| aggregate
1212
sum:=sum(x)
1313
| values sum

runtime/sam/op/count/count.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ type Op struct {
1616
func New(sctx *super.Context, parent sbuf.Puller, alias string, in expr.Evaluator) (*Op, error) {
1717
o := &Op{parent: parent, alias: alias}
1818
var elems []expr.RecordElem
19-
elems = append(elems, expr.RecordElem{Name: alias, Field: evalfunc(o.evalCount)})
2019
if in != nil {
2120
elems = append(elems, expr.RecordElem{Spread: in})
2221
}
22+
elems = append(elems, expr.RecordElem{Name: alias, Field: evalfunc(o.evalCount)})
2323
var err error
2424
o.expr, err = expr.NewRecordExpr(sctx, elems)
2525
return o, err

runtime/vam/op/count.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ type Count struct {
1717
func NewCount(sctx *super.Context, parent vector.Puller, alias string, in expr.Evaluator) *Count {
1818
o := &Count{parent: parent, alias: alias}
1919
var elems []expr.RecordElem
20-
elems = append(elems, expr.RecordElem{Name: alias, Expr: evalfunc(o.evalCount)})
2120
if in != nil {
2221
elems = append(elems, expr.RecordElem{Expr: in})
2322
}
23+
elems = append(elems, expr.RecordElem{Name: alias, Expr: evalfunc(o.evalCount)})
2424
o.expr = expr.NewRecordExpr(sctx, elems)
2525
return o
2626
}

runtime/ztests/op/count.yaml

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,56 @@
11
script: |
2+
super -s -c 'values {x:1},{x:2} | count'
3+
echo // ===
24
super -s -c 'values null,null | count {count}'
35
echo // ===
4-
super -s -c 'values {x:1},{x:2} | count {row_number,...this}'
6+
super -s -c 'values {x:1},{x:2} | count {...this,row_number}'
57
echo // ===
6-
super -s -c 'values {x:1,y:1},{x:2,y:2} | count {row_number,x}'
8+
super -s -c 'values {x:1,y:1},{x:2,y:2} | count {x,row_number}'
79
echo // ===
8-
super -s -c 'values [1,2],[3,4] | unnest this into ( count {c,val:this} )'
9-
! super -s -c 'values null | count {count} | count := count+"hello"'
10+
super -s -c 'values [1,2],[3,4] | unnest this into ( count {val:this,c} )'
11+
! super -s -c 'values null | count | count := count+"hello"'
1012
>&2 echo // ===
11-
! super -s -c 'values {x:"foo"} | count {row,...this} | x := x+1'
13+
! super -s -c 'values {x:"foo"} | count {...this,row} | x := x+1'
1214
>&2 echo // ===
1315
! super -s -c 'values {x:"foo"} | count {...this}'
16+
>&2 echo // ===
17+
! super -s -c 'count {foo:"foo",1}'
1418
1519
vector: true
1620

1721
outputs:
1822
- name: stdout
1923
data: |
24+
{that:{x:1},count:1::uint64}
25+
{that:{x:2},count:2::uint64}
26+
// ===
2027
{count:1::uint64}
2128
{count:2::uint64}
2229
// ===
23-
{row_number:1::uint64,x:1}
24-
{row_number:2::uint64,x:2}
30+
{x:1,row_number:1::uint64}
31+
{x:2,row_number:2::uint64}
2532
// ===
26-
{row_number:1::uint64,x:1}
27-
{row_number:2::uint64,x:2}
33+
{x:1,row_number:1::uint64}
34+
{x:2,row_number:2::uint64}
2835
// ===
29-
{c:1::uint64,val:1}
30-
{c:2::uint64,val:2}
31-
{c:1::uint64,val:3}
32-
{c:2::uint64,val:4}
36+
{val:1,c:1::uint64}
37+
{val:2,c:2::uint64}
38+
{val:3,c:1::uint64}
39+
{val:4,c:2::uint64}
3340
- name: stderr
3441
data: |
35-
type mismatch at line 1, column 40:
36-
values null | count {count} | count := count+"hello"
37-
~~~~~~~~~~~~~
42+
type mismatch at line 1, column 32:
43+
values null | count | count := count+"hello"
44+
~~~~~~~~~~~~~
3845
// ===
3946
type mismatch at line 1, column 47:
40-
values {x:"foo"} | count {row,...this} | x := x+1
47+
values {x:"foo"} | count {...this,row} | x := x+1
4148
~~~
4249
// ===
43-
first element in record expression for count must be an identifier at line 1, column 26:
50+
last element in record expression for count must be an identifier at line 1, column 27:
4451
values {x:"foo"} | count {...this}
45-
~~~~~~~~~
52+
~~~~~~~
53+
// ===
54+
last element in record expression for count must be an identifier at line 1, column 18:
55+
count {foo:"foo",1}
56+
~

0 commit comments

Comments
 (0)