$ super -version && super -c "
fn walk(n): (
values {n}
| values n <= 0 ? [] : [{a: n, b: n * 2, c: 'x', d: [n, n], e: {f: n}}, ...walk(n - 1)]
)
fork
( values walk(200) | unnest this )
( values walk(200) | unnest this )
( values walk(200) | unnest this )
( values walk(200) | unnest this )"
Version: v0.3.0-372-g217a042d8
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0xb5c1a68]
goroutine 23 [running]:
github.com/brimdata/super/runtime/vam/expr.(*UDF).Call(0x32ad71390140, {0x32ad7118e920, 0x1, 0x32ad70ca7b60?})
/Users/phil/work/super/runtime/vam/expr/udf.go:43 +0x4c8
github.com/brimdata/super/vector.Apply(0x2, 0x32ad711bed88, {0x32ad7118e920, 0x1, 0x1})
/Users/phil/work/super/vector/apply.go:62 +0x3e5
github.com/brimdata/super/runtime/vam/expr.(*Call).Eval(0x32ad70dae5a0, {0xd1b5e10, 0x32ad71191590})
/Users/phil/work/super/runtime/vam/expr/eval.go:67 +0x19c
github.com/brimdata/super/runtime/vam/expr.(*ArrayExpr).Eval(0x32ad711914a0, {0xd1b5e10, 0x32ad71191590})
/Users/phil/work/super/runtime/vam/expr/arrayexpr.go:41 +0x1c8
github.com/brimdata/super/runtime/vam/expr.(*conditional).eval(0x32ad70eea700, {0x32ad70da8640?, 0xd1b5b70?, 0x32ad70ca7aa0?})
/Users/phil/work/super/runtime/vam/expr/conditional.go:48 +0x21f
github.com/brimdata/super/vector.Apply(0x2, 0x32ad711bf0b0, {0x32ad70da8640, 0x2, 0x2})
/Users/phil/work/super/vector/apply.go:62 +0x3e5
github.com/brimdata/super/runtime/vam/expr.(*conditional).Eval(0x32ad70eea700, {0xd1b5e10, 0x32ad71191590})
/Users/phil/work/super/runtime/vam/expr/conditional.go:28 +0x199
github.com/brimdata/super/runtime/vam/op.(*Values).Pull(0x32ad71191500, 0x0)
/Users/phil/work/super/runtime/vam/op/values.go:34 +0x102
github.com/brimdata/super/runtime/vam/op.(*Subquery).bodyPull(0x32ad70c502d0)
/Users/phil/work/super/runtime/vam/op/subquery.go:84 +0x27
github.com/brimdata/super/runtime/vam/op.(*Subquery).Eval(0x32ad70c502d0, {0xd1b5e10, 0x32ad70d9e6c0})
/Users/phil/work/super/runtime/vam/op/subquery.go:78 +0x2a8
github.com/brimdata/super/runtime/vam/op.(*Subquery).Eval(0x32ad70ece750, {0xd1b5e10, 0x32ad70d9e6c0})
/Users/phil/work/super/runtime/vam/op/subquery.go:66 +0x205
github.com/brimdata/super/runtime/vam/expr.(*UDF).Call(0x32ad70f4c7d0, {0x32ad70f47cb0, 0x1, 0x32ad70f8c150?})
/Users/phil/work/super/runtime/vam/expr/udf.go:43 +0x4db
github.com/brimdata/super/vector.Apply(0x2, 0x32ad70e77638, {0x32ad70f47cb0, 0x1, 0x1})
/Users/phil/work/super/vector/apply.go:62 +0x3e5
github.com/brimdata/super/runtime/vam/expr.(*Call).Eval(0x32ad70f4cd20, {0xd1b5e10, 0x32ad70d9e390})
/Users/phil/work/super/runtime/vam/expr/eval.go:67 +0x19c
github.com/brimdata/super/runtime/vam/expr.(*ArrayExpr).Eval(0x32ad70bb81e0, {0xd1b5e10, 0x32ad70d9e390})
/Users/phil/work/super/runtime/vam/expr/arrayexpr.go:41 +0x1c8
github.com/brimdata/super/runtime/vam/expr.(*conditional).eval(0x32ad7106b540, {0x32ad70f08e60?, 0xd1b5b70?, 0x32ad70f8c060?})
/Users/phil/work/super/runtime/vam/expr/conditional.go:48 +0x21f
github.com/brimdata/super/vector.Apply(0x2, 0x32ad70e77960, {0x32ad70f08e60, 0x2, 0x2})
/Users/phil/work/super/vector/apply.go:62 +0x3e5
github.com/brimdata/super/runtime/vam/expr.(*conditional).Eval(0x32ad7106b540, {0xd1b5e10, 0x32ad70d9e390})
/Users/phil/work/super/runtime/vam/expr/conditional.go:28 +0x199
github.com/brimdata/super/runtime/vam/op.(*Values).Pull(0x32ad70bb8240, 0x0)
/Users/phil/work/super/runtime/vam/op/values.go:34 +0x102
github.com/brimdata/super/runtime/vam/op.(*Subquery).bodyPull(0x32ad70ece750)
/Users/phil/work/super/runtime/vam/op/subquery.go:84 +0x27
github.com/brimdata/super/runtime/vam/op.(*Subquery).Eval(0x32ad70ece750, {0xd1b5e10, 0x32ad70d9e270})
/Users/phil/work/super/runtime/vam/op/subquery.go:78 +0x2a8
github.com/brimdata/super/runtime/vam/expr.(*UDF).Call(0x32ad70f4c7d0, {0x32ad709f8350, 0x1, 0x32ad70f8c018?})
/Users/phil/work/super/runtime/vam/expr/udf.go:43 +0x4db
github.com/brimdata/super/vector.Apply(0x2, 0x32ad70d18dc0, {0x32ad709f8350, 0x1, 0x1})
/Users/phil/work/super/vector/apply.go:62 +0x3e5
github.com/brimdata/super/runtime/vam/expr.(*Call).Eval(0x32ad70f4ceb0, {0xd1b5da0, 0x32ad70f2e400})
/Users/phil/work/super/runtime/vam/expr/eval.go:67 +0x19c
github.com/brimdata/super/runtime/vam/op.(*Values).Pull(0x32ad70bb8450, 0x0)
/Users/phil/work/super/runtime/vam/op/values.go:34 +0x102
github.com/brimdata/super/runtime/vam/op.(*Unnest).Pull(0x32ad70bb84b0, 0x0)
/Users/phil/work/super/runtime/vam/op/unnest.go:30 +0x35
github.com/brimdata/super/runtime/vam/op.(*combineParent).run(0x32ad70eeac00)
/Users/phil/work/super/runtime/vam/op/combine.go:109 +0x3c
created by github.com/brimdata/super/runtime/vam/op.(*Combine).Pull.func1 in goroutine 1
/Users/phil/work/super/runtime/vam/op/combine.go:42 +0x35
panic: runtime error: invalid memory address or nil pointer dereference
This crash was uncovered while helping an advisor with prototyping their "paged API" use case. They'd already created a recursive function that was working to their satisfaction, but then wanted to invoke it in parallel branches of a fork. If for some reason that wasn't possible, they expressed intent to do it with join instead, but it turns out this problem affects queries that have parallelism in general: fork, join, switch, and SQL UNION ALL. As I learned, it's not limited to queries that ask for parallelism, since the optimizer introduces it on its own, so a plain linear pipeline like this one crashes too:
$ seq 500 | awk '{print "{k:" $1%7 "}"}' |
super -s -c "
fn walk(n): (
values {n}
| values n <= 0 ? [] : [{a: n, b: n*2, c: 'x'}, ...walk(n - 1)]
)
where k == 3 | values walk(20) | unnest this | count()" -
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x83b5a68]
goroutine 61 [running]:
github.com/brimdata/super/runtime/vam/expr.(*UDF).Call(0x72095deec30, {0x72095c7baf0, 0x1, 0x72095f17cb0?})
/Users/phil/work/super/runtime/vam/expr/udf.go:43 +0x4c8
...
I used Claude to help create the simplified repro, and as it was doing that it uncovered what it believes are two races that contribute to this crash and other insights into possible fixes, so I've made its full write-up available in a Gist.
Details
Repro is with super commit 217a042.
This crash was uncovered while helping an advisor with prototyping their "paged API" use case. They'd already created a recursive function that was working to their satisfaction, but then wanted to invoke it in parallel branches of a
fork. If for some reason that wasn't possible, they expressed intent to do it withjoininstead, but it turns out this problem affects queries that have parallelism in general:fork,join,switch, and SQLUNION ALL. As I learned, it's not limited to queries that ask for parallelism, since the optimizer introduces it on its own, so a plain linear pipeline like this one crashes too:I used Claude to help create the simplified repro, and as it was doing that it uncovered what it believes are two races that contribute to this crash and other insights into possible fixes, so I've made its full write-up available in a Gist.