Skip to content

Commit

Permalink
colexec: add support for Pow binary operator
Browse files Browse the repository at this point in the history
This commit resolves: cockroachdb#49465

Previously, there was no support for Pow (^) in vectorized engine.
This commit adds Pow operator. I added Pow to binaryOpMethods
and registered inputs/outputs for this operator.

Release note (sql change): Vectorized engine now support Pow operator.
  • Loading branch information
sooryranga committed Jun 16, 2020
1 parent af0f7bb commit f6ab386
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 1 deletion.
37 changes: 36 additions & 1 deletion pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ var binaryOpDecMethod = map[tree.BinaryOperator]string{
tree.Div: "Quo",
tree.FloorDiv: "QuoInteger",
tree.Mod: "Rem",
tree.Pow: "Pow",
}

var binaryOpFloatMethod = map[tree.BinaryOperator]string{
tree.FloorDiv: "math.Trunc",
tree.Mod: "math.Mod",
tree.Pow: "math.Pow",
}

var binaryOpDecCtx = map[tree.BinaryOperator]string{
Expand All @@ -45,6 +47,7 @@ var binaryOpDecCtx = map[tree.BinaryOperator]string{
tree.Div: "DecimalCtx",
tree.FloorDiv: "HighPrecisionCtx",
tree.Mod: "HighPrecisionCtx",
tree.Pow: "DecimalCtx",
}

var compatibleCanonicalTypeFamilies = map[types.Family][]types.Family{
Expand Down Expand Up @@ -185,6 +188,19 @@ func registerBinOpOutputTypes() {
}
}

// Pow arithmetic binary operators.
for _, binOp := range []tree.BinaryOperator{tree.Pow} {
binOpOutputTypes[binOp] = make(map[typePair]*types.T)
binOpOutputTypes[binOp][typePair{types.FloatFamily, anyWidth, types.FloatFamily, anyWidth}] = types.Float
binOpOutputTypes[binOp][typePair{types.DecimalFamily, anyWidth, types.DecimalFamily, anyWidth}] = types.Decimal
for _, intWidth := range supportedWidthsByCanonicalTypeFamily[types.IntFamily] {
for _, intWidth2 := range supportedWidthsByCanonicalTypeFamily[types.IntFamily] {
binOpOutputTypes[binOp][typePair{types.IntFamily, intWidth, types.IntFamily, intWidth2}] = types.Int
}
binOpOutputTypes[binOp][typePair{types.DecimalFamily, anyWidth, types.IntFamily, intWidth}] = types.Decimal
}
}

// Other non-arithmetic binary operators.
binOpOutputTypes[tree.Concat] = map[typePair]*types.T{
{types.BytesFamily, anyWidth, types.BytesFamily, anyWidth}: types.Bytes,
Expand Down Expand Up @@ -317,7 +333,7 @@ func (c floatCustomizer) getBinOpAssignFunc() assignFunc {
switch binOp {
case tree.FloorDiv:
computeBinOp = fmt.Sprintf("%s(float64(%s) / float64(%s))", binaryOpFloatMethod[binOp], leftElem, rightElem)
case tree.Mod:
case tree.Mod, tree.Pow:
computeBinOp = fmt.Sprintf("%s(float64(%s), float64(%s))", binaryOpFloatMethod[binOp], leftElem, rightElem)
default:
computeBinOp = fmt.Sprintf("float64(%s) %s float64(%s)", leftElem, binOp, rightElem)
Expand All @@ -329,6 +345,7 @@ func (c floatCustomizer) getBinOpAssignFunc() assignFunc {
"ComputeBinOp": computeBinOp,
}
buf := strings.Builder{}

t := template.Must(template.New("").Parse(`
{
{{if .CheckRightIsZero}}
Expand All @@ -339,6 +356,7 @@ func (c floatCustomizer) getBinOpAssignFunc() assignFunc {
{{.Target}} = {{.ComputeBinOp}}
}
`))

if err := t.Execute(&buf, args); err != nil {
colexecerror.InternalError(err)
}
Expand Down Expand Up @@ -444,7 +462,24 @@ func (c intCustomizer) getBinOpAssignFunc() assignFunc {
}
}
`))
case tree.Pow:
args["Ctx"] = binaryOpDecCtx[binOp]

t = template.Must(template.New("").Parse(`
{
leftTmpDec, rightTmpDec := &_overloadHelper.tmpDec1, &_overloadHelper.tmpDec2
leftTmpDec.SetInt64(int64({{.Left}}))
rightTmpDec.SetInt64(int64({{.Right}}))
if _, err := tree.{{.Ctx}}.Pow(leftTmpDec, leftTmpDec, rightTmpDec); err != nil {
colexecerror.ExpectedError(err)
}
resultInt, err := leftTmpDec.Int64()
if err != nil {
colexecerror.ExpectedError(tree.ErrIntOutOfRange)
}
{{.Target}} = resultInt
}
`))
case tree.FloorDiv, tree.Mod:
// Note that these operators have integer result.
t = template.Must(template.New("").Parse(fmt.Sprintf(`
Expand Down
1 change: 1 addition & 0 deletions pkg/sql/colexec/execgen/supported_bin_cmp_ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ var BinaryOpName = map[tree.BinaryOperator]string{
tree.Div: "Div",
tree.FloorDiv: "FloorDiv",
tree.Mod: "Mod",
tree.Pow: "Pow",
tree.Concat: "Concat",
tree.JSONFetchVal: "JSONFetchVal",
}
Expand Down
45 changes: 45 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/vectorize_overloads
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,37 @@ EXPLAIN (VEC) SELECT _inet - _int2 FROM many_types
└ *colexec.projMinusDatumInt16Op
└ *colexec.colBatchScan

query T
EXPLAIN (VEC) SELECT _int2^_int4 FROM many_types
----
└ Node 1
└ *colexec.projPowInt16Int32Op
└ *colexec.colBatchScan

query T
EXPLAIN (VEC) SELECT _int2^_int FROM many_types
----
└ Node 1
└ *colexec.projPowInt16Int64Op
└ *colexec.colBatchScan

query T
EXPLAIN (VEC) SELECT _float^_float FROM many_types
----
└ Node 1
└ *colexec.projPowFloat64Float64Op
└ *colexec.colBatchScan

query T rowsort
SELECT (_float^_float)::STRING FROM many_types
----
NULL
1.28998092100128
1011.29924392386

query T rowsort
SELECT _inet - _int2 FROM many_types
----
Expand Down Expand Up @@ -283,6 +314,20 @@ EXPLAIN (VEC) SELECT _json -> _int2 FROM many_types
└ *colexec.projJSONFetchValDatumInt16Op
└ *colexec.colBatchScan


query T rowsort
SELECT (_int2^_int2)::STRING FROM many_types WHERE _int2 < 10 AND _int2 < 10
----
4

statement error integer out of range
SELECT (_int2^_int2)::STRING FROM many_types

query T rowsort
SELECT (_int2^_int4)::STRING FROM many_types WHERE _int2 < 10 AND _int4 < 10
----
4

query T
SELECT _json -> _int2 FROM many_types
----
Expand Down

0 comments on commit f6ab386

Please sign in to comment.