Skip to content

Commit

Permalink
colexec: clean up hash aggregate functions
Browse files Browse the repository at this point in the history
Hash aggregate function always have non-nil `sel`, and this commit
removes the code generation for nil `sel` case (meaning it removes the
dead code). It also templates out nulls vs no-nulls cases in `bool_and`
and `bool_or` aggregates.

Release note: None
  • Loading branch information
yuzefovich committed Aug 6, 2020
1 parent a175e68 commit 98c19d0
Show file tree
Hide file tree
Showing 26 changed files with 1,248 additions and 3,540 deletions.
34 changes: 17 additions & 17 deletions pkg/sql/colexec/any_not_null_agg_tmpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,32 +129,32 @@ func (a *anyNotNull_TYPE_AGGKINDAgg) Compute(
_ = col.Get(inputLen - 1)
// {{if eq "_AGGKIND" "Ordered"}}
groups := a.groups
// {{end}}
if nulls.MaybeHasNulls() {
if sel != nil {
sel = sel[:inputLen]
for _, i := range sel {
// {{/*
// We don't need to check whether sel is non-nil when performing
// hash aggregation because the hash aggregator always uses non-nil
// sel to specify the tuples to be aggregated.
// */}}
if sel == nil {
_ = groups[inputLen-1]
if nulls.MaybeHasNulls() {
for i := 0; i < inputLen; i++ {
_FIND_ANY_NOT_NULL(a, groups, nulls, i, true)
}
} else {
// {{if eq "_AGGKIND" "Ordered"}}
_ = groups[inputLen-1]
// {{end}}
for i := 0; i < inputLen; i++ {
_FIND_ANY_NOT_NULL(a, groups, nulls, i, true)
_FIND_ANY_NOT_NULL(a, groups, nulls, i, false)
}
}
} else {
if sel != nil {
sel = sel[:inputLen]
} else
// {{end}}
{
sel = sel[:inputLen]
if nulls.MaybeHasNulls() {
for _, i := range sel {
_FIND_ANY_NOT_NULL(a, groups, nulls, i, false)
_FIND_ANY_NOT_NULL(a, groups, nulls, i, true)
}
} else {
// {{if eq "_AGGKIND" "Ordered"}}
_ = groups[inputLen-1]
// {{end}}
for i := 0; i < inputLen; i++ {
for _, i := range sel {
_FIND_ANY_NOT_NULL(a, groups, nulls, i, false)
}
}
Expand Down
34 changes: 21 additions & 13 deletions pkg/sql/colexec/avg_agg_tmpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,27 +144,35 @@ func (a *avg_TYPE_AGGKINDAgg) Compute(
// {{end}}
vec := vecs[inputIdxs[0]]
col, nulls := vec.TemplateType(), vec.Nulls()
if nulls.MaybeHasNulls() {
if sel != nil {
sel = sel[:inputLen]
for _, i := range sel {
// {{if eq "_AGGKIND" "Ordered"}}
groups := a.groups
// {{/*
// We don't need to check whether sel is non-nil when performing
// hash aggregation because the hash aggregator always uses non-nil
// sel to specify the tuples to be aggregated.
// */}}
if sel == nil {
_ = groups[inputLen-1]
col = col[:inputLen]
if nulls.MaybeHasNulls() {
for i := range col {
_ACCUMULATE_AVG(a, nulls, i, true)
}
} else {
col = col[:inputLen]
for i := range col {
_ACCUMULATE_AVG(a, nulls, i, true)
_ACCUMULATE_AVG(a, nulls, i, false)
}
}
} else {
if sel != nil {
sel = sel[:inputLen]
} else
// {{end}}
{
sel = sel[:inputLen]
if nulls.MaybeHasNulls() {
for _, i := range sel {
_ACCUMULATE_AVG(a, nulls, i, false)
_ACCUMULATE_AVG(a, nulls, i, true)
}
} else {
col = col[:inputLen]
for i := range col {
for _, i := range sel {
_ACCUMULATE_AVG(a, nulls, i, false)
}
}
Expand Down Expand Up @@ -216,7 +224,7 @@ func _ACCUMULATE_AVG(a *_AGG_TYPE_AGGKINDAgg, nulls *coldata.Nulls, i int, _HAS_
// {{define "accumulateAvg"}}

// {{if eq "_AGGKIND" "Ordered"}}
if a.groups[i] {
if groups[i] {
// If we encounter a new group, and we haven't found any non-nulls for the
// current group, the output for this group should be null.
if !a.scratch.foundNonNullForCurrentGroup {
Expand Down
50 changes: 38 additions & 12 deletions pkg/sql/colexec/bool_and_or_agg_tmpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,37 @@ func (a *bool_OP_TYPE_AGGKINDAgg) Compute(
) {
vec := vecs[inputIdxs[0]]
col, nulls := vec.Bool(), vec.Nulls()
if sel != nil {
sel = sel[:inputLen]
for _, i := range sel {
_ACCUMULATE_BOOLEAN(a, nulls, i)
}
} else {
// {{if eq "_AGGKIND" "Ordered"}}
groups := a.groups
// {{/*
// We don't need to check whether sel is non-nil when performing
// hash aggregation because the hash aggregator always uses non-nil
// sel to specify the tuples to be aggregated.
// */}}
if sel == nil {
_ = groups[inputLen-1]
col = col[:inputLen]
for i := range col {
_ACCUMULATE_BOOLEAN(a, nulls, i)
if nulls.MaybeHasNulls() {
for i := range col {
_ACCUMULATE_BOOLEAN(a, nulls, i, true)
}
} else {
for i := range col {
_ACCUMULATE_BOOLEAN(a, nulls, i, false)
}
}
} else
// {{end}}
{
sel = sel[:inputLen]
if nulls.MaybeHasNulls() {
for _, i := range sel {
_ACCUMULATE_BOOLEAN(a, nulls, i, true)
}
} else {
for _, i := range sel {
_ACCUMULATE_BOOLEAN(a, nulls, i, false)
}
}
}
}
Expand Down Expand Up @@ -141,11 +163,11 @@ func (a *bool_OP_TYPE_AGGKINDAggAlloc) newAggFunc() aggregateFunc {

// {{/*
// _ACCUMULATE_BOOLEAN aggregates the boolean value at index i into the boolean aggregate.
func _ACCUMULATE_BOOLEAN(a *bool_OP_TYPE_AGGKINDAgg, nulls *coldata.Nulls, i int) { // */}}
func _ACCUMULATE_BOOLEAN(a *bool_OP_TYPE_AGGKINDAgg, nulls *coldata.Nulls, i int, _HAS_NULLS bool) { // */}}
// {{define "accumulateBoolean" -}}

// {{if eq "_AGGKIND" "Ordered"}}
if a.groups[i] {
if groups[i] {
if !a.sawNonNull {
a.nulls.SetNull(a.curIdx)
} else {
Expand All @@ -159,8 +181,12 @@ func _ACCUMULATE_BOOLEAN(a *bool_OP_TYPE_AGGKINDAgg, nulls *coldata.Nulls, i int
}
// {{end}}

// TODO(yuzefovich): template out has nulls vs no nulls cases.
isNull := nulls.NullAt(i)
var isNull bool
// {{if .HasNulls}}
isNull = nulls.NullAt(i)
// {{else}}
isNull = false
// {{end}}
if !isNull {
// {{with .Global}}
_ASSIGN_BOOL_OP(a.curAgg, a.curAgg, col[i])
Expand Down
31 changes: 20 additions & 11 deletions pkg/sql/colexec/concat_agg_tmpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,34 @@ func (a *concat_AGGKINDAgg) Compute(
[]coldata.Vec{a.vec},
func() {
previousAggValMemoryUsage := a.aggValMemoryUsage()
if nulls.MaybeHasNulls() {
if sel != nil {
sel = sel[:inputLen]
for _, i := range sel {
// {{if eq "_AGGKIND" "Ordered"}}
groups := a.groups
// {{/*
// We don't need to check whether sel is non-nil when performing
// hash aggregation because the hash aggregator always uses non-nil
// sel to specify the tuples to be aggregated.
// */}}
if sel == nil {
_ = groups[inputLen-1]
if nulls.MaybeHasNulls() {
for i := 0; i < inputLen; i++ {
_ACCUMULATE_CONCAT(a, nulls, i, true)
}
} else {
for i := 0; i < inputLen; i++ {
_ACCUMULATE_CONCAT(a, nulls, i, true)
_ACCUMULATE_CONCAT(a, nulls, i, false)
}
}
} else {
if sel != nil {
sel = sel[:inputLen]
} else
// {{end}}
{
sel = sel[:inputLen]
if nulls.MaybeHasNulls() {
for _, i := range sel {
_ACCUMULATE_CONCAT(a, nulls, i, false)
_ACCUMULATE_CONCAT(a, nulls, i, true)
}
} else {
for i := 0; i < inputLen; i++ {
for _, i := range sel {
_ACCUMULATE_CONCAT(a, nulls, i, false)
}
}
Expand Down Expand Up @@ -156,7 +165,7 @@ type concat_AGGKINDAgg struct {
func _ACCUMULATE_CONCAT(a *concat_AGGKINDAgg, nulls *coldata.Nulls, i int, _HAS_NULLS bool) { // */}}
// {{define "accumulateConcat" }}
// {{if eq "_AGGKIND" "Ordered"}}
if a.groups[i] {
if groups[i] {
// If we encounter a new group, and we haven't found any non-nulls for the
// current group, the output for this group should be null.
if !a.foundNonNullForCurrentGroup {
Expand Down
38 changes: 28 additions & 10 deletions pkg/sql/colexec/count_agg_tmpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,31 +75,49 @@ func (a *count_COUNTKIND_AGGKINDAgg) Compute(
vecs []coldata.Vec, inputIdxs []uint32, inputLen int, sel []int,
) {
var i int
// Remove unused warning.
_ = i

// {{if not (eq .CountKind "Rows")}}
// If this is a COUNT(col) aggregator and there are nulls in this batch,
// we must check each value for nullity. Note that it is only legal to do a
// COUNT aggregate on a single column.
nulls := vecs[inputIdxs[0]].Nulls()
if nulls.MaybeHasNulls() {
if sel != nil {
for _, i = range sel[:inputLen] {
// {{end}}
// {{if eq "_AGGKIND" "Ordered"}}
groups := a.groups
// {{/*
// We don't need to check whether sel is non-nil when performing
// hash aggregation because the hash aggregator always uses non-nil
// sel to specify the tuples to be aggregated.
// */}}
if sel == nil {
_ = groups[inputLen-1]
// {{if not (eq .CountKind "Rows")}}
if nulls.MaybeHasNulls() {
for i = 0; i < inputLen; i++ {
_ACCUMULATE_COUNT(a, nulls, i, true)
}
} else {
} else
// {{end}}
{
for i = 0; i < inputLen; i++ {
_ACCUMULATE_COUNT(a, nulls, i, true)
_ACCUMULATE_COUNT(a, nulls, i, false)
}
}
} else
// {{end}}
{
if sel != nil {
sel = sel[:inputLen]
// {{if not (eq .CountKind "Rows")}}
if nulls.MaybeHasNulls() {
for _, i = range sel[:inputLen] {
_ACCUMULATE_COUNT(a, nulls, i, false)
_ACCUMULATE_COUNT(a, nulls, i, true)
}
} else {
for i = 0; i < inputLen; i++ {
} else
// {{end}}
{
for _, i = range sel[:inputLen] {
_ACCUMULATE_COUNT(a, nulls, i, false)
}
}
Expand Down Expand Up @@ -148,7 +166,7 @@ func _ACCUMULATE_COUNT(a *countAgg, nulls *coldata.Nulls, i int, _COL_WITH_NULLS
// {{define "accumulateCount" -}}

// {{if eq "_AGGKIND" "Ordered"}}
if a.groups[i] {
if groups[i] {
a.vec[a.curIdx] = a.curAgg
a.curIdx++
a.curAgg = int64(0)
Expand Down
2 changes: 0 additions & 2 deletions pkg/sql/colexec/default_agg_tmpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ func (a *default_AGGKINDAgg) Compute(
// aggregator always uses non-nil sel to specify the tuples to be
// aggregated. Also, the hash aggregator converts the batch "sparsely",
// so converted values are at the same positions as the original ones.
// TODO(yuzefovich): remove sel==nil case from all other hash aggregate
// functions.
var convertedTupleIdx int
for _, origTupleIdx := range sel[:inputLen] {
convertedTupleIdx = origTupleIdx
Expand Down
4 changes: 2 additions & 2 deletions pkg/sql/colexec/execgen/cmd/execgen/bool_and_or_agg_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ func genBooleanAgg(inputFileContents string, wr io.Writer) error {
)
s := r.Replace(inputFileContents)

accumulateBoolean := makeFunctionRegex("_ACCUMULATE_BOOLEAN", 3)
s = accumulateBoolean.ReplaceAllString(s, `{{template "accumulateBoolean" buildDict "Global" .}}`)
accumulateBoolean := makeFunctionRegex("_ACCUMULATE_BOOLEAN", 4)
s = accumulateBoolean.ReplaceAllString(s, `{{template "accumulateBoolean" buildDict "Global" . "HasNulls" $4}}`)

assignBoolRe := makeFunctionRegex("_ASSIGN_BOOL_OP", 3)
s = assignBoolRe.ReplaceAllString(s, makeTemplateFunctionCall(`AssignBoolOp`, 3))
Expand Down
Loading

0 comments on commit 98c19d0

Please sign in to comment.