Created
June 5, 2020 21:42
-
-
Save jordanlewis/36b2cf775198886c6a65ac91de1911d0 to your computer and use it in GitHub Desktop.
distinct.eg.go after execgen:inline
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Code generated by execgen; DO NOT EDIT. | |
// Copyright 2018 The Cockroach Authors. | |
// Use of this software is governed by the Business Source License | |
// included in the file licenses/BSL.txt. | |
// As of the Change Date specified in that file, in accordance with | |
// the Business Source License, use of this software will be governed | |
// by the Apache License, Version 2.0, included in the file | |
// licenses/APL.txt. | |
package colexec | |
import ( | |
"bytes" | |
"context" | |
"math" | |
"time" | |
"github.com/cockroachdb/apd" | |
"github.com/cockroachdb/cockroach/pkg/col/coldata" | |
"github.com/cockroachdb/cockroach/pkg/col/coldataext" | |
"github.com/cockroachdb/cockroach/pkg/col/typeconv" | |
"github.com/cockroachdb/cockroach/pkg/sql/colexec/execgen" | |
"github.com/cockroachdb/cockroach/pkg/sql/colexecbase" | |
"github.com/cockroachdb/cockroach/pkg/sql/colexecbase/colexecerror" | |
"github.com/cockroachdb/cockroach/pkg/sql/sem/tree" | |
"github.com/cockroachdb/cockroach/pkg/sql/types" | |
"github.com/cockroachdb/cockroach/pkg/util/duration" | |
"github.com/cockroachdb/errors" | |
) | |
// OrderedDistinctColsToOperators is a utility function that given an input and | |
// a slice of columns, creates a chain of distinct operators and returns the | |
// last distinct operator in that chain as well as its output column. | |
func OrderedDistinctColsToOperators( | |
input colexecbase.Operator, distinctCols []uint32, typs []*types.T, | |
) (colexecbase.Operator, []bool, error) { | |
distinctCol := make([]bool, coldata.BatchSize()) | |
// zero the boolean column on every iteration. | |
input = fnOp{ | |
OneInputNode: NewOneInputNode(input), | |
fn: func() { copy(distinctCol, zeroBoolColumn) }, | |
} | |
var ( | |
err error | |
r resettableOperator | |
ok bool | |
) | |
for i := range distinctCols { | |
input, err = newSingleDistinct(input, int(distinctCols[i]), distinctCol, typs[distinctCols[i]]) | |
if err != nil { | |
return nil, nil, err | |
} | |
} | |
if r, ok = input.(resettableOperator); !ok { | |
colexecerror.InternalError("unexpectedly an ordered distinct is not a resetter") | |
} | |
distinctChain := &distinctChainOps{ | |
resettableOperator: r, | |
} | |
return distinctChain, distinctCol, nil | |
} | |
type distinctChainOps struct { | |
resettableOperator | |
} | |
var _ resettableOperator = &distinctChainOps{} | |
// NewOrderedDistinct creates a new ordered distinct operator on the given | |
// input columns with the given types. | |
func NewOrderedDistinct( | |
input colexecbase.Operator, distinctCols []uint32, typs []*types.T, | |
) (colexecbase.Operator, error) { | |
op, outputCol, err := OrderedDistinctColsToOperators(input, distinctCols, typs) | |
if err != nil { | |
return nil, err | |
} | |
return &boolVecToSelOp{ | |
OneInputNode: NewOneInputNode(op), | |
outputCol: outputCol, | |
}, nil | |
} | |
// Remove unused warning. | |
var _ = execgen.UNSAFEGET | |
func newSingleDistinct( | |
input colexecbase.Operator, distinctColIdx int, outputCol []bool, t *types.T, | |
) (colexecbase.Operator, error) { | |
switch typeconv.TypeFamilyToCanonicalTypeFamily(t.Family()) { | |
case types.BoolFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return &distinctBoolOp{ | |
OneInputNode: NewOneInputNode(input), | |
distinctColIdx: distinctColIdx, | |
outputCol: outputCol, | |
}, nil | |
} | |
case types.BytesFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return &distinctBytesOp{ | |
OneInputNode: NewOneInputNode(input), | |
distinctColIdx: distinctColIdx, | |
outputCol: outputCol, | |
}, nil | |
} | |
case types.DecimalFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return &distinctDecimalOp{ | |
OneInputNode: NewOneInputNode(input), | |
distinctColIdx: distinctColIdx, | |
outputCol: outputCol, | |
}, nil | |
} | |
case types.IntFamily: | |
switch t.Width() { | |
case 16: | |
return &distinctInt16Op{ | |
OneInputNode: NewOneInputNode(input), | |
distinctColIdx: distinctColIdx, | |
outputCol: outputCol, | |
}, nil | |
case 32: | |
return &distinctInt32Op{ | |
OneInputNode: NewOneInputNode(input), | |
distinctColIdx: distinctColIdx, | |
outputCol: outputCol, | |
}, nil | |
case -1: | |
default: | |
return &distinctInt64Op{ | |
OneInputNode: NewOneInputNode(input), | |
distinctColIdx: distinctColIdx, | |
outputCol: outputCol, | |
}, nil | |
} | |
case types.FloatFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return &distinctFloat64Op{ | |
OneInputNode: NewOneInputNode(input), | |
distinctColIdx: distinctColIdx, | |
outputCol: outputCol, | |
}, nil | |
} | |
case types.TimestampTZFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return &distinctTimestampOp{ | |
OneInputNode: NewOneInputNode(input), | |
distinctColIdx: distinctColIdx, | |
outputCol: outputCol, | |
}, nil | |
} | |
case types.IntervalFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return &distinctIntervalOp{ | |
OneInputNode: NewOneInputNode(input), | |
distinctColIdx: distinctColIdx, | |
outputCol: outputCol, | |
}, nil | |
} | |
case typeconv.DatumVecCanonicalTypeFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return &distinctDatumOp{ | |
OneInputNode: NewOneInputNode(input), | |
distinctColIdx: distinctColIdx, | |
outputCol: outputCol, | |
}, nil | |
} | |
} | |
return nil, errors.Errorf("unsupported distinct type %s", t) | |
} | |
// partitioner is a simple implementation of sorted distinct that's useful for | |
// other operators that need to partition an arbitrarily-sized Vec. | |
type partitioner interface { | |
// partition partitions the input colVec of size n, writing true to the | |
// outputCol for every value that differs from the previous one. | |
partition(colVec coldata.Vec, outputCol []bool, n int) | |
// partitionWithOrder is like partition, except it performs the partitioning | |
// on the input Vec as if it were ordered via the input order vector, which is | |
// a selection vector. The output is written in absolute order, however. For | |
// example, with an input vector [a,b,b] and an order vector [1,2,0], which | |
// implies a reordered input vector [b,b,a], the resultant outputCol would be | |
// [true, false, true], indicating a distinct value at the 0th and 2nd | |
// elements. | |
partitionWithOrder(colVec coldata.Vec, order []int, outputCol []bool, n int) | |
} | |
// newPartitioner returns a new partitioner on type t. | |
func newPartitioner(t *types.T) (partitioner, error) { | |
switch typeconv.TypeFamilyToCanonicalTypeFamily(t.Family()) { | |
case types.BoolFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return partitionerBool{}, nil | |
} | |
case types.BytesFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return partitionerBytes{}, nil | |
} | |
case types.DecimalFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return partitionerDecimal{}, nil | |
} | |
case types.IntFamily: | |
switch t.Width() { | |
case 16: | |
return partitionerInt16{}, nil | |
case 32: | |
return partitionerInt32{}, nil | |
case -1: | |
default: | |
return partitionerInt64{}, nil | |
} | |
case types.FloatFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return partitionerFloat64{}, nil | |
} | |
case types.TimestampTZFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return partitionerTimestamp{}, nil | |
} | |
case types.IntervalFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return partitionerInterval{}, nil | |
} | |
case typeconv.DatumVecCanonicalTypeFamily: | |
switch t.Width() { | |
case -1: | |
default: | |
return partitionerDatum{}, nil | |
} | |
} | |
return nil, errors.Errorf("unsupported partition type %s", t) | |
} | |
// distinctBoolOp runs a distinct on the column in distinctColIdx, writing | |
// true to the resultant bool column for every value that differs from the | |
// previous one. | |
type distinctBoolOp struct { | |
OneInputNode | |
// distinctColIdx is the index of the column to distinct upon. | |
distinctColIdx int | |
// outputCol is the boolean output column. It is shared by all of the | |
// other distinct operators in a distinct operator set. | |
outputCol []bool | |
// Set to true at runtime when we've seen the first row. Distinct always | |
// outputs the first row that it sees. | |
foundFirstRow bool | |
// lastVal is the last value seen by the operator, so that the distincting | |
// still works across batch boundaries. | |
lastVal bool | |
lastValNull bool | |
} | |
var _ resettableOperator = &distinctBoolOp{} | |
func (p *distinctBoolOp) Init() { | |
p.input.Init() | |
} | |
func (p *distinctBoolOp) reset(ctx context.Context) { | |
p.foundFirstRow = false | |
p.lastValNull = false | |
if resetter, ok := p.input.(resetter); ok { | |
resetter.reset(ctx) | |
} | |
} | |
func (p *distinctBoolOp) Next(ctx context.Context) coldata.Batch { | |
batch := p.input.Next(ctx) | |
if batch.Length() == 0 { | |
return batch | |
} | |
outputCol := p.outputCol | |
vec := batch.ColVec(p.distinctColIdx) | |
var nulls *coldata.Nulls | |
if vec.MaybeHasNulls() { | |
nulls = vec.Nulls() | |
} | |
col := vec.Bool() | |
// We always output the first row. | |
lastVal := p.lastVal | |
lastValNull := p.lastValNull | |
sel := batch.Selection() | |
firstIdx := 0 | |
if sel != nil { | |
firstIdx = sel[0] | |
} | |
if !p.foundFirstRow { | |
outputCol[firstIdx] = true | |
p.foundFirstRow = true | |
} else if nulls == nil && lastValNull { | |
// The last value of the previous batch was null, so the first value of this | |
// non-null batch is distinct. | |
outputCol[firstIdx] = true | |
lastValNull = false | |
} | |
n := batch.Length() | |
if sel != nil { | |
// Bounds check elimination. | |
sel = sel[:n] | |
if nulls != nil { | |
for _, idx := range sel { | |
{ | |
var __retval_lastVal bool | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
if !v && lastVal { | |
cmpResult = -1 | |
} else if v && !lastVal { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for _, idx := range sel { | |
{ | |
var __retval_0 bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
if !v && lastVal { | |
cmpResult = -1 | |
} else if v && !lastVal { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} else { | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
_ = outputCol[n-1] | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal bool | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
if !v && lastVal { | |
cmpResult = -1 | |
} else if v && !lastVal { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
if !v && lastVal { | |
cmpResult = -1 | |
} else if v && !lastVal { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
p.lastVal = lastVal | |
p.lastValNull = lastValNull | |
return batch | |
} | |
// partitionerBool partitions an arbitrary-length colVec by running a distinct | |
// operation over it. It writes the same format to outputCol that sorted | |
// distinct does: true for every row that differs from the previous row in the | |
// input column. | |
type partitionerBool struct{} | |
func (p partitionerBool) partitionWithOrder( | |
colVec coldata.Vec, order []int, outputCol []bool, n int, | |
) { | |
var lastVal bool | |
var lastValNull bool | |
var nulls *coldata.Nulls | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Bool() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_lastVal bool | |
var __retval_lastValNull bool | |
{ | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
if !v && lastVal { | |
cmpResult = -1 | |
} else if v && !lastVal { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_0 bool | |
{ | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
if !v && lastVal { | |
cmpResult = -1 | |
} else if v && !lastVal { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
func (p partitionerBool) partition(colVec coldata.Vec, outputCol []bool, n int) { | |
var ( | |
lastVal bool | |
lastValNull bool | |
nulls *coldata.Nulls | |
) | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Bool() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal bool | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
if !v && lastVal { | |
cmpResult = -1 | |
} else if v && !lastVal { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
if !v && lastVal { | |
cmpResult = -1 | |
} else if v && !lastVal { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
// distinctBytesOp runs a distinct on the column in distinctColIdx, writing | |
// true to the resultant bool column for every value that differs from the | |
// previous one. | |
type distinctBytesOp struct { | |
OneInputNode | |
// distinctColIdx is the index of the column to distinct upon. | |
distinctColIdx int | |
// outputCol is the boolean output column. It is shared by all of the | |
// other distinct operators in a distinct operator set. | |
outputCol []bool | |
// Set to true at runtime when we've seen the first row. Distinct always | |
// outputs the first row that it sees. | |
foundFirstRow bool | |
// lastVal is the last value seen by the operator, so that the distincting | |
// still works across batch boundaries. | |
lastVal []byte | |
lastValNull bool | |
} | |
var _ resettableOperator = &distinctBytesOp{} | |
func (p *distinctBytesOp) Init() { | |
p.input.Init() | |
} | |
func (p *distinctBytesOp) reset(ctx context.Context) { | |
p.foundFirstRow = false | |
p.lastValNull = false | |
if resetter, ok := p.input.(resetter); ok { | |
resetter.reset(ctx) | |
} | |
} | |
func (p *distinctBytesOp) Next(ctx context.Context) coldata.Batch { | |
batch := p.input.Next(ctx) | |
if batch.Length() == 0 { | |
return batch | |
} | |
outputCol := p.outputCol | |
vec := batch.ColVec(p.distinctColIdx) | |
var nulls *coldata.Nulls | |
if vec.MaybeHasNulls() { | |
nulls = vec.Nulls() | |
} | |
col := vec.Bytes() | |
// We always output the first row. | |
lastVal := p.lastVal | |
lastValNull := p.lastValNull | |
sel := batch.Selection() | |
firstIdx := 0 | |
if sel != nil { | |
firstIdx = sel[0] | |
} | |
if !p.foundFirstRow { | |
outputCol[firstIdx] = true | |
p.foundFirstRow = true | |
} else if nulls == nil && lastValNull { | |
// The last value of the previous batch was null, so the first value of this | |
// non-null batch is distinct. | |
outputCol[firstIdx] = true | |
lastValNull = false | |
} | |
n := batch.Length() | |
if sel != nil { | |
// Bounds check elimination. | |
sel = sel[:n] | |
if nulls != nil { | |
for _, idx := range sel { | |
{ | |
var __retval_lastVal []byte | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col.Get(checkIdx) | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = bytes.Compare(v, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = append(lastVal[:0], v...) | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for _, idx := range sel { | |
{ | |
var __retval_0 []byte | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col.Get(checkIdx) | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = bytes.Compare(v, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = append(lastVal[:0], v...) | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} else { | |
col = col | |
_ = 0 | |
_ = n | |
outputCol = outputCol[:n] | |
_ = outputCol[n-1] | |
if nulls != nil { | |
for idx := 0; idx < n; idx++ { | |
{ | |
var __retval_lastVal []byte | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col.Get(checkIdx) | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = bytes.Compare(v, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = append(lastVal[:0], v...) | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := 0; idx < n; idx++ { | |
{ | |
var __retval_0 []byte | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col.Get(checkIdx) | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = bytes.Compare(v, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = append(lastVal[:0], v...) | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
p.lastVal = lastVal | |
p.lastValNull = lastValNull | |
return batch | |
} | |
// partitionerBytes partitions an arbitrary-length colVec by running a distinct | |
// operation over it. It writes the same format to outputCol that sorted | |
// distinct does: true for every row that differs from the previous row in the | |
// input column. | |
type partitionerBytes struct{} | |
func (p partitionerBytes) partitionWithOrder( | |
colVec coldata.Vec, order []int, outputCol []bool, n int, | |
) { | |
var lastVal []byte | |
var lastValNull bool | |
var nulls *coldata.Nulls | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Bytes() | |
col = col | |
_ = 0 | |
_ = n | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_lastVal []byte | |
var __retval_lastValNull bool | |
{ | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col.Get(checkIdx) | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = bytes.Compare(v, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = append(lastVal[:0], v...) | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_0 []byte | |
{ | |
v := col.Get(checkIdx) | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = bytes.Compare(v, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = append(lastVal[:0], v...) | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
func (p partitionerBytes) partition(colVec coldata.Vec, outputCol []bool, n int) { | |
var ( | |
lastVal []byte | |
lastValNull bool | |
nulls *coldata.Nulls | |
) | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Bytes() | |
col = col | |
_ = 0 | |
_ = n | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for idx := 0; idx < n; idx++ { | |
{ | |
var __retval_lastVal []byte | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col.Get(checkIdx) | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = bytes.Compare(v, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = append(lastVal[:0], v...) | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := 0; idx < n; idx++ { | |
{ | |
var __retval_0 []byte | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col.Get(checkIdx) | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = bytes.Compare(v, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = append(lastVal[:0], v...) | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
// distinctDecimalOp runs a distinct on the column in distinctColIdx, writing | |
// true to the resultant bool column for every value that differs from the | |
// previous one. | |
type distinctDecimalOp struct { | |
OneInputNode | |
// distinctColIdx is the index of the column to distinct upon. | |
distinctColIdx int | |
// outputCol is the boolean output column. It is shared by all of the | |
// other distinct operators in a distinct operator set. | |
outputCol []bool | |
// Set to true at runtime when we've seen the first row. Distinct always | |
// outputs the first row that it sees. | |
foundFirstRow bool | |
// lastVal is the last value seen by the operator, so that the distincting | |
// still works across batch boundaries. | |
lastVal apd.Decimal | |
lastValNull bool | |
} | |
var _ resettableOperator = &distinctDecimalOp{} | |
func (p *distinctDecimalOp) Init() { | |
p.input.Init() | |
} | |
func (p *distinctDecimalOp) reset(ctx context.Context) { | |
p.foundFirstRow = false | |
p.lastValNull = false | |
if resetter, ok := p.input.(resetter); ok { | |
resetter.reset(ctx) | |
} | |
} | |
func (p *distinctDecimalOp) Next(ctx context.Context) coldata.Batch { | |
batch := p.input.Next(ctx) | |
if batch.Length() == 0 { | |
return batch | |
} | |
outputCol := p.outputCol | |
vec := batch.ColVec(p.distinctColIdx) | |
var nulls *coldata.Nulls | |
if vec.MaybeHasNulls() { | |
nulls = vec.Nulls() | |
} | |
col := vec.Decimal() | |
// We always output the first row. | |
lastVal := p.lastVal | |
lastValNull := p.lastValNull | |
sel := batch.Selection() | |
firstIdx := 0 | |
if sel != nil { | |
firstIdx = sel[0] | |
} | |
if !p.foundFirstRow { | |
outputCol[firstIdx] = true | |
p.foundFirstRow = true | |
} else if nulls == nil && lastValNull { | |
// The last value of the previous batch was null, so the first value of this | |
// non-null batch is distinct. | |
outputCol[firstIdx] = true | |
lastValNull = false | |
} | |
n := batch.Length() | |
if sel != nil { | |
// Bounds check elimination. | |
sel = sel[:n] | |
if nulls != nil { | |
for _, idx := range sel { | |
{ | |
var __retval_lastVal apd.Decimal | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = tree.CompareDecimals(&v, &lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal.Set(&v) | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for _, idx := range sel { | |
{ | |
var __retval_0 apd.Decimal | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = tree.CompareDecimals(&v, &lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal.Set(&v) | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} else { | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
_ = outputCol[n-1] | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal apd.Decimal | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = tree.CompareDecimals(&v, &lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal.Set(&v) | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 apd.Decimal | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = tree.CompareDecimals(&v, &lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal.Set(&v) | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
p.lastVal = lastVal | |
p.lastValNull = lastValNull | |
return batch | |
} | |
// partitionerDecimal partitions an arbitrary-length colVec by running a distinct | |
// operation over it. It writes the same format to outputCol that sorted | |
// distinct does: true for every row that differs from the previous row in the | |
// input column. | |
type partitionerDecimal struct{} | |
func (p partitionerDecimal) partitionWithOrder( | |
colVec coldata.Vec, order []int, outputCol []bool, n int, | |
) { | |
var lastVal apd.Decimal | |
var lastValNull bool | |
var nulls *coldata.Nulls | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Decimal() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_lastVal apd.Decimal | |
var __retval_lastValNull bool | |
{ | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = tree.CompareDecimals(&v, &lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal.Set(&v) | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_0 apd.Decimal | |
{ | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = tree.CompareDecimals(&v, &lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal.Set(&v) | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
func (p partitionerDecimal) partition(colVec coldata.Vec, outputCol []bool, n int) { | |
var ( | |
lastVal apd.Decimal | |
lastValNull bool | |
nulls *coldata.Nulls | |
) | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Decimal() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal apd.Decimal | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = tree.CompareDecimals(&v, &lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal.Set(&v) | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 apd.Decimal | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = tree.CompareDecimals(&v, &lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal.Set(&v) | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
// distinctInt16Op runs a distinct on the column in distinctColIdx, writing | |
// true to the resultant bool column for every value that differs from the | |
// previous one. | |
type distinctInt16Op struct { | |
OneInputNode | |
// distinctColIdx is the index of the column to distinct upon. | |
distinctColIdx int | |
// outputCol is the boolean output column. It is shared by all of the | |
// other distinct operators in a distinct operator set. | |
outputCol []bool | |
// Set to true at runtime when we've seen the first row. Distinct always | |
// outputs the first row that it sees. | |
foundFirstRow bool | |
// lastVal is the last value seen by the operator, so that the distincting | |
// still works across batch boundaries. | |
lastVal int16 | |
lastValNull bool | |
} | |
var _ resettableOperator = &distinctInt16Op{} | |
func (p *distinctInt16Op) Init() { | |
p.input.Init() | |
} | |
func (p *distinctInt16Op) reset(ctx context.Context) { | |
p.foundFirstRow = false | |
p.lastValNull = false | |
if resetter, ok := p.input.(resetter); ok { | |
resetter.reset(ctx) | |
} | |
} | |
func (p *distinctInt16Op) Next(ctx context.Context) coldata.Batch { | |
batch := p.input.Next(ctx) | |
if batch.Length() == 0 { | |
return batch | |
} | |
outputCol := p.outputCol | |
vec := batch.ColVec(p.distinctColIdx) | |
var nulls *coldata.Nulls | |
if vec.MaybeHasNulls() { | |
nulls = vec.Nulls() | |
} | |
col := vec.Int16() | |
// We always output the first row. | |
lastVal := p.lastVal | |
lastValNull := p.lastValNull | |
sel := batch.Selection() | |
firstIdx := 0 | |
if sel != nil { | |
firstIdx = sel[0] | |
} | |
if !p.foundFirstRow { | |
outputCol[firstIdx] = true | |
p.foundFirstRow = true | |
} else if nulls == nil && lastValNull { | |
// The last value of the previous batch was null, so the first value of this | |
// non-null batch is distinct. | |
outputCol[firstIdx] = true | |
lastValNull = false | |
} | |
n := batch.Length() | |
if sel != nil { | |
// Bounds check elimination. | |
sel = sel[:n] | |
if nulls != nil { | |
for _, idx := range sel { | |
{ | |
var __retval_lastVal int16 | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for _, idx := range sel { | |
{ | |
var __retval_0 int16 | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} else { | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
_ = outputCol[n-1] | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal int16 | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 int16 | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
p.lastVal = lastVal | |
p.lastValNull = lastValNull | |
return batch | |
} | |
// partitionerInt16 partitions an arbitrary-length colVec by running a distinct | |
// operation over it. It writes the same format to outputCol that sorted | |
// distinct does: true for every row that differs from the previous row in the | |
// input column. | |
type partitionerInt16 struct{} | |
func (p partitionerInt16) partitionWithOrder( | |
colVec coldata.Vec, order []int, outputCol []bool, n int, | |
) { | |
var lastVal int16 | |
var lastValNull bool | |
var nulls *coldata.Nulls | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Int16() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_lastVal int16 | |
var __retval_lastValNull bool | |
{ | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_0 int16 | |
{ | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
func (p partitionerInt16) partition(colVec coldata.Vec, outputCol []bool, n int) { | |
var ( | |
lastVal int16 | |
lastValNull bool | |
nulls *coldata.Nulls | |
) | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Int16() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal int16 | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 int16 | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
// distinctInt32Op runs a distinct on the column in distinctColIdx, writing | |
// true to the resultant bool column for every value that differs from the | |
// previous one. | |
type distinctInt32Op struct { | |
OneInputNode | |
// distinctColIdx is the index of the column to distinct upon. | |
distinctColIdx int | |
// outputCol is the boolean output column. It is shared by all of the | |
// other distinct operators in a distinct operator set. | |
outputCol []bool | |
// Set to true at runtime when we've seen the first row. Distinct always | |
// outputs the first row that it sees. | |
foundFirstRow bool | |
// lastVal is the last value seen by the operator, so that the distincting | |
// still works across batch boundaries. | |
lastVal int32 | |
lastValNull bool | |
} | |
var _ resettableOperator = &distinctInt32Op{} | |
func (p *distinctInt32Op) Init() { | |
p.input.Init() | |
} | |
func (p *distinctInt32Op) reset(ctx context.Context) { | |
p.foundFirstRow = false | |
p.lastValNull = false | |
if resetter, ok := p.input.(resetter); ok { | |
resetter.reset(ctx) | |
} | |
} | |
func (p *distinctInt32Op) Next(ctx context.Context) coldata.Batch { | |
batch := p.input.Next(ctx) | |
if batch.Length() == 0 { | |
return batch | |
} | |
outputCol := p.outputCol | |
vec := batch.ColVec(p.distinctColIdx) | |
var nulls *coldata.Nulls | |
if vec.MaybeHasNulls() { | |
nulls = vec.Nulls() | |
} | |
col := vec.Int32() | |
// We always output the first row. | |
lastVal := p.lastVal | |
lastValNull := p.lastValNull | |
sel := batch.Selection() | |
firstIdx := 0 | |
if sel != nil { | |
firstIdx = sel[0] | |
} | |
if !p.foundFirstRow { | |
outputCol[firstIdx] = true | |
p.foundFirstRow = true | |
} else if nulls == nil && lastValNull { | |
// The last value of the previous batch was null, so the first value of this | |
// non-null batch is distinct. | |
outputCol[firstIdx] = true | |
lastValNull = false | |
} | |
n := batch.Length() | |
if sel != nil { | |
// Bounds check elimination. | |
sel = sel[:n] | |
if nulls != nil { | |
for _, idx := range sel { | |
{ | |
var __retval_lastVal int32 | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for _, idx := range sel { | |
{ | |
var __retval_0 int32 | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} else { | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
_ = outputCol[n-1] | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal int32 | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 int32 | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
p.lastVal = lastVal | |
p.lastValNull = lastValNull | |
return batch | |
} | |
// partitionerInt32 partitions an arbitrary-length colVec by running a distinct | |
// operation over it. It writes the same format to outputCol that sorted | |
// distinct does: true for every row that differs from the previous row in the | |
// input column. | |
type partitionerInt32 struct{} | |
func (p partitionerInt32) partitionWithOrder( | |
colVec coldata.Vec, order []int, outputCol []bool, n int, | |
) { | |
var lastVal int32 | |
var lastValNull bool | |
var nulls *coldata.Nulls | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Int32() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_lastVal int32 | |
var __retval_lastValNull bool | |
{ | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_0 int32 | |
{ | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
func (p partitionerInt32) partition(colVec coldata.Vec, outputCol []bool, n int) { | |
var ( | |
lastVal int32 | |
lastValNull bool | |
nulls *coldata.Nulls | |
) | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Int32() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal int32 | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 int32 | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
// distinctInt64Op runs a distinct on the column in distinctColIdx, writing | |
// true to the resultant bool column for every value that differs from the | |
// previous one. | |
type distinctInt64Op struct { | |
OneInputNode | |
// distinctColIdx is the index of the column to distinct upon. | |
distinctColIdx int | |
// outputCol is the boolean output column. It is shared by all of the | |
// other distinct operators in a distinct operator set. | |
outputCol []bool | |
// Set to true at runtime when we've seen the first row. Distinct always | |
// outputs the first row that it sees. | |
foundFirstRow bool | |
// lastVal is the last value seen by the operator, so that the distincting | |
// still works across batch boundaries. | |
lastVal int64 | |
lastValNull bool | |
} | |
var _ resettableOperator = &distinctInt64Op{} | |
func (p *distinctInt64Op) Init() { | |
p.input.Init() | |
} | |
func (p *distinctInt64Op) reset(ctx context.Context) { | |
p.foundFirstRow = false | |
p.lastValNull = false | |
if resetter, ok := p.input.(resetter); ok { | |
resetter.reset(ctx) | |
} | |
} | |
func (p *distinctInt64Op) Next(ctx context.Context) coldata.Batch { | |
batch := p.input.Next(ctx) | |
if batch.Length() == 0 { | |
return batch | |
} | |
outputCol := p.outputCol | |
vec := batch.ColVec(p.distinctColIdx) | |
var nulls *coldata.Nulls | |
if vec.MaybeHasNulls() { | |
nulls = vec.Nulls() | |
} | |
col := vec.Int64() | |
// We always output the first row. | |
lastVal := p.lastVal | |
lastValNull := p.lastValNull | |
sel := batch.Selection() | |
firstIdx := 0 | |
if sel != nil { | |
firstIdx = sel[0] | |
} | |
if !p.foundFirstRow { | |
outputCol[firstIdx] = true | |
p.foundFirstRow = true | |
} else if nulls == nil && lastValNull { | |
// The last value of the previous batch was null, so the first value of this | |
// non-null batch is distinct. | |
outputCol[firstIdx] = true | |
lastValNull = false | |
} | |
n := batch.Length() | |
if sel != nil { | |
// Bounds check elimination. | |
sel = sel[:n] | |
if nulls != nil { | |
for _, idx := range sel { | |
{ | |
var __retval_lastVal int64 | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for _, idx := range sel { | |
{ | |
var __retval_0 int64 | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} else { | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
_ = outputCol[n-1] | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal int64 | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 int64 | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
p.lastVal = lastVal | |
p.lastValNull = lastValNull | |
return batch | |
} | |
// partitionerInt64 partitions an arbitrary-length colVec by running a distinct | |
// operation over it. It writes the same format to outputCol that sorted | |
// distinct does: true for every row that differs from the previous row in the | |
// input column. | |
type partitionerInt64 struct{} | |
func (p partitionerInt64) partitionWithOrder( | |
colVec coldata.Vec, order []int, outputCol []bool, n int, | |
) { | |
var lastVal int64 | |
var lastValNull bool | |
var nulls *coldata.Nulls | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Int64() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_lastVal int64 | |
var __retval_lastValNull bool | |
{ | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_0 int64 | |
{ | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
func (p partitionerInt64) partition(colVec coldata.Vec, outputCol []bool, n int) { | |
var ( | |
lastVal int64 | |
lastValNull bool | |
nulls *coldata.Nulls | |
) | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Int64() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal int64 | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 int64 | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := int64(v), int64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
// distinctFloat64Op runs a distinct on the column in distinctColIdx, writing | |
// true to the resultant bool column for every value that differs from the | |
// previous one. | |
type distinctFloat64Op struct { | |
OneInputNode | |
// distinctColIdx is the index of the column to distinct upon. | |
distinctColIdx int | |
// outputCol is the boolean output column. It is shared by all of the | |
// other distinct operators in a distinct operator set. | |
outputCol []bool | |
// Set to true at runtime when we've seen the first row. Distinct always | |
// outputs the first row that it sees. | |
foundFirstRow bool | |
// lastVal is the last value seen by the operator, so that the distincting | |
// still works across batch boundaries. | |
lastVal float64 | |
lastValNull bool | |
} | |
var _ resettableOperator = &distinctFloat64Op{} | |
func (p *distinctFloat64Op) Init() { | |
p.input.Init() | |
} | |
func (p *distinctFloat64Op) reset(ctx context.Context) { | |
p.foundFirstRow = false | |
p.lastValNull = false | |
if resetter, ok := p.input.(resetter); ok { | |
resetter.reset(ctx) | |
} | |
} | |
func (p *distinctFloat64Op) Next(ctx context.Context) coldata.Batch { | |
batch := p.input.Next(ctx) | |
if batch.Length() == 0 { | |
return batch | |
} | |
outputCol := p.outputCol | |
vec := batch.ColVec(p.distinctColIdx) | |
var nulls *coldata.Nulls | |
if vec.MaybeHasNulls() { | |
nulls = vec.Nulls() | |
} | |
col := vec.Float64() | |
// We always output the first row. | |
lastVal := p.lastVal | |
lastValNull := p.lastValNull | |
sel := batch.Selection() | |
firstIdx := 0 | |
if sel != nil { | |
firstIdx = sel[0] | |
} | |
if !p.foundFirstRow { | |
outputCol[firstIdx] = true | |
p.foundFirstRow = true | |
} else if nulls == nil && lastValNull { | |
// The last value of the previous batch was null, so the first value of this | |
// non-null batch is distinct. | |
outputCol[firstIdx] = true | |
lastValNull = false | |
} | |
n := batch.Length() | |
if sel != nil { | |
// Bounds check elimination. | |
sel = sel[:n] | |
if nulls != nil { | |
for _, idx := range sel { | |
{ | |
var __retval_lastVal float64 | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := float64(v), float64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else if a == b { | |
cmpResult = 0 | |
} else if math.IsNaN(a) { | |
if math.IsNaN(b) { | |
cmpResult = 0 | |
} else { | |
cmpResult = -1 | |
} | |
} else { | |
cmpResult = 1 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for _, idx := range sel { | |
{ | |
var __retval_0 float64 | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := float64(v), float64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else if a == b { | |
cmpResult = 0 | |
} else if math.IsNaN(a) { | |
if math.IsNaN(b) { | |
cmpResult = 0 | |
} else { | |
cmpResult = -1 | |
} | |
} else { | |
cmpResult = 1 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} else { | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
_ = outputCol[n-1] | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal float64 | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := float64(v), float64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else if a == b { | |
cmpResult = 0 | |
} else if math.IsNaN(a) { | |
if math.IsNaN(b) { | |
cmpResult = 0 | |
} else { | |
cmpResult = -1 | |
} | |
} else { | |
cmpResult = 1 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 float64 | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := float64(v), float64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else if a == b { | |
cmpResult = 0 | |
} else if math.IsNaN(a) { | |
if math.IsNaN(b) { | |
cmpResult = 0 | |
} else { | |
cmpResult = -1 | |
} | |
} else { | |
cmpResult = 1 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
p.lastVal = lastVal | |
p.lastValNull = lastValNull | |
return batch | |
} | |
// partitionerFloat64 partitions an arbitrary-length colVec by running a distinct | |
// operation over it. It writes the same format to outputCol that sorted | |
// distinct does: true for every row that differs from the previous row in the | |
// input column. | |
type partitionerFloat64 struct{} | |
func (p partitionerFloat64) partitionWithOrder( | |
colVec coldata.Vec, order []int, outputCol []bool, n int, | |
) { | |
var lastVal float64 | |
var lastValNull bool | |
var nulls *coldata.Nulls | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Float64() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_lastVal float64 | |
var __retval_lastValNull bool | |
{ | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := float64(v), float64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else if a == b { | |
cmpResult = 0 | |
} else if math.IsNaN(a) { | |
if math.IsNaN(b) { | |
cmpResult = 0 | |
} else { | |
cmpResult = -1 | |
} | |
} else { | |
cmpResult = 1 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_0 float64 | |
{ | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := float64(v), float64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else if a == b { | |
cmpResult = 0 | |
} else if math.IsNaN(a) { | |
if math.IsNaN(b) { | |
cmpResult = 0 | |
} else { | |
cmpResult = -1 | |
} | |
} else { | |
cmpResult = 1 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
func (p partitionerFloat64) partition(colVec coldata.Vec, outputCol []bool, n int) { | |
var ( | |
lastVal float64 | |
lastValNull bool | |
nulls *coldata.Nulls | |
) | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Float64() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal float64 | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := float64(v), float64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else if a == b { | |
cmpResult = 0 | |
} else if math.IsNaN(a) { | |
if math.IsNaN(b) { | |
cmpResult = 0 | |
} else { | |
cmpResult = -1 | |
} | |
} else { | |
cmpResult = 1 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 float64 | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
{ | |
a, b := float64(v), float64(lastVal) | |
if a < b { | |
cmpResult = -1 | |
} else if a > b { | |
cmpResult = 1 | |
} else if a == b { | |
cmpResult = 0 | |
} else if math.IsNaN(a) { | |
if math.IsNaN(b) { | |
cmpResult = 0 | |
} else { | |
cmpResult = -1 | |
} | |
} else { | |
cmpResult = 1 | |
} | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
// distinctTimestampOp runs a distinct on the column in distinctColIdx, writing | |
// true to the resultant bool column for every value that differs from the | |
// previous one. | |
type distinctTimestampOp struct { | |
OneInputNode | |
// distinctColIdx is the index of the column to distinct upon. | |
distinctColIdx int | |
// outputCol is the boolean output column. It is shared by all of the | |
// other distinct operators in a distinct operator set. | |
outputCol []bool | |
// Set to true at runtime when we've seen the first row. Distinct always | |
// outputs the first row that it sees. | |
foundFirstRow bool | |
// lastVal is the last value seen by the operator, so that the distincting | |
// still works across batch boundaries. | |
lastVal time.Time | |
lastValNull bool | |
} | |
var _ resettableOperator = &distinctTimestampOp{} | |
func (p *distinctTimestampOp) Init() { | |
p.input.Init() | |
} | |
func (p *distinctTimestampOp) reset(ctx context.Context) { | |
p.foundFirstRow = false | |
p.lastValNull = false | |
if resetter, ok := p.input.(resetter); ok { | |
resetter.reset(ctx) | |
} | |
} | |
func (p *distinctTimestampOp) Next(ctx context.Context) coldata.Batch { | |
batch := p.input.Next(ctx) | |
if batch.Length() == 0 { | |
return batch | |
} | |
outputCol := p.outputCol | |
vec := batch.ColVec(p.distinctColIdx) | |
var nulls *coldata.Nulls | |
if vec.MaybeHasNulls() { | |
nulls = vec.Nulls() | |
} | |
col := vec.Timestamp() | |
// We always output the first row. | |
lastVal := p.lastVal | |
lastValNull := p.lastValNull | |
sel := batch.Selection() | |
firstIdx := 0 | |
if sel != nil { | |
firstIdx = sel[0] | |
} | |
if !p.foundFirstRow { | |
outputCol[firstIdx] = true | |
p.foundFirstRow = true | |
} else if nulls == nil && lastValNull { | |
// The last value of the previous batch was null, so the first value of this | |
// non-null batch is distinct. | |
outputCol[firstIdx] = true | |
lastValNull = false | |
} | |
n := batch.Length() | |
if sel != nil { | |
// Bounds check elimination. | |
sel = sel[:n] | |
if nulls != nil { | |
for _, idx := range sel { | |
{ | |
var __retval_lastVal time.Time | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
if v.Before(lastVal) { | |
cmpResult = -1 | |
} else if lastVal.Before(v) { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for _, idx := range sel { | |
{ | |
var __retval_0 time.Time | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
if v.Before(lastVal) { | |
cmpResult = -1 | |
} else if lastVal.Before(v) { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} else { | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
_ = outputCol[n-1] | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal time.Time | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
if v.Before(lastVal) { | |
cmpResult = -1 | |
} else if lastVal.Before(v) { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 time.Time | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
if v.Before(lastVal) { | |
cmpResult = -1 | |
} else if lastVal.Before(v) { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
p.lastVal = lastVal | |
p.lastValNull = lastValNull | |
return batch | |
} | |
// partitionerTimestamp partitions an arbitrary-length colVec by running a distinct | |
// operation over it. It writes the same format to outputCol that sorted | |
// distinct does: true for every row that differs from the previous row in the | |
// input column. | |
type partitionerTimestamp struct{} | |
func (p partitionerTimestamp) partitionWithOrder( | |
colVec coldata.Vec, order []int, outputCol []bool, n int, | |
) { | |
var lastVal time.Time | |
var lastValNull bool | |
var nulls *coldata.Nulls | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Timestamp() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_lastVal time.Time | |
var __retval_lastValNull bool | |
{ | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
if v.Before(lastVal) { | |
cmpResult = -1 | |
} else if lastVal.Before(v) { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_0 time.Time | |
{ | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
if v.Before(lastVal) { | |
cmpResult = -1 | |
} else if lastVal.Before(v) { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
func (p partitionerTimestamp) partition(colVec coldata.Vec, outputCol []bool, n int) { | |
var ( | |
lastVal time.Time | |
lastValNull bool | |
nulls *coldata.Nulls | |
) | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Timestamp() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal time.Time | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
if v.Before(lastVal) { | |
cmpResult = -1 | |
} else if lastVal.Before(v) { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 time.Time | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
if v.Before(lastVal) { | |
cmpResult = -1 | |
} else if lastVal.Before(v) { | |
cmpResult = 1 | |
} else { | |
cmpResult = 0 | |
} | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
// distinctIntervalOp runs a distinct on the column in distinctColIdx, writing | |
// true to the resultant bool column for every value that differs from the | |
// previous one. | |
type distinctIntervalOp struct { | |
OneInputNode | |
// distinctColIdx is the index of the column to distinct upon. | |
distinctColIdx int | |
// outputCol is the boolean output column. It is shared by all of the | |
// other distinct operators in a distinct operator set. | |
outputCol []bool | |
// Set to true at runtime when we've seen the first row. Distinct always | |
// outputs the first row that it sees. | |
foundFirstRow bool | |
// lastVal is the last value seen by the operator, so that the distincting | |
// still works across batch boundaries. | |
lastVal duration.Duration | |
lastValNull bool | |
} | |
var _ resettableOperator = &distinctIntervalOp{} | |
func (p *distinctIntervalOp) Init() { | |
p.input.Init() | |
} | |
func (p *distinctIntervalOp) reset(ctx context.Context) { | |
p.foundFirstRow = false | |
p.lastValNull = false | |
if resetter, ok := p.input.(resetter); ok { | |
resetter.reset(ctx) | |
} | |
} | |
func (p *distinctIntervalOp) Next(ctx context.Context) coldata.Batch { | |
batch := p.input.Next(ctx) | |
if batch.Length() == 0 { | |
return batch | |
} | |
outputCol := p.outputCol | |
vec := batch.ColVec(p.distinctColIdx) | |
var nulls *coldata.Nulls | |
if vec.MaybeHasNulls() { | |
nulls = vec.Nulls() | |
} | |
col := vec.Interval() | |
// We always output the first row. | |
lastVal := p.lastVal | |
lastValNull := p.lastValNull | |
sel := batch.Selection() | |
firstIdx := 0 | |
if sel != nil { | |
firstIdx = sel[0] | |
} | |
if !p.foundFirstRow { | |
outputCol[firstIdx] = true | |
p.foundFirstRow = true | |
} else if nulls == nil && lastValNull { | |
// The last value of the previous batch was null, so the first value of this | |
// non-null batch is distinct. | |
outputCol[firstIdx] = true | |
lastValNull = false | |
} | |
n := batch.Length() | |
if sel != nil { | |
// Bounds check elimination. | |
sel = sel[:n] | |
if nulls != nil { | |
for _, idx := range sel { | |
{ | |
var __retval_lastVal duration.Duration | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.Compare(lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for _, idx := range sel { | |
{ | |
var __retval_0 duration.Duration | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.Compare(lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} else { | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
_ = outputCol[n-1] | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal duration.Duration | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.Compare(lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 duration.Duration | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.Compare(lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
p.lastVal = lastVal | |
p.lastValNull = lastValNull | |
return batch | |
} | |
// partitionerInterval partitions an arbitrary-length colVec by running a distinct | |
// operation over it. It writes the same format to outputCol that sorted | |
// distinct does: true for every row that differs from the previous row in the | |
// input column. | |
type partitionerInterval struct{} | |
func (p partitionerInterval) partitionWithOrder( | |
colVec coldata.Vec, order []int, outputCol []bool, n int, | |
) { | |
var lastVal duration.Duration | |
var lastValNull bool | |
var nulls *coldata.Nulls | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Interval() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_lastVal duration.Duration | |
var __retval_lastValNull bool | |
{ | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.Compare(lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_0 duration.Duration | |
{ | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.Compare(lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
func (p partitionerInterval) partition(colVec coldata.Vec, outputCol []bool, n int) { | |
var ( | |
lastVal duration.Duration | |
lastValNull bool | |
nulls *coldata.Nulls | |
) | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Interval() | |
col = col[0:n] | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for idx := range col { | |
{ | |
var __retval_lastVal duration.Duration | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col[checkIdx] | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.Compare(lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := range col { | |
{ | |
var __retval_0 duration.Duration | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col[checkIdx] | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.Compare(lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
// distinctDatumOp runs a distinct on the column in distinctColIdx, writing | |
// true to the resultant bool column for every value that differs from the | |
// previous one. | |
type distinctDatumOp struct { | |
OneInputNode | |
// distinctColIdx is the index of the column to distinct upon. | |
distinctColIdx int | |
// outputCol is the boolean output column. It is shared by all of the | |
// other distinct operators in a distinct operator set. | |
outputCol []bool | |
// Set to true at runtime when we've seen the first row. Distinct always | |
// outputs the first row that it sees. | |
foundFirstRow bool | |
// lastVal is the last value seen by the operator, so that the distincting | |
// still works across batch boundaries. | |
lastVal interface{} | |
lastValNull bool | |
} | |
var _ resettableOperator = &distinctDatumOp{} | |
func (p *distinctDatumOp) Init() { | |
p.input.Init() | |
} | |
func (p *distinctDatumOp) reset(ctx context.Context) { | |
p.foundFirstRow = false | |
p.lastValNull = false | |
if resetter, ok := p.input.(resetter); ok { | |
resetter.reset(ctx) | |
} | |
} | |
func (p *distinctDatumOp) Next(ctx context.Context) coldata.Batch { | |
batch := p.input.Next(ctx) | |
if batch.Length() == 0 { | |
return batch | |
} | |
outputCol := p.outputCol | |
vec := batch.ColVec(p.distinctColIdx) | |
var nulls *coldata.Nulls | |
if vec.MaybeHasNulls() { | |
nulls = vec.Nulls() | |
} | |
col := vec.Datum() | |
// We always output the first row. | |
lastVal := p.lastVal | |
lastValNull := p.lastValNull | |
sel := batch.Selection() | |
firstIdx := 0 | |
if sel != nil { | |
firstIdx = sel[0] | |
} | |
if !p.foundFirstRow { | |
outputCol[firstIdx] = true | |
p.foundFirstRow = true | |
} else if nulls == nil && lastValNull { | |
// The last value of the previous batch was null, so the first value of this | |
// non-null batch is distinct. | |
outputCol[firstIdx] = true | |
lastValNull = false | |
} | |
n := batch.Length() | |
if sel != nil { | |
// Bounds check elimination. | |
sel = sel[:n] | |
if nulls != nil { | |
for _, idx := range sel { | |
{ | |
var __retval_lastVal interface{} | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col.Get(checkIdx) | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.(*coldataext.Datum).CompareDatum(col, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for _, idx := range sel { | |
{ | |
var __retval_0 interface{} | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col.Get(checkIdx) | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.(*coldataext.Datum).CompareDatum(col, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} else { | |
col = col.Slice(0, n) | |
outputCol = outputCol[:n] | |
_ = outputCol[n-1] | |
if nulls != nil { | |
for idx := 0; idx < n; idx++ { | |
{ | |
var __retval_lastVal interface{} | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col.Get(checkIdx) | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.(*coldataext.Datum).CompareDatum(col, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := 0; idx < n; idx++ { | |
{ | |
var __retval_0 interface{} | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col.Get(checkIdx) | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.(*coldataext.Datum).CompareDatum(col, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
p.lastVal = lastVal | |
p.lastValNull = lastValNull | |
return batch | |
} | |
// partitionerDatum partitions an arbitrary-length colVec by running a distinct | |
// operation over it. It writes the same format to outputCol that sorted | |
// distinct does: true for every row that differs from the previous row in the | |
// input column. | |
type partitionerDatum struct{} | |
func (p partitionerDatum) partitionWithOrder( | |
colVec coldata.Vec, order []int, outputCol []bool, n int, | |
) { | |
var lastVal interface{} | |
var lastValNull bool | |
var nulls *coldata.Nulls | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Datum() | |
col = col.Slice(0, n) | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_lastVal interface{} | |
var __retval_lastValNull bool | |
{ | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col.Get(checkIdx) | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.(*coldataext.Datum).CompareDatum(col, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for outputIdx, checkIdx := range order { | |
{ | |
var __retval_0 interface{} | |
{ | |
v := col.Get(checkIdx) | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.(*coldataext.Datum).CompareDatum(col, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
func (p partitionerDatum) partition(colVec coldata.Vec, outputCol []bool, n int) { | |
var ( | |
lastVal interface{} | |
lastValNull bool | |
nulls *coldata.Nulls | |
) | |
if colVec.MaybeHasNulls() { | |
nulls = colVec.Nulls() | |
} | |
col := colVec.Datum() | |
col = col.Slice(0, n) | |
outputCol = outputCol[:n] | |
outputCol[0] = true | |
if nulls != nil { | |
for idx := 0; idx < n; idx++ { | |
{ | |
var __retval_lastVal interface{} | |
var __retval_lastValNull bool | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
null := nulls.NullAt(checkIdx) | |
if null { | |
if !lastValNull { | |
// The current value is null while the previous was not. | |
outputCol[outputIdx] = true | |
} | |
} else { | |
v := col.Get(checkIdx) | |
if lastValNull { | |
// The previous value was null while the current is not. | |
outputCol[outputIdx] = true | |
} else { | |
// Neither value is null, so we must compare. | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.(*coldataext.Datum).CompareDatum(col, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
} | |
lastVal = v | |
} | |
{ | |
__retval_lastVal = lastVal | |
__retval_lastValNull = null | |
} | |
} | |
lastVal, lastValNull = __retval_lastVal, __retval_lastValNull | |
} | |
} | |
} else { | |
for idx := 0; idx < n; idx++ { | |
{ | |
var __retval_0 interface{} | |
{ | |
checkIdx := idx | |
outputIdx := idx | |
v := col.Get(checkIdx) | |
var unique bool | |
{ | |
var cmpResult int | |
cmpResult = v.(*coldataext.Datum).CompareDatum(col, lastVal) | |
unique = cmpResult != 0 | |
} | |
outputCol[outputIdx] = outputCol[outputIdx] || unique | |
lastVal = v | |
{ | |
__retval_0 = lastVal | |
} | |
} | |
lastVal = __retval_0 | |
} | |
} | |
} | |
} | |
// checkDistinct retrieves the value at the ith index of col, compares it | |
// to the passed in lastVal, and sets the ith value of outputCol to true if the | |
// compared values were distinct. It presumes that the current batch has no null | |
// values. | |
// execgen:inline | |
const _ = "inlined" | |
// checkDistinctWithNulls behaves the same as checkDistinct, but it also | |
// considers whether the previous and current values are null. It assumes that | |
// `nulls` is non-nil. | |
// execgen:inline | |
const _ = "inlined" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment