diff --git a/server/functions/abs.go b/server/functions/abs.go new file mode 100644 index 0000000000..88841edd80 --- /dev/null +++ b/server/functions/abs.go @@ -0,0 +1,49 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import ( + "github.com/dolthub/doltgresql/utils" +) + +// abs represents the PostgreSQL function of the same name. +var abs = Function{ + Name: "abs", + Overloads: []interface{}{abs_int, abs_float, abs_numeric}, +} + +// abs_int is one of the overloads of abs. +func abs_int(num IntegerType) (IntegerType, error) { + if num.IsNull { + return IntegerType{IsNull: true}, nil + } + return IntegerType{Value: utils.Abs(num.Value)}, nil +} + +// abs_float is one of the overloads of abs. +func abs_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: utils.Abs(num.Value)}, nil +} + +// abs_numeric is one of the overloads of abs. +func abs_numeric(num NumericType) (NumericType, error) { + if num.IsNull { + return NumericType{IsNull: true}, nil + } + return NumericType{Value: utils.Abs(num.Value)}, nil +} diff --git a/server/functions/acos.go b/server/functions/acos.go new file mode 100644 index 0000000000..f2edb0e2d6 --- /dev/null +++ b/server/functions/acos.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// acos represents the PostgreSQL function of the same name. +var acos = Function{ + Name: "acos", + Overloads: []interface{}{acos_float}, +} + +// acos_float is one of the overloads of acos. +func acos_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Acos(num.Value)}, nil +} diff --git a/server/functions/acosd.go b/server/functions/acosd.go new file mode 100644 index 0000000000..1ba0383d55 --- /dev/null +++ b/server/functions/acosd.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// acosd represents the PostgreSQL function of the same name. +var acosd = Function{ + Name: "acosd", + Overloads: []interface{}{acosd_float}, +} + +// acosd_float is one of the overloads of acosd. +func acosd_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: toDegrees(math.Acos(num.Value))}, nil +} diff --git a/server/functions/acosh.go b/server/functions/acosh.go new file mode 100644 index 0000000000..789762c08e --- /dev/null +++ b/server/functions/acosh.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// acosh represents the PostgreSQL function of the same name. +var acosh = Function{ + Name: "acosh", + Overloads: []interface{}{acosh_float}, +} + +// acosh_float is one of the overloads of acosh. +func acosh_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Acosh(num.Value)}, nil +} diff --git a/server/functions/ascii.go b/server/functions/ascii.go new file mode 100644 index 0000000000..1f8c52673c --- /dev/null +++ b/server/functions/ascii.go @@ -0,0 +1,33 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// ascii represents the PostgreSQL function of the same name. +var ascii = Function{ + Name: "ascii", + Overloads: []interface{}{ascii_string}, +} + +// ascii_string is one of the overloads of ascii. +func ascii_string(text StringType) (IntegerType, error) { + if text.IsNull { + return IntegerType{IsNull: true}, nil + } + if len(text.Value) == 0 { + return IntegerType{Value: 0}, nil + } + runes := []rune(text.Value) + return IntegerType{Value: int64(runes[0])}, nil +} diff --git a/server/functions/asin.go b/server/functions/asin.go new file mode 100644 index 0000000000..ab85f5da88 --- /dev/null +++ b/server/functions/asin.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// asin represents the PostgreSQL function of the same name. +var asin = Function{ + Name: "asin", + Overloads: []interface{}{asin_float}, +} + +// asin_float is one of the overloads of asin. +func asin_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Asin(num.Value)}, nil +} diff --git a/server/functions/asind.go b/server/functions/asind.go new file mode 100644 index 0000000000..42b78e4b5e --- /dev/null +++ b/server/functions/asind.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// asind represents the PostgreSQL function of the same name. +var asind = Function{ + Name: "asind", + Overloads: []interface{}{asind_float}, +} + +// asind_float is one of the overloads of asind. +func asind_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: toDegrees(math.Asin(num.Value))}, nil +} diff --git a/server/functions/asinh.go b/server/functions/asinh.go new file mode 100644 index 0000000000..180c068785 --- /dev/null +++ b/server/functions/asinh.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// asinh represents the PostgreSQL function of the same name. +var asinh = Function{ + Name: "asinh", + Overloads: []interface{}{asinh_float}, +} + +// asinh_float is one of the overloads of asinh. +func asinh_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Asinh(num.Value)}, nil +} diff --git a/server/functions/atan.go b/server/functions/atan.go new file mode 100644 index 0000000000..ef740e9b23 --- /dev/null +++ b/server/functions/atan.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// atan represents the PostgreSQL function of the same name. +var atan = Function{ + Name: "atan", + Overloads: []interface{}{atan_float}, +} + +// atan_float is one of the overloads of atan. +func atan_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Atan(num.Value)}, nil +} diff --git a/server/functions/atan2.go b/server/functions/atan2.go new file mode 100644 index 0000000000..3f49bda180 --- /dev/null +++ b/server/functions/atan2.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// atan2 represents the PostgreSQL function of the same name. +var atan2 = Function{ + Name: "atan2", + Overloads: []interface{}{atan2_float}, +} + +// atan2_float is one of the overloads of atan2. +func atan2_float(y FloatType, x FloatType) (FloatType, error) { + if y.IsNull || x.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Atan2(y.Value, x.Value)}, nil +} diff --git a/server/functions/atan2d.go b/server/functions/atan2d.go new file mode 100644 index 0000000000..8625da6bab --- /dev/null +++ b/server/functions/atan2d.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// atan2d represents the PostgreSQL function of the same name. +var atan2d = Function{ + Name: "atan2d", + Overloads: []interface{}{atan2d_float}, +} + +// atan2d_float is one of the overloads of atan2d. +func atan2d_float(y FloatType, x FloatType) (FloatType, error) { + if y.IsNull || x.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: toDegrees(math.Atan2(y.Value, x.Value))}, nil +} diff --git a/server/functions/atand.go b/server/functions/atand.go new file mode 100644 index 0000000000..fc54779295 --- /dev/null +++ b/server/functions/atand.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// atand represents the PostgreSQL function of the same name. +var atand = Function{ + Name: "atand", + Overloads: []interface{}{atand_float}, +} + +// atand_float is one of the overloads of atand. +func atand_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: toDegrees(math.Atan(num.Value))}, nil +} diff --git a/server/functions/atanh.go b/server/functions/atanh.go new file mode 100644 index 0000000000..9344578a23 --- /dev/null +++ b/server/functions/atanh.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// atanh represents the PostgreSQL function of the same name. +var atanh = Function{ + Name: "atanh", + Overloads: []interface{}{atanh_float}, +} + +// atanh_float is one of the overloads of atanh. +func atanh_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Atanh(num.Value)}, nil +} diff --git a/server/functions/bit_length.go b/server/functions/bit_length.go new file mode 100644 index 0000000000..0e80f0d767 --- /dev/null +++ b/server/functions/bit_length.go @@ -0,0 +1,33 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// bit_length represents the PostgreSQL function of the same name. +var bit_length = Function{ + Name: "bit_length", + Overloads: []interface{}{bit_length_string}, +} + +// bit_length_string is one of the overloads of bit_length. +func bit_length_string(text StringType) (IntegerType, error) { + if text.IsNull { + return IntegerType{IsNull: true}, nil + } + result, err := octet_length_string(text) + if err != nil { + return IntegerType{}, err + } + return IntegerType{Value: result.Value * 8}, nil +} diff --git a/server/functions/btrim.go b/server/functions/btrim.go new file mode 100644 index 0000000000..c1f6743941 --- /dev/null +++ b/server/functions/btrim.go @@ -0,0 +1,43 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// btrim represents the PostgreSQL function of the same name. +var btrim = Function{ + Name: "btrim", + Overloads: []interface{}{btrim_string, btrim_string_string}, +} + +// btrim_string is one of the overloads of btrim. +func btrim_string(str StringType) (StringType, error) { + return btrim_string_string(str, StringType{ + Value: " ", + IsNull: false, + OriginalType: ParameterType_String, + Source: Source_Constant, + }) +} + +// btrim_string_string is one of the overloads of btrim. +func btrim_string_string(str StringType, characters StringType) (StringType, error) { + if str.IsNull || characters.IsNull { + return StringType{IsNull: true}, nil + } + result, err := ltrim_string_string(str, characters) + if err != nil { + return StringType{}, err + } + return rtrim_string_string(result, characters) +} diff --git a/server/functions/ceil.go b/server/functions/ceil.go new file mode 100644 index 0000000000..2b806ce920 --- /dev/null +++ b/server/functions/ceil.go @@ -0,0 +1,47 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import ( + "math" +) + +// ceil represents the PostgreSQL function of the same name. +var ceil = Function{ + Name: "ceil", + Overloads: []interface{}{ceil_float, ceil_numeric}, +} + +// ceiling represents the PostgreSQL function of the same name. +var ceiling = Function{ + Name: "ceiling", + Overloads: []interface{}{ceil_float, ceil_numeric}, +} + +// ceil_float is one of the overloads of ceil. +func ceil_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Ceil(num.Value)}, nil +} + +// ceil_numeric is one of the overloads of ceil. +func ceil_numeric(num NumericType) (NumericType, error) { + if num.IsNull { + return NumericType{IsNull: true}, nil + } + return NumericType{Value: math.Ceil(num.Value)}, nil +} diff --git a/server/functions/char_length.go b/server/functions/char_length.go new file mode 100644 index 0000000000..5a7bc1e8f6 --- /dev/null +++ b/server/functions/char_length.go @@ -0,0 +1,35 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// char_length represents the PostgreSQL function of the same name. +var char_length = Function{ + Name: "char_length", + Overloads: []interface{}{char_length_string}, +} + +// character_length represents the PostgreSQL function of the same name. +var character_length = Function{ + Name: "character_length", + Overloads: []interface{}{char_length_string}, +} + +// char_length_string is one of the overloads of char_length. +func char_length_string(text StringType) (IntegerType, error) { + if text.IsNull { + return IntegerType{IsNull: true}, nil + } + return IntegerType{Value: int64(len([]rune(text.Value)))}, nil +} diff --git a/server/functions/chr.go b/server/functions/chr.go new file mode 100644 index 0000000000..6551c094a3 --- /dev/null +++ b/server/functions/chr.go @@ -0,0 +1,36 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "fmt" + +// chr represents the PostgreSQL function of the same name. +var chr = Function{ + Name: "chr", + Overloads: []interface{}{chr_string}, +} + +// chr_string is one of the overloads of chr. +func chr_string(num IntegerType) (StringType, error) { + if num.IsNull { + return StringType{IsNull: true}, nil + } + if num.Value == 0 { + return StringType{}, fmt.Errorf("null character not permitted") + } else if num.Value < 0 { + return StringType{}, fmt.Errorf("character number must be positive") + } + return StringType{Value: string(rune(num.Value))}, nil +} diff --git a/server/functions/cos.go b/server/functions/cos.go new file mode 100644 index 0000000000..540d6c40f5 --- /dev/null +++ b/server/functions/cos.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// cos represents the PostgreSQL function of the same name. +var cos = Function{ + Name: "cos", + Overloads: []interface{}{cos_float}, +} + +// cos_float is one of the overloads of cos. +func cos_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Cos(num.Value)}, nil +} diff --git a/server/functions/cosd.go b/server/functions/cosd.go new file mode 100644 index 0000000000..74b600244c --- /dev/null +++ b/server/functions/cosd.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// cosd represents the PostgreSQL function of the same name. +var cosd = Function{ + Name: "cosd", + Overloads: []interface{}{cosd_float}, +} + +// cosd_float is one of the overloads of cosd. +func cosd_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: toDegrees(math.Cos(num.Value))}, nil +} diff --git a/server/functions/cosh.go b/server/functions/cosh.go new file mode 100644 index 0000000000..90a8b9c5a9 --- /dev/null +++ b/server/functions/cosh.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// cosh represents the PostgreSQL function of the same name. +var cosh = Function{ + Name: "cosh", + Overloads: []interface{}{cosh_float}, +} + +// cosh_float is one of the overloads of cosh. +func cosh_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Cosh(num.Value)}, nil +} diff --git a/server/functions/cot.go b/server/functions/cot.go new file mode 100644 index 0000000000..bfa78ed027 --- /dev/null +++ b/server/functions/cot.go @@ -0,0 +1,34 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// cot represents the PostgreSQL function of the same name. +var cot = Function{ + Name: "cot", + Overloads: []interface{}{cot_float}, +} + +// cot_float is one of the overloads of cot. +func cot_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + if num.Value == 0 { + return FloatType{Value: math.Inf(1)}, nil + } + return FloatType{Value: math.Cos(num.Value) / math.Sin(num.Value)}, nil +} diff --git a/server/functions/cotd.go b/server/functions/cotd.go new file mode 100644 index 0000000000..2e9a621133 --- /dev/null +++ b/server/functions/cotd.go @@ -0,0 +1,34 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// cotd represents the PostgreSQL function of the same name. +var cotd = Function{ + Name: "cotd", + Overloads: []interface{}{cotd_float}, +} + +// cotd_float is one of the overloads of cotd. +func cotd_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + if num.Value == 0 { + return FloatType{Value: math.Inf(1)}, nil + } + return FloatType{Value: toDegrees(math.Cos(num.Value) / math.Sin(num.Value))}, nil +} diff --git a/server/functions/degrees.go b/server/functions/degrees.go new file mode 100644 index 0000000000..53eed1c7d3 --- /dev/null +++ b/server/functions/degrees.go @@ -0,0 +1,36 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// degrees represents the PostgreSQL function of the same name. +var degrees = Function{ + Name: "degrees", + Overloads: []interface{}{degrees_float}, +} + +// degrees_float is one of the overloads of degrees. +func degrees_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: toDegrees(num.Value)}, nil +} + +// toDegrees converts the given radians to degrees. +func toDegrees(radians float64) float64 { + return (radians * 180.0) / math.Pi +} diff --git a/server/functions/div.go b/server/functions/div.go new file mode 100644 index 0000000000..671c8c482f --- /dev/null +++ b/server/functions/div.go @@ -0,0 +1,32 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// div represents the PostgreSQL function of the same name. +var div = Function{ + Name: "div", + Overloads: []interface{}{div_num_num}, +} + +// div_num_num is one of the overloads of div. +func div_num_num(num1 NumericType, num2 NumericType) (NumericType, error) { + if num1.IsNull || num2.IsNull { + return NumericType{IsNull: true}, nil + } + val := num1.Value / num2.Value + return NumericType{Value: math.Trunc(val)}, nil +} diff --git a/server/functions/exp.go b/server/functions/exp.go new file mode 100644 index 0000000000..5db5765c5f --- /dev/null +++ b/server/functions/exp.go @@ -0,0 +1,39 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// exp represents the PostgreSQL function of the same name. +var exp = Function{ + Name: "exp", + Overloads: []interface{}{exp_float, exp_numeric}, +} + +// exp_float is one of the overloads of exp. +func exp_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Exp(num.Value)}, nil +} + +// exp_numeric is one of the overloads of exp. +func exp_numeric(num NumericType) (NumericType, error) { + if num.IsNull { + return NumericType{IsNull: true}, nil + } + return NumericType{Value: math.Exp(num.Value)}, nil +} diff --git a/server/functions/factorial.go b/server/functions/factorial.go new file mode 100644 index 0000000000..54b20ed686 --- /dev/null +++ b/server/functions/factorial.go @@ -0,0 +1,38 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "fmt" + +// factorial represents the PostgreSQL function of the same name. +var factorial = Function{ + Name: "factorial", + Overloads: []interface{}{factorial_int}, +} + +// factorial_int is one of the overloads of factorial. +func factorial_int(num IntegerType) (IntegerType, error) { + if num.IsNull { + return IntegerType{IsNull: true}, nil + } + if num.Value < 0 { + return IntegerType{}, fmt.Errorf("factorial of a negative number is undefined") + } + total := int64(1) + for i := int64(2); i <= num.Value; i++ { + total *= i + } + return IntegerType{Value: total}, nil +} diff --git a/server/functions/floor.go b/server/functions/floor.go new file mode 100644 index 0000000000..87f9bb9466 --- /dev/null +++ b/server/functions/floor.go @@ -0,0 +1,39 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// floor represents the PostgreSQL function of the same name. +var floor = Function{ + Name: "floor", + Overloads: []interface{}{floor_float, floor_numeric}, +} + +// floor_float is one of the overloads of floor. +func floor_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Floor(num.Value)}, nil +} + +// floor_numeric is one of the overloads of floor. +func floor_numeric(num NumericType) (NumericType, error) { + if num.IsNull { + return NumericType{IsNull: true}, nil + } + return NumericType{Value: math.Floor(num.Value)}, nil +} diff --git a/server/functions/initcap.go b/server/functions/initcap.go new file mode 100644 index 0000000000..58720dd69e --- /dev/null +++ b/server/functions/initcap.go @@ -0,0 +1,34 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import ( + "golang.org/x/text/cases" + "golang.org/x/text/language" +) + +// initcap represents the PostgreSQL function of the same name. +var initcap = Function{ + Name: "initcap", + Overloads: []interface{}{initcap_string}, +} + +// initcap_string is one of the overloads of initcap. +func initcap_string(text StringType) (StringType, error) { + if text.IsNull { + return StringType{IsNull: true}, nil + } + return StringType{Value: cases.Title(language.English).String(text.Value)}, nil +} diff --git a/server/functions/lcm.go b/server/functions/lcm.go index 29919d0342..42c9641b9c 100644 --- a/server/functions/lcm.go +++ b/server/functions/lcm.go @@ -23,11 +23,11 @@ import ( // lcm represents the PostgreSQL function of the same name. var lcm = Function{ Name: "lcm", - Overloads: []interface{}{lcm1_int_int}, + Overloads: []interface{}{lcm_int_int}, } -// lcm1 is one of the overloads of lcm. -func lcm1_int_int(num1 IntegerType, num2 IntegerType) (IntegerType, error) { +// lcm_int_int is one of the overloads of lcm. +func lcm_int_int(num1 IntegerType, num2 IntegerType) (IntegerType, error) { if num1.IsNull || num2.IsNull { return IntegerType{IsNull: true}, nil } diff --git a/server/functions/left.go b/server/functions/left.go new file mode 100644 index 0000000000..5a812061e2 --- /dev/null +++ b/server/functions/left.go @@ -0,0 +1,33 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// left represents the PostgreSQL function of the same name. +var left = Function{ + Name: "left", + Overloads: []interface{}{left_string}, +} + +// left_string is one of the overloads of left. +func left_string(string StringType, n IntegerType) (StringType, error) { + if string.IsNull || n.IsNull { + return StringType{IsNull: true}, nil + } + if n.Value >= 0 { + return StringType{Value: string.Value[:n.Value]}, nil + } else { + return StringType{Value: string.Value[:len(string.Value)+int(n.Value)]}, nil + } +} diff --git a/server/functions/length.go b/server/functions/length.go new file mode 100644 index 0000000000..c3eb09a152 --- /dev/null +++ b/server/functions/length.go @@ -0,0 +1,29 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// length represents the PostgreSQL function of the same name. +var length = Function{ + Name: "length", + Overloads: []interface{}{length_string}, +} + +// length_string is one of the overloads of length. +func length_string(text StringType) (IntegerType, error) { + if text.IsNull { + return IntegerType{IsNull: true}, nil + } + return IntegerType{Value: int64(len([]rune(text.Value)))}, nil +} diff --git a/server/functions/ln.go b/server/functions/ln.go new file mode 100644 index 0000000000..0e456471a8 --- /dev/null +++ b/server/functions/ln.go @@ -0,0 +1,39 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// ln represents the PostgreSQL function of the same name. +var ln = Function{ + Name: "ln", + Overloads: []interface{}{ln_float, ln_numeric}, +} + +// ln_float is one of the overloads of ln. +func ln_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Log(num.Value)}, nil +} + +// ln_numeric is one of the overloads of ln. +func ln_numeric(num NumericType) (NumericType, error) { + if num.IsNull { + return NumericType{IsNull: true}, nil + } + return NumericType{Value: math.Log(num.Value)}, nil +} diff --git a/server/functions/log.go b/server/functions/log.go new file mode 100644 index 0000000000..34b84d0dac --- /dev/null +++ b/server/functions/log.go @@ -0,0 +1,65 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import ( + "fmt" + "math" +) + +// log represents the PostgreSQL function of the same name. +var log = Function{ + Name: "log", + Overloads: []interface{}{log_float, log_numeric, log_numeric_numeric}, +} + +// log_float is one of the overloads of log. +func log_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + if num.Value == 0 { + return FloatType{}, fmt.Errorf("cannot take logarithm of zero") + } else if num.Value < 0 { + return FloatType{}, fmt.Errorf("cannot take logarithm of a negative number") + } + return FloatType{Value: math.Log10(num.Value)}, nil +} + +// log_numeric is one of the overloads of log. +func log_numeric(num NumericType) (NumericType, error) { + if num.IsNull { + return NumericType{IsNull: true}, nil + } + if num.Value == 0 { + return NumericType{}, fmt.Errorf("cannot take logarithm of zero") + } else if num.Value < 0 { + return NumericType{}, fmt.Errorf("cannot take logarithm of a negative number") + } + return NumericType{Value: math.Log10(num.Value)}, nil +} + +// log_numeric_numeric is one of the overloads of log. +func log_numeric_numeric(base NumericType, num NumericType) (NumericType, error) { + if base.IsNull || num.IsNull { + return NumericType{IsNull: true}, nil + } + if base.Value == 0 || num.Value == 0 { + return NumericType{}, fmt.Errorf("cannot take logarithm of zero") + } else if base.Value < 0 || num.Value < 0 { + return NumericType{}, fmt.Errorf("cannot take logarithm of a negative number") + } + return NumericType{Value: math.Log(num.Value) / math.Log(base.Value)}, nil +} diff --git a/server/functions/log10.go b/server/functions/log10.go new file mode 100644 index 0000000000..9a8949fdfe --- /dev/null +++ b/server/functions/log10.go @@ -0,0 +1,21 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// log10 represents the PostgreSQL function of the same name. +var log10 = Function{ + Name: "log10", + Overloads: []interface{}{log_float, log_numeric}, +} diff --git a/server/functions/lower.go b/server/functions/lower.go new file mode 100644 index 0000000000..9dcb15a4b7 --- /dev/null +++ b/server/functions/lower.go @@ -0,0 +1,32 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "strings" + +// lower represents the PostgreSQL function of the same name. +var lower = Function{ + Name: "lower", + Overloads: []interface{}{lower_string}, +} + +// lower_string is one of the overloads of lower. +func lower_string(text StringType) (StringType, error) { + if text.IsNull { + return StringType{IsNull: true}, nil + } + //TODO: this doesn't respect collations + return StringType{Value: strings.ToLower(text.Value)}, nil +} diff --git a/server/functions/lpad.go b/server/functions/lpad.go new file mode 100644 index 0000000000..3422c13324 --- /dev/null +++ b/server/functions/lpad.go @@ -0,0 +1,53 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// lpad represents the PostgreSQL function of the same name. +var lpad = Function{ + Name: "lpad", + Overloads: []interface{}{lpad_string_int, lpad_string_int_string}, +} + +// lpad_string_int is one of the overloads of lpad. +func lpad_string_int(str StringType, length IntegerType) (StringType, error) { + return lpad_string_int_string(str, length, StringType{ + Value: " ", + IsNull: false, + OriginalType: ParameterType_String, + Source: Source_Constant, + }) +} + +// lpad_string_int_string is one of the overloads of lpad. +func lpad_string_int_string(str StringType, length IntegerType, fill StringType) (StringType, error) { + if str.IsNull || length.IsNull || fill.IsNull { + return StringType{IsNull: true}, nil + } + if length.Value <= 0 { + return StringType{Value: ""}, nil + } + runes := []rune(str.Value) + fillTarget := length.Value - int64(len(runes)) + fillRunes := []rune(fill.Value) + var result []rune + if fillTarget > 0 { + for int64(len(result)) < fillTarget { + result = append(result, fillRunes...) + } + result = result[:fillTarget] + } + result = append(result, runes...) + return StringType{Value: string(result[:length.Value])}, nil +} diff --git a/server/functions/ltrim.go b/server/functions/ltrim.go new file mode 100644 index 0000000000..4a8f02d865 --- /dev/null +++ b/server/functions/ltrim.go @@ -0,0 +1,50 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// ltrim represents the PostgreSQL function of the same name. +var ltrim = Function{ + Name: "ltrim", + Overloads: []interface{}{ltrim_string, ltrim_string_string}, +} + +// ltrim_string is one of the overloads of ltrim. +func ltrim_string(str StringType) (StringType, error) { + return ltrim_string_string(str, StringType{ + Value: " ", + IsNull: false, + OriginalType: ParameterType_String, + Source: Source_Constant, + }) +} + +// ltrim_string_string is one of the overloads of ltrim. +func ltrim_string_string(str StringType, characters StringType) (StringType, error) { + if str.IsNull || characters.IsNull { + return StringType{IsNull: true}, nil + } + runes := []rune(str.Value) + trimChars := make(map[rune]struct{}) + for _, c := range characters.Value { + trimChars[c] = struct{}{} + } + trimIdx := 0 + for ; trimIdx < len(runes); trimIdx++ { + if _, ok := trimChars[runes[trimIdx]]; !ok { + break + } + } + return StringType{Value: string(runes[trimIdx:])}, nil +} diff --git a/server/functions/md5.go b/server/functions/md5.go new file mode 100644 index 0000000000..27115048c8 --- /dev/null +++ b/server/functions/md5.go @@ -0,0 +1,34 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import ( + md5_package "crypto/md5" + "fmt" +) + +// md5 represents the PostgreSQL function of the same name. +var md5 = Function{ + Name: "md5", + Overloads: []interface{}{md5_string}, +} + +// md5_string is one of the overloads of md5. +func md5_string(text StringType) (StringType, error) { + if text.IsNull { + return StringType{IsNull: true}, nil + } + return StringType{Value: fmt.Sprintf("%x", md5_package.Sum([]byte(text.Value)))}, nil +} diff --git a/server/functions/min_scale.go b/server/functions/min_scale.go new file mode 100644 index 0000000000..946a826179 --- /dev/null +++ b/server/functions/min_scale.go @@ -0,0 +1,45 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import ( + "strconv" + "strings" +) + +// min_scale represents the PostgreSQL function of the same name. +var min_scale = Function{ + Name: "min_scale", + Overloads: []interface{}{min_scale_numeric}, +} + +// min_scale_numeric is one of the overloads of min_scale. +func min_scale_numeric(num NumericType) (NumericType, error) { + if num.IsNull { + return NumericType{IsNull: true}, nil + } + str := strconv.FormatFloat(num.Value, 'f', -1, 64) + if idx := strings.Index(str, "."); idx != -1 { + str = str[idx+1:] + i := len(str) - 1 + for ; i >= 0; i-- { + if str[i] != '0' { + break + } + } + return NumericType{Value: float64(i + 1)}, nil + } + return NumericType{Value: 0}, nil +} diff --git a/server/functions/mod.go b/server/functions/mod.go new file mode 100644 index 0000000000..0c256ccb20 --- /dev/null +++ b/server/functions/mod.go @@ -0,0 +1,37 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// mod represents the PostgreSQL function of the same name. +var mod = Function{ + Name: "mod", + Overloads: []interface{}{mod_int_int, mod_num_num}, +} + +// mod_int_int is one of the overloads of mod. +func mod_int_int(num1 IntegerType, num2 IntegerType) (IntegerType, error) { + if num1.IsNull || num2.IsNull { + return IntegerType{IsNull: true}, nil + } + return IntegerType{Value: num1.Value % num2.Value}, nil +} + +// mod_num_num is one of the overloads of mod. +func mod_num_num(num1 NumericType, num2 NumericType) (NumericType, error) { + if num1.IsNull || num2.IsNull { + return NumericType{IsNull: true}, nil + } + return NumericType{Value: float64(int64(num1.Value) % int64(num2.Value))}, nil +} diff --git a/server/functions/octet_length.go b/server/functions/octet_length.go new file mode 100644 index 0000000000..44f26d4536 --- /dev/null +++ b/server/functions/octet_length.go @@ -0,0 +1,29 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// octet_length represents the PostgreSQL function of the same name. +var octet_length = Function{ + Name: "octet_length", + Overloads: []interface{}{octet_length_string}, +} + +// octet_length_string is one of the overloads of octet_length. +func octet_length_string(text StringType) (IntegerType, error) { + if text.IsNull { + return IntegerType{IsNull: true}, nil + } + return IntegerType{Value: int64(len(text.Value))}, nil +} diff --git a/server/functions/pi.go b/server/functions/pi.go new file mode 100644 index 0000000000..b89fcb5e18 --- /dev/null +++ b/server/functions/pi.go @@ -0,0 +1,28 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// pi represents the PostgreSQL function of the same name. +var pi = Function{ + Name: "pi", + Overloads: []interface{}{pi_float}, +} + +// pi_float is one of the overloads of pi. +func pi_float() (FloatType, error) { + return FloatType{Value: math.Pi}, nil +} diff --git a/server/functions/power.go b/server/functions/power.go new file mode 100644 index 0000000000..9f50fd0c5e --- /dev/null +++ b/server/functions/power.go @@ -0,0 +1,39 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// power represents the PostgreSQL function of the same name. +var power = Function{ + Name: "power", + Overloads: []interface{}{power_float_float, power_num_num}, +} + +// power_float_float is one of the overloads of power. +func power_float_float(num1 FloatType, num2 FloatType) (FloatType, error) { + if num1.IsNull || num2.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Pow(num1.Value, num2.Value)}, nil +} + +// power_num_num is one of the overloads of power. +func power_num_num(num1 NumericType, num2 NumericType) (NumericType, error) { + if num1.IsNull || num2.IsNull { + return NumericType{IsNull: true}, nil + } + return NumericType{Value: math.Pow(num1.Value, num2.Value)}, nil +} diff --git a/server/functions/radians.go b/server/functions/radians.go new file mode 100644 index 0000000000..6507986942 --- /dev/null +++ b/server/functions/radians.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// radians represents the PostgreSQL function of the same name. +var radians = Function{ + Name: "radians", + Overloads: []interface{}{radians_float}, +} + +// radians_float is one of the overloads of radians. +func radians_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: num.Value * (180.0 / math.Pi)}, nil +} diff --git a/server/functions/random.go b/server/functions/random.go new file mode 100644 index 0000000000..ebdf0aa62c --- /dev/null +++ b/server/functions/random.go @@ -0,0 +1,28 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math/rand" + +// random represents the PostgreSQL function of the same name. +var random = Function{ + Name: "random", + Overloads: []interface{}{random_float}, +} + +// random_float is one of the overloads of random. +func random_float() (FloatType, error) { + return FloatType{Value: rand.Float64()}, nil +} diff --git a/server/functions/repeat.go b/server/functions/repeat.go new file mode 100644 index 0000000000..8f8d1f1b79 --- /dev/null +++ b/server/functions/repeat.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "strings" + +// repeat represents the PostgreSQL function of the same name. +var repeat = Function{ + Name: "repeat", + Overloads: []interface{}{repeat_string}, +} + +// repeat_string is one of the overloads of repeat. +func repeat_string(str StringType, num IntegerType) (StringType, error) { + if str.IsNull || num.IsNull { + return StringType{IsNull: true}, nil + } + return StringType{Value: strings.Repeat(str.Value, int(num.Value))}, nil +} diff --git a/server/functions/replace.go b/server/functions/replace.go new file mode 100644 index 0000000000..baf3d2c11a --- /dev/null +++ b/server/functions/replace.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "strings" + +// replace represents the PostgreSQL function of the same name. +var replace = Function{ + Name: "replace", + Overloads: []interface{}{replace_string_string_string}, +} + +// replace_string is one of the overloads of replace. +func replace_string_string_string(str StringType, from StringType, to StringType) (StringType, error) { + if str.IsNull || from.IsNull || to.IsNull { + return StringType{IsNull: true}, nil + } + return StringType{Value: strings.ReplaceAll(str.Value, from.Value, to.Value)}, nil +} diff --git a/server/functions/reverse.go b/server/functions/reverse.go new file mode 100644 index 0000000000..3b728956ee --- /dev/null +++ b/server/functions/reverse.go @@ -0,0 +1,33 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// reverse represents the PostgreSQL function of the same name. +var reverse = Function{ + Name: "reverse", + Overloads: []interface{}{reverse_string}, +} + +// reverse_string is one of the overloads of reverse. +func reverse_string(text StringType) (StringType, error) { + if text.IsNull { + return StringType{IsNull: true}, nil + } + runes := []rune(text.Value) + for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 { + runes[i], runes[j] = runes[j], runes[i] + } + return StringType{Value: string(runes)}, nil +} diff --git a/server/functions/right.go b/server/functions/right.go new file mode 100644 index 0000000000..2e98a055df --- /dev/null +++ b/server/functions/right.go @@ -0,0 +1,33 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// right represents the PostgreSQL function of the same name. +var right = Function{ + Name: "right", + Overloads: []interface{}{right_string}, +} + +// right_string is one of the overloads of right. +func right_string(string StringType, n IntegerType) (StringType, error) { + if string.IsNull || n.IsNull { + return StringType{IsNull: true}, nil + } + if n.Value >= 0 { + return StringType{Value: string.Value[len(string.Value)-int(n.Value):]}, nil + } else { + return StringType{Value: string.Value[int(-n.Value):]}, nil + } +} diff --git a/server/functions/round.go b/server/functions/round.go index 1b441d808c..5fc77a245e 100644 --- a/server/functions/round.go +++ b/server/functions/round.go @@ -22,7 +22,7 @@ var round = Function{ Overloads: []interface{}{round_num, round_float, round_num_dec}, } -// round1 is one of the overloads of round. +// round_num is one of the overloads of round. func round_num(num NumericType) (NumericType, error) { if num.IsNull { return NumericType{IsNull: true}, nil @@ -30,7 +30,7 @@ func round_num(num NumericType) (NumericType, error) { return NumericType{Value: math.Round(num.Value)}, nil } -// round2 is one of the overloads of round. +// round_float is one of the overloads of round. func round_float(num FloatType) (FloatType, error) { if num.IsNull { return FloatType{IsNull: true}, nil @@ -38,7 +38,7 @@ func round_float(num FloatType) (FloatType, error) { return FloatType{Value: math.RoundToEven(num.Value)}, nil } -// round3 is one of the overloads of round. +// round_num_dec is one of the overloads of round. func round_num_dec(num NumericType, decimalPlaces IntegerType) (NumericType, error) { if num.IsNull || decimalPlaces.IsNull { return NumericType{IsNull: true}, nil diff --git a/server/functions/rpad.go b/server/functions/rpad.go new file mode 100644 index 0000000000..826801ab99 --- /dev/null +++ b/server/functions/rpad.go @@ -0,0 +1,47 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// rpad represents the PostgreSQL function of the same name. +var rpad = Function{ + Name: "rpad", + Overloads: []interface{}{rpad_string_int, rpad_string_int_string}, +} + +// rpad_string_int is one of the overloads of rpad. +func rpad_string_int(str StringType, length IntegerType) (StringType, error) { + return rpad_string_int_string(str, length, StringType{ + Value: " ", + IsNull: false, + OriginalType: ParameterType_String, + Source: Source_Constant, + }) +} + +// rpad_string_int_string is one of the overloads of rpad. +func rpad_string_int_string(str StringType, length IntegerType, fill StringType) (StringType, error) { + if str.IsNull || length.IsNull || fill.IsNull { + return StringType{IsNull: true}, nil + } + if length.Value <= 0 { + return StringType{Value: ""}, nil + } + runes := []rune(str.Value) + fillRunes := []rune(fill.Value) + for int64(len(runes)) < length.Value { + runes = append(runes, fillRunes...) + } + return StringType{Value: string(runes[:length.Value])}, nil +} diff --git a/server/functions/rtrim.go b/server/functions/rtrim.go new file mode 100644 index 0000000000..efc181668a --- /dev/null +++ b/server/functions/rtrim.go @@ -0,0 +1,50 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// rtrim represents the PostgreSQL function of the same name. +var rtrim = Function{ + Name: "rtrim", + Overloads: []interface{}{rtrim_string, rtrim_string_string}, +} + +// rtrim_string is one of the overloads of rtrim. +func rtrim_string(str StringType) (StringType, error) { + return rtrim_string_string(str, StringType{ + Value: " ", + IsNull: false, + OriginalType: ParameterType_String, + Source: Source_Constant, + }) +} + +// rtrim_string_string is one of the overloads of rtrim. +func rtrim_string_string(str StringType, characters StringType) (StringType, error) { + if str.IsNull || characters.IsNull { + return StringType{IsNull: true}, nil + } + runes := []rune(str.Value) + trimChars := make(map[rune]struct{}) + for _, c := range characters.Value { + trimChars[c] = struct{}{} + } + trimIdx := len(runes) + for ; trimIdx > 0; trimIdx-- { + if _, ok := trimChars[runes[trimIdx-1]]; !ok { + break + } + } + return StringType{Value: string(runes[:trimIdx])}, nil +} diff --git a/server/functions/scale.go b/server/functions/scale.go new file mode 100644 index 0000000000..2993565c10 --- /dev/null +++ b/server/functions/scale.go @@ -0,0 +1,28 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// scale represents the PostgreSQL function of the same name. +var scale = Function{ + Name: "scale", + Overloads: []interface{}{scale_numeric}, +} + +// scale_numeric is one of the overloads of scale. +func scale_numeric(num NumericType) (IntegerType, error) { + //TODO: this is incorrect, as we process the numeric type as a float, which loses the scale + res, err := min_scale_numeric(num) + return IntegerType{Value: int64(res.Value)}, err +} diff --git a/server/functions/sign.go b/server/functions/sign.go new file mode 100644 index 0000000000..1a8a5275b7 --- /dev/null +++ b/server/functions/sign.go @@ -0,0 +1,49 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// sign represents the PostgreSQL function of the same name. +var sign = Function{ + Name: "sign", + Overloads: []interface{}{sign_float, sign_numeric}, +} + +// sign_float is one of the overloads of sign. +func sign_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + if num.Value < 0 { + return FloatType{Value: -1}, nil + } else if num.Value > 0 { + return FloatType{Value: 1}, nil + } else { + return FloatType{Value: 0}, nil + } +} + +// sign_numeric is one of the overloads of sign. +func sign_numeric(num NumericType) (NumericType, error) { + if num.IsNull { + return NumericType{IsNull: true}, nil + } + if num.Value < 0 { + return NumericType{Value: -1}, nil + } else if num.Value > 0 { + return NumericType{Value: 1}, nil + } else { + return NumericType{Value: 0}, nil + } +} diff --git a/server/functions/sin.go b/server/functions/sin.go new file mode 100644 index 0000000000..379a3856a2 --- /dev/null +++ b/server/functions/sin.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// sin represents the PostgreSQL function of the same name. +var sin = Function{ + Name: "sin", + Overloads: []interface{}{sin_float}, +} + +// sin_float is one of the overloads of sin. +func sin_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Sin(num.Value)}, nil +} diff --git a/server/functions/sind.go b/server/functions/sind.go new file mode 100644 index 0000000000..f10ddd3553 --- /dev/null +++ b/server/functions/sind.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// sind represents the PostgreSQL function of the same name. +var sind = Function{ + Name: "sind", + Overloads: []interface{}{sind_float}, +} + +// sind_float is one of the overloads of sind. +func sind_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: toDegrees(math.Sin(num.Value))}, nil +} diff --git a/server/functions/sinh.go b/server/functions/sinh.go new file mode 100644 index 0000000000..6c908ec164 --- /dev/null +++ b/server/functions/sinh.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// sinh represents the PostgreSQL function of the same name. +var sinh = Function{ + Name: "sinh", + Overloads: []interface{}{sinh_float}, +} + +// sinh_float is one of the overloads of sinh. +func sinh_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Sinh(num.Value)}, nil +} diff --git a/server/functions/split_part.go b/server/functions/split_part.go new file mode 100644 index 0000000000..c0aa9ead47 --- /dev/null +++ b/server/functions/split_part.go @@ -0,0 +1,47 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import ( + "fmt" + "strings" + + "github.com/dolthub/doltgresql/utils" +) + +// split_part represents the PostgreSQL function of the same name. +var split_part = Function{ + Name: "split_part", + Overloads: []interface{}{split_part_string}, +} + +// split_part_string is one of the overloads of split_part. +func split_part_string(str StringType, delimiter StringType, n IntegerType) (StringType, error) { + if str.IsNull || delimiter.IsNull || n.IsNull { + return StringType{IsNull: true}, nil + } + if n.Value == 0 { + return StringType{}, fmt.Errorf("field position must not be zero") + } + parts := strings.Split(str.Value, delimiter.Value) + if int(utils.Abs(n.Value)) > len(parts) { + return StringType{Value: ""}, nil + } + if n.Value > 0 { + return StringType{Value: parts[n.Value-1]}, nil + } else { + return StringType{Value: parts[int64(len(parts))+n.Value]}, nil + } +} diff --git a/server/functions/sqrt.go b/server/functions/sqrt.go new file mode 100644 index 0000000000..8a7d58d6e1 --- /dev/null +++ b/server/functions/sqrt.go @@ -0,0 +1,39 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// sqrt represents the PostgreSQL function of the same name. +var sqrt = Function{ + Name: "sqrt", + Overloads: []interface{}{sqrt_float, sqrt_numeric}, +} + +// sqrt_float is one of the overloads of sqrt. +func sqrt_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Sqrt(num.Value)}, nil +} + +// sqrt_numeric is one of the overloads of sqrt. +func sqrt_numeric(num NumericType) (NumericType, error) { + if num.IsNull { + return NumericType{IsNull: true}, nil + } + return NumericType{Value: math.Sqrt(num.Value)}, nil +} diff --git a/server/functions/strpos.go b/server/functions/strpos.go new file mode 100644 index 0000000000..667d5f42c3 --- /dev/null +++ b/server/functions/strpos.go @@ -0,0 +1,35 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "strings" + +// strpos represents the PostgreSQL function of the same name. +var strpos = Function{ + Name: "strpos", + Overloads: []interface{}{strpos_string}, +} + +// strpos_string is one of the overloads of strpos. +func strpos_string(str StringType, substring StringType) (IntegerType, error) { + if str.IsNull || substring.IsNull { + return IntegerType{IsNull: true}, nil + } + idx := strings.Index(str.Value, substring.Value) + if idx == -1 { + idx = 0 + } + return IntegerType{Value: int64(idx)}, nil +} diff --git a/server/functions/substr.go b/server/functions/substr.go new file mode 100644 index 0000000000..aacd3d4424 --- /dev/null +++ b/server/functions/substr.go @@ -0,0 +1,39 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// substr represents the PostgreSQL function of the same name. +var substr = Function{ + Name: "substr", + Overloads: []interface{}{substr_string_int, substr_string_int_int}, +} + +// substr_string_int is one of the overloads of substr. +func substr_string_int(str StringType, start IntegerType) (StringType, error) { + if str.IsNull || start.IsNull { + return StringType{IsNull: true}, nil + } + runes := []rune(str.Value) + return StringType{Value: string(runes[start.Value:])}, nil +} + +// substr_string_int_int is one of the overloads of substr. +func substr_string_int_int(str StringType, start IntegerType, count IntegerType) (StringType, error) { + if str.IsNull || start.IsNull || count.IsNull { + return StringType{IsNull: true}, nil + } + runes := []rune(str.Value) + return StringType{Value: string(runes[start.Value : start.Value+count.Value])}, nil +} diff --git a/server/functions/tan.go b/server/functions/tan.go new file mode 100644 index 0000000000..a38afb4555 --- /dev/null +++ b/server/functions/tan.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// tan represents the PostgreSQL function of the same name. +var tan = Function{ + Name: "tan", + Overloads: []interface{}{tan_float}, +} + +// tan_float is one of the overloads of tan. +func tan_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Tan(num.Value)}, nil +} diff --git a/server/functions/tand.go b/server/functions/tand.go new file mode 100644 index 0000000000..3b8530dee0 --- /dev/null +++ b/server/functions/tand.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// tand represents the PostgreSQL function of the same name. +var tand = Function{ + Name: "tand", + Overloads: []interface{}{tand_float}, +} + +// tand_float is one of the overloads of tand. +func tand_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: toDegrees(math.Tan(num.Value))}, nil +} diff --git a/server/functions/tanh.go b/server/functions/tanh.go new file mode 100644 index 0000000000..5f28311dc4 --- /dev/null +++ b/server/functions/tanh.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// tanh represents the PostgreSQL function of the same name. +var tanh = Function{ + Name: "tanh", + Overloads: []interface{}{tanh_float}, +} + +// tanh_float is one of the overloads of tanh. +func tanh_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Tanh(num.Value)}, nil +} diff --git a/server/functions/to_hex.go b/server/functions/to_hex.go new file mode 100644 index 0000000000..6e6cb89f9d --- /dev/null +++ b/server/functions/to_hex.go @@ -0,0 +1,31 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "fmt" + +// to_hex represents the PostgreSQL function of the same name. +var to_hex = Function{ + Name: "to_hex", + Overloads: []interface{}{to_hex_string}, +} + +// to_hex_string is one of the overloads of to_hex. +func to_hex_string(num IntegerType) (StringType, error) { + if num.IsNull { + return StringType{IsNull: true}, nil + } + return StringType{Value: fmt.Sprintf("%x", num.Value)}, nil +} diff --git a/server/functions/trim_scale.go b/server/functions/trim_scale.go new file mode 100644 index 0000000000..3b48a3eb23 --- /dev/null +++ b/server/functions/trim_scale.go @@ -0,0 +1,30 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +// trim_scale represents the PostgreSQL function of the same name. +var trim_scale = Function{ + Name: "trim_scale", + Overloads: []interface{}{trim_scale_numeric}, +} + +// trim_scale_numeric is one of the overloads of trim_scale. +func trim_scale_numeric(num NumericType) (NumericType, error) { + //TODO: numeric is currently just a float, so we cannot modify the scale, therefore making this function incorrect + if num.IsNull { + return NumericType{IsNull: true}, nil + } + return NumericType{Value: num.Value}, nil +} diff --git a/server/functions/trunc.go b/server/functions/trunc.go new file mode 100644 index 0000000000..458afbe13f --- /dev/null +++ b/server/functions/trunc.go @@ -0,0 +1,48 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "math" + +// trunc represents the PostgreSQL function of the same name. +var trunc = Function{ + Name: "trunc", + Overloads: []interface{}{trunc_float, trunc_num, trunc_num_int}, +} + +// trunc_float is one of the overloads of trunc. +func trunc_float(num FloatType) (FloatType, error) { + if num.IsNull { + return FloatType{IsNull: true}, nil + } + return FloatType{Value: math.Trunc(num.Value)}, nil +} + +// trunc_num is one of the overloads of trunc. +func trunc_num(num NumericType) (NumericType, error) { + if num.IsNull { + return NumericType{IsNull: true}, nil + } + return NumericType{Value: math.Trunc(num.Value)}, nil +} + +// trunc_num_int is one of the overloads of trunc. +func trunc_num_int(num NumericType, places IntegerType) (NumericType, error) { + if num.IsNull || places.IsNull { + return NumericType{IsNull: true}, nil + } + power := math.Pow10(int(places.Value)) + return NumericType{Value: math.Trunc(num.Value*power) / power}, nil +} diff --git a/server/functions/upper.go b/server/functions/upper.go new file mode 100644 index 0000000000..1a49938010 --- /dev/null +++ b/server/functions/upper.go @@ -0,0 +1,32 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import "strings" + +// upper represents the PostgreSQL function of the same name. +var upper = Function{ + Name: "upper", + Overloads: []interface{}{upper_string}, +} + +// upper_string is one of the overloads of upper. +func upper_string(text StringType) (StringType, error) { + if text.IsNull { + return StringType{IsNull: true}, nil + } + //TODO: this doesn't respect collations + return StringType{Value: strings.ToUpper(text.Value)}, nil +} diff --git a/server/functions/width_bucket.go b/server/functions/width_bucket.go new file mode 100644 index 0000000000..04cb05b1e7 --- /dev/null +++ b/server/functions/width_bucket.go @@ -0,0 +1,50 @@ +// Copyright 2024 Dolthub, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package functions + +import ( + "fmt" + "math" +) + +// width_bucket represents the PostgreSQL function of the same name. +var width_bucket = Function{ + Name: "width_bucket", + Overloads: []interface{}{width_bucket_float, width_bucket_numeric}, +} + +// width_bucket_float is one of the overloads of width_bucket. +func width_bucket_float(operand FloatType, low FloatType, high FloatType, count IntegerType) (IntegerType, error) { + if operand.IsNull || low.IsNull || high.IsNull || count.IsNull { + return IntegerType{IsNull: true}, nil + } + if count.Value <= 0 { + return IntegerType{}, fmt.Errorf("count must be greater than zero") + } + bucket := (high.Value - low.Value) / float64(count.Value) + result := int64(math.Ceil((operand.Value - low.Value) / bucket)) + if result < 0 { + result = 0 + } else if result > count.Value+1 { + result = count.Value + 1 + } + return IntegerType{Value: result}, nil +} + +// width_bucket_numeric is one of the overloads of width_bucket. +func width_bucket_numeric(operand NumericType, low NumericType, high NumericType, count IntegerType) (IntegerType, error) { + //TODO: need to implement proper numeric support + return width_bucket_float(FloatType(operand), FloatType(low), FloatType(high), count) +} diff --git a/server/functions/zinternal_catalog.go b/server/functions/zinternal_catalog.go index d6d6dac5c5..8994bf2ff4 100644 --- a/server/functions/zinternal_catalog.go +++ b/server/functions/zinternal_catalog.go @@ -32,10 +32,80 @@ type Function struct { // Catalog contains all of the PostgreSQL functions. If a new function is added, make sure to add it to the catalog here. var Catalog = []Function{ + abs, + acos, + acosd, + acosh, + ascii, + asin, + asind, + asinh, + atan, + atan2, + atan2d, + atand, + atanh, + bit_length, + btrim, cbrt, + ceil, + ceiling, + char_length, + character_length, + chr, + cos, + cosd, + cosh, + cot, + cotd, + degrees, + div, + exp, + factorial, + floor, gcd, + initcap, lcm, + left, + length, + ln, + log, + log10, + lower, + lpad, + ltrim, + md5, + min_scale, + mod, + octet_length, + pi, + power, + radians, + random, + repeat, + replace, + reverse, + right, round, + rpad, + rtrim, + scale, + sign, + sin, + sind, + sinh, + split_part, + sqrt, + strpos, + substr, + tan, + tand, + tanh, + to_hex, + trim_scale, + trunc, + upper, + width_bucket, } // init handles the initialization of the catalog by overwriting the built-in GMS functions, since they do not apply to