diff --git a/pkg/sql/colexec/colexechash/hashtable.go b/pkg/sql/colexec/colexechash/hashtable.go index 16c590e0a592..9c24aba1a91a 100644 --- a/pkg/sql/colexec/colexechash/hashtable.go +++ b/pkg/sql/colexec/colexechash/hashtable.go @@ -518,6 +518,7 @@ func (ht *HashTable) checkCols(probeVecs []coldata.Vec, nToCheck uint64, probeSe // checkColsForDistinctTuples performs a column by column check to find distinct // tuples in the probe table that are not present in the build table. +// NOTE: It assumes that probeSel has already been populated and it is not nil. func (ht *HashTable) checkColsForDistinctTuples( probeVecs []coldata.Vec, nToCheck uint64, probeSel []int, ) { diff --git a/pkg/sql/colexec/colexechash/hashtable_distinct.eg.go b/pkg/sql/colexec/colexechash/hashtable_distinct.eg.go index 195a5b2cdde1..a32cd23e2cf5 100644 --- a/pkg/sql/colexec/colexechash/hashtable_distinct.eg.go +++ b/pkg/sql/colexec/colexechash/hashtable_distinct.eg.go @@ -30,9 +30,10 @@ var ( _ tree.AggType ) -// checkColAgainstItself is similar to checkCol, but it probes the vector -// against itself. -func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel []int) { +// checkColAgainstItselfForDistinct is similar to checkCol, but it probes the +// vector against itself for the purposes of finding matches to unordered +// distinct columns. +func (ht *HashTable) checkColAgainstItselfForDistinct(vec coldata.Vec, nToCheck uint64, sel []int) { probeVec, buildVec, probeSel := vec, vec, sel switch probeVec.CanonicalTypeFamily() { case types.BoolFamily: @@ -56,58 +57,55 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - if !probeVal && buildVal { - cmpResult = -1 - } else if probeVal && !buildVal { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + var cmpResult int - unique = cmpResult != 0 + if !probeVal && buildVal { + cmpResult = -1 + } else if probeVal && !buildVal { + cmpResult = 1 + } else { + cmpResult = 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -118,57 +116,54 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - if !probeVal && buildVal { - cmpResult = -1 - } else if probeVal && !buildVal { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + var cmpResult int - unique = cmpResult != 0 + if !probeVal && buildVal { + cmpResult = -1 + } else if probeVal && !buildVal { + cmpResult = 1 + } else { + cmpResult = 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -181,57 +176,54 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - if !probeVal && buildVal { - cmpResult = -1 - } else if probeVal && !buildVal { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + var cmpResult int - unique = cmpResult != 0 + if !probeVal && buildVal { + cmpResult = -1 + } else if probeVal && !buildVal { + cmpResult = 1 + } else { + cmpResult = 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -242,56 +234,53 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - if !probeVal && buildVal { - cmpResult = -1 - } else if probeVal && !buildVal { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + var cmpResult int - unique = cmpResult != 0 + if !probeVal && buildVal { + cmpResult = -1 + } else if probeVal && !buildVal { + cmpResult = 1 + } else { + cmpResult = 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -306,56 +295,53 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - if !probeVal && buildVal { - cmpResult = -1 - } else if probeVal && !buildVal { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + var cmpResult int - unique = cmpResult != 0 + if !probeVal && buildVal { + cmpResult = -1 + } else if probeVal && !buildVal { + cmpResult = 1 + } else { + cmpResult = 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -366,55 +352,52 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - if !probeVal && buildVal { - cmpResult = -1 - } else if probeVal && !buildVal { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + var cmpResult int - unique = cmpResult != 0 + if !probeVal && buildVal { + cmpResult = -1 + } else if probeVal && !buildVal { + cmpResult = 1 + } else { + cmpResult = 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -427,55 +410,52 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - if !probeVal && buildVal { - cmpResult = -1 - } else if probeVal && !buildVal { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + var cmpResult int - unique = cmpResult != 0 + if !probeVal && buildVal { + cmpResult = -1 + } else if probeVal && !buildVal { + cmpResult = 1 + } else { + cmpResult = 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -486,54 +466,51 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - if !probeVal && buildVal { - cmpResult = -1 - } else if probeVal && !buildVal { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + var cmpResult int - unique = cmpResult != 0 + if !probeVal && buildVal { + cmpResult = -1 + } else if probeVal && !buildVal { + cmpResult = 1 + } else { + cmpResult = 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -563,50 +540,47 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 - } + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = bytes.Compare(probeVal, buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -617,49 +591,46 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 - } + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = bytes.Compare(probeVal, buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -672,49 +643,46 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 - } + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = bytes.Compare(probeVal, buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -725,48 +693,45 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 - } + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = bytes.Compare(probeVal, buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -781,48 +746,45 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 - } + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = bytes.Compare(probeVal, buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -833,47 +795,44 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 - } + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = bytes.Compare(probeVal, buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -886,47 +845,44 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 - } + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = bytes.Compare(probeVal, buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -937,46 +893,43 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 - } + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = bytes.Compare(probeVal, buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -1006,50 +959,47 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = tree.CompareDecimals(&probeVal, &buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -1060,49 +1010,46 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = tree.CompareDecimals(&probeVal, &buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -1115,49 +1062,46 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = tree.CompareDecimals(&probeVal, &buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -1168,48 +1112,45 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = tree.CompareDecimals(&probeVal, &buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -1224,48 +1165,45 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = tree.CompareDecimals(&probeVal, &buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -1276,47 +1214,44 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = tree.CompareDecimals(&probeVal, &buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -1329,47 +1264,44 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = tree.CompareDecimals(&probeVal, &buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -1380,46 +1312,43 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = tree.CompareDecimals(&probeVal, &buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -1447,61 +1376,58 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -1512,60 +1438,57 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -1578,60 +1501,57 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -1642,59 +1562,56 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -1709,59 +1626,56 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -1772,58 +1686,55 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -1836,58 +1747,55 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -1898,57 +1806,54 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -1973,61 +1878,58 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -2038,60 +1940,57 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -2104,60 +2003,57 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -2168,59 +2064,56 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -2235,59 +2128,56 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -2298,58 +2188,55 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -2362,58 +2249,55 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -2424,57 +2308,54 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -2501,61 +2382,58 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -2566,60 +2444,57 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -2632,60 +2507,57 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -2696,59 +2568,56 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -2763,59 +2632,56 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -2826,58 +2692,55 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -2890,58 +2753,55 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -2952,57 +2812,54 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -3032,69 +2889,66 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := float64(probeVal), float64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else if a == b { + { + a, b := float64(probeVal), float64(buildVal) + 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 if math.IsNaN(a) { - if math.IsNaN(b) { - cmpResult = 0 - } else { - cmpResult = -1 - } } else { - cmpResult = 1 + cmpResult = -1 } + } else { + cmpResult = 1 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -3105,68 +2959,65 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := float64(probeVal), float64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else if a == b { + { + a, b := float64(probeVal), float64(buildVal) + 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 if math.IsNaN(a) { - if math.IsNaN(b) { - cmpResult = 0 - } else { - cmpResult = -1 - } } else { - cmpResult = 1 + cmpResult = -1 } + } else { + cmpResult = 1 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -3179,68 +3030,65 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := float64(probeVal), float64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else if a == b { + { + a, b := float64(probeVal), float64(buildVal) + 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 if math.IsNaN(a) { - if math.IsNaN(b) { - cmpResult = 0 - } else { - cmpResult = -1 - } } else { - cmpResult = 1 + cmpResult = -1 } + } else { + cmpResult = 1 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -3251,67 +3099,64 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := float64(probeVal), float64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else if a == b { + { + a, b := float64(probeVal), float64(buildVal) + 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 if math.IsNaN(a) { - if math.IsNaN(b) { - cmpResult = 0 - } else { - cmpResult = -1 - } } else { - cmpResult = 1 + cmpResult = -1 } + } else { + cmpResult = 1 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -3326,67 +3171,64 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := float64(probeVal), float64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else if a == b { + { + a, b := float64(probeVal), float64(buildVal) + 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 if math.IsNaN(a) { - if math.IsNaN(b) { - cmpResult = 0 - } else { - cmpResult = -1 - } } else { - cmpResult = 1 + cmpResult = -1 } + } else { + cmpResult = 1 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -3397,66 +3239,63 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := float64(probeVal), float64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else if a == b { + { + a, b := float64(probeVal), float64(buildVal) + 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 if math.IsNaN(a) { - if math.IsNaN(b) { - cmpResult = 0 - } else { - cmpResult = -1 - } } else { - cmpResult = 1 + cmpResult = -1 } + } else { + cmpResult = 1 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -3469,66 +3308,63 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := float64(probeVal), float64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else if a == b { + { + a, b := float64(probeVal), float64(buildVal) + 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 if math.IsNaN(a) { - if math.IsNaN(b) { - cmpResult = 0 - } else { - cmpResult = -1 - } } else { - cmpResult = 1 + cmpResult = -1 } + } else { + cmpResult = 1 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -3539,65 +3375,62 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - { - a, b := float64(probeVal), float64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else if a == b { + { + a, b := float64(probeVal), float64(buildVal) + 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 if math.IsNaN(a) { - if math.IsNaN(b) { - cmpResult = 0 - } else { - cmpResult = -1 - } } else { - cmpResult = 1 + cmpResult = -1 } + } else { + cmpResult = 1 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -3627,57 +3460,54 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 + if probeVal.Before(buildVal) { + cmpResult = -1 + } else if buildVal.Before(probeVal) { + cmpResult = 1 + } else { + cmpResult = 0 } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -3688,56 +3518,53 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 + if probeVal.Before(buildVal) { + cmpResult = -1 + } else if buildVal.Before(probeVal) { + cmpResult = 1 + } else { + cmpResult = 0 } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -3750,56 +3577,53 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 + if probeVal.Before(buildVal) { + cmpResult = -1 + } else if buildVal.Before(probeVal) { + cmpResult = 1 + } else { + cmpResult = 0 } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -3810,55 +3634,52 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 + if probeVal.Before(buildVal) { + cmpResult = -1 + } else if buildVal.Before(probeVal) { + cmpResult = 1 + } else { + cmpResult = 0 } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -3873,55 +3694,52 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 + if probeVal.Before(buildVal) { + cmpResult = -1 + } else if buildVal.Before(probeVal) { + cmpResult = 1 + } else { + cmpResult = 0 } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -3932,54 +3750,51 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 + if probeVal.Before(buildVal) { + cmpResult = -1 + } else if buildVal.Before(probeVal) { + cmpResult = 1 + } else { + cmpResult = 0 } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -3992,54 +3807,51 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 + if probeVal.Before(buildVal) { + cmpResult = -1 + } else if buildVal.Before(probeVal) { + cmpResult = 1 + } else { + cmpResult = 0 } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -4050,53 +3862,50 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 + if probeVal.Before(buildVal) { + cmpResult = -1 + } else if buildVal.Before(probeVal) { + cmpResult = 1 + } else { + cmpResult = 0 } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -4126,50 +3935,47 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = probeVal.Compare(buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -4180,49 +3986,46 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = probeVal.Compare(buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -4235,49 +4038,46 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = probeVal.Compare(buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -4288,48 +4088,45 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = probeVal.Compare(buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -4344,48 +4141,45 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = probeVal.Compare(buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -4396,47 +4190,44 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = probeVal.Compare(buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -4449,47 +4240,44 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = probeVal.Compare(buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -4500,46 +4288,43 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = probeVal.Compare(buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -4569,56 +4354,53 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } + { + var cmpResult int - unique = cmpResult != 0 + var err error + cmpResult, err = probeVal.Compare(buildVal) + if err != nil { + colexecerror.ExpectedError(err) } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -4629,55 +4411,52 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } + { + var cmpResult int - unique = cmpResult != 0 + var err error + cmpResult, err = probeVal.Compare(buildVal) + if err != nil { + colexecerror.ExpectedError(err) } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -4690,55 +4469,52 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } + { + var cmpResult int - unique = cmpResult != 0 + var err error + cmpResult, err = probeVal.Compare(buildVal) + if err != nil { + colexecerror.ExpectedError(err) } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -4749,54 +4525,51 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } + { + var cmpResult int - unique = cmpResult != 0 + var err error + cmpResult, err = probeVal.Compare(buildVal) + if err != nil { + colexecerror.ExpectedError(err) } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -4811,54 +4584,51 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } + { + var cmpResult int - unique = cmpResult != 0 + var err error + cmpResult, err = probeVal.Compare(buildVal) + if err != nil { + colexecerror.ExpectedError(err) } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -4869,53 +4639,50 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } + { + var cmpResult int - unique = cmpResult != 0 + var err error + cmpResult, err = probeVal.Compare(buildVal) + if err != nil { + colexecerror.ExpectedError(err) } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -4928,53 +4695,50 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } + { + var cmpResult int - unique = cmpResult != 0 + var err error + cmpResult, err = probeVal.Compare(buildVal) + if err != nil { + colexecerror.ExpectedError(err) } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -4985,52 +4749,49 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } + { + var cmpResult int - unique = cmpResult != 0 + var err error + cmpResult, err = probeVal.Compare(buildVal) + if err != nil { + colexecerror.ExpectedError(err) } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -5060,52 +4821,49 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 - } + cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -5116,51 +4874,48 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 - } + cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -5173,51 +4928,48 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 - } + cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -5228,50 +4980,47 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - // The vector is probed against itself, so buildVec has the same - // selection vector as probeVec. - buildIdx = probeSel[keyID-1] - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = probeSel[toCheck] + // The vector is probed against itself, so buildVec has the same + // selection vector as probeVec. + buildIdx = probeSel[keyID-1] + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 - } + cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -5286,50 +5035,47 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 - } + cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -5340,49 +5086,46 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = int(toCheck) + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 - } + cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -5395,49 +5138,46 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 - } + cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } else { @@ -5448,48 +5188,45 @@ func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. - { - var cmpResult int + probeIdx = int(toCheck) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 - } + cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } } } @@ -5516,982 +5253,1536 @@ func (ht *HashTable) checkColForDistinctTuples( default: probeKeys := probeVec.Bool() buildKeys := buildVec.Bool() - if probeSel != nil { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int + if probeVec.MaybeHasNulls() { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - if !probeVal && buildVal { - cmpResult = -1 - } else if probeVal && !buildVal { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + var cmpResult int - unique = cmpResult != 0 + if !probeVal && buildVal { + cmpResult = -1 + } else if probeVal && !buildVal { + cmpResult = 1 + } else { + cmpResult = 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int + + if !probeVal && buildVal { + cmpResult = -1 + } else if probeVal && !buildVal { + cmpResult = 1 + } else { + cmpResult = 0 } + + unique = cmpResult != 0 } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - { - var cmpResult int + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + } + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } + } else { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - if !probeVal && buildVal { - cmpResult = -1 - } else if probeVal && !buildVal { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + var cmpResult int - unique = cmpResult != 0 + if !probeVal && buildVal { + cmpResult = -1 + } else if probeVal && !buildVal { + cmpResult = 1 + } else { + cmpResult = 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - if !probeVal && buildVal { - cmpResult = -1 - } else if probeVal && !buildVal { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + var cmpResult int - unique = cmpResult != 0 + if !probeVal && buildVal { + cmpResult = -1 + } else if probeVal && !buildVal { + cmpResult = 1 + } else { + cmpResult = 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int + } + } + } + } + } + } + case types.BytesFamily: + switch probeVec.Type().Width() { + case -1: + default: + switch probeVec.CanonicalTypeFamily() { + case types.BytesFamily: + switch probeVec.Type().Width() { + case -1: + default: + probeKeys := probeVec.Bytes() + buildKeys := buildVec.Bytes() + if probeVec.MaybeHasNulls() { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - if !probeVal && buildVal { - cmpResult = -1 - } else if probeVal && !buildVal { - cmpResult = 1 - } else { - cmpResult = 0 - } + { + var cmpResult int + cmpResult = bytes.Compare(probeVal, buildVal) + unique = cmpResult != 0 + } - unique = cmpResult != 0 - } + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + } + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int + cmpResult = bytes.Compare(probeVal, buildVal) + unique = cmpResult != 0 + } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + } + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } + } else { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = bytes.Compare(probeVal, buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int + cmpResult = bytes.Compare(probeVal, buildVal) + unique = cmpResult != 0 + } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } } + } + } + } + } + case types.DecimalFamily: + switch probeVec.Type().Width() { + case -1: + default: + switch probeVec.CanonicalTypeFamily() { + case types.IntFamily: + switch probeVec.Type().Width() { + } + case types.FloatFamily: + switch probeVec.Type().Width() { + } + case types.DecimalFamily: + switch probeVec.Type().Width() { + case -1: + default: + probeKeys := probeVec.Decimal() + buildKeys := buildVec.Decimal() + if probeVec.MaybeHasNulls() { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int + cmpResult = tree.CompareDecimals(&probeVal, &buildVal) + unique = cmpResult != 0 + } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + } + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int + cmpResult = tree.CompareDecimals(&probeVal, &buildVal) + unique = cmpResult != 0 + } + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + } + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } } else { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int + cmpResult = tree.CompareDecimals(&probeVal, &buildVal) + unique = cmpResult != 0 } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - { - var cmpResult int + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + } + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int + cmpResult = tree.CompareDecimals(&probeVal, &buildVal) + unique = cmpResult != 0 + } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + } + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } + } + } + } + } + case types.IntFamily: + switch probeVec.Type().Width() { + case 16: + switch probeVec.CanonicalTypeFamily() { + case types.IntFamily: + switch probeVec.Type().Width() { + case 16: + probeKeys := probeVec.Int16() + buildKeys := buildVec.Int16() + if probeVec.MaybeHasNulls() { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int - if !probeVal && buildVal { + { + a, b := int64(probeVal), int64(buildVal) + if a < b { cmpResult = -1 - } else if probeVal && !buildVal { + } else if a > b { cmpResult = 1 } else { cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - if !probeVal && buildVal { + { + a, b := int64(probeVal), int64(buildVal) + if a < b { cmpResult = -1 - } else if probeVal && !buildVal { + } else if a > b { cmpResult = 1 } else { cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + } + } else { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - if !probeVal && buildVal { + { + a, b := int64(probeVal), int64(buildVal) + if a < b { cmpResult = -1 - } else if probeVal && !buildVal { + } else if a > b { cmpResult = 1 } else { cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - { - var cmpResult int + { + var cmpResult int - if !probeVal && buildVal { + { + a, b := int64(probeVal), int64(buildVal) + if a < b { cmpResult = -1 - } else if probeVal && !buildVal { + } else if a > b { cmpResult = 1 } else { cmpResult = 0 } - - unique = cmpResult != 0 } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } } - } } + case types.FloatFamily: + switch probeVec.Type().Width() { + } + case types.DecimalFamily: + switch probeVec.Type().Width() { + } } - } - case types.BytesFamily: - switch probeVec.Type().Width() { - case -1: - default: + case 32: switch probeVec.CanonicalTypeFamily() { - case types.BytesFamily: + case types.IntFamily: switch probeVec.Type().Width() { - case -1: - default: - probeKeys := probeVec.Bytes() - buildKeys := buildVec.Bytes() - if probeSel != nil { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + case 32: + probeKeys := probeVec.Int32() + buildKeys := buildVec.Int32() + if probeVec.MaybeHasNulls() { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 + } } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 + } } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + } + } else { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 + } } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 + } } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } } + } + } + case types.FloatFamily: + switch probeVec.Type().Width() { + } + case types.DecimalFamily: + switch probeVec.Type().Width() { + } + } + case -1: + default: + switch probeVec.CanonicalTypeFamily() { + case types.IntFamily: + switch probeVec.Type().Width() { + case -1: + default: + probeKeys := probeVec.Int64() + buildKeys := buildVec.Int64() + if probeVec.MaybeHasNulls() { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - } else { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + { + var cmpResult int { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 + } } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 + } } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + } + } else { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 + } } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int { - var cmpResult int - cmpResult = bytes.Compare(probeVal, buildVal) - unique = cmpResult != 0 + a, b := int64(probeVal), int64(buildVal) + if a < b { + cmpResult = -1 + } else if a > b { + cmpResult = 1 + } else { + cmpResult = 0 + } } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } } - } } + case types.FloatFamily: + switch probeVec.Type().Width() { + } + case types.DecimalFamily: + switch probeVec.Type().Width() { + } } } - case types.DecimalFamily: + case types.FloatFamily: switch probeVec.Type().Width() { case -1: default: @@ -6500,4698 +6791,1270 @@ func (ht *HashTable) checkColForDistinctTuples( switch probeVec.Type().Width() { } case types.FloatFamily: - switch probeVec.Type().Width() { - } - case types.DecimalFamily: switch probeVec.Type().Width() { case -1: default: - probeKeys := probeVec.Decimal() - buildKeys := buildVec.Decimal() - if probeSel != nil { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + probeKeys := probeVec.Float64() + buildKeys := buildVec.Float64() + if probeVec.MaybeHasNulls() { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 + a, b := float64(probeVal), float64(buildVal) + 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 + } } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 + a, b := float64(probeVal), float64(buildVal) + 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 + } } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } + } else { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int + + { + a, b := float64(probeVal), float64(buildVal) + 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 + } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } else { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - cmpResult = tree.CompareDecimals(&probeVal, &buildVal) - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } - } - } - } - case types.IntFamily: - switch probeVec.Type().Width() { - case 16: - switch probeVec.CanonicalTypeFamily() { - case types.IntFamily: - switch probeVec.Type().Width() { - case 16: - probeKeys := probeVec.Int16() - buildKeys := buildVec.Int16() - if probeSel != nil { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } else { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } - } - case types.FloatFamily: - switch probeVec.Type().Width() { - } - case types.DecimalFamily: - switch probeVec.Type().Width() { - } - } - case 32: - switch probeVec.CanonicalTypeFamily() { - case types.IntFamily: - switch probeVec.Type().Width() { - case 32: - probeKeys := probeVec.Int32() - buildKeys := buildVec.Int32() - if probeSel != nil { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } else { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } - } - case types.FloatFamily: - switch probeVec.Type().Width() { - } - case types.DecimalFamily: - switch probeVec.Type().Width() { - } - } - case -1: - default: - switch probeVec.CanonicalTypeFamily() { - case types.IntFamily: - switch probeVec.Type().Width() { - case -1: - default: - probeKeys := probeVec.Int64() - buildKeys := buildVec.Int64() - if probeSel != nil { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } else { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := int64(probeVal), int64(buildVal) - if a < b { - cmpResult = -1 - } else if a > b { - cmpResult = 1 - } else { - cmpResult = 0 - } - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } - } - case types.FloatFamily: - switch probeVec.Type().Width() { - } - case types.DecimalFamily: - switch probeVec.Type().Width() { - } - } - } - case types.FloatFamily: - switch probeVec.Type().Width() { - case -1: - default: - switch probeVec.CanonicalTypeFamily() { - case types.IntFamily: - switch probeVec.Type().Width() { - } - case types.FloatFamily: - switch probeVec.Type().Width() { - case -1: - default: - probeKeys := probeVec.Float64() - buildKeys := buildVec.Float64() - if probeSel != nil { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := float64(probeVal), float64(buildVal) - 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 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := float64(probeVal), float64(buildVal) - 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 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := float64(probeVal), float64(buildVal) - 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 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := float64(probeVal), float64(buildVal) - 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 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } else { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := float64(probeVal), float64(buildVal) - 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 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := float64(probeVal), float64(buildVal) - 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 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := float64(probeVal), float64(buildVal) - 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 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - { - a, b := float64(probeVal), float64(buildVal) - 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 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } - } - case types.DecimalFamily: - switch probeVec.Type().Width() { - } - } - } - case types.TimestampTZFamily: - switch probeVec.Type().Width() { - case -1: - default: - switch probeVec.CanonicalTypeFamily() { - case types.TimestampTZFamily: - switch probeVec.Type().Width() { - case -1: - default: - probeKeys := probeVec.Timestamp() - buildKeys := buildVec.Timestamp() - if probeSel != nil { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } else { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - if probeVal.Before(buildVal) { - cmpResult = -1 - } else if buildVal.Before(probeVal) { - cmpResult = 1 - } else { - cmpResult = 0 - } - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } - } - } - } - case types.IntervalFamily: - switch probeVec.Type().Width() { - case -1: - default: - switch probeVec.CanonicalTypeFamily() { - case types.IntervalFamily: - switch probeVec.Type().Width() { - case -1: - default: - probeKeys := probeVec.Interval() - buildKeys := buildVec.Interval() - if probeSel != nil { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } else { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool + { + var cmpResult int { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 + a, b := float64(probeVal), float64(buildVal) + 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 + } } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } + unique = cmpResult != 0 } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - { - var cmpResult int - cmpResult = probeVal.Compare(buildVal) - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } } - } } + case types.DecimalFamily: + switch probeVec.Type().Width() { + } } } - case types.JsonFamily: + case types.TimestampTZFamily: switch probeVec.Type().Width() { case -1: default: switch probeVec.CanonicalTypeFamily() { - case types.JsonFamily: + case types.TimestampTZFamily: switch probeVec.Type().Width() { case -1: default: - probeKeys := probeVec.JSON() - buildKeys := buildVec.JSON() - if probeSel != nil { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } - - } else { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } - - unique = cmpResult != 0 - } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { + probeKeys := probeVec.Timestamp() + buildKeys := buildVec.Timestamp() + if probeVec.MaybeHasNulls() { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { ht.ProbeScratch.distinct[toCheck] = true - } - } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - unique = cmpResult != 0 - } + { + var cmpResult int - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique - } - } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } - } - } - } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue + if probeVal.Before(buildVal) { + cmpResult = -1 + } else if buildVal.Before(probeVal) { + cmpResult = 1 + } else { + cmpResult = 0 } + unique = cmpResult != 0 } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - { - var cmpResult int + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + } + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } + { + var cmpResult int - unique = cmpResult != 0 + if probeVal.Before(buildVal) { + cmpResult = -1 + } else if buildVal.Before(probeVal) { + cmpResult = 1 + } else { + cmpResult = 0 } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue + } + } + } else { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int + + if probeVal.Before(buildVal) { + cmpResult = -1 + } else if buildVal.Before(probeVal) { + cmpResult = 1 + } else { + cmpResult = 0 } + unique = cmpResult != 0 } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - { - var cmpResult int + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + } + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - var err error - cmpResult, err = probeVal.Compare(buildVal) - if err != nil { - colexecerror.ExpectedError(err) - } + { + var cmpResult int - unique = cmpResult != 0 + if probeVal.Before(buildVal) { + cmpResult = -1 + } else if buildVal.Before(probeVal) { + cmpResult = 1 + } else { + cmpResult = 0 } - - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } } - } } } } - case typeconv.DatumVecCanonicalTypeFamily: + case types.IntervalFamily: switch probeVec.Type().Width() { case -1: default: switch probeVec.CanonicalTypeFamily() { - case typeconv.DatumVecCanonicalTypeFamily: + case types.IntervalFamily: switch probeVec.Type().Width() { case -1: default: - probeKeys := probeVec.Datum() - buildKeys := buildVec.Datum() - if probeSel != nil { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) - - unique = cmpResult != 0 - } + probeKeys := probeVec.Interval() + buildKeys := buildVec.Interval() + if probeVec.MaybeHasNulls() { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = probeVal.Compare(buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int - - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) - - unique = cmpResult != 0 - } + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + { + var cmpResult int + cmpResult = probeVal.Compare(buildVal) + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } + } else { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int + cmpResult = probeVal.Compare(buildVal) + unique = cmpResult != 0 + } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int + cmpResult = probeVal.Compare(buildVal) + unique = cmpResult != 0 } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - { - var cmpResult int + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + } + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } + } + } + } + } + case types.JsonFamily: + switch probeVec.Type().Width() { + case -1: + default: + switch probeVec.CanonicalTypeFamily() { + case types.JsonFamily: + switch probeVec.Type().Width() { + case -1: + default: + probeKeys := probeVec.JSON() + buildKeys := buildVec.JSON() + if probeVec.MaybeHasNulls() { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 + var err error + cmpResult, err = probeVal.Compare(buildVal) + if err != nil { + colexecerror.ExpectedError(err) } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = probeSel[toCheck] - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 + var err error + cmpResult, err = probeVal.Compare(buildVal) + if err != nil { + colexecerror.ExpectedError(err) } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } } - } else { - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 + var err error + cmpResult, err = probeVal.Compare(buildVal) + if err != nil { + colexecerror.ExpectedError(err) } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - probeIsNull = probeVec.Nulls().NullAt(probeIdx) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 + var err error + cmpResult, err = probeVal.Compare(buildVal) + if err != nil { + colexecerror.ExpectedError(err) } - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } + } + } + } + } + case typeconv.DatumVecCanonicalTypeFamily: + switch probeVec.Type().Width() { + case -1: + default: + switch probeVec.CanonicalTypeFamily() { + case typeconv.DatumVecCanonicalTypeFamily: + switch probeVec.Type().Width() { + case -1: + default: + probeKeys := probeVec.Datum() + buildKeys := buildVec.Datum() + if probeVec.MaybeHasNulls() { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int + + cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + + unique = cmpResult != 0 + } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } } else { - if buildVec.MaybeHasNulls() { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - buildIsNull = buildVec.Nulls().NullAt(buildIdx) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + probeIsNull = probeVec.Nulls().NullAt(probeIdx) + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 - } + cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { - ht.ProbeScratch.distinct[toCheck] = true - } + } else { + ht.ProbeScratch.distinct[toCheck] = true } - } else { - var ( - probeIdx, buildIdx int - probeIsNull, buildIsNull bool - ) - for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { - // keyID of 0 is reserved to represent the end of the next chain. - keyID := ht.ProbeScratch.GroupID[toCheck] - if keyID != 0 { - // the build table key (calculated using keys[keyID - 1] = key) is - // compared to the corresponding probe table to determine if a match is - // found. - - probeIdx = int(toCheck) - buildIdx = int(keyID - 1) - if ht.allowNullEquality { - if probeIsNull && buildIsNull { - // Both values are NULLs, and since we're allowing null equality, we - // proceed to the next value to check. - continue - } else if probeIsNull { - // Only probing value is NULL, so it is different from the build value - // (which is non-NULL). We mark it as "different" and proceed to the - // next value to check. This behavior is special in case of allowing - // null equality because we don't want to reset the GroupID of the - // current probing tuple. - ht.ProbeScratch.differs[toCheck] = true - continue - } - } - if probeIsNull { - ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 - } else if buildIsNull { - ht.ProbeScratch.differs[toCheck] = true - } else { - probeVal := probeKeys.Get(probeIdx) - buildVal := buildKeys.Get(buildIdx) - var unique bool - - { - var cmpResult int + } + } + } else { + if buildVec.MaybeHasNulls() { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + buildIsNull = buildVec.Nulls().NullAt(buildIdx) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { + ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool - cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + { + var cmpResult int - unique = cmpResult != 0 - } + cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) - ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique + unique = cmpResult != 0 } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - if keyID == 0 { + } else { + ht.ProbeScratch.distinct[toCheck] = true + } + } + } else { + var ( + probeIdx, buildIdx int + probeIsNull, buildIsNull bool + ) + for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { + // keyID of 0 is reserved to represent the end of the next chain. + keyID := ht.ProbeScratch.GroupID[toCheck] + if keyID != 0 { + // the build table key (calculated using keys[keyID - 1] = key) is + // compared to the corresponding probe table to determine if a match is + // found. + + probeIdx = probeSel[toCheck] + buildIdx = int(keyID - 1) + if ht.allowNullEquality { + if probeIsNull && buildIsNull { + // Both values are NULLs, and since we're allowing null equality, we + // proceed to the next value to check. + continue + } else if probeIsNull { + // Only probing value is NULL, so it is different from the build value + // (which is non-NULL). We mark it as "different" and proceed to the + // next value to check. This behavior is special in case of allowing + // null equality because we don't want to reset the GroupID of the + // current probing tuple. + ht.ProbeScratch.differs[toCheck] = true + continue + } + } + if probeIsNull { ht.ProbeScratch.distinct[toCheck] = true + } else if buildIsNull { + ht.ProbeScratch.differs[toCheck] = true + } else { + probeVal := probeKeys.Get(probeIdx) + buildVal := buildKeys.Get(buildIdx) + var unique bool + + { + var cmpResult int + + cmpResult = coldataext.CompareDatum(probeVal, probeKeys, buildVal) + + unique = cmpResult != 0 + } + + ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } + } else { + ht.ProbeScratch.distinct[toCheck] = true } } } - } } } @@ -11203,7 +8066,7 @@ func (ht *HashTable) checkColForDistinctTuples( // in the probe table. func (ht *HashTable) CheckProbeForDistinct(vecs []coldata.Vec, nToCheck uint64, sel []int) uint64 { for i := range ht.keyCols { - ht.checkColAgainstItself(vecs[i], nToCheck, sel) + ht.checkColAgainstItselfForDistinct(vecs[i], nToCheck, sel) } nDiffers := uint64(0) toCheckSlice := ht.ProbeScratch.ToCheck @@ -11212,7 +8075,7 @@ func (ht *HashTable) CheckProbeForDistinct(vecs []coldata.Vec, nToCheck uint64, //gcassert:bce toCheck := toCheckSlice[toCheckPos] if ht.ProbeScratch.distinct[toCheck] { - ht.ProbeScratch.HeadID[toCheck] = ht.ProbeScratch.GroupID[toCheck] + ht.ProbeScratch.HeadID[toCheck] = toCheck + 1 continue } if !ht.ProbeScratch.differs[toCheck] { diff --git a/pkg/sql/colexec/colexechash/hashtable_tmpl.go b/pkg/sql/colexec/colexechash/hashtable_tmpl.go index 15feb875b687..96a62c8da0ab 100644 --- a/pkg/sql/colexec/colexechash/hashtable_tmpl.go +++ b/pkg/sql/colexec/colexechash/hashtable_tmpl.go @@ -63,13 +63,22 @@ func _ASSIGN_NE(_, _, _, _, _, _ interface{}) int { // This is a code snippet that is the main body of checkCol* functions. It // takes in the following template "meta" variables that enable/disable certain // code paths: +// _GLOBAL - a string replaced by "$global" (the local template variable +// referring to the NotEqual overload) before performing the template function +// call. It is needed because _CHECK_COL_BODY template function is called from +// two places where the overload is in different template context (in one case +// it is `.`, and in another it is `.Global`). We work around it by replacing +// _GLOBAL with the local variable during the initial preprocessing of the +// template. // _PROBE_HAS_NULLS - a boolean as .ProbeHasNulls that determines whether the // probe vector might have NULL values. // _BUILD_HAS_NULLS - a boolean as .BuildHasNulls that determines whether the // build vector might have NULL values. // _SELECT_DISTINCT - a boolean as .SelectDistinct that determines whether a -// probe tuple should be marked as "distinct" if its GroupID is zero (meaning -// that there is no tuple in the hash table with the same hash code). +// probe tuple should be marked as "distinct" if there is no tuple in the hash +// table that might be a duplicate of the probe tuple (either because the +// GroupID of the probe tuple is 0 - meaning no hash matches - or because the +// probe tuple has a NULL value when NULLs are treated as not equal). // _USE_PROBE_SEL - a boolean as .UseProbeSel that determines whether there is // a selection vector on the probe vector. // _PROBING_AGAINST_ITSELF - a boolean as .ProbingAgainstItself that tells us @@ -82,6 +91,7 @@ func _ASSIGN_NE(_, _, _, _, _, _ interface{}) int { // When it is true, the HashTable uses 'visited' slice to mark previously // matched tuples as "deleted" so they won't get matched again. func _CHECK_COL_BODY( + _GLOBAL interface{}, _PROBE_HAS_NULLS bool, _BUILD_HAS_NULLS bool, _SELECT_DISTINCT bool, @@ -97,7 +107,19 @@ func _CHECK_COL_BODY( for _, toCheck := range ht.ProbeScratch.ToCheck[:nToCheck] { // keyID of 0 is reserved to represent the end of the next chain. keyID := ht.ProbeScratch.GroupID[toCheck] + // {{if or (not .SelectDistinct) (not .ProbingAgainstItself)}} + // {{/* + // When we're selecting distinct tuples and probing against itself, + // we're in the code path of the unordered distinct where we're + // trying to find duplicates within a single input batch. In such a + // case we will never hit keyID of 0 because each tuple in the + // batch is equal to itself (and possibly others). Once we find a + // match, the tuple is no longer checked, so we never reach the end + // of the corresponding hash chain which could result in keyID + // being 0. + // */}} if keyID != 0 { + // {{end}} // the build table key (calculated using keys[keyID - 1] = key) is // compared to the corresponding probe table to determine if a match is // found. @@ -153,20 +175,14 @@ func _CHECK_COL_BODY( } } if probeIsNull { - // {{if or (.SelectDistinct) (.ProbingAgainstItself)}} + // {{if .SelectDistinct}} // {{/* // We know that nulls are distinct (because // allowNullEquality case is handled above) and our probing // tuple has a NULL value in the current column, so the - // probing tuple is distinct from the build table. Both - // parts of the template condition above are only 'true' if - // the hash table is used for the unordered distinct - // operator, and in that scenario we want to mark the - // current probing tuple as distinct but also set its - // GroupID such that it (the probing tuple) matches itself. + // probing tuple is distinct from the build table. // */}} ht.ProbeScratch.distinct[toCheck] = true - ht.ProbeScratch.GroupID[toCheck] = toCheck + 1 // {{else}} ht.ProbeScratch.GroupID[toCheck] = 0 // {{end}} @@ -179,10 +195,11 @@ func _CHECK_COL_BODY( _ASSIGN_NE(unique, probeVal, buildVal, _, probeKeys, buildKeys) ht.ProbeScratch.differs[toCheck] = ht.ProbeScratch.differs[toCheck] || unique } - } - // {{if .SelectDistinct}} - if keyID == 0 { + // {{if and .SelectDistinct (not .ProbingAgainstItself)}} + } else { ht.ProbeScratch.distinct[toCheck] = true + // {{end}} + // {{if or (not .SelectDistinct) (not .ProbingAgainstItself)}} } // {{end}} } @@ -191,30 +208,38 @@ func _CHECK_COL_BODY( } func _CHECK_COL_WITH_NULLS( - _USE_PROBE_SEL bool, _PROBING_AGAINST_ITSELF bool, _DELETING_PROBE_MODE bool, + _SELECT_DISTINCT bool, + _USE_PROBE_SEL bool, + _PROBING_AGAINST_ITSELF bool, + _DELETING_PROBE_MODE bool, ) { // */}} // {{define "checkColWithNulls" -}} + // {{$global := .Global}} + // {{$selectDistinct := .SelectDistinct}} // {{$probingAgainstItself := .ProbingAgainstItself}} // {{$deletingProbeMode := .DeletingProbeMode}} if probeVec.MaybeHasNulls() { if buildVec.MaybeHasNulls() { - _CHECK_COL_BODY(true, true, false, _USE_PROBE_SEL, _PROBING_AGAINST_ITSELF, _DELETING_PROBE_MODE) + _CHECK_COL_BODY(_GLOBAL, true, true, _SELECT_DISTINCT, _USE_PROBE_SEL, _PROBING_AGAINST_ITSELF, _DELETING_PROBE_MODE) } else { - _CHECK_COL_BODY(true, false, false, _USE_PROBE_SEL, _PROBING_AGAINST_ITSELF, _DELETING_PROBE_MODE) + _CHECK_COL_BODY(_GLOBAL, true, false, _SELECT_DISTINCT, _USE_PROBE_SEL, _PROBING_AGAINST_ITSELF, _DELETING_PROBE_MODE) } } else { if buildVec.MaybeHasNulls() { - _CHECK_COL_BODY(false, true, false, _USE_PROBE_SEL, _PROBING_AGAINST_ITSELF, _DELETING_PROBE_MODE) + _CHECK_COL_BODY(_GLOBAL, false, true, _SELECT_DISTINCT, _USE_PROBE_SEL, _PROBING_AGAINST_ITSELF, _DELETING_PROBE_MODE) } else { - _CHECK_COL_BODY(false, false, false, _USE_PROBE_SEL, _PROBING_AGAINST_ITSELF, _DELETING_PROBE_MODE) + _CHECK_COL_BODY(_GLOBAL, false, false, _SELECT_DISTINCT, _USE_PROBE_SEL, _PROBING_AGAINST_ITSELF, _DELETING_PROBE_MODE) } } // {{end}} // {{/* } -func _CHECK_COL_FUNCTION_TEMPLATE(_PROBING_AGAINST_ITSELF bool, _DELETING_PROBE_MODE bool) { // */}} +func _CHECK_COL_FUNCTION_TEMPLATE( + _SELECT_DISTINCT bool, _PROBING_AGAINST_ITSELF bool, _DELETING_PROBE_MODE bool, +) { // */}} // {{define "checkColFunctionTemplate" -}} + // {{$selectDistinct := .SelectDistinct}} // {{$probingAgainstItself := .ProbingAgainstItself}} // {{$deletingProbeMode := .DeletingProbeMode}} // {{with .Global}} @@ -252,9 +277,9 @@ func _CHECK_COL_FUNCTION_TEMPLATE(_PROBING_AGAINST_ITSELF bool, _DELETING_PROBE_ probeKeys := probeVec._ProbeType() buildKeys := buildVec._BuildType() if probeSel != nil { - _CHECK_COL_WITH_NULLS(true, _PROBING_AGAINST_ITSELF, _DELETING_PROBE_MODE) + _CHECK_COL_WITH_NULLS(_SELECT_DISTINCT, true, _PROBING_AGAINST_ITSELF, _DELETING_PROBE_MODE) } else { - _CHECK_COL_WITH_NULLS(false, _PROBING_AGAINST_ITSELF, _DELETING_PROBE_MODE) + _CHECK_COL_WITH_NULLS(_SELECT_DISTINCT, false, _PROBING_AGAINST_ITSELF, _DELETING_PROBE_MODE) } // {{end}} // {{end}} @@ -282,7 +307,7 @@ func (ht *HashTable) checkCol( probeVec, buildVec coldata.Vec, keyColIdx int, nToCheck uint64, probeSel []int, ) { // {{with .Overloads}} - _CHECK_COL_FUNCTION_TEMPLATE(false, false) + _CHECK_COL_FUNCTION_TEMPLATE(false, false, false) // {{end}} } @@ -290,16 +315,17 @@ func (ht *HashTable) checkCol( // {{if .HashTableMode.IsDistinctBuild}} -// checkColAgainstItself is similar to checkCol, but it probes the vector -// against itself. -func (ht *HashTable) checkColAgainstItself(vec coldata.Vec, nToCheck uint64, sel []int) { +// checkColAgainstItselfForDistinct is similar to checkCol, but it probes the +// vector against itself for the purposes of finding matches to unordered +// distinct columns. +func (ht *HashTable) checkColAgainstItselfForDistinct(vec coldata.Vec, nToCheck uint64, sel []int) { // {{/* // In order to reuse the same template function as checkCol uses, we use // the same variable names. // */}} probeVec, buildVec, probeSel := vec, vec, sel // {{with .Overloads}} - _CHECK_COL_FUNCTION_TEMPLATE(true, false) + _CHECK_COL_FUNCTION_TEMPLATE(true, true, false) // {{end}} } @@ -316,33 +342,12 @@ func (ht *HashTable) checkColDeleting( probeVec, buildVec coldata.Vec, keyColIdx int, nToCheck uint64, probeSel []int, ) { // {{with .Overloads}} - _CHECK_COL_FUNCTION_TEMPLATE(false, true) + _CHECK_COL_FUNCTION_TEMPLATE(false, false, true) // {{end}} } // {{end}} -// {{/* -func _CHECK_COL_FOR_DISTINCT_WITH_NULLS(_USE_PROBE_SEL bool) { // */}} - // {{define "checkColForDistinctWithNulls" -}} - if probeVec.MaybeHasNulls() { - if buildVec.MaybeHasNulls() { - _CHECK_COL_BODY(true, true, true, _USE_PROBE_SEL, false, false) - } else { - _CHECK_COL_BODY(true, false, true, _USE_PROBE_SEL, false, false) - } - } else { - if buildVec.MaybeHasNulls() { - _CHECK_COL_BODY(false, true, true, _USE_PROBE_SEL, false, false) - } else { - _CHECK_COL_BODY(false, false, true, _USE_PROBE_SEL, false, false) - } - } - - // {{end}} - // {{/* -} // */}} - // {{if .HashTableMode.IsDistinctBuild}} // {{with .Overloads}} @@ -376,10 +381,19 @@ func (ht *HashTable) checkColForDistinctTuples( case _RIGHT_TYPE_WIDTH: probeKeys := probeVec._ProbeType() buildKeys := buildVec._ProbeType() - if probeSel != nil { - _CHECK_COL_FOR_DISTINCT_WITH_NULLS(true) + // {{$global := .}} + if probeVec.MaybeHasNulls() { + if buildVec.MaybeHasNulls() { + _CHECK_COL_BODY(_GLOBAL, true, true, true, true, false, false) + } else { + _CHECK_COL_BODY(_GLOBAL, true, false, true, true, false, false) + } } else { - _CHECK_COL_FOR_DISTINCT_WITH_NULLS(false) + if buildVec.MaybeHasNulls() { + _CHECK_COL_BODY(_GLOBAL, false, true, true, true, false, false) + } else { + _CHECK_COL_BODY(_GLOBAL, false, false, true, true, false, false) + } } // {{end}} // {{end}} @@ -405,7 +419,16 @@ func _CHECK_BODY(_SELECT_SAME_TUPLES bool, _DELETING_PROBE_MODE bool, _SELECT_DI toCheck := toCheckSlice[toCheckPos] // {{if .SelectDistinct}} if ht.ProbeScratch.distinct[toCheck] { - ht.ProbeScratch.HeadID[toCheck] = ht.ProbeScratch.GroupID[toCheck] + // {{/* + // The hash table is used for the unordered distinct operator. + // This code block is only relevant when we're probing the batch + // against itself in order to separate all tuples in the batch + // into equality buckets (where equality buckets are specified + // by the same HeadID values). In this case we see that the + // probing tuple is distinct (i.e. it is unique in the batch), + // so we want to mark it as equal to itself only. + // */}} + ht.ProbeScratch.HeadID[toCheck] = toCheck + 1 continue } // {{end}} @@ -514,7 +537,7 @@ func (ht *HashTable) Check(probeVecs []coldata.Vec, nToCheck uint64, probeSel [] // in the probe table. func (ht *HashTable) CheckProbeForDistinct(vecs []coldata.Vec, nToCheck uint64, sel []int) uint64 { for i := range ht.keyCols { - ht.checkColAgainstItself(vecs[i], nToCheck, sel) + ht.checkColAgainstItselfForDistinct(vecs[i], nToCheck, sel) } nDiffers := uint64(0) _CHECK_BODY(false, false, true) diff --git a/pkg/sql/colexec/colexectestutils/utils.go b/pkg/sql/colexec/colexectestutils/utils.go index 0e5c04ab9123..b0db336ca2ec 100644 --- a/pkg/sql/colexec/colexectestutils/utils.go +++ b/pkg/sql/colexec/colexectestutils/utils.go @@ -682,8 +682,8 @@ func RunTestsWithFn( if typs != nil { inputTypes = typs[i] } - rng, _ := randutil.NewTestRand() - inputSources[i] = newOpTestSelInput(allocator, rng, batchSize, tup, inputTypes) + inputSources[i] = newOpTestSelInput(allocator, batchSize, tup, inputTypes) + inputSources[i].(*opTestInput).batchLengthRandomizationEnabled = true } } else { for i, tup := range tups { @@ -691,6 +691,7 @@ func RunTestsWithFn( inputTypes = typs[i] } inputSources[i] = NewOpTestInput(allocator, batchSize, tup, inputTypes) + inputSources[i].(*opTestInput).batchLengthRandomizationEnabled = true } } test(t, inputSources) @@ -835,8 +836,9 @@ type opTestInput struct { typs []*types.T - batchSize int - tuples Tuples + batchSize int + batchLengthRandomizationEnabled bool + tuples Tuples // initialTuples are tuples passed in into the constructor, and we keep the // reference to them in order to be able to reset the operator. initialTuples Tuples @@ -875,12 +877,11 @@ func NewOpTestInput( } func newOpTestSelInput( - allocator *colmem.Allocator, rng *rand.Rand, batchSize int, tuples Tuples, typs []*types.T, + allocator *colmem.Allocator, batchSize int, tuples Tuples, typs []*types.T, ) *opTestInput { ret := &opTestInput{ allocator: allocator, useSel: true, - rng: rng, batchSize: batchSize, tuples: tuples, initialTuples: tuples, @@ -898,7 +899,7 @@ func (s *opTestInput) Init(context.Context) { s.typs = extrapolateTypesFromTuples(s.tuples) } s.batch = s.allocator.NewMemBatchWithMaxCapacity(s.typs) - + s.rng, _ = randutil.NewTestRand() s.selection = make([]int, coldata.BatchSize()) for i := range s.selection { s.selection[i] = i @@ -914,6 +915,13 @@ func (s *opTestInput) Next() coldata.Batch { if len(s.tuples) < batchSize { batchSize = len(s.tuples) } + if s.batchLengthRandomizationEnabled { + // With 50% probability for this particular batch use a random length in + // range [1, batchSize]. + if s.rng.Float64() < 0.5 { + batchSize = s.rng.Intn(batchSize) + 1 + } + } tups := s.tuples[:batchSize] s.tuples = s.tuples[batchSize:] diff --git a/pkg/sql/colexec/distinct_test.go b/pkg/sql/colexec/distinct_test.go index 700197b03faf..dc9e46d614b0 100644 --- a/pkg/sql/colexec/distinct_test.go +++ b/pkg/sql/colexec/distinct_test.go @@ -298,6 +298,28 @@ var distinctTestCases = []distinctTestCase{ errorOnDup: "\"duplicate\" distinct nulls", noError: true, }, + { + distinctCols: []uint32{0, 1}, + typs: []*types.T{types.Int, types.Int}, + // Tuples have been carefully constructed so that all of them have the + // same hash, only one tuple among first three is inserted into the hash + // table, and the last two tuples are distinct. This is a regression + // unit test for #74795. + tuples: colexectestutils.Tuples{ + {1, 2}, + {1, 2}, + {1, 2}, + {nil, 7}, + {nil, 7}, + }, + expected: colexectestutils.Tuples{ + {1, 2}, + {nil, 7}, + {nil, 7}, + }, + isOrderedOnDistinctCols: false, + nullsAreDistinct: true, + }, } func mustParseJSON(s string) json.JSON { diff --git a/pkg/sql/colexec/execgen/cmd/execgen/hashtable_gen.go b/pkg/sql/colexec/execgen/cmd/execgen/hashtable_gen.go index e55329bc1b07..541da081d779 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/hashtable_gen.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/hashtable_gen.go @@ -81,6 +81,8 @@ func genHashTable(inputFileContents string, wr io.Writer, htm hashTableMode) err "_RIGHT_TYPE_WIDTH", typeWidthReplacement, "_ProbeType", "{{.Left.VecMethod}}", "_BuildType", "{{.Right.VecMethod}}", + "_GLOBAL", "$global", + "_SELECT_DISTINCT", "$selectDistinct", "_USE_PROBE_SEL", ".UseProbeSel", "_PROBING_AGAINST_ITSELF", "$probingAgainstItself", "_DELETING_PROBE_MODE", "$deletingProbeMode", @@ -91,24 +93,19 @@ func genHashTable(inputFileContents string, wr io.Writer, htm hashTableMode) err assignNeRe := makeFunctionRegex("_ASSIGN_NE", 6) s = assignNeRe.ReplaceAllString(s, makeTemplateFunctionCall("Global.Right.Assign", 6)) - checkColBody := makeFunctionRegex("_CHECK_COL_BODY", 6) + checkColBody := makeFunctionRegex("_CHECK_COL_BODY", 7) s = checkColBody.ReplaceAllString(s, - `{{template "checkColBody" buildDict "Global" .Global "ProbeHasNulls" $1 "BuildHasNulls" $2 "SelectDistinct" $3 "UseProbeSel" $4 "ProbingAgainstItself" $5 "DeletingProbeMode" $6}}`, + `{{template "checkColBody" buildDict "Global" $1 "ProbeHasNulls" $2 "BuildHasNulls" $3 "SelectDistinct" $4 "UseProbeSel" $5 "ProbingAgainstItself" $6 "DeletingProbeMode" $7}}`, ) - checkColWithNulls := makeFunctionRegex("_CHECK_COL_WITH_NULLS", 3) + checkColWithNulls := makeFunctionRegex("_CHECK_COL_WITH_NULLS", 4) s = checkColWithNulls.ReplaceAllString(s, - `{{template "checkColWithNulls" buildDict "Global" . "UseProbeSel" $1 "ProbingAgainstItself" $2 "DeletingProbeMode" $3}}`, + `{{template "checkColWithNulls" buildDict "Global" . "SelectDistinct" $1 "UseProbeSel" $2 "ProbingAgainstItself" $3 "DeletingProbeMode" $4}}`, ) - checkColFunctionTemplate := makeFunctionRegex("_CHECK_COL_FUNCTION_TEMPLATE", 2) + checkColFunctionTemplate := makeFunctionRegex("_CHECK_COL_FUNCTION_TEMPLATE", 3) s = checkColFunctionTemplate.ReplaceAllString(s, - `{{template "checkColFunctionTemplate" buildDict "Global" . "ProbingAgainstItself" $1 "DeletingProbeMode" $2}}`, - ) - - checkColForDistinctWithNulls := makeFunctionRegex("_CHECK_COL_FOR_DISTINCT_WITH_NULLS", 1) - s = checkColForDistinctWithNulls.ReplaceAllString(s, - `{{template "checkColForDistinctWithNulls" buildDict "Global" . "UseProbeSel" $1}}`, + `{{template "checkColFunctionTemplate" buildDict "Global" . "SelectDistinct" $1 "ProbingAgainstItself" $2 "DeletingProbeMode" $3}}`, ) checkBody := makeFunctionRegex("_CHECK_BODY", 3) diff --git a/pkg/sql/logictest/testdata/logic_test/insert b/pkg/sql/logictest/testdata/logic_test/insert index bdcd76dcfa8b..2cc19ea9cf61 100644 --- a/pkg/sql/logictest/testdata/logic_test/insert +++ b/pkg/sql/logictest/testdata/logic_test/insert @@ -788,3 +788,27 @@ SELECT * FROM gen_as_id_seqopt ORDER BY a 8 5 7 9 8 11 10 11 2 + +# Regression test for hitting an internal error in the vectorized unordered +# distinct when NULLs are present in the rows being inserted (#74795). +statement ok +CREATE TABLE t74795 ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + account_id TEXT NOT NULL, + deletion_request_id TEXT, + UNIQUE INDEX (account_id, deletion_request_id) +); +INSERT INTO t74795 + (account_id) +VALUES + ('foo'), + ('foo'), + ('foo') +ON CONFLICT (account_id, deletion_request_id) DO NOTHING; + +query TT +SELECT account_id, deletion_request_id FROM t74795 +---- +foo NULL +foo NULL +foo NULL