Skip to content

Commit 1cccdff

Browse files
committed
Reformat count operator
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 1cccdff

File tree

9 files changed

+3468
-3391
lines changed

9 files changed

+3468
-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: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -652,23 +652,40 @@ 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+
exprElem, ok := last.(*ast.ExprElem)
672+
if !ok {
673+
t.error(last, errors.New("last element in record expression for count must be an identifier"))
674+
return append(seq, badOp())
675+
}
676+
id, ok := exprElem.Expr.(*ast.IDExpr)
677+
if !ok {
678+
t.error(last, errors.New("last element in record expression for count must be an identifier"))
679+
return append(seq, badOp())
680+
}
681+
alias = id.Name
682+
if len(o.Expr.Elems) > 1 {
683+
expr = t.expr(&ast.RecordExpr{
684+
Kind: "RecordExpr",
685+
Elems: o.Expr.Elems[:n-1],
686+
Loc: o.Expr.Loc,
687+
})
688+
}
672689
}
673690
return append(seq, &sem.CountOp{
674691
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)