github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/builtin/unary/math.go (about)

     1  // Copyright 2022 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package unary
    16  
    17  import (
    18  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    19  	"github.com/matrixorigin/matrixone/pkg/container/types"
    20  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    21  	"github.com/matrixorigin/matrixone/pkg/sql/plan/function/operator"
    22  	"github.com/matrixorigin/matrixone/pkg/vectorize/momath"
    23  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    24  )
    25  
    26  type mathFn func(*vector.Vector, *vector.Vector) error
    27  
    28  func math1(vs []*vector.Vector, proc *process.Process, fn mathFn) (*vector.Vector, error) {
    29  	origVec := vs[0]
    30  	//Here we need to classify it into three scenes
    31  	//1. if it is a constant
    32  	//	1.1 if it's not a null value
    33  	//  1.2 if it's a null value
    34  	//2 common scene
    35  	if origVec.IsScalar() {
    36  		if origVec.IsScalarNull() {
    37  			return proc.AllocScalarNullVector(types.Type{Oid: types.T_float64, Size: 8}), nil
    38  		} else {
    39  			resultVector := proc.AllocScalarVector(types.Type{Oid: types.T_float64, Size: 8})
    40  			resultValues := make([]float64, 1)
    41  			vector.SetCol(resultVector, resultValues)
    42  			if err := fn(origVec, resultVector); err != nil {
    43  				return nil, err
    44  			}
    45  			return resultVector, nil
    46  		}
    47  	} else {
    48  		vecLen := int64(vector.Length(origVec))
    49  		resultVector, err := proc.AllocVectorOfRows(types.T_float64.ToType(), vecLen, origVec.Nsp)
    50  		if err != nil {
    51  			return nil, err
    52  		}
    53  		if err = fn(origVec, resultVector); err != nil {
    54  			return nil, err
    55  		}
    56  		return resultVector, nil
    57  	}
    58  }
    59  
    60  func Acos(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
    61  	return math1(vs, proc, momath.Acos)
    62  }
    63  
    64  func Atan(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
    65  	//If the vs's lenght is 1, just use the  function with one parameter
    66  	if len(vs) == 1 {
    67  		return math1(vs, proc, momath.Atan)
    68  	} else {
    69  		return operator.Arith[float64, float64](vs, proc, vs[0].GetType(), momath.AtanWithTwoArg)
    70  	}
    71  
    72  }
    73  
    74  func Cos(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
    75  	return math1(vs, proc, momath.Cos)
    76  }
    77  
    78  func Cot(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
    79  	return math1(vs, proc, momath.Cot)
    80  }
    81  
    82  func Exp(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
    83  	return math1(vs, proc, momath.Exp)
    84  }
    85  
    86  func Ln(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
    87  	return math1(vs, proc, momath.Ln)
    88  }
    89  
    90  func Log(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
    91  	if len(vs) == 1 {
    92  		return math1(vs, proc, momath.Ln)
    93  	}
    94  	if vs[0].IsScalarNull() {
    95  		return vector.NewConstNull(vs[0].Typ, vs[1].Length()), nil
    96  	}
    97  	vals := vs[0].Col.([]float64)
    98  	for i := range vals {
    99  		if vals[i] == float64(1) {
   100  			return nil, moerr.NewInvalidArg(proc.Ctx, "log base", 1)
   101  		}
   102  	}
   103  	v1, err := math1([]*vector.Vector{vs[0]}, proc, momath.Ln)
   104  	if err != nil {
   105  		return nil, moerr.NewInvalidArg(proc.Ctx, "log input", "<= 0")
   106  	}
   107  	v2, err := math1([]*vector.Vector{vs[1]}, proc, momath.Ln)
   108  	if err != nil {
   109  		return nil, moerr.NewInvalidArg(proc.Ctx, "log input", "<= 0")
   110  	}
   111  	return operator.DivFloat[float64]([]*vector.Vector{v2, v1}, proc)
   112  }
   113  
   114  func Sin(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
   115  	return math1(vs, proc, momath.Sin)
   116  }
   117  
   118  func Sinh(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
   119  	return math1(vs, proc, momath.Sinh)
   120  }
   121  
   122  func Tan(vs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
   123  	return math1(vs, proc, momath.Tan)
   124  }