From f6ab3864cdc8ff9765d5abad5ee1a4c54315f4bf Mon Sep 17 00:00:00 2001 From: Arun Ranganathan Date: Sat, 13 Jun 2020 23:07:58 -0400 Subject: [PATCH] colexec: add support for Pow binary operator This commit resolves: #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. --- .../execgen/cmd/execgen/overloads_bin.go | 37 ++++++++++++++- .../colexec/execgen/supported_bin_cmp_ops.go | 1 + .../testdata/logic_test/vectorize_overloads | 45 +++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go b/pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go index d94378b98273..a126c2107790 100644 --- a/pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go +++ b/pkg/sql/colexec/execgen/cmd/execgen/overloads_bin.go @@ -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{ @@ -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{ @@ -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, @@ -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) @@ -329,6 +345,7 @@ func (c floatCustomizer) getBinOpAssignFunc() assignFunc { "ComputeBinOp": computeBinOp, } buf := strings.Builder{} + t := template.Must(template.New("").Parse(` { {{if .CheckRightIsZero}} @@ -339,6 +356,7 @@ func (c floatCustomizer) getBinOpAssignFunc() assignFunc { {{.Target}} = {{.ComputeBinOp}} } `)) + if err := t.Execute(&buf, args); err != nil { colexecerror.InternalError(err) } @@ -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(` diff --git a/pkg/sql/colexec/execgen/supported_bin_cmp_ops.go b/pkg/sql/colexec/execgen/supported_bin_cmp_ops.go index 250824521c68..ba47816ae070 100644 --- a/pkg/sql/colexec/execgen/supported_bin_cmp_ops.go +++ b/pkg/sql/colexec/execgen/supported_bin_cmp_ops.go @@ -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", } diff --git a/pkg/sql/logictest/testdata/logic_test/vectorize_overloads b/pkg/sql/logictest/testdata/logic_test/vectorize_overloads index b9b85e408c64..8e5855898665 100644 --- a/pkg/sql/logictest/testdata/logic_test/vectorize_overloads +++ b/pkg/sql/logictest/testdata/logic_test/vectorize_overloads @@ -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 ---- @@ -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 ----