chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '&' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryBitAnd registers the functions to the catalog.
|
||||
func initBinaryBitAnd() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryBitAnd, int2and)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryBitAnd, int4and)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryBitAnd, int8and)
|
||||
}
|
||||
|
||||
// int2and_callable is the callable logic for the int2and function.
|
||||
func int2and_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int16(val1.(int16) & val2.(int16)), nil
|
||||
}
|
||||
|
||||
// int2and represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2and = framework.Function2{
|
||||
Name: "int2and",
|
||||
Return: pgtypes.Int16,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: int2and_callable,
|
||||
}
|
||||
|
||||
// int4and_callable is the callable logic for the int4and function.
|
||||
func int4and_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int32(val1.(int32) & val2.(int32)), nil
|
||||
}
|
||||
|
||||
// int4and represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4and = framework.Function2{
|
||||
Name: "int4and",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: int4and_callable,
|
||||
}
|
||||
|
||||
// int8and_callable is the callable logic for the int8and function.
|
||||
func int8and_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int64(val1.(int64) & val2.(int64)), nil
|
||||
}
|
||||
|
||||
// int8and represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8and = framework.Function2{
|
||||
Name: "int8and",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: int8and_callable,
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '|' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryBitOr registers the functions to the catalog.
|
||||
func initBinaryBitOr() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryBitOr, int2or)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryBitOr, int4or)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryBitOr, int8or)
|
||||
}
|
||||
|
||||
// int2or_callable is the callable logic for the int2or function.
|
||||
func int2or_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int16(val1.(int16) | val2.(int16)), nil
|
||||
}
|
||||
|
||||
// int2or represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2or = framework.Function2{
|
||||
Name: "int2or",
|
||||
Return: pgtypes.Int16,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: int2or_callable,
|
||||
}
|
||||
|
||||
// int4or_callable is the callable logic for the int4or function.
|
||||
func int4or_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int32(val1.(int32) | val2.(int32)), nil
|
||||
}
|
||||
|
||||
// int4or represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4or = framework.Function2{
|
||||
Name: "int4or",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: int4or_callable,
|
||||
}
|
||||
|
||||
// int8or_callable is the callable logic for the int8or function.
|
||||
func int8or_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int64(val1.(int64) | val2.(int64)), nil
|
||||
}
|
||||
|
||||
// int8or represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8or = framework.Function2{
|
||||
Name: "int8or",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: int8or_callable,
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '#' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryBitXor registers the functions to the catalog.
|
||||
func initBinaryBitXor() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryBitXor, int2xor)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryBitXor, int4xor)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryBitXor, int8xor)
|
||||
}
|
||||
|
||||
// int2xor_callable is the callable logic for the int2xor function.
|
||||
func int2xor_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int16(val1.(int16) ^ val2.(int16)), nil
|
||||
}
|
||||
|
||||
// int2xor represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2xor = framework.Function2{
|
||||
Name: "int2xor",
|
||||
Return: pgtypes.Int16,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: int2xor_callable,
|
||||
}
|
||||
|
||||
// int4xor_callable is the callable logic for the int4xor function.
|
||||
func int4xor_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int32(val1.(int32) ^ val2.(int32)), nil
|
||||
}
|
||||
|
||||
// int4xor represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4xor = framework.Function2{
|
||||
Name: "int4xor",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: int4xor_callable,
|
||||
}
|
||||
|
||||
// int8xor_callable is the callable logic for the int8xor function.
|
||||
func int8xor_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int64(val1.(int64) ^ val2.(int64)), nil
|
||||
}
|
||||
|
||||
// int8xor represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8xor = framework.Function2{
|
||||
Name: "int8xor",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: int8xor_callable,
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
gmstypes "github.com/dolthub/go-mysql-server/sql/types"
|
||||
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '||' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryConcatenate registers the functions to the catalog.
|
||||
func initBinaryConcatenate() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryConcatenate, anytextcat)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryConcatenate, array_append)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryConcatenate, array_cat)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryConcatenate, array_prepend)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryConcatenate, byteacat)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryConcatenate, jsonb_concat)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryConcatenate, textanycat)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryConcatenate, textcat)
|
||||
// TODO: bitcat, tsquery_or, tsvector_concat
|
||||
}
|
||||
|
||||
// anytextcat_callable is the callable logic for the anytextcat function.
|
||||
func anytextcat_callable(ctx *sql.Context, paramsAndReturn [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
valType := paramsAndReturn[0]
|
||||
val1String, err := valType.IoOutput(ctx, val1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return val1String + val2.(string), nil
|
||||
}
|
||||
|
||||
// anytextcat represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var anytextcat = framework.Function2{
|
||||
Name: "anytextcat",
|
||||
Return: pgtypes.Text,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.AnyNonArray, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: anytextcat_callable,
|
||||
}
|
||||
|
||||
// array_append represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var array_append = framework.Function2{
|
||||
Name: "array_append",
|
||||
Return: pgtypes.AnyArray, // TODO: should be anycompatiblearray
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.AnyArray, pgtypes.AnyElement}, // TODO: should be anycompatiblearray, anycompatible
|
||||
Strict: false,
|
||||
Callable: func(ctx *sql.Context, paramsAndReturn [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val1 == nil {
|
||||
return []any{val2}, nil
|
||||
}
|
||||
array := val1.([]any)
|
||||
returnArray := make([]any, len(array)+1)
|
||||
copy(returnArray, array)
|
||||
returnArray[len(returnArray)-1] = val2
|
||||
return returnArray, nil
|
||||
},
|
||||
}
|
||||
|
||||
// array_cat represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var array_cat = framework.Function2{
|
||||
Name: "array_cat",
|
||||
Return: pgtypes.AnyArray, // TODO: should be anycompatiblearray
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.AnyArray, pgtypes.AnyArray}, // TODO: should be anycompatiblearray, anycompatiblearray
|
||||
Strict: false,
|
||||
Callable: func(ctx *sql.Context, paramsAndReturn [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val1 == nil && val2 == nil {
|
||||
return nil, nil
|
||||
} else if val1 == nil {
|
||||
return val2, nil
|
||||
} else if val2 == nil {
|
||||
return val1, nil
|
||||
}
|
||||
|
||||
array1 := val1.([]any)
|
||||
array2 := val2.([]any)
|
||||
|
||||
// Concatenate the arrays
|
||||
result := make([]any, len(array1)+len(array2))
|
||||
copy(result, array1)
|
||||
copy(result[len(array1):], array2)
|
||||
|
||||
return result, nil
|
||||
},
|
||||
}
|
||||
|
||||
// array_prepend represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var array_prepend = framework.Function2{
|
||||
Name: "array_prepend",
|
||||
Return: pgtypes.AnyArray, // TODO: should be anycompatiblearray
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.AnyElement, pgtypes.AnyArray}, // TODO: should be anycompatible, anycompatiblearray
|
||||
Strict: false,
|
||||
Callable: func(ctx *sql.Context, paramsAndReturn [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2 == nil {
|
||||
return []any{val1}, nil
|
||||
}
|
||||
return append([]any{val1}, val2.([]any)...), nil
|
||||
},
|
||||
}
|
||||
|
||||
// byteacat_callable is the callable logic for the byteacat function.
|
||||
func byteacat_callable(ctx *sql.Context, paramsAndReturn [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
v1 := val1.([]byte)
|
||||
v2 := val2.([]byte)
|
||||
copied := make([]byte, len(v1)+len(v2))
|
||||
copy(copied, v1)
|
||||
copy(copied[len(v1):], v2)
|
||||
return copied, nil
|
||||
}
|
||||
|
||||
// byteacat represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var byteacat = framework.Function2{
|
||||
Name: "byteacat",
|
||||
Return: pgtypes.Bytea,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bytea, pgtypes.Bytea},
|
||||
Strict: true,
|
||||
Callable: byteacat_callable,
|
||||
}
|
||||
|
||||
// jsonb_concat_callable is the callable logic for the jsonb_concat function.
|
||||
func jsonb_concat_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1Interface any, val2Interface any) (any, error) {
|
||||
// TODO: for two IndexedJsonDocuments, we could get much faster results on large documents by merging the underlying
|
||||
// JSON trees instead of loading them into memory. This would require a new method on sql.MutableJSON
|
||||
wrapper1, ok1 := val1Interface.(sql.JSONWrapper)
|
||||
wrapper2, ok2 := val2Interface.(sql.JSONWrapper)
|
||||
if !ok1 || !ok2 {
|
||||
return nil, fmt.Errorf("jsonb_concat: unexpected types %T, %T", val1Interface, val2Interface)
|
||||
}
|
||||
v1, err := wrapper1.ToInterface(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v2, err := wrapper2.ToInterface(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Merge objects if both are objects
|
||||
obj1, isObj1 := v1.(map[string]interface{})
|
||||
obj2, isObj2 := v2.(map[string]interface{})
|
||||
if isObj1 && isObj2 {
|
||||
newObj := make(map[string]interface{}, len(obj1)+len(obj2))
|
||||
for k, v := range obj1 {
|
||||
newObj[k] = v
|
||||
}
|
||||
for k, v := range obj2 {
|
||||
newObj[k] = v
|
||||
}
|
||||
return gmstypes.JSONDocument{Val: newObj}, nil
|
||||
}
|
||||
// Not both objects: wrap non-arrays in single-element arrays and concatenate
|
||||
arr1, isArr1 := v1.([]interface{})
|
||||
arr2, isArr2 := v2.([]interface{})
|
||||
if !isArr1 {
|
||||
arr1 = []interface{}{v1}
|
||||
}
|
||||
if !isArr2 {
|
||||
arr2 = []interface{}{v2}
|
||||
}
|
||||
newArray := make([]interface{}, len(arr1)+len(arr2))
|
||||
copy(newArray, arr1)
|
||||
copy(newArray[len(arr1):], arr2)
|
||||
return gmstypes.JSONDocument{Val: newArray}, nil
|
||||
}
|
||||
|
||||
// jsonb_concat represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_concat = framework.Function2{
|
||||
Name: "jsonb_concat",
|
||||
Return: pgtypes.JsonB,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.JsonB},
|
||||
Strict: true,
|
||||
Callable: jsonb_concat_callable,
|
||||
}
|
||||
|
||||
// textanycat_callable is the callable logic for the textanycat function.
|
||||
func textanycat_callable(ctx *sql.Context, paramsAndReturn [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
valType := paramsAndReturn[1]
|
||||
val2String, err := valType.IoOutput(ctx, val2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return val1.(string) + val2String, nil
|
||||
}
|
||||
|
||||
// textanycat represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var textanycat = framework.Function2{
|
||||
Name: "textanycat",
|
||||
Return: pgtypes.Text,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.AnyNonArray},
|
||||
Strict: true,
|
||||
Callable: textanycat_callable,
|
||||
}
|
||||
|
||||
// textcat_callable is the callable logic for the textcat function.
|
||||
func textcat_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return val1.(string) + val2.(string), nil
|
||||
}
|
||||
|
||||
// textcat represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var textcat = framework.Function2{
|
||||
Name: "textcat",
|
||||
Return: pgtypes.Text,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: textcat_callable,
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
"github.com/cockroachdb/apd/v3"
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/postgres/parser/duration"
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '/' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryDivide registers the functions to the catalog.
|
||||
func initBinaryDivide() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, float4div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, float48div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, float8div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, float84div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, int2div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, int24div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, int28div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, int4div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, int42div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, int48div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, int8div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, int82div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, int84div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, interval_div)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryDivide, numeric_div)
|
||||
}
|
||||
|
||||
// float4div_callable is the callable logic for the float4div function.
|
||||
func float4div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(float32) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return val1.(float32) / val2.(float32), nil
|
||||
}
|
||||
|
||||
// float4div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float4div = framework.Function2{
|
||||
Name: "float4div",
|
||||
Return: pgtypes.Float32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: float4div_callable,
|
||||
}
|
||||
|
||||
// float48div_callable is the callable logic for the float48div function.
|
||||
func float48div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(float64) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return float64(val1.(float32)) / val2.(float64), nil
|
||||
}
|
||||
|
||||
// float48div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float48div = framework.Function2{
|
||||
Name: "float48div",
|
||||
Return: pgtypes.Float64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: float48div_callable,
|
||||
}
|
||||
|
||||
// float8div_callable is the callable logic for the float8div function.
|
||||
func float8div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(float64) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return val1.(float64) / val2.(float64), nil
|
||||
}
|
||||
|
||||
// float8div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float8div = framework.Function2{
|
||||
Name: "float8div",
|
||||
Return: pgtypes.Float64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: float8div_callable,
|
||||
}
|
||||
|
||||
// float84div_callable is the callable logic for the float84div function.
|
||||
func float84div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(float32) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return val1.(float64) / float64(val2.(float32)), nil
|
||||
}
|
||||
|
||||
// float84div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float84div = framework.Function2{
|
||||
Name: "float84div",
|
||||
Return: pgtypes.Float64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: float84div_callable,
|
||||
}
|
||||
|
||||
// int2div_callable is the callable logic for the int2div function.
|
||||
func int2div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(int16) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return val1.(int16) / val2.(int16), nil
|
||||
}
|
||||
|
||||
// int2div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2div = framework.Function2{
|
||||
Name: "int2div",
|
||||
Return: pgtypes.Int16,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: int2div_callable,
|
||||
}
|
||||
|
||||
// int24div_callable is the callable logic for the int24div function.
|
||||
func int24div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(int32) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return int32(val1.(int16)) / val2.(int32), nil
|
||||
}
|
||||
|
||||
// int24div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int24div = framework.Function2{
|
||||
Name: "int24div",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: int24div_callable,
|
||||
}
|
||||
|
||||
// int28div_callable is the callable logic for the int28div function.
|
||||
func int28div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(int64) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return int64(val1.(int16)) / val2.(int64), nil
|
||||
}
|
||||
|
||||
// int28div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int28div = framework.Function2{
|
||||
Name: "int28div",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: int28div_callable,
|
||||
}
|
||||
|
||||
// int4div_callable is the callable logic for the int4div function.
|
||||
func int4div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(int32) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return val1.(int32) / val2.(int32), nil
|
||||
}
|
||||
|
||||
// int4div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4div = framework.Function2{
|
||||
Name: "int4div",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: int4div_callable,
|
||||
}
|
||||
|
||||
// int42div_callable is the callable logic for the int42div function.
|
||||
func int42div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(int16) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return val1.(int32) / int32(val2.(int16)), nil
|
||||
}
|
||||
|
||||
// int42div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int42div = framework.Function2{
|
||||
Name: "int42div",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: int42div_callable,
|
||||
}
|
||||
|
||||
// int48div_callable is the callable logic for the int48div function.
|
||||
func int48div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(int64) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return int64(val1.(int32)) / val2.(int64), nil
|
||||
}
|
||||
|
||||
// int48div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int48div = framework.Function2{
|
||||
Name: "int48div",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: int48div_callable,
|
||||
}
|
||||
|
||||
// int8div_callable is the callable logic for the int8div function.
|
||||
func int8div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(int64) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return val1.(int64) / val2.(int64), nil
|
||||
}
|
||||
|
||||
// int8div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8div = framework.Function2{
|
||||
Name: "int8div",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: int8div_callable,
|
||||
}
|
||||
|
||||
// int82div_callable is the callable logic for the int82div function.
|
||||
func int82div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(int16) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return val1.(int64) / int64(val2.(int16)), nil
|
||||
}
|
||||
|
||||
// int82div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int82div = framework.Function2{
|
||||
Name: "int82div",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: int82div_callable,
|
||||
}
|
||||
|
||||
// int84div_callable is the callable logic for the int84div function.
|
||||
func int84div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(int32) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return val1.(int64) / int64(val2.(int32)), nil
|
||||
}
|
||||
|
||||
// int84div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int84div = framework.Function2{
|
||||
Name: "int84div",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: int84div_callable,
|
||||
}
|
||||
|
||||
// interval_div_callable is the callable logic for the interval_div function.
|
||||
func interval_div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(float64) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return val1.(duration.Duration).DivFloat(val2.(float64)), nil
|
||||
}
|
||||
|
||||
// interval_div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_div = framework.Function2{
|
||||
Name: "interval_div",
|
||||
Return: pgtypes.Interval,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: interval_div_callable,
|
||||
}
|
||||
|
||||
// numeric_div_callable is the callable logic for the numeric_div function.
|
||||
func numeric_div_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
num1 := val1.(*apd.Decimal)
|
||||
num2 := val2.(*apd.Decimal)
|
||||
if num1.Form == apd.NaN || num2.Form == apd.NaN ||
|
||||
(num1.Form == apd.Infinite && num2.Form == apd.Infinite) {
|
||||
return pgtypes.NumericNaN, nil
|
||||
}
|
||||
if num2.IsZero() {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
if num1.Form == apd.Infinite {
|
||||
return num1, nil
|
||||
}
|
||||
if num2.Form == apd.Infinite {
|
||||
return apd.New(0, 0), nil
|
||||
}
|
||||
|
||||
res := new(apd.Decimal)
|
||||
// enough precision to scale to at most 16 decimal places
|
||||
p := num1.NumDigits() + int64(math.Abs(float64(num1.Exponent))) + 16
|
||||
_, err := sql.DecimalCtx.WithPrecision(uint32(p)).Quo(res, num1, num2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// the exponent value depends on the number of digits before decimal places.
|
||||
parts := strings.Split(res.Text('f'), ".")
|
||||
whole := (len(parts[0]) + 4 - 1) / 4
|
||||
exp := int32(16 - (whole-1)*4)
|
||||
|
||||
return sql.DecimalRound(res, exp)
|
||||
}
|
||||
|
||||
// numeric_div represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var numeric_div = framework.Function2{
|
||||
Name: "numeric_div",
|
||||
Return: pgtypes.Numeric,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Numeric, pgtypes.Numeric},
|
||||
Strict: true,
|
||||
Callable: numeric_div_callable,
|
||||
}
|
||||
@@ -0,0 +1,739 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/apd/v3"
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/core/id"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/duration"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timeofday"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timetz"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/uuid"
|
||||
"github.com/dolthub/doltgresql/server/compare"
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '=' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryEqual registers the functions to the catalog.
|
||||
func initBinaryEqual() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, biteq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, booleq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, bpchareq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, byteaeq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, chareq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, date_eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, date_eq_timestamp)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, date_eq_timestamptz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, enum_eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, float4eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, float48eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, float84eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, float8eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, int2eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, int24eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, int28eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, int42eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, int4eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, int48eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, int82eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, int84eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, int8eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, interval_eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, jsonb_eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, nameeq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, nameeqtext)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, numeric_eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, oideq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, oidvectoreq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, texteqname)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, text_eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, record_eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, time_eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, timestamp_eq_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, timestamp_eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, timestamp_eq_timestamptz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, timestamptz_eq_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, timestamptz_eq_timestamp)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, timestamptz_eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, timetz_eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, uuid_eq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, varbiteq)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, xideqint4)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryEqual, xideq)
|
||||
}
|
||||
|
||||
// booleq_callable is the callable logic for the booleq function.
|
||||
func booleq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Bool.Compare(ctx, val1.(bool), val2.(bool))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// booleq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var booleq = framework.Function2{
|
||||
Name: "booleq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bool, pgtypes.Bool},
|
||||
Strict: true,
|
||||
Callable: booleq_callable,
|
||||
}
|
||||
|
||||
// bpchareq_callable is the callable logic for the bpchareq function.
|
||||
func bpchareq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.BpChar.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// bpchareq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var bpchareq = framework.Function2{
|
||||
Name: "bpchareq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.BpChar, pgtypes.BpChar},
|
||||
Strict: true,
|
||||
Callable: bpchareq_callable,
|
||||
}
|
||||
|
||||
// byteaeq_callable is the callable logic for the byteaeq function.
|
||||
func byteaeq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Bytea.Compare(ctx, val1, val2)
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// byteaeq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var byteaeq = framework.Function2{
|
||||
Name: "byteaeq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bytea, pgtypes.Bytea},
|
||||
Strict: true,
|
||||
Callable: byteaeq_callable,
|
||||
}
|
||||
|
||||
// chareq_callable is the callable logic for the chareq function.
|
||||
func chareq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.InternalChar.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// chareq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var chareq = framework.Function2{
|
||||
Name: "chareq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.InternalChar, pgtypes.InternalChar},
|
||||
Strict: true,
|
||||
Callable: chareq_callable,
|
||||
}
|
||||
|
||||
// date_eq_callable is the callable logic for the date_eq function.
|
||||
func date_eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Date.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// date_eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_eq = framework.Function2{
|
||||
Name: "date_eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: date_eq_callable,
|
||||
}
|
||||
|
||||
// date_eq_timestamp_callable is the callable logic for the date_eq_timestamp function.
|
||||
func date_eq_timestamp_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res == 0, nil
|
||||
}
|
||||
|
||||
// date_eq_timestamp represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_eq_timestamp = framework.Function2{
|
||||
Name: "date_eq_timestamp",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: date_eq_timestamp_callable,
|
||||
}
|
||||
|
||||
// date_eq_timestamptz_callable is the callable logic for the date_eq_timestamptz function.
|
||||
func date_eq_timestamptz_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res == 0, nil
|
||||
}
|
||||
|
||||
// date_eq_timestamptz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_eq_timestamptz = framework.Function2{
|
||||
Name: "date_eq_timestamptz",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: date_eq_timestamptz_callable,
|
||||
}
|
||||
|
||||
// enum_eq_callable is the callable logic for the enum_eq function.
|
||||
func enum_eq_callable(ctx *sql.Context, t [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
// TODO: if given types are not the same enum type, it cannot compare
|
||||
res, err := t[0].Compare(ctx, val1, val2)
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// enum_eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var enum_eq = framework.Function2{
|
||||
Name: "enum_eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.AnyEnum, pgtypes.AnyEnum},
|
||||
Strict: true,
|
||||
Callable: enum_eq_callable,
|
||||
}
|
||||
|
||||
// float4eq_callable is the callable logic for the float4eq function.
|
||||
func float4eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float32.Compare(ctx, val1.(float32), val2.(float32))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// float4eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float4eq = framework.Function2{
|
||||
Name: "float4eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: float4eq_callable,
|
||||
}
|
||||
|
||||
// float48eq_callable is the callable logic for the float48eq function.
|
||||
func float48eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, float64(val1.(float32)), val2.(float64))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// float48eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float48eq = framework.Function2{
|
||||
Name: "float48eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: float48eq_callable,
|
||||
}
|
||||
|
||||
// float84eq_callable is the callable logic for the float84eq function.
|
||||
func float84eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, val1.(float64), float64(val2.(float32)))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// float84eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float84eq = framework.Function2{
|
||||
Name: "float84eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: float84eq_callable,
|
||||
}
|
||||
|
||||
// float8eq_callable is the callable logic for the float8eq function.
|
||||
func float8eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, val1.(float64), val2.(float64))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// float8eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float8eq = framework.Function2{
|
||||
Name: "float8eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: float8eq_callable,
|
||||
}
|
||||
|
||||
// int2eq_callable is the callable logic for the int2eq function.
|
||||
func int2eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int16.Compare(ctx, val1.(int16), val2.(int16))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// int2eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2eq = framework.Function2{
|
||||
Name: "int2eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: int2eq_callable,
|
||||
}
|
||||
|
||||
// int24eq_callable is the callable logic for the int24eq function.
|
||||
func int24eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, int32(val1.(int16)), val2.(int32))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// int24eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int24eq = framework.Function2{
|
||||
Name: "int24eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: int24eq_callable,
|
||||
}
|
||||
|
||||
// int28eq_callable is the callable logic for the int28eq function.
|
||||
func int28eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(int16)), val2.(int64))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// int28eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int28eq = framework.Function2{
|
||||
Name: "int28eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: int28eq_callable,
|
||||
}
|
||||
|
||||
// int42eq_callable is the callable logic for the int42eq function.
|
||||
func int42eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, val1.(int32), int32(val2.(int16)))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// int42eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int42eq = framework.Function2{
|
||||
Name: "int42eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: int42eq_callable,
|
||||
}
|
||||
|
||||
// int4eq_callable is the callable logic for the int4eq function.
|
||||
func int4eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, val1.(int32), val2.(int32))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// int4eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4eq = framework.Function2{
|
||||
Name: "int4eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: int4eq_callable,
|
||||
}
|
||||
|
||||
// int48eq_callable is the callable logic for the int48eq function.
|
||||
func int48eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(int32)), val2.(int64))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// int48eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int48eq = framework.Function2{
|
||||
Name: "int48eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: int48eq_callable,
|
||||
}
|
||||
|
||||
// int82eq_callable is the callable logic for the int82eq function.
|
||||
func int82eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), int64(val2.(int16)))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// int82eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int82eq = framework.Function2{
|
||||
Name: "int82eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: int82eq_callable,
|
||||
}
|
||||
|
||||
// int84eq_callable is the callable logic for the int84eq function.
|
||||
func int84eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), int64(val2.(int32)))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// int84eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int84eq = framework.Function2{
|
||||
Name: "int84eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: int84eq_callable,
|
||||
}
|
||||
|
||||
// int8eq_callable is the callable logic for the int8eq function.
|
||||
func int8eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), val2.(int64))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// int8eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8eq = framework.Function2{
|
||||
Name: "int8eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: int8eq_callable,
|
||||
}
|
||||
|
||||
// interval_eq_callable is the callable logic for the interval_eq function.
|
||||
func interval_eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Interval.Compare(ctx, val1.(duration.Duration), val2.(duration.Duration))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// interval_eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_eq = framework.Function2{
|
||||
Name: "interval_eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: interval_eq_callable,
|
||||
}
|
||||
|
||||
// jsonb_eq_callable is the callable logic for the jsonb_eq function.
|
||||
func jsonb_eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.JsonB.Compare(ctx, val1, val2)
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// jsonb_eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_eq = framework.Function2{
|
||||
Name: "jsonb_eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.JsonB},
|
||||
Strict: true,
|
||||
Callable: jsonb_eq_callable,
|
||||
}
|
||||
|
||||
// nameeq_callable is the callable logic for the nameeq function.
|
||||
func nameeq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Name.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// nameeq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var nameeq = framework.Function2{
|
||||
Name: "nameeq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Name},
|
||||
Strict: true,
|
||||
Callable: nameeq_callable,
|
||||
}
|
||||
|
||||
// nameeqtext_callable is the callable logic for the nameeqtext function.
|
||||
func nameeqtext_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// nameeqtext represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var nameeqtext = framework.Function2{
|
||||
Name: "nameeqtext",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: nameeqtext_callable,
|
||||
}
|
||||
|
||||
// numeric_eq_callable is the callable logic for the numeric_eq function.
|
||||
func numeric_eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Numeric.Compare(ctx, val1.(*apd.Decimal), val2.(*apd.Decimal))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// numeric_eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var numeric_eq = framework.Function2{
|
||||
Name: "numeric_eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Numeric, pgtypes.Numeric},
|
||||
Strict: true,
|
||||
Callable: numeric_eq_callable,
|
||||
}
|
||||
|
||||
// oideq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var oideq = framework.Function2{
|
||||
Name: "oideq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Oid, pgtypes.Oid},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
// This method doesn't use DoltgresType.Compare because it's on the critical path for many tooling queries that
|
||||
// examine the pg_catalog tables.
|
||||
val1id, val2id := val1.(id.Id), val2.(id.Id)
|
||||
return val1id == val2id, nil
|
||||
},
|
||||
}
|
||||
|
||||
// oidvectoreq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var oidvectoreq = framework.Function2{
|
||||
Name: "oidvectoreq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Oidvector, pgtypes.Oidvector},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Oidvector.Compare(ctx, val1.([]any), val2.([]any))
|
||||
return res == 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// texteqname_callable is the callable logic for the texteqname function.
|
||||
func texteqname_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// texteqname represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var texteqname = framework.Function2{
|
||||
Name: "texteqname",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Name},
|
||||
Strict: true,
|
||||
Callable: texteqname_callable,
|
||||
}
|
||||
|
||||
// text_eq_callable is the callable logic for the text_eq function.
|
||||
func text_eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1, val2)
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// text_eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var text_eq = framework.Function2{
|
||||
Name: "text_eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: text_eq_callable,
|
||||
}
|
||||
|
||||
// record_eq_callable is the callable logic for the record_eq function.
|
||||
func record_eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return compare.CompareRecords(ctx, framework.Operator_BinaryEqual, val1, val2)
|
||||
}
|
||||
|
||||
// varbiteq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var varbiteq = framework.Function2{
|
||||
Name: "varbiteq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.VarBit, pgtypes.VarBit},
|
||||
Strict: true,
|
||||
Callable: varbit_eq_callable,
|
||||
}
|
||||
|
||||
// biteq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var biteq = framework.Function2{
|
||||
Name: "biteq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bit, pgtypes.Bit},
|
||||
Strict: true,
|
||||
Callable: bit_eq_callable,
|
||||
}
|
||||
|
||||
// varbit_eq_callable is the callable logic for the varbiteq function.
|
||||
func varbit_eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.VarBit.Compare(ctx, val1, val2)
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// bit_eq_callable is the callable logic for the varbiteq function.
|
||||
func bit_eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Bit.Compare(ctx, val1, val2)
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// record_eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var record_eq = framework.Function2{
|
||||
Name: "record_eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Record, pgtypes.Record},
|
||||
Strict: true,
|
||||
Callable: record_eq_callable,
|
||||
}
|
||||
|
||||
// time_eq_callable is the callable logic for the time_eq function.
|
||||
func time_eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Time.Compare(ctx, val1.(timeofday.TimeOfDay), val2.(timeofday.TimeOfDay))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// time_eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var time_eq = framework.Function2{
|
||||
Name: "time_eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Time, pgtypes.Time},
|
||||
Strict: true,
|
||||
Callable: time_eq_callable,
|
||||
}
|
||||
|
||||
// timestamp_eq_date_callable is the callable logic for the timestamp_eq_date function.
|
||||
func timestamp_eq_date_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res == 0, nil
|
||||
}
|
||||
|
||||
// timestamp_eq_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_eq_date = framework.Function2{
|
||||
Name: "timestamp_eq_date",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: timestamp_eq_date_callable,
|
||||
}
|
||||
|
||||
// timestamp_eq_callable is the callable logic for the timestamp_eq function.
|
||||
func timestamp_eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Timestamp.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// timestamp_eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_eq = framework.Function2{
|
||||
Name: "timestamp_eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: timestamp_eq_callable,
|
||||
}
|
||||
|
||||
// timestamp_eq_timestamptz_callable is the callable logic for the timestamp_eq_timestamptz function.
|
||||
func timestamp_eq_timestamptz_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// timestamp_eq_timestamptz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_eq_timestamptz = framework.Function2{
|
||||
Name: "timestamp_eq_timestamptz",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: timestamp_eq_timestamptz_callable,
|
||||
}
|
||||
|
||||
// timestamptz_eq_date_callable is the callable logic for the timestamptz_eq_date function.
|
||||
func timestamptz_eq_date_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res == 0, nil
|
||||
}
|
||||
|
||||
// timestamptz_eq_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_eq_date = framework.Function2{
|
||||
Name: "timestamptz_eq_date",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: timestamptz_eq_date_callable,
|
||||
}
|
||||
|
||||
// timestamptz_eq_timestamp_callable is the callable logic for the timestamptz_eq_timestamp function.
|
||||
func timestamptz_eq_timestamp_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// timestamptz_eq_timestamp represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_eq_timestamp = framework.Function2{
|
||||
Name: "timestamptz_eq_timestamp",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: timestamptz_eq_timestamp_callable,
|
||||
}
|
||||
|
||||
// timestamptz_eq_callable is the callable logic for the timestamptz_eq function.
|
||||
func timestamptz_eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// timestamptz_eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_eq = framework.Function2{
|
||||
Name: "timestamptz_eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: timestamptz_eq_callable,
|
||||
}
|
||||
|
||||
// timetz_eq_callable is the callable logic for the timetz_eq function.
|
||||
func timetz_eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimeTZ.Compare(ctx, val1.(timetz.TimeTZ), val2.(timetz.TimeTZ))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// timetz_eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timetz_eq = framework.Function2{
|
||||
Name: "timetz_eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimeTZ, pgtypes.TimeTZ},
|
||||
Strict: true,
|
||||
Callable: timetz_eq_callable,
|
||||
}
|
||||
|
||||
// uuid_eq_callable is the callable logic for the uuid_eq function.
|
||||
func uuid_eq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Uuid.Compare(ctx, val1.(uuid.UUID), val2.(uuid.UUID))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// uuid_eq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var uuid_eq = framework.Function2{
|
||||
Name: "uuid_eq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Uuid, pgtypes.Uuid},
|
||||
Strict: true,
|
||||
Callable: uuid_eq_callable,
|
||||
}
|
||||
|
||||
// xideqint4_callable is the callable logic for the xideqint4 function.
|
||||
func xideqint4_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
// TODO: investigate the edge cases
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(uint32)), int64(val2.(int32)))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// xideqint4 represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var xideqint4 = framework.Function2{
|
||||
Name: "xideqint4",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Xid, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: xideqint4_callable,
|
||||
}
|
||||
|
||||
// xideq_callable is the callable logic for the xideq function.
|
||||
func xideq_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Xid.Compare(ctx, val1.(uint32), val2.(uint32))
|
||||
return res == 0, err
|
||||
}
|
||||
|
||||
// xideq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var xideq = framework.Function2{
|
||||
Name: "xideq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Xid, pgtypes.Xid},
|
||||
Strict: true,
|
||||
Callable: xideq_callable,
|
||||
}
|
||||
@@ -0,0 +1,558 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/apd/v3"
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/core/id"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/duration"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timeofday"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timetz"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/uuid"
|
||||
"github.com/dolthub/doltgresql/server/compare"
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '>' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryGreaterThan registers the functions to the catalog.
|
||||
func initBinaryGreaterThan() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, boolgt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, bpchargt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, byteagt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, chargt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, date_gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, date_gt_timestamp)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, date_gt_timestamptz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, enum_gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, float4gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, float48gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, float84gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, float8gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, int2gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, int24gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, int28gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, int42gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, int4gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, int48gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, int82gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, int84gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, int8gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, interval_gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, jsonb_gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, namegt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, namegttext)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, numeric_gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, oidgt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, oidvectorgt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, textgtname)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, text_gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, time_gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, timestamp_gt_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, timestamp_gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, timestamp_gt_timestamptz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, timestamptz_gt_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, timestamptz_gt_timestamp)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, timestamptz_gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, timetz_gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, record_gt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterThan, uuid_gt)
|
||||
}
|
||||
|
||||
// boolgt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var boolgt = framework.Function2{
|
||||
Name: "boolgt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bool, pgtypes.Bool},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Bool.Compare(ctx, val1.(bool), val2.(bool))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// bpchargt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var bpchargt = framework.Function2{
|
||||
Name: "bpchargt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.BpChar, pgtypes.BpChar},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.BpChar.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// byteagt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var byteagt = framework.Function2{
|
||||
Name: "byteagt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bytea, pgtypes.Bytea},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Bytea.Compare(ctx, val1, val2)
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// chargt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var chargt = framework.Function2{
|
||||
Name: "chargt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.InternalChar, pgtypes.InternalChar},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.InternalChar.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// date_gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_gt = framework.Function2{
|
||||
Name: "date_gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Date.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// date_gt_timestamp represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_gt_timestamp = framework.Function2{
|
||||
Name: "date_gt_timestamp",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res == 1, nil
|
||||
},
|
||||
}
|
||||
|
||||
// date_gt_timestamptz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_gt_timestamptz = framework.Function2{
|
||||
Name: "date_gt_timestamptz",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res == 1, nil
|
||||
},
|
||||
}
|
||||
|
||||
// enum_gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var enum_gt = framework.Function2{
|
||||
Name: "enum_gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.AnyEnum, pgtypes.AnyEnum},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, t [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := t[0].Compare(ctx, val1, val2)
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// float4gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float4gt = framework.Function2{
|
||||
Name: "float4gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float32.Compare(ctx, val1.(float32), val2.(float32))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// float48gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float48gt = framework.Function2{
|
||||
Name: "float48gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, float64(val1.(float32)), val2.(float64))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// float84gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float84gt = framework.Function2{
|
||||
Name: "float84gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, val1.(float64), float64(val2.(float32)))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// float8gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float8gt = framework.Function2{
|
||||
Name: "float8gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, val1.(float64), val2.(float64))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int2gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2gt = framework.Function2{
|
||||
Name: "int2gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int16.Compare(ctx, val1.(int16), val2.(int16))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int24gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int24gt = framework.Function2{
|
||||
Name: "int24gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, int32(val1.(int16)), val2.(int32))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int28gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int28gt = framework.Function2{
|
||||
Name: "int28gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(int16)), val2.(int64))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int42gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int42gt = framework.Function2{
|
||||
Name: "int42gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, val1.(int32), int32(val2.(int16)))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int4gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4gt = framework.Function2{
|
||||
Name: "int4gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, val1.(int32), val2.(int32))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int48gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int48gt = framework.Function2{
|
||||
Name: "int48gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(int32)), val2.(int64))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int82gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int82gt = framework.Function2{
|
||||
Name: "int82gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), int64(val2.(int16)))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int84gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int84gt = framework.Function2{
|
||||
Name: "int84gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), int64(val2.(int32)))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int8gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8gt = framework.Function2{
|
||||
Name: "int8gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), val2.(int64))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// interval_gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_gt = framework.Function2{
|
||||
Name: "interval_gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Interval.Compare(ctx, val1.(duration.Duration), val2.(duration.Duration))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_gt = framework.Function2{
|
||||
Name: "jsonb_gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.JsonB},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.JsonB.Compare(ctx, val1, val2)
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// namegt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var namegt = framework.Function2{
|
||||
Name: "namegt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Name},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Name.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// namegttext represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var namegttext = framework.Function2{
|
||||
Name: "namegttext",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// numeric_gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var numeric_gt = framework.Function2{
|
||||
Name: "numeric_gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Numeric, pgtypes.Numeric},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Numeric.Compare(ctx, val1.(*apd.Decimal), val2.(*apd.Decimal))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// oidgt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var oidgt = framework.Function2{
|
||||
Name: "oidgt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Oid, pgtypes.Oid},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := cmp.Compare(id.Cache().ToOID(val1.(id.Id)), id.Cache().ToOID(val2.(id.Id)))
|
||||
return res == 1, nil
|
||||
},
|
||||
}
|
||||
|
||||
// oidvectorgt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var oidvectorgt = framework.Function2{
|
||||
Name: "oidvectorgt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Oidvector, pgtypes.Oidvector},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Oidvector.Compare(ctx, val1.([]any), val2.([]any))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// textgtname represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var textgtname = framework.Function2{
|
||||
Name: "textgtname",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Name},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// text_gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var text_gt = framework.Function2{
|
||||
Name: "text_gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1, val2)
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// time_gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var time_gt = framework.Function2{
|
||||
Name: "time_gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Time, pgtypes.Time},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Time.Compare(ctx, val1.(timeofday.TimeOfDay), val2.(timeofday.TimeOfDay))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_gt_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_gt_date = framework.Function2{
|
||||
Name: "timestamp_gt_date",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res == 1, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_gt = framework.Function2{
|
||||
Name: "timestamp_gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Timestamp.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_gt_timestamptz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_gt_timestamptz = framework.Function2{
|
||||
Name: "timestamp_gt_timestamptz",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_gt_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_gt_date = framework.Function2{
|
||||
Name: "timestamptz_gt_date",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res == 1, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_gt_timestamp represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_gt_timestamp = framework.Function2{
|
||||
Name: "timestamptz_gt_timestamp",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_gt = framework.Function2{
|
||||
Name: "timestamptz_gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// timetz_gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timetz_gt = framework.Function2{
|
||||
Name: "timetz_gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimeTZ, pgtypes.TimeTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimeTZ.Compare(ctx, val1.(timetz.TimeTZ), val2.(timetz.TimeTZ))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
|
||||
// record_gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var record_gt = framework.Function2{
|
||||
Name: "record_gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Record, pgtypes.Record},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return compare.CompareRecords(ctx, framework.Operator_BinaryGreaterThan, val1, val2)
|
||||
},
|
||||
}
|
||||
|
||||
// uuid_gt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var uuid_gt = framework.Function2{
|
||||
Name: "uuid_gt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Uuid, pgtypes.Uuid},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Uuid.Compare(ctx, val1.(uuid.UUID), val2.(uuid.UUID))
|
||||
return res == 1, err
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,558 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/apd/v3"
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/core/id"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/duration"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timeofday"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timetz"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/uuid"
|
||||
"github.com/dolthub/doltgresql/server/compare"
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '>=' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryGreaterOrEqual registers the functions to the catalog.
|
||||
func initBinaryGreaterOrEqual() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, boolge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, bpcharge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, byteage)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, charge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, date_ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, date_ge_timestamp)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, date_ge_timestamptz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, enum_ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, float4ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, float48ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, float84ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, float8ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, int2ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, int24ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, int28ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, int42ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, int4ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, int48ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, int82ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, int84ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, int8ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, interval_ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, jsonb_ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, namege)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, namegetext)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, numeric_ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, oidge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, oidvectorge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, textgename)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, text_ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, time_ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, timestamp_ge_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, timestamp_ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, timestamp_ge_timestamptz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, timestamptz_ge_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, timestamptz_ge_timestamp)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, timestamptz_ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, timetz_ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, record_ge)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryGreaterOrEqual, uuid_ge)
|
||||
}
|
||||
|
||||
// boolge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var boolge = framework.Function2{
|
||||
Name: "boolge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bool, pgtypes.Bool},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Bool.Compare(ctx, val1.(bool), val2.(bool))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// bpcharge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var bpcharge = framework.Function2{
|
||||
Name: "bpcharge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.BpChar, pgtypes.BpChar},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.BpChar.Compare(ctx, val1.(string), val2.(string))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// byteage represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var byteage = framework.Function2{
|
||||
Name: "byteage",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bytea, pgtypes.Bytea},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Bytea.Compare(ctx, val1.([]byte), val2.([]byte))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// charge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var charge = framework.Function2{
|
||||
Name: "charge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.InternalChar, pgtypes.InternalChar},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.InternalChar.Compare(ctx, val1.(string), val2.(string))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// date_ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_ge = framework.Function2{
|
||||
Name: "date_ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Date.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// date_ge_timestamp represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_ge_timestamp = framework.Function2{
|
||||
Name: "date_ge_timestamp",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res >= 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// date_ge_timestamptz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_ge_timestamptz = framework.Function2{
|
||||
Name: "date_ge_timestamptz",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res >= 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// enum_ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var enum_ge = framework.Function2{
|
||||
Name: "enum_ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.AnyEnum, pgtypes.AnyEnum},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, t [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := t[0].Compare(ctx, val1, val2)
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// float4ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float4ge = framework.Function2{
|
||||
Name: "float4ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float32.Compare(ctx, val1.(float32), val2.(float32))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// float48ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float48ge = framework.Function2{
|
||||
Name: "float48ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, float64(val1.(float32)), val2.(float64))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// float84ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float84ge = framework.Function2{
|
||||
Name: "float84ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, val1.(float64), float64(val2.(float32)))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// float8ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float8ge = framework.Function2{
|
||||
Name: "float8ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, val1.(float64), val2.(float64))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int2ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2ge = framework.Function2{
|
||||
Name: "int2ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int16.Compare(ctx, val1.(int16), val2.(int16))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int24ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int24ge = framework.Function2{
|
||||
Name: "int24ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, int32(val1.(int16)), val2.(int32))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int28ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int28ge = framework.Function2{
|
||||
Name: "int28ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(int16)), val2.(int64))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int42ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int42ge = framework.Function2{
|
||||
Name: "int42ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, val1.(int32), int32(val2.(int16)))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int4ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4ge = framework.Function2{
|
||||
Name: "int4ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, val1.(int32), val2.(int32))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int48ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int48ge = framework.Function2{
|
||||
Name: "int48ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(int32)), val2.(int64))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int82ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int82ge = framework.Function2{
|
||||
Name: "int82ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), int64(val2.(int16)))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int84ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int84ge = framework.Function2{
|
||||
Name: "int84ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), int64(val2.(int32)))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int8ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8ge = framework.Function2{
|
||||
Name: "int8ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), val2.(int64))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// interval_ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_ge = framework.Function2{
|
||||
Name: "interval_ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Interval.Compare(ctx, val1.(duration.Duration), val2.(duration.Duration))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_ge = framework.Function2{
|
||||
Name: "jsonb_ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.JsonB},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.JsonB.Compare(ctx, val1, val2)
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// namege represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var namege = framework.Function2{
|
||||
Name: "namege",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Name},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Name.Compare(ctx, val1.(string), val2.(string))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// namegetext represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var namegetext = framework.Function2{
|
||||
Name: "namegetext",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// numeric_ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var numeric_ge = framework.Function2{
|
||||
Name: "numeric_ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Numeric, pgtypes.Numeric},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Numeric.Compare(ctx, val1.(*apd.Decimal), val2.(*apd.Decimal))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// oidge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var oidge = framework.Function2{
|
||||
Name: "oidge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Oid, pgtypes.Oid},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := cmp.Compare(id.Cache().ToOID(val1.(id.Id)), id.Cache().ToOID(val2.(id.Id)))
|
||||
return res >= 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// oidvectorge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var oidvectorge = framework.Function2{
|
||||
Name: "oidvectorge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Oidvector, pgtypes.Oidvector},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Oidvector.Compare(ctx, val1.([]any), val2.([]any))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// textgename represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var textgename = framework.Function2{
|
||||
Name: "textgename",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Name},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// text_ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var text_ge = framework.Function2{
|
||||
Name: "text_ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// time_ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var time_ge = framework.Function2{
|
||||
Name: "time_ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Time, pgtypes.Time},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Time.Compare(ctx, val1.(timeofday.TimeOfDay), val2.(timeofday.TimeOfDay))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_ge_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_ge_date = framework.Function2{
|
||||
Name: "timestamp_ge_date",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res >= 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_ge = framework.Function2{
|
||||
Name: "timestamp_ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Timestamp.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_ge_timestamptz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_ge_timestamptz = framework.Function2{
|
||||
Name: "timestamp_ge_timestamptz",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_ge_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_ge_date = framework.Function2{
|
||||
Name: "timestamptz_ge_date",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res >= 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_ge_timestamp represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_ge_timestamp = framework.Function2{
|
||||
Name: "timestamptz_ge_timestamp",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_ge = framework.Function2{
|
||||
Name: "timestamptz_ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timetz_ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timetz_ge = framework.Function2{
|
||||
Name: "timetz_ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimeTZ, pgtypes.TimeTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimeTZ.Compare(ctx, val1.(timetz.TimeTZ), val2.(timetz.TimeTZ))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// record_ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var record_ge = framework.Function2{
|
||||
Name: "record_ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Record, pgtypes.Record},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return compare.CompareRecords(ctx, framework.Operator_BinaryGreaterOrEqual, val1, val2)
|
||||
},
|
||||
}
|
||||
|
||||
// uuid_ge represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var uuid_ge = framework.Function2{
|
||||
Name: "uuid_ge",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Uuid, pgtypes.Uuid},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Uuid.Compare(ctx, val1.(uuid.UUID), val2.(uuid.UUID))
|
||||
return res >= 0, err
|
||||
},
|
||||
}
|
||||
@@ -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 binary
|
||||
|
||||
// Init initializes all binary operators in this package.
|
||||
func Init() {
|
||||
initBinaryBitAnd()
|
||||
initBinaryBitOr()
|
||||
initBinaryBitXor()
|
||||
initBinaryConcatenate()
|
||||
initBinaryDivide()
|
||||
initBinaryEqual()
|
||||
initBinaryGreaterOrEqual()
|
||||
initBinaryGreaterThan()
|
||||
initBinaryLessOrEqual()
|
||||
initBinaryLessThan()
|
||||
initBinaryMinus()
|
||||
initBinaryMod()
|
||||
initBinaryMultiply()
|
||||
initBinaryNotEqual()
|
||||
initBinaryPlus()
|
||||
initBinaryShiftLeft()
|
||||
initBinaryShiftRight()
|
||||
initJSON()
|
||||
}
|
||||
@@ -0,0 +1,849 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
"github.com/dolthub/go-mysql-server/sql/types"
|
||||
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// makeObjectKeyPath builds a JSON path that selects the given top-level
|
||||
// object key, quoting and escaping the key so any characters are allowed.
|
||||
func makeObjectKeyPath(key string) string {
|
||||
return "$" + objectKeyPathSegment(key)
|
||||
}
|
||||
|
||||
// objectKeyPathSegment builds a single object-key step (e.g. `."key"`), quoting
|
||||
// and escaping the key so any characters are allowed. Used both on its own and
|
||||
// when composing a multi-step JSON path.
|
||||
func objectKeyPathSegment(key string) string {
|
||||
return `."` + strings.ReplaceAll(key, `"`, `\"`) + `"`
|
||||
}
|
||||
|
||||
// makeArrayIndexPath builds a JSON path that selects the given top-level
|
||||
// array element by non-negative index.
|
||||
func makeArrayIndexPath(idx int) string {
|
||||
return "$" + arrayIndexPathSegment(idx)
|
||||
}
|
||||
|
||||
// arrayIndexPathSegment builds a single array-index step (e.g. `[3]`). Used both
|
||||
// on its own and when composing a multi-step JSON path.
|
||||
func arrayIndexPathSegment(idx int) string {
|
||||
return "[" + strconv.Itoa(idx) + "]"
|
||||
}
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = <OPERATOR> ORDER BY o.oprcode::varchar;
|
||||
// Replace <OPERATOR> with the desired JSON operator
|
||||
|
||||
// initJSON registers the functions to the catalog.
|
||||
func initJSON() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONExtractJson, json_array_element)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONExtractJson, jsonb_array_element)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONExtractJson, json_object_field)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONExtractJson, jsonb_object_field)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONExtractText, json_array_element_text)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONExtractText, jsonb_array_element_text)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONExtractText, json_object_field_text)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONExtractText, jsonb_object_field_text)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONExtractPathJson, json_extract_path)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONExtractPathJson, jsonb_extract_path)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONExtractPathText, json_extract_path_text)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONExtractPathText, jsonb_extract_path_text)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONContainsRight, jsonb_contains)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONContainsLeft, jsonb_contained)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONTopLevel, jsonb_exists)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONTopLevelAny, jsonb_exists_any)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryJSONTopLevelAll, jsonb_exists_all)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, jsonb_delete_text)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, jsonb_delete_text_array)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, jsonb_delete_int32)
|
||||
}
|
||||
|
||||
// toJSONWrapper converts a JSON value (either string or sql.JSONWrapper) to a sql.JSONWrapper.
|
||||
func toJSONWrapper(ctx *sql.Context, val any) (sql.JSONWrapper, error) {
|
||||
switch v := val.(type) {
|
||||
case sql.JSONWrapper:
|
||||
return v, nil
|
||||
case sql.StringWrapper:
|
||||
s, err := v.Unwrap(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
doc, err := pgtypes.JsonB.IoInput(ctx, s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if doc == nil {
|
||||
return nil, nil
|
||||
}
|
||||
w, ok := doc.(sql.JSONWrapper)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type from IoInput: %T", doc)
|
||||
}
|
||||
return w, nil
|
||||
case string:
|
||||
doc, err := pgtypes.JsonB.IoInput(ctx, v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if doc == nil {
|
||||
return nil, nil
|
||||
}
|
||||
w, ok := doc.(sql.JSONWrapper)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected type from IoInput: %T", doc)
|
||||
}
|
||||
return w, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected type for JSON operation: %T", val)
|
||||
}
|
||||
}
|
||||
|
||||
// jsonWrapperElementToText converts a JSON element (sql.JSONWrapper) to its text representation.
|
||||
// For string values, it returns the raw string without quotes. For other types, it returns the JSON representation.
|
||||
func jsonWrapperElementToText(ctx *sql.Context, wrapper sql.JSONWrapper) (string, error) {
|
||||
v, err := wrapper.ToInterface(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if v == nil {
|
||||
return "", nil
|
||||
}
|
||||
if s, ok := v.(string); ok {
|
||||
return s, nil
|
||||
}
|
||||
return types.JSONDocument{Val: v}.JSONString()
|
||||
}
|
||||
|
||||
// json_array_element represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var json_array_element = framework.Function2{
|
||||
Name: "json_array_element",
|
||||
Return: pgtypes.Json,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Json, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
newVal, err := toJSONWrapper(ctx, val1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if newVal == nil {
|
||||
return nil, nil
|
||||
}
|
||||
var unusedTypes [3]*pgtypes.DoltgresType
|
||||
retVal, err := jsonb_array_element_callable(ctx, unusedTypes, newVal, val2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if retVal == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return pgtypes.JsonB.IoOutput(ctx, retVal)
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_array_element represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_array_element = framework.Function2{
|
||||
Name: "jsonb_array_element",
|
||||
Return: pgtypes.JsonB,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: jsonb_array_element_callable,
|
||||
}
|
||||
|
||||
func jsonb_array_element_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
wrapper, ok := val1.(sql.JSONWrapper)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
idx := int(val2.(int32))
|
||||
// Fast path: for a ComparableJSON wrapper backed by an indexed JSON
|
||||
// array, use Lookup to fetch the element without materializing the
|
||||
// entire array. Negative indices need the array length, so they fall
|
||||
// through to the materialized path even on indexed values.
|
||||
if comparable, ok := wrapper.(types.ComparableJSON); ok {
|
||||
jt, err := comparable.JsonType(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if jt != "ARRAY" {
|
||||
return nil, nil
|
||||
}
|
||||
if idx >= 0 {
|
||||
result, err := types.LookupJSONValue(ctx, wrapper, makeArrayIndexPath(idx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if result == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
// Materialized fallback: covers wrappers that don't implement
|
||||
// ComparableJSON (e.g. literal jsonb values) and the negative-index
|
||||
// case on ComparableJSON arrays.
|
||||
v, err := wrapper.ToInterface(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
array, ok := v.([]interface{})
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
if idx < 0 {
|
||||
idx += len(array)
|
||||
}
|
||||
if idx < 0 || idx >= len(array) {
|
||||
return nil, nil
|
||||
}
|
||||
return types.JSONDocument{Val: array[idx]}, nil
|
||||
}
|
||||
|
||||
// json_object_field represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var json_object_field = framework.Function2{
|
||||
Name: "json_object_field",
|
||||
Return: pgtypes.Json,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Json, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
// TODO: make a bespoke implementation that preserves whitespace
|
||||
newVal, err := toJSONWrapper(ctx, val1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if newVal == nil {
|
||||
return nil, nil
|
||||
}
|
||||
var unusedTypes [3]*pgtypes.DoltgresType
|
||||
retVal, err := jsonb_object_field.Callable(ctx, unusedTypes, newVal, val2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if retVal == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return pgtypes.JsonB.IoOutput(ctx, retVal)
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_object_field represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_object_field = framework.Function2{
|
||||
Name: "jsonb_object_field",
|
||||
Return: pgtypes.JsonB,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
wrapper, ok := val1.(sql.JSONWrapper)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
key := val2.(string)
|
||||
// Fast path: for a ComparableJSON wrapper backed by an indexed JSON
|
||||
// object, use Lookup to fetch the value without materializing the
|
||||
// entire document.
|
||||
if isObj, err := isComparableJsonObject(ctx, wrapper); err != nil {
|
||||
return nil, err
|
||||
} else if isObj {
|
||||
result, err := types.LookupJSONValue(ctx, wrapper, makeObjectKeyPath(key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if result == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
// Materialized fallback: covers wrappers that don't implement
|
||||
// ComparableJSON (e.g. literal jsonb values), where the embedded
|
||||
// jsonpath library has trouble with edge cases like keys that
|
||||
// contain escaped quotes, or array operands with text paths.
|
||||
v, err := wrapper.ToInterface(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
obj, ok := v.(map[string]any)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
val, ok := obj[key]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
return types.JSONDocument{Val: val}, nil
|
||||
},
|
||||
}
|
||||
|
||||
// json_array_element_text represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var json_array_element_text = framework.Function2{
|
||||
Name: "json_array_element_text",
|
||||
Return: pgtypes.Text,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Json, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
// TODO: make a bespoke implementation that preserves whitespace
|
||||
newVal, err := toJSONWrapper(ctx, val1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if newVal == nil {
|
||||
return nil, nil
|
||||
}
|
||||
var unusedTypes [3]*pgtypes.DoltgresType
|
||||
return jsonb_array_element_text.Callable(ctx, unusedTypes, newVal, val2)
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_array_element_text represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_array_element_text = framework.Function2{
|
||||
Name: "jsonb_array_element_text",
|
||||
Return: pgtypes.Text,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, dt [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
elem, err := jsonb_array_element_callable(ctx, dt, val1, val2)
|
||||
if err != nil || elem == nil {
|
||||
return nil, err
|
||||
}
|
||||
wrapper, ok := elem.(sql.JSONWrapper)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
return jsonWrapperElementToText(ctx, wrapper)
|
||||
},
|
||||
}
|
||||
|
||||
// json_object_field_text represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var json_object_field_text = framework.Function2{
|
||||
Name: "json_object_field_text",
|
||||
Return: pgtypes.Text,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Json, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
// TODO: make a bespoke implementation that preserves whitespace
|
||||
newVal, err := toJSONWrapper(ctx, val1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if newVal == nil {
|
||||
return nil, nil
|
||||
}
|
||||
var unusedTypes [3]*pgtypes.DoltgresType
|
||||
return jsonb_object_field_text.Callable(ctx, unusedTypes, newVal, val2)
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_object_field_text represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_object_field_text = framework.Function2{
|
||||
Name: "jsonb_object_field_text",
|
||||
Return: pgtypes.Text,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, dt [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
elem, err := jsonb_object_field.Callable(ctx, dt, val1, val2)
|
||||
if err != nil || elem == nil {
|
||||
return nil, err
|
||||
}
|
||||
wrapper, ok := elem.(sql.JSONWrapper)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
return jsonWrapperElementToText(ctx, wrapper)
|
||||
},
|
||||
}
|
||||
|
||||
// json_extract_path represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var json_extract_path = framework.Function2{
|
||||
Name: "json_extract_path",
|
||||
Return: pgtypes.Json,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Json, pgtypes.TextArray},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
// TODO: make a bespoke implementation that preserves whitespace
|
||||
newVal, err := toJSONWrapper(ctx, val1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if newVal == nil {
|
||||
return nil, nil
|
||||
}
|
||||
var unusedTypes [3]*pgtypes.DoltgresType
|
||||
retVal, err := jsonb_extract_path_callable(ctx, unusedTypes, newVal, val2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if retVal == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return pgtypes.JsonB.IoOutput(ctx, retVal)
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_extract_path represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_extract_path = framework.Function2{
|
||||
Name: "jsonb_extract_path",
|
||||
Return: pgtypes.JsonB,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.TextArray},
|
||||
Strict: true,
|
||||
Callable: jsonb_extract_path_callable,
|
||||
}
|
||||
|
||||
func jsonb_extract_path_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
cur, ok := val1.(sql.JSONWrapper)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
paths := val2.([]interface{})
|
||||
|
||||
// Fast path: for an indexed JSON document, build a single JSON path spanning
|
||||
// every step and resolve it in one traversal via SearchableJSON.Lookup,
|
||||
if _, ok := cur.(types.SearchableJSON); ok && len(paths) > 0 {
|
||||
result, authoritative, err := extractJsonPathBySingleLookup(ctx, cur, paths)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if authoritative {
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
if cur == nil {
|
||||
return nil, nil
|
||||
}
|
||||
textPath, ok := path.(string)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
next, err := extractOneJsonPathStep(ctx, cur, textPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if next == nil {
|
||||
return nil, nil
|
||||
}
|
||||
cur = next
|
||||
}
|
||||
return cur, nil
|
||||
}
|
||||
|
||||
// extractJsonPathBySingleLookup resolves returns the path in a JSON document by building a JSON path expression
|
||||
// from the text slice provided.
|
||||
// For numeric values, there's ambiguity as to whether they should be interpreted as array indices or object keys,
|
||||
// so a nil result in that case is not authoritative and the caller should fall back to the step-by-step walk.
|
||||
func extractJsonPathBySingleLookup(ctx *sql.Context, doc sql.JSONWrapper, paths []interface{}) (sql.JSONWrapper, bool, error) {
|
||||
var sb strings.Builder
|
||||
sb.WriteString("$")
|
||||
ambiguous := false
|
||||
for _, path := range paths {
|
||||
var textPath string
|
||||
switch path := path.(type) {
|
||||
case string:
|
||||
textPath = path
|
||||
case sql.StringWrapper:
|
||||
var err error
|
||||
textPath, err = path.Unwrap(ctx)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
case nil:
|
||||
return nil, true, nil
|
||||
}
|
||||
|
||||
if idx, err := strconv.Atoi(textPath); err == nil {
|
||||
// An integer element could be an array index or a numeric object
|
||||
// key (or a negative index), so the lookup result isn't conclusive.
|
||||
ambiguous = true
|
||||
if idx >= 0 {
|
||||
sb.WriteString(arrayIndexPathSegment(idx))
|
||||
continue
|
||||
}
|
||||
}
|
||||
sb.WriteString(objectKeyPathSegment(textPath))
|
||||
}
|
||||
result, err := types.LookupJSONValue(ctx, doc, sb.String())
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if result != nil {
|
||||
// A non-nil result could still be semantically NULL
|
||||
i, err := result.ToInterface(ctx)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if ia, ok := i.([]interface{}); ok && len(ia) == 0 {
|
||||
return nil, !ambiguous, nil
|
||||
}
|
||||
|
||||
return result, true, nil
|
||||
}
|
||||
|
||||
return nil, !ambiguous, nil
|
||||
}
|
||||
|
||||
// extractOneJsonPathStep performs a single Postgres-style extract step against
|
||||
// the given JSON wrapper. The text is treated as a key when the wrapper is an
|
||||
// object and as an integer index when the wrapper is an array. Returns nil if
|
||||
// the step cannot be resolved (missing key, out-of-range index, scalar
|
||||
// wrapper, or non-integer text on an array).
|
||||
func extractOneJsonPathStep(ctx *sql.Context, cur sql.JSONWrapper, textPath string) (sql.JSONWrapper, error) {
|
||||
// Fast path: use the ComparableJSON.JsonType / SearchableJSON.Lookup
|
||||
// interfaces to avoid materializing the entire document.
|
||||
if comparable, ok := cur.(types.ComparableJSON); ok {
|
||||
jt, err := comparable.JsonType(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch jt {
|
||||
case "OBJECT":
|
||||
return types.LookupJSONValue(ctx, cur, makeObjectKeyPath(textPath))
|
||||
case "ARRAY":
|
||||
idx, err := strconv.Atoi(textPath)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
if idx >= 0 {
|
||||
return types.LookupJSONValue(ctx, cur, makeArrayIndexPath(idx))
|
||||
}
|
||||
// Negative indices count from the end and require knowing the
|
||||
// array length, so fall through to the materialized path below.
|
||||
default:
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
// Materialized fallback for wrappers that don't implement ComparableJSON,
|
||||
// and for negative array indices on ones that do.
|
||||
v, err := cur.ToInterface(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch currentValue := v.(type) {
|
||||
case map[string]interface{}:
|
||||
next, ok := currentValue[textPath]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
return types.JSONDocument{Val: next}, nil
|
||||
case []interface{}:
|
||||
idx, err := strconv.Atoi(textPath)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
if idx < 0 {
|
||||
idx += len(currentValue)
|
||||
}
|
||||
if idx < 0 || idx >= len(currentValue) {
|
||||
return nil, nil
|
||||
}
|
||||
return types.JSONDocument{Val: currentValue[idx]}, nil
|
||||
default:
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
// json_extract_path_text represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var json_extract_path_text = framework.Function2{
|
||||
Name: "json_extract_path_text",
|
||||
Return: pgtypes.Text,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Json, pgtypes.TextArray},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
// TODO: make a bespoke implementation that preserves whitespace
|
||||
newVal, err := toJSONWrapper(ctx, val1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if newVal == nil {
|
||||
return nil, nil
|
||||
}
|
||||
var unusedTypes [3]*pgtypes.DoltgresType
|
||||
return jsonb_extract_path_text_callable(ctx, unusedTypes, newVal, val2)
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_extract_path_text represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_extract_path_text = framework.Function2{
|
||||
Name: "jsonb_extract_path_text",
|
||||
Return: pgtypes.Text,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.TextArray},
|
||||
Strict: true,
|
||||
Callable: jsonb_extract_path_text_callable,
|
||||
}
|
||||
|
||||
func jsonb_extract_path_text_callable(ctx *sql.Context, dt [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
elem, err := jsonb_extract_path_callable(ctx, dt, val1, val2)
|
||||
if err != nil || elem == nil {
|
||||
return nil, err
|
||||
}
|
||||
wrapper, ok := elem.(sql.JSONWrapper)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
return jsonWrapperElementToText(ctx, wrapper)
|
||||
}
|
||||
|
||||
// jsonb_contains represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_contains = framework.Function2{
|
||||
Name: "jsonb_contains",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.JsonB},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return nil, errors.Errorf("JSON contains is not yet supported")
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_contained represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_contained = framework.Function2{
|
||||
Name: "jsonb_contained",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.JsonB},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, dt [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return jsonb_contains.Callable(ctx, dt, val2, val1)
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_exists represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_exists = framework.Function2{
|
||||
Name: "jsonb_exists",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
wrapper, ok := val1.(sql.JSONWrapper)
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
key := val2.(string)
|
||||
// Fast path: for an indexed JSON object, use Lookup to test for the
|
||||
// key without materializing the document.
|
||||
if isObj, err := isComparableJsonObject(ctx, wrapper); err != nil {
|
||||
return nil, err
|
||||
} else if isObj {
|
||||
found, err := types.LookupJSONValue(ctx, wrapper, makeObjectKeyPath(key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return found != nil, nil
|
||||
}
|
||||
value, err := wrapper.ToInterface(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch v := value.(type) {
|
||||
case map[string]interface{}:
|
||||
_, ok := v[key]
|
||||
return ok, nil
|
||||
case []interface{}:
|
||||
for _, item := range v {
|
||||
if s, ok := item.(string); ok && s == key {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
case string:
|
||||
return v == key, nil
|
||||
default:
|
||||
return false, nil
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// isComparableJsonObject reports whether the JSON wrapper is a JSON object and
|
||||
// also implements types.ComparableJSON
|
||||
func isComparableJsonObject(ctx *sql.Context, wrapper sql.JSONWrapper) (bool, error) {
|
||||
comparable, ok := wrapper.(types.ComparableJSON)
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
jt, err := comparable.JsonType(ctx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return jt == "OBJECT", nil
|
||||
}
|
||||
|
||||
// jsonb_exists_any represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_exists_any = framework.Function2{
|
||||
Name: "jsonb_exists_any",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.TextArray},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
wrapper, ok := val1.(sql.JSONWrapper)
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
keys := val2.([]interface{})
|
||||
// Fast path: for an indexed JSON object, test each key with Lookup
|
||||
// instead of materializing the document.
|
||||
if isObj, err := isComparableJsonObject(ctx, wrapper); err != nil {
|
||||
return nil, err
|
||||
} else if isObj {
|
||||
for _, key := range keys {
|
||||
found, err := types.LookupJSONValue(ctx, wrapper, makeObjectKeyPath(key.(string)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if found != nil {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
value, err := wrapper.ToInterface(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch v := value.(type) {
|
||||
case map[string]interface{}:
|
||||
for _, key := range keys {
|
||||
if _, ok := v[key.(string)]; ok {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
case []interface{}:
|
||||
for _, key := range keys {
|
||||
for _, item := range v {
|
||||
if s, ok := item.(string); ok && s == key.(string) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
case string:
|
||||
for _, key := range keys {
|
||||
if v == key.(string) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
default:
|
||||
return false, nil
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_exists_all represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_exists_all = framework.Function2{
|
||||
Name: "jsonb_exists_all",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.TextArray},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
wrapper, ok := val1.(sql.JSONWrapper)
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
keys := val2.([]interface{})
|
||||
// Fast path: for an indexed JSON object, test each key with Lookup
|
||||
// instead of materializing the document.
|
||||
if isObj, err := isComparableJsonObject(ctx, wrapper); err != nil {
|
||||
return nil, err
|
||||
} else if isObj {
|
||||
for _, key := range keys {
|
||||
found, err := types.LookupJSONValue(ctx, wrapper, makeObjectKeyPath(key.(string)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if found == nil {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
value, err := wrapper.ToInterface(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch v := value.(type) {
|
||||
case map[string]interface{}:
|
||||
for _, key := range keys {
|
||||
if _, ok := v[key.(string)]; !ok {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
case []interface{}:
|
||||
for _, key := range keys {
|
||||
found := false
|
||||
for _, item := range v {
|
||||
if s, ok := item.(string); ok && s == key.(string) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
case string:
|
||||
for _, key := range keys {
|
||||
if v != key.(string) {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
default:
|
||||
return false, nil
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_delete_text represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_delete_text = framework.Function2{
|
||||
Name: "jsonb_delete",
|
||||
Return: pgtypes.JsonB,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return nil, errors.Errorf("JSON deletions are not yet supported")
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_delete_text_array represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_delete_text_array = framework.Function2{
|
||||
Name: "jsonb_delete",
|
||||
Return: pgtypes.JsonB,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.TextArray},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return nil, errors.Errorf("JSON deletions are not yet supported")
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_delete_int32 represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_delete_int32 = framework.Function2{
|
||||
Name: "jsonb_delete",
|
||||
Return: pgtypes.JsonB,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return nil, errors.Errorf("JSON deletions are not yet supported")
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,558 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/apd/v3"
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/core/id"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/duration"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timeofday"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timetz"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/uuid"
|
||||
"github.com/dolthub/doltgresql/server/compare"
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '<' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryLessThan registers the functions to the catalog.
|
||||
func initBinaryLessThan() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, boollt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, bpcharlt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, bytealt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, charlt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, date_lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, date_lt_timestamp)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, date_lt_timestamptz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, enum_lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, float4lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, float48lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, float84lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, float8lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, int2lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, int24lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, int28lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, int42lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, int4lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, int48lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, int82lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, int84lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, int8lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, interval_lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, jsonb_lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, namelt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, namelttext)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, numeric_lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, oidlt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, oidvectorlt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, textltname)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, text_lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, time_lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, timestamp_lt_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, timestamp_lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, timestamp_lt_timestamptz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, timestamptz_lt_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, timestamptz_lt_timestamp)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, timestamptz_lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, timetz_lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, record_lt)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessThan, uuid_lt)
|
||||
}
|
||||
|
||||
// boollt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var boollt = framework.Function2{
|
||||
Name: "boollt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bool, pgtypes.Bool},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Bool.Compare(ctx, val1.(bool), val2.(bool))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// bpcharlt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var bpcharlt = framework.Function2{
|
||||
Name: "bpcharlt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.BpChar, pgtypes.BpChar},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.BpChar.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// bytealt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var bytealt = framework.Function2{
|
||||
Name: "bytealt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bytea, pgtypes.Bytea},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Bytea.Compare(ctx, val1, val2)
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// charlt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var charlt = framework.Function2{
|
||||
Name: "charlt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.InternalChar, pgtypes.InternalChar},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.InternalChar.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// date_lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_lt = framework.Function2{
|
||||
Name: "date_lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Date.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// date_lt_timestamp represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_lt_timestamp = framework.Function2{
|
||||
Name: "date_lt_timestamp",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res == -1, nil
|
||||
},
|
||||
}
|
||||
|
||||
// date_lt_timestamptz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_lt_timestamptz = framework.Function2{
|
||||
Name: "date_lt_timestamptz",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res == -1, nil
|
||||
},
|
||||
}
|
||||
|
||||
// enum_lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var enum_lt = framework.Function2{
|
||||
Name: "enum_lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.AnyEnum, pgtypes.AnyEnum},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, t [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := t[0].Compare(ctx, val1, val2)
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// float4lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float4lt = framework.Function2{
|
||||
Name: "float4lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float32.Compare(ctx, val1.(float32), val2.(float32))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// float48lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float48lt = framework.Function2{
|
||||
Name: "float48lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, float64(val1.(float32)), val2.(float64))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// float84lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float84lt = framework.Function2{
|
||||
Name: "float84lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, val1.(float64), float64(val2.(float32)))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// float8lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float8lt = framework.Function2{
|
||||
Name: "float8lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, val1.(float64), val2.(float64))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int2lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2lt = framework.Function2{
|
||||
Name: "int2lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int16.Compare(ctx, val1.(int16), val2.(int16))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int24lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int24lt = framework.Function2{
|
||||
Name: "int24lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, int32(val1.(int16)), val2.(int32))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int28lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int28lt = framework.Function2{
|
||||
Name: "int28lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(int16)), val2.(int64))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int42lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int42lt = framework.Function2{
|
||||
Name: "int42lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, val1.(int32), int32(val2.(int16)))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int4lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4lt = framework.Function2{
|
||||
Name: "int4lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, val1.(int32), val2.(int32))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int48lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int48lt = framework.Function2{
|
||||
Name: "int48lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(int32)), val2.(int64))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int82lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int82lt = framework.Function2{
|
||||
Name: "int82lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), int64(val2.(int16)))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int84lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int84lt = framework.Function2{
|
||||
Name: "int84lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), int64(val2.(int32)))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// int8lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8lt = framework.Function2{
|
||||
Name: "int8lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), val2.(int64))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// interval_lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_lt = framework.Function2{
|
||||
Name: "interval_lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Interval.Compare(ctx, val1.(duration.Duration), val2.(duration.Duration))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_lt = framework.Function2{
|
||||
Name: "jsonb_lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.JsonB},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.JsonB.Compare(ctx, val1, val2)
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// namelt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var namelt = framework.Function2{
|
||||
Name: "namelt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Name},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Name.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// namelttext represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var namelttext = framework.Function2{
|
||||
Name: "namelttext",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// numeric_lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var numeric_lt = framework.Function2{
|
||||
Name: "numeric_lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Numeric, pgtypes.Numeric},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Numeric.Compare(ctx, val1.(*apd.Decimal), val2.(*apd.Decimal))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// oidlt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var oidlt = framework.Function2{
|
||||
Name: "oidlt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Oid, pgtypes.Oid},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := cmp.Compare(id.Cache().ToOID(val1.(id.Id)), id.Cache().ToOID(val2.(id.Id)))
|
||||
return res == -1, nil
|
||||
},
|
||||
}
|
||||
|
||||
// oidvectorlt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var oidvectorlt = framework.Function2{
|
||||
Name: "oidvectorlt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Oidvector, pgtypes.Oidvector},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Oidvector.Compare(ctx, val1.([]any), val2.([]any))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// textltname represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var textltname = framework.Function2{
|
||||
Name: "textltname",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Name},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// text_lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var text_lt = framework.Function2{
|
||||
Name: "text_lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1, val2)
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// time_lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var time_lt = framework.Function2{
|
||||
Name: "time_lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Time, pgtypes.Time},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Time.Compare(ctx, val1.(timeofday.TimeOfDay), val2.(timeofday.TimeOfDay))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_lt_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_lt_date = framework.Function2{
|
||||
Name: "timestamp_lt_date",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res == -1, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_lt = framework.Function2{
|
||||
Name: "timestamp_lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Timestamp.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_lt_timestamptz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_lt_timestamptz = framework.Function2{
|
||||
Name: "timestamp_lt_timestamptz",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_lt_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_lt_date = framework.Function2{
|
||||
Name: "timestamptz_lt_date",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res == -1, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_lt_timestamp represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_lt_timestamp = framework.Function2{
|
||||
Name: "timestamptz_lt_timestamp",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_lt = framework.Function2{
|
||||
Name: "timestamptz_lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// timetz_lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timetz_lt = framework.Function2{
|
||||
Name: "timetz_lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimeTZ, pgtypes.TimeTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimeTZ.Compare(ctx, val1.(timetz.TimeTZ), val2.(timetz.TimeTZ))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
|
||||
// record_lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var record_lt = framework.Function2{
|
||||
Name: "record_lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Record, pgtypes.Record},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return compare.CompareRecords(ctx, framework.Operator_BinaryLessThan, val1, val2)
|
||||
},
|
||||
}
|
||||
|
||||
// uuid_lt represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var uuid_lt = framework.Function2{
|
||||
Name: "uuid_lt",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Uuid, pgtypes.Uuid},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Uuid.Compare(ctx, val1.(uuid.UUID), val2.(uuid.UUID))
|
||||
return res == -1, err
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,558 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/apd/v3"
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/core/id"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/duration"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timeofday"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timetz"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/uuid"
|
||||
"github.com/dolthub/doltgresql/server/compare"
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '<=' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryLessOrEqual registers the functions to the catalog.
|
||||
func initBinaryLessOrEqual() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, boolle)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, bpcharle)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, byteale)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, charle)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, date_le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, date_le_timestamp)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, date_le_timestamptz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, enum_le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, float4le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, float48le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, float84le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, float8le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, int2le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, int24le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, int28le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, int42le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, int4le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, int48le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, int82le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, int84le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, int8le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, interval_le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, jsonb_le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, namele)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, nameletext)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, numeric_le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, oidle)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, oidvectorle)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, textlename)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, text_le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, time_le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, timestamp_le_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, timestamp_le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, timestamp_le_timestamptz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, timestamptz_le_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, timestamptz_le_timestamp)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, timestamptz_le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, timetz_le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, record_le)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryLessOrEqual, uuid_le)
|
||||
}
|
||||
|
||||
// boolle represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var boolle = framework.Function2{
|
||||
Name: "boolle",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bool, pgtypes.Bool},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Bool.Compare(ctx, val1.(bool), val2.(bool))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// bpcharle represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var bpcharle = framework.Function2{
|
||||
Name: "bpcharle",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.BpChar, pgtypes.BpChar},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.BpChar.Compare(ctx, val1.(string), val2.(string))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// byteale represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var byteale = framework.Function2{
|
||||
Name: "byteale",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bytea, pgtypes.Bytea},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Bytea.Compare(ctx, val1.([]byte), val2.([]byte))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// charle represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var charle = framework.Function2{
|
||||
Name: "charle",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.InternalChar, pgtypes.InternalChar},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.InternalChar.Compare(ctx, val1.(string), val2.(string))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// date_le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_le = framework.Function2{
|
||||
Name: "date_le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Date.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// date_le_timestamp represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_le_timestamp = framework.Function2{
|
||||
Name: "date_le_timestamp",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res <= 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// date_le_timestamptz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_le_timestamptz = framework.Function2{
|
||||
Name: "date_le_timestamptz",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res <= 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// enum_le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var enum_le = framework.Function2{
|
||||
Name: "enum_le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.AnyEnum, pgtypes.AnyEnum},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, t [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := t[0].Compare(ctx, val1, val2)
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// float4le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float4le = framework.Function2{
|
||||
Name: "float4le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float32.Compare(ctx, val1.(float32), val2.(float32))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// float48le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float48le = framework.Function2{
|
||||
Name: "float48le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, float64(val1.(float32)), val2.(float64))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// float84le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float84le = framework.Function2{
|
||||
Name: "float84le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, val1.(float64), float64(val2.(float32)))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// float8le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float8le = framework.Function2{
|
||||
Name: "float8le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, val1.(float64), val2.(float64))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int2le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2le = framework.Function2{
|
||||
Name: "int2le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int16.Compare(ctx, val1.(int16), val2.(int16))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int24le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int24le = framework.Function2{
|
||||
Name: "int24le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, int32(val1.(int16)), val2.(int32))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int28le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int28le = framework.Function2{
|
||||
Name: "int28le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(int16)), val2.(int64))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int42le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int42le = framework.Function2{
|
||||
Name: "int42le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, val1.(int32), int32(val2.(int16)))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int4le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4le = framework.Function2{
|
||||
Name: "int4le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, val1.(int32), val2.(int32))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int48le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int48le = framework.Function2{
|
||||
Name: "int48le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(int32)), val2.(int64))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int82le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int82le = framework.Function2{
|
||||
Name: "int82le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), int64(val2.(int16)))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int84le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int84le = framework.Function2{
|
||||
Name: "int84le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), int64(val2.(int32)))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int8le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8le = framework.Function2{
|
||||
Name: "int8le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), val2.(int64))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// interval_le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_le = framework.Function2{
|
||||
Name: "interval_le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Interval.Compare(ctx, val1.(duration.Duration), val2.(duration.Duration))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_le = framework.Function2{
|
||||
Name: "jsonb_le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.JsonB},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.JsonB.Compare(ctx, val1, val2)
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// namele represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var namele = framework.Function2{
|
||||
Name: "namele",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Name},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Name.Compare(ctx, val1.(string), val2.(string))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// nameletext represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var nameletext = framework.Function2{
|
||||
Name: "nameletext",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// numeric_le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var numeric_le = framework.Function2{
|
||||
Name: "numeric_le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Numeric, pgtypes.Numeric},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Numeric.Compare(ctx, val1.(*apd.Decimal), val2.(*apd.Decimal))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// oidle represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var oidle = framework.Function2{
|
||||
Name: "oidle",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Oid, pgtypes.Oid},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := cmp.Compare(id.Cache().ToOID(val1.(id.Id)), id.Cache().ToOID(val2.(id.Id)))
|
||||
return res <= 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// oidvectorle represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var oidvectorle = framework.Function2{
|
||||
Name: "oidvectorle",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Oidvector, pgtypes.Oidvector},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Oidvector.Compare(ctx, val1.([]any), val2.([]any))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// textlename represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var textlename = framework.Function2{
|
||||
Name: "textlename",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Name},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// text_le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var text_le = framework.Function2{
|
||||
Name: "text_le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// time_le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var time_le = framework.Function2{
|
||||
Name: "time_le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Time, pgtypes.Time},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Time.Compare(ctx, val1.(timeofday.TimeOfDay), val2.(timeofday.TimeOfDay))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_le_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_le_date = framework.Function2{
|
||||
Name: "timestamp_le_date",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res <= 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_le = framework.Function2{
|
||||
Name: "timestamp_le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Timestamp.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_le_timestamptz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_le_timestamptz = framework.Function2{
|
||||
Name: "timestamp_le_timestamptz",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_le_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_le_date = framework.Function2{
|
||||
Name: "timestamptz_le_date",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res <= 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_le_timestamp represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_le_timestamp = framework.Function2{
|
||||
Name: "timestamptz_le_timestamp",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_le = framework.Function2{
|
||||
Name: "timestamptz_le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timetz_le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timetz_le = framework.Function2{
|
||||
Name: "timetz_le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimeTZ, pgtypes.TimeTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimeTZ.Compare(ctx, val1.(timetz.TimeTZ), val2.(timetz.TimeTZ))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// record_le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var record_le = framework.Function2{
|
||||
Name: "record_le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Record, pgtypes.Record},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return compare.CompareRecords(ctx, framework.Operator_BinaryLessOrEqual, val1, val2)
|
||||
},
|
||||
}
|
||||
|
||||
// uuid_le represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var uuid_le = framework.Function2{
|
||||
Name: "uuid_le",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Uuid, pgtypes.Uuid},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Uuid.Compare(ctx, val1.(uuid.UUID), val2.(uuid.UUID))
|
||||
return res <= 0, err
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,429 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/apd/v3"
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/postgres/parser/duration"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timeofday"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timetz"
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '-' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryMinus registers the functions to the catalog.
|
||||
func initBinaryMinus() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, date_mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, date_mii)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, date_mi_interval)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, float4mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, float48mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, float8mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, float84mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, int2mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, int24mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, int28mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, int4mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, int42mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, int48mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, int8mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, int82mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, int84mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, interval_mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, numeric_sub)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, time_mi_interval)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, time_mi_time)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, timetz_mi_interval)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, timestamp_mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, timestamp_mi_interval)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, timestamptz_mi)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMinus, timestamptz_mi_interval)
|
||||
}
|
||||
|
||||
// float4mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float4mi = framework.Function2{
|
||||
Name: "float4mi",
|
||||
Return: pgtypes.Float32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return val1.(float32) - val2.(float32), nil
|
||||
},
|
||||
}
|
||||
|
||||
// float48mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float48mi = framework.Function2{
|
||||
Name: "float48mi",
|
||||
Return: pgtypes.Float64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return float64(val1.(float32)) - val2.(float64), nil
|
||||
},
|
||||
}
|
||||
|
||||
// float8mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float8mi = framework.Function2{
|
||||
Name: "float8mi",
|
||||
Return: pgtypes.Float64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return val1.(float64) - val2.(float64), nil
|
||||
},
|
||||
}
|
||||
|
||||
// float84mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float84mi = framework.Function2{
|
||||
Name: "float84mi",
|
||||
Return: pgtypes.Float64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return val1.(float64) - float64(val2.(float32)), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int2mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2mi = framework.Function2{
|
||||
Name: "int2mi",
|
||||
Return: pgtypes.Int16,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
result := int64(val1.(int16)) - int64(val2.(int16))
|
||||
if result > math.MaxInt16 || result < math.MinInt16 {
|
||||
return nil, errors.Errorf("smallint out of range")
|
||||
}
|
||||
return int16(result), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int24mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int24mi = framework.Function2{
|
||||
Name: "int24mi",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
result := int64(val1.(int16)) - int64(val2.(int32))
|
||||
if result > math.MaxInt16 || result < math.MinInt16 {
|
||||
return nil, errors.Errorf("integer out of range")
|
||||
}
|
||||
return int32(result), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int28mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int28mi = framework.Function2{
|
||||
Name: "int28mi",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return minusOverflow(int64(val1.(int16)), val2.(int64))
|
||||
},
|
||||
}
|
||||
|
||||
// int4mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4mi = framework.Function2{
|
||||
Name: "int4mi",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
result := int64(val1.(int32)) - int64(val2.(int32))
|
||||
if result > math.MaxInt32 || result < math.MinInt32 {
|
||||
return nil, errors.Errorf("integer out of range")
|
||||
}
|
||||
return int32(result), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int42mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int42mi = framework.Function2{
|
||||
Name: "int42mi",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
result := int64(val1.(int32)) - int64(val2.(int16))
|
||||
if result > math.MaxInt32 || result < math.MinInt32 {
|
||||
return nil, errors.Errorf("integer out of range")
|
||||
}
|
||||
return int32(result), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int48mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int48mi = framework.Function2{
|
||||
Name: "int48mi",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return minusOverflow(int64(val1.(int32)), val2.(int64))
|
||||
},
|
||||
}
|
||||
|
||||
// int8mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8mi = framework.Function2{
|
||||
Name: "int8mi",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return minusOverflow(val1.(int64), val2.(int64))
|
||||
},
|
||||
}
|
||||
|
||||
// int82mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int82mi = framework.Function2{
|
||||
Name: "int82mi",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return minusOverflow(val1.(int64), int64(val2.(int16)))
|
||||
},
|
||||
}
|
||||
|
||||
// int84mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int84mi = framework.Function2{
|
||||
Name: "int84mi",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return minusOverflow(val1.(int64), int64(val2.(int32)))
|
||||
},
|
||||
}
|
||||
|
||||
// interval_mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_mi = framework.Function2{
|
||||
Name: "interval_mi",
|
||||
Return: pgtypes.Interval,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
dur1 := val1.(duration.Duration)
|
||||
dur2 := val2.(duration.Duration)
|
||||
return dur1.Sub(dur2), nil
|
||||
},
|
||||
}
|
||||
|
||||
// numeric_sub represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var numeric_sub = framework.Function2{
|
||||
Name: "numeric_sub",
|
||||
Return: pgtypes.Numeric,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Numeric, pgtypes.Numeric},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
num1 := val1.(*apd.Decimal)
|
||||
num2 := val2.(*apd.Decimal)
|
||||
res := new(apd.Decimal)
|
||||
p := uint32(math.Max(float64(num1.NumDigits()), float64(num2.NumDigits())+
|
||||
math.Max(math.Abs(float64(num1.Exponent)), math.Abs(float64(num2.Exponent)))))
|
||||
_, err := sql.DecimalCtx.WithPrecision(p).Sub(res, num1, num2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
},
|
||||
}
|
||||
|
||||
// date_mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_mi = framework.Function2{
|
||||
Name: "date_mi",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
date1 := val1.(time.Time)
|
||||
date2 := val2.(time.Time)
|
||||
|
||||
// Calculate the difference in days
|
||||
duration := date1.Sub(date2)
|
||||
days := int32(duration.Hours() / 24)
|
||||
|
||||
return days, nil
|
||||
},
|
||||
}
|
||||
|
||||
// date_mii represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_mii = framework.Function2{
|
||||
Name: "date_mii",
|
||||
Return: pgtypes.Date,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
date := val1.(time.Time)
|
||||
days := val2.(int32)
|
||||
|
||||
// Subtract the specified number of days from the date
|
||||
result := date.AddDate(0, 0, -int(days))
|
||||
|
||||
return result, nil
|
||||
},
|
||||
}
|
||||
|
||||
// date_mi_interval represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_mi_interval = framework.Function2{
|
||||
Name: "date_mi_interval",
|
||||
Return: pgtypes.Timestamp,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
date := val1.(time.Time)
|
||||
interval := val2.(duration.Duration)
|
||||
seconds, ok := interval.AsInt64()
|
||||
if !ok {
|
||||
return nil, errors.New("overflown interval")
|
||||
}
|
||||
// above truncates partial seconds.
|
||||
nanos := seconds*duration.NanosPerMicro*duration.MicrosPerMilli*duration.MillisPerSec + interval.Nanos()%int64(time.Second)
|
||||
// Subtract the interval from the date using negative duration
|
||||
result := date.Add(-time.Duration(nanos))
|
||||
|
||||
return result, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_mi = framework.Function2{
|
||||
Name: "timestamptz_mi",
|
||||
Return: pgtypes.Interval,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
ts1 := val1.(time.Time)
|
||||
ts2 := val2.(time.Time)
|
||||
|
||||
// Calculate the difference and return as interval
|
||||
diff := ts1.Sub(ts2)
|
||||
return duration.MakeDuration(diff.Nanoseconds(), 0, 0), nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_mi_interval represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_mi_interval = framework.Function2{
|
||||
Name: "timestamptz_mi_interval",
|
||||
Return: pgtypes.TimestampTZ,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
timestamptz := val1.(time.Time)
|
||||
interval := val2.(duration.Duration)
|
||||
|
||||
// Subtract the interval from the timestamptz
|
||||
return timestamptz.Add(-time.Duration(interval.Nanos())), nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_mi represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_mi = framework.Function2{
|
||||
Name: "timestamp_mi",
|
||||
Return: pgtypes.Interval,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
ts1 := val1.(time.Time)
|
||||
ts2 := val2.(time.Time)
|
||||
|
||||
// Calculate the difference and return as interval
|
||||
diff := ts1.Sub(ts2)
|
||||
return duration.MakeDuration(diff.Nanoseconds(), 0, 0), nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_mi_interval represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_mi_interval = framework.Function2{
|
||||
Name: "timestamp_mi_interval",
|
||||
Return: pgtypes.Timestamp,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
timestamp := val1.(time.Time)
|
||||
interval := val2.(duration.Duration)
|
||||
|
||||
// Subtract the interval from the timestamp
|
||||
return timestamp.Add(-time.Duration(interval.Nanos())), nil
|
||||
},
|
||||
}
|
||||
|
||||
// time_mi_time represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var time_mi_time = framework.Function2{
|
||||
Name: "time_mi_time",
|
||||
Return: pgtypes.Interval,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Time, pgtypes.Time},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
time1 := val1.(timeofday.TimeOfDay)
|
||||
time2 := val2.(timeofday.TimeOfDay)
|
||||
|
||||
// Calculate the difference and return as interval
|
||||
return timeofday.TimeOfDay(int64(time1) - int64(time2)).Round(time.Microsecond), nil
|
||||
},
|
||||
}
|
||||
|
||||
// time_mi_interval represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var time_mi_interval = framework.Function2{
|
||||
Name: "time_mi_interval",
|
||||
Return: pgtypes.Time,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Time, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
timeVal := val1.(timeofday.TimeOfDay)
|
||||
interval := val2.(duration.Duration)
|
||||
return timeVal.Sub(interval), nil
|
||||
},
|
||||
}
|
||||
|
||||
// timetz_mi_interval represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timetz_mi_interval = framework.Function2{
|
||||
Name: "timetz_mi_interval",
|
||||
Return: pgtypes.TimeTZ,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.TimeTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
interval := val1.(duration.Duration)
|
||||
timetzVal := val2.(timetz.TimeTZ)
|
||||
timetzVal.TimeOfDay = timetzVal.TimeOfDay.Sub(interval)
|
||||
return timetzVal, nil
|
||||
},
|
||||
}
|
||||
|
||||
// minusOverflow is a convenience function that checks for overflow for int64 subtraction.
|
||||
func minusOverflow(val1 int64, val2 int64) (any, error) {
|
||||
if val2 > 0 {
|
||||
if val1 < math.MinInt64+val2 {
|
||||
return nil, errors.Errorf("bigint out of range")
|
||||
}
|
||||
} else {
|
||||
if val1 > math.MaxInt64+val2 {
|
||||
return nil, errors.Errorf("bigint out of range")
|
||||
}
|
||||
}
|
||||
return val1 - val2, nil
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"github.com/cockroachdb/apd/v3"
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
"github.com/dolthub/go-mysql-server/sql/types"
|
||||
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '%' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryMod registers the functions to the catalog.
|
||||
func initBinaryMod() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMod, int2mod)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMod, int4mod)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMod, int8mod)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMod, numeric_mod)
|
||||
}
|
||||
|
||||
// int2mod represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2mod = framework.Function2{
|
||||
Name: "int2mod",
|
||||
Return: pgtypes.Int16,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(int16) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return val1.(int16) % val2.(int16), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int4mod represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4mod = framework.Function2{
|
||||
Name: "int4mod",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(int32) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return val1.(int32) % val2.(int32), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int8mod represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8mod = framework.Function2{
|
||||
Name: "int8mod",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
if val2.(int64) == 0 {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
return val1.(int64) % val2.(int64), nil
|
||||
},
|
||||
}
|
||||
|
||||
// numeric_mod represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var numeric_mod = framework.Function2{
|
||||
Name: "numeric_mod",
|
||||
Return: pgtypes.Numeric,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Numeric, pgtypes.Numeric},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
num1 := val1.(*apd.Decimal)
|
||||
num2 := val2.(*apd.Decimal)
|
||||
if num1.Form == apd.NaN || num2.Form == apd.NaN ||
|
||||
(num1.Form == apd.Infinite && num2.Form == apd.Infinite) {
|
||||
return pgtypes.NumericNaN, nil
|
||||
}
|
||||
if num2.IsZero() {
|
||||
return nil, errors.Errorf("division by zero")
|
||||
}
|
||||
if num1.Form == apd.Infinite {
|
||||
return num1, nil
|
||||
}
|
||||
if num2.Form == apd.Infinite {
|
||||
return apd.New(0, 0), nil
|
||||
}
|
||||
return types.DecimalMod(num1, num2)
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/cockroachdb/apd/v3"
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/postgres/parser/duration"
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '*' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryMultiply registers the functions to the catalog.
|
||||
func initBinaryMultiply() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, float4mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, float48mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, float8mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, float84mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, int2mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, int24mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, int28mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, int4mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, int42mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, int48mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, int8mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, int82mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, int84mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, interval_mul)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryMultiply, numeric_mul)
|
||||
}
|
||||
|
||||
// float4mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float4mul = framework.Function2{
|
||||
Name: "float4mul",
|
||||
Return: pgtypes.Float32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return val1.(float32) * val2.(float32), nil
|
||||
},
|
||||
}
|
||||
|
||||
// float48mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float48mul = framework.Function2{
|
||||
Name: "float48mul",
|
||||
Return: pgtypes.Float64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return float64(val1.(float32)) * val2.(float64), nil
|
||||
},
|
||||
}
|
||||
|
||||
// float8mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float8mul = framework.Function2{
|
||||
Name: "float8mul",
|
||||
Return: pgtypes.Float64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return val1.(float64) * val2.(float64), nil
|
||||
},
|
||||
}
|
||||
|
||||
// float84mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float84mul = framework.Function2{
|
||||
Name: "float84mul",
|
||||
Return: pgtypes.Float64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return val1.(float64) * float64(val2.(float32)), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int2mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2mul = framework.Function2{
|
||||
Name: "int2mul",
|
||||
Return: pgtypes.Int16,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
result := int64(val1.(int16)) * int64(val2.(int16))
|
||||
if result > math.MaxInt16 || result < math.MinInt16 {
|
||||
return nil, errors.Errorf("smallint out of range")
|
||||
}
|
||||
return int16(result), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int24mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int24mul = framework.Function2{
|
||||
Name: "int24mul",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
result := int64(val1.(int16)) * int64(val2.(int32))
|
||||
if result > math.MaxInt16 || result < math.MinInt16 {
|
||||
return nil, errors.Errorf("integer out of range")
|
||||
}
|
||||
return int32(result), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int28mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int28mul = framework.Function2{
|
||||
Name: "int28mul",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return multiplyOverflow(int64(val1.(int16)), val2.(int64))
|
||||
},
|
||||
}
|
||||
|
||||
// int4mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4mul = framework.Function2{
|
||||
Name: "int4mul",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
result := int64(val1.(int32)) * int64(val2.(int32))
|
||||
if result > math.MaxInt32 || result < math.MinInt32 {
|
||||
return nil, errors.Errorf("integer out of range")
|
||||
}
|
||||
return int32(result), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int42mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int42mul = framework.Function2{
|
||||
Name: "int42mul",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
result := int64(val1.(int32)) * int64(val2.(int16))
|
||||
if result > math.MaxInt32 || result < math.MinInt32 {
|
||||
return nil, errors.Errorf("integer out of range")
|
||||
}
|
||||
return int32(result), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int48mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int48mul = framework.Function2{
|
||||
Name: "int48mul",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return multiplyOverflow(int64(val1.(int32)), val2.(int64))
|
||||
},
|
||||
}
|
||||
|
||||
// int8mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8mul = framework.Function2{
|
||||
Name: "int8mul",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return multiplyOverflow(val1.(int64), val2.(int64))
|
||||
},
|
||||
}
|
||||
|
||||
// int82mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int82mul = framework.Function2{
|
||||
Name: "int82mul",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return multiplyOverflow(val1.(int64), int64(val2.(int16)))
|
||||
},
|
||||
}
|
||||
|
||||
// int84mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int84mul = framework.Function2{
|
||||
Name: "int84mul",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return multiplyOverflow(val1.(int64), int64(val2.(int32)))
|
||||
},
|
||||
}
|
||||
|
||||
// interval_mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_mul = framework.Function2{
|
||||
Name: "interval_mul",
|
||||
Return: pgtypes.Interval,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return val1.(duration.Duration).MulFloat(val2.(float64)), nil
|
||||
},
|
||||
}
|
||||
|
||||
// numeric_mul represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var numeric_mul = framework.Function2{
|
||||
Name: "numeric_mul",
|
||||
Return: pgtypes.Numeric,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Numeric, pgtypes.Numeric},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
num1 := val1.(*apd.Decimal)
|
||||
num2 := val2.(*apd.Decimal)
|
||||
if (num1.Form == apd.Infinite || num2.Form == apd.Infinite) && (num1.IsZero() || num2.IsZero()) {
|
||||
return pgtypes.NumericNaN, nil
|
||||
}
|
||||
res := new(apd.Decimal)
|
||||
p := num1.NumDigits() + num2.NumDigits() + int64(math.Max(math.Abs(float64(num1.Exponent)), math.Abs(float64(num2.Exponent))))
|
||||
_, err := sql.DecimalCtx.WithPrecision(uint32(p)).Mul(res, num1, num2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
},
|
||||
}
|
||||
|
||||
// multiplyOverflow is a convenience function that checks for overflow for int64 multiplication.
|
||||
func multiplyOverflow(val1 int64, val2 int64) (any, error) {
|
||||
result := val1 * val2
|
||||
if val2 != 0 && result/val2 != val1 {
|
||||
return nil, errors.Errorf("bigint out of range")
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -0,0 +1,584 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/apd/v3"
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/core/id"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/duration"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timeofday"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timetz"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/uuid"
|
||||
"github.com/dolthub/doltgresql/server/compare"
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '<>' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryNotEqual registers the functions to the catalog.
|
||||
func initBinaryNotEqual() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, boolne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, bpcharne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, byteane)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, charne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, date_ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, date_ne_timestamp)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, date_ne_timestamptz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, enum_ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, float4ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, float48ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, float84ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, float8ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, int2ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, int24ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, int28ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, int42ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, int4ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, int48ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, int82ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, int84ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, int8ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, interval_ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, jsonb_ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, namene)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, namenetext)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, numeric_ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, oidne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, oidvectorne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, textnename)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, text_ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, time_ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, timestamp_ne_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, timestamp_ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, timestamp_ne_timestamptz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, timestamptz_ne_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, timestamptz_ne_timestamp)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, timestamptz_ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, timetz_ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, record_ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, uuid_ne)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, xidneqint4)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryNotEqual, xidneq)
|
||||
}
|
||||
|
||||
// boolne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var boolne = framework.Function2{
|
||||
Name: "boolne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bool, pgtypes.Bool},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Bool.Compare(ctx, val1.(bool), val2.(bool))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// bpcharne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var bpcharne = framework.Function2{
|
||||
Name: "bpcharne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.BpChar, pgtypes.BpChar},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.BpChar.Compare(ctx, val1.(string), val2.(string))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// byteane represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var byteane = framework.Function2{
|
||||
Name: "byteane",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Bytea, pgtypes.Bytea},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Bytea.Compare(ctx, val1.([]byte), val2.([]byte))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// charne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var charne = framework.Function2{
|
||||
Name: "charne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.InternalChar, pgtypes.InternalChar},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.InternalChar.Compare(ctx, val1.(string), val2.(string))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// date_ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_ne = framework.Function2{
|
||||
Name: "date_ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Date.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// date_ne_timestamp represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_ne_timestamp = framework.Function2{
|
||||
Name: "date_ne_timestamp",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res != 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// date_ne_timestamptz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_ne_timestamptz = framework.Function2{
|
||||
Name: "date_ne_timestamptz",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res != 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// enum_ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var enum_ne = framework.Function2{
|
||||
Name: "enum_ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.AnyEnum, pgtypes.AnyEnum},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, t [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := t[0].Compare(ctx, val1, val2)
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// float4ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float4ne = framework.Function2{
|
||||
Name: "float4ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float32.Compare(ctx, val1.(float32), val2.(float32))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// float48ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float48ne = framework.Function2{
|
||||
Name: "float48ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, float64(val1.(float32)), val2.(float64))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// float84ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float84ne = framework.Function2{
|
||||
Name: "float84ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, val1.(float64), float64(val2.(float32)))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// float8ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float8ne = framework.Function2{
|
||||
Name: "float8ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Float64.Compare(ctx, val1.(float64), val2.(float64))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int2ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2ne = framework.Function2{
|
||||
Name: "int2ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int16.Compare(ctx, val1.(int16), val2.(int16))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int24ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int24ne = framework.Function2{
|
||||
Name: "int24ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, int32(val1.(int16)), val2.(int32))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int28ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int28ne = framework.Function2{
|
||||
Name: "int28ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(int16)), val2.(int64))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int42ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int42ne = framework.Function2{
|
||||
Name: "int42ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, val1.(int32), int32(val2.(int16)))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int4ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4ne = framework.Function2{
|
||||
Name: "int4ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int32.Compare(ctx, val1.(int32), val2.(int32))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int48ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int48ne = framework.Function2{
|
||||
Name: "int48ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(int32)), val2.(int64))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int82ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int82ne = framework.Function2{
|
||||
Name: "int82ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), int64(val2.(int16)))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int84ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int84ne = framework.Function2{
|
||||
Name: "int84ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), int64(val2.(int32)))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// int8ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8ne = framework.Function2{
|
||||
Name: "int8ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Int64.Compare(ctx, val1.(int64), val2.(int64))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// interval_ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_ne = framework.Function2{
|
||||
Name: "interval_ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Interval.Compare(ctx, val1.(duration.Duration), val2.(duration.Duration))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// jsonb_ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var jsonb_ne = framework.Function2{
|
||||
Name: "jsonb_ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.JsonB, pgtypes.JsonB},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.JsonB.Compare(ctx, val1, val2)
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// namene represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var namene = framework.Function2{
|
||||
Name: "namene",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Name},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Name.Compare(ctx, val1.(string), val2.(string))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// namenetext represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var namenetext = framework.Function2{
|
||||
Name: "namenetext",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Name, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// numeric_ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var numeric_ne = framework.Function2{
|
||||
Name: "numeric_ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Numeric, pgtypes.Numeric},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Numeric.Compare(ctx, val1.(*apd.Decimal), val2.(*apd.Decimal))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// oidne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var oidne = framework.Function2{
|
||||
Name: "oidne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Oid, pgtypes.Oid},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Oid.Compare(ctx, val1.(id.Id), val2.(id.Id))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// oidvectorne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var oidvectorne = framework.Function2{
|
||||
Name: "oidvectorne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Oidvector, pgtypes.Oidvector},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Oidvector.Compare(ctx, val1.([]any), val2.([]any))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// textnename represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var textnename = framework.Function2{
|
||||
Name: "textnename",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Name},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// text_ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var text_ne = framework.Function2{
|
||||
Name: "text_ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Text, pgtypes.Text},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Text.Compare(ctx, val1.(string), val2.(string))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// time_ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var time_ne = framework.Function2{
|
||||
Name: "time_ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Time, pgtypes.Time},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Time.Compare(ctx, val1.(timeofday.TimeOfDay), val2.(timeofday.TimeOfDay))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_ne_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_ne_date = framework.Function2{
|
||||
Name: "timestamp_ne_date",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res != 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_ne = framework.Function2{
|
||||
Name: "timestamp_ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Timestamp.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_ne_timestamptz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_ne_timestamptz = framework.Function2{
|
||||
Name: "timestamp_ne_timestamptz",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_ne_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_ne_date = framework.Function2{
|
||||
Name: "timestamptz_ne_date",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res := val1.(time.Time).Compare(val2.(time.Time))
|
||||
return res != 0, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_ne_timestamp represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_ne_timestamp = framework.Function2{
|
||||
Name: "timestamptz_ne_timestamp",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_ne = framework.Function2{
|
||||
Name: "timestamptz_ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimestampTZ.Compare(ctx, val1.(time.Time), val2.(time.Time))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// timetz_ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timetz_ne = framework.Function2{
|
||||
Name: "timetz_ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimeTZ, pgtypes.TimeTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.TimeTZ.Compare(ctx, val1.(timetz.TimeTZ), val2.(timetz.TimeTZ))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// record_ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var record_ne = framework.Function2{
|
||||
Name: "record_ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Record, pgtypes.Record},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return compare.CompareRecords(ctx, framework.Operator_BinaryNotEqual, val1, val2)
|
||||
},
|
||||
}
|
||||
|
||||
// uuid_ne represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var uuid_ne = framework.Function2{
|
||||
Name: "uuid_ne",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Uuid, pgtypes.Uuid},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Uuid.Compare(ctx, val1.(uuid.UUID), val2.(uuid.UUID))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// xidneqint4 represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var xidneqint4 = framework.Function2{
|
||||
Name: "xidneqint4",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Xid, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
// TODO: investigate the edge cases
|
||||
res, err := pgtypes.Int64.Compare(ctx, int64(val1.(uint32)), int64(val2.(int32)))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
|
||||
// xidneq represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var xidneq = framework.Function2{
|
||||
Name: "xidneq",
|
||||
Return: pgtypes.Bool,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Xid, pgtypes.Xid},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
res, err := pgtypes.Xid.Compare(ctx, val1.(uint32), val2.(uint32))
|
||||
return res != 0, err
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,617 @@
|
||||
// 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 binary
|
||||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/apd/v3"
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/postgres/parser/duration"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timeofday"
|
||||
"github.com/dolthub/doltgresql/postgres/parser/timetz"
|
||||
"github.com/dolthub/doltgresql/server/functions"
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '+' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryPlus registers the functions to the catalog.
|
||||
func initBinaryPlus() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, date_pl_interval)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, date_pli)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, datetime_pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, datetimetz_pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, float4pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, float48pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, float8pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, float84pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, int2pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, int24pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, int28pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, int4pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, int42pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, int48pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, int8pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, int82pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, int84pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, integer_pl_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, interval_pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, interval_pl_time)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, interval_pl_date)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, interval_pl_timetz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, interval_pl_timestamp)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, interval_pl_timestamptz)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, numeric_add)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, time_pl_interval)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, timedate_pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, timetz_pl_interval)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, timetzdate_pl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, timestamp_pl_interval)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryPlus, timestamptz_pl_interval)
|
||||
}
|
||||
|
||||
// float4pl_callable is the callable logic for the float4pl function.
|
||||
func float4pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return val1.(float32) + val2.(float32), nil
|
||||
}
|
||||
|
||||
// float4pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float4pl = framework.Function2{
|
||||
Name: "float4pl",
|
||||
Return: pgtypes.Float32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: float4pl_callable,
|
||||
}
|
||||
|
||||
// float48pl_callable is the callable logic for the float48pl function.
|
||||
func float48pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return float64(val1.(float32)) + val2.(float64), nil
|
||||
}
|
||||
|
||||
// float48pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float48pl = framework.Function2{
|
||||
Name: "float48pl",
|
||||
Return: pgtypes.Float64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float32, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: float48pl_callable,
|
||||
}
|
||||
|
||||
// float8pl_callable is the callable logic for the float8pl function.
|
||||
func float8pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return val1.(float64) + val2.(float64), nil
|
||||
}
|
||||
|
||||
// float8pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float8pl = framework.Function2{
|
||||
Name: "float8pl",
|
||||
Return: pgtypes.Float64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float64},
|
||||
Strict: true,
|
||||
Callable: float8pl_callable,
|
||||
}
|
||||
|
||||
// float84pl_callable is the callable logic for the float84pl function.
|
||||
func float84pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return val1.(float64) + float64(val2.(float32)), nil
|
||||
}
|
||||
|
||||
// float84pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var float84pl = framework.Function2{
|
||||
Name: "float84pl",
|
||||
Return: pgtypes.Float64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Float64, pgtypes.Float32},
|
||||
Strict: true,
|
||||
Callable: float84pl_callable,
|
||||
}
|
||||
|
||||
// int2pl_callable is the callable logic for the int2pl function.
|
||||
func int2pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
result := int64(val1.(int16)) + int64(val2.(int16))
|
||||
if result > math.MaxInt16 || result < math.MinInt16 {
|
||||
return nil, errors.Errorf("smallint out of range")
|
||||
}
|
||||
return int16(result), nil
|
||||
}
|
||||
|
||||
// int2pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2pl = framework.Function2{
|
||||
Name: "int2pl",
|
||||
Return: pgtypes.Int16,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: int2pl_callable,
|
||||
}
|
||||
|
||||
// int24pl_callable is the callable logic for the int24pl function.
|
||||
func int24pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
result := int64(val1.(int16)) + int64(val2.(int32))
|
||||
if result > math.MaxInt16 || result < math.MinInt16 {
|
||||
return nil, errors.Errorf("integer out of range")
|
||||
}
|
||||
return int32(result), nil
|
||||
}
|
||||
|
||||
// int24pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int24pl = framework.Function2{
|
||||
Name: "int24pl",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: int24pl_callable,
|
||||
}
|
||||
|
||||
// int28pl_callable is the callable logic for the int28pl function.
|
||||
func int28pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return plusOverflow(int64(val1.(int16)), val2.(int64))
|
||||
}
|
||||
|
||||
// int28pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int28pl = framework.Function2{
|
||||
Name: "int28pl",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: int28pl_callable,
|
||||
}
|
||||
|
||||
// int4pl_callable is the callable logic for the int4pl function.
|
||||
func int4pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
result := int64(val1.(int32)) + int64(val2.(int32))
|
||||
if result > math.MaxInt32 || result < math.MinInt32 {
|
||||
return nil, errors.Errorf("integer out of range")
|
||||
}
|
||||
return int32(result), nil
|
||||
}
|
||||
|
||||
// int4pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4pl = framework.Function2{
|
||||
Name: "int4pl",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: int4pl_callable,
|
||||
}
|
||||
|
||||
// int42pl_callable is the callable logic for the int42pl function.
|
||||
func int42pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
result := int64(val1.(int32)) + int64(val2.(int16))
|
||||
if result > math.MaxInt32 || result < math.MinInt32 {
|
||||
return nil, errors.Errorf("integer out of range")
|
||||
}
|
||||
return int32(result), nil
|
||||
}
|
||||
|
||||
// int42pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int42pl = framework.Function2{
|
||||
Name: "int42pl",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: int42pl_callable,
|
||||
}
|
||||
|
||||
// int48pl_callable is the callable logic for the int48pl function.
|
||||
func int48pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return plusOverflow(int64(val1.(int32)), val2.(int64))
|
||||
}
|
||||
|
||||
// int48pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int48pl = framework.Function2{
|
||||
Name: "int48pl",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: int48pl_callable,
|
||||
}
|
||||
|
||||
// int8pl_callable is the callable logic for the int8pl function.
|
||||
func int8pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return plusOverflow(val1.(int64), val2.(int64))
|
||||
}
|
||||
|
||||
// int8pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8pl = framework.Function2{
|
||||
Name: "int8pl",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int64},
|
||||
Strict: true,
|
||||
Callable: int8pl_callable,
|
||||
}
|
||||
|
||||
// int82pl_callable is the callable logic for the int82pl function.
|
||||
func int82pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return plusOverflow(val1.(int64), int64(val2.(int16)))
|
||||
}
|
||||
|
||||
// int82pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int82pl = framework.Function2{
|
||||
Name: "int82pl",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int16},
|
||||
Strict: true,
|
||||
Callable: int82pl_callable,
|
||||
}
|
||||
|
||||
// int84pl_callable is the callable logic for the int84pl function.
|
||||
func int84pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return plusOverflow(val1.(int64), int64(val2.(int32)))
|
||||
}
|
||||
|
||||
// int84pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int84pl = framework.Function2{
|
||||
Name: "int84pl",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: int84pl_callable,
|
||||
}
|
||||
|
||||
// integer_pl_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var integer_pl_date = framework.Function2{
|
||||
Name: "integer_pl_date",
|
||||
Return: pgtypes.Date,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
days := val1.(int32)
|
||||
date := val2.(time.Time)
|
||||
|
||||
// Add the specified number of days to the date (reverse of date_pli)
|
||||
result := date.AddDate(0, 0, int(days))
|
||||
|
||||
return result, nil
|
||||
},
|
||||
}
|
||||
|
||||
// interval_pl_callable is the callable logic for the interval_pl function.
|
||||
func interval_pl_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
dur1 := val1.(duration.Duration)
|
||||
dur2 := val2.(duration.Duration)
|
||||
return dur1.Add(dur2), nil
|
||||
}
|
||||
|
||||
// interval_pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_pl = framework.Function2{
|
||||
Name: "interval_pl",
|
||||
Return: pgtypes.Interval,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: interval_pl_callable,
|
||||
}
|
||||
|
||||
// interval_pl_time_callable is the callable logic for the interval_pl_time function.
|
||||
func interval_pl_time_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
interval := val1.(duration.Duration)
|
||||
timeVal := val2.(timeofday.TimeOfDay)
|
||||
return timeVal.Add(interval), nil
|
||||
}
|
||||
|
||||
// interval_pl_time represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_pl_time = framework.Function2{
|
||||
Name: "interval_pl_time",
|
||||
Return: pgtypes.Time,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.Time},
|
||||
Strict: true,
|
||||
Callable: interval_pl_time_callable,
|
||||
}
|
||||
|
||||
// interval_pl_date_callable is the callable logic for the interval_pl_date function.
|
||||
func interval_pl_date_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return intervalPlusNonInterval(val1.(duration.Duration), val2.(time.Time))
|
||||
}
|
||||
|
||||
// interval_pl_date represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_pl_date = framework.Function2{
|
||||
Name: "interval_pl_date",
|
||||
Return: pgtypes.Timestamp,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: interval_pl_date_callable,
|
||||
}
|
||||
|
||||
// interval_pl_timetz_callable is the callable logic for the interval_pl_timetz function.
|
||||
func interval_pl_timetz_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
interval := val1.(duration.Duration)
|
||||
timeVal := val2.(timetz.TimeTZ)
|
||||
timeVal.TimeOfDay = timeVal.TimeOfDay.Add(interval)
|
||||
return timeVal, nil
|
||||
}
|
||||
|
||||
// interval_pl_timetz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_pl_timetz = framework.Function2{
|
||||
Name: "interval_pl_timetz",
|
||||
Return: pgtypes.TimeTZ,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.TimeTZ},
|
||||
Strict: true,
|
||||
Callable: interval_pl_timetz_callable,
|
||||
}
|
||||
|
||||
// interval_pl_timestamp_callable is the callable logic for the interval_pl_timestamp function.
|
||||
func interval_pl_timestamp_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return intervalPlusNonInterval(val1.(duration.Duration), val2.(time.Time))
|
||||
}
|
||||
|
||||
// interval_pl_timestamp represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_pl_timestamp = framework.Function2{
|
||||
Name: "interval_pl_timestamp",
|
||||
Return: pgtypes.Timestamp,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.Timestamp},
|
||||
Strict: true,
|
||||
Callable: interval_pl_timestamp_callable,
|
||||
}
|
||||
|
||||
// interval_pl_timestamptz_callable is the callable logic for the interval_pl_timestamptz function.
|
||||
func interval_pl_timestamptz_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return intervalPlusNonInterval(val1.(duration.Duration), val2.(time.Time))
|
||||
}
|
||||
|
||||
// interval_pl_timestamptz represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var interval_pl_timestamptz = framework.Function2{
|
||||
Name: "interval_pl_timestamptz",
|
||||
Return: pgtypes.TimestampTZ,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Interval, pgtypes.TimestampTZ},
|
||||
Strict: true,
|
||||
Callable: interval_pl_timestamptz_callable,
|
||||
}
|
||||
|
||||
// numeric_add_callable is the callable logic for the numeric_add function.
|
||||
func numeric_add_callable(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
num1 := val1.(*apd.Decimal)
|
||||
num2 := val2.(*apd.Decimal)
|
||||
if num1.Form == apd.NaN || num2.Form == apd.NaN ||
|
||||
(num1.Form == apd.Infinite && num2.Form == apd.Infinite && num2.Negative) ||
|
||||
(num2.Form == apd.Infinite && num1.Form == apd.Infinite && num1.Negative) {
|
||||
return pgtypes.NumericNaN, nil
|
||||
}
|
||||
if num1.Form == apd.Infinite || num2.Form == apd.Infinite {
|
||||
if num1.Negative || num2.Negative {
|
||||
return pgtypes.NumericNegInf, nil
|
||||
}
|
||||
return pgtypes.NumericInf, nil
|
||||
}
|
||||
|
||||
res := new(apd.Decimal)
|
||||
p := uint32(math.Max(float64(num1.NumDigits()), float64(num2.NumDigits())+
|
||||
math.Max(math.Abs(float64(num1.Exponent)), math.Abs(float64(num2.Exponent)))))
|
||||
_, err := sql.DecimalCtx.WithPrecision(p).Add(res, num1, num2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// numeric_add represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var numeric_add = framework.Function2{
|
||||
Name: "numeric_add",
|
||||
Return: pgtypes.Numeric,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Numeric, pgtypes.Numeric},
|
||||
Strict: true,
|
||||
Callable: numeric_add_callable,
|
||||
}
|
||||
|
||||
// plusOverflow is a convenience function that checks for overflow for int64 addition.
|
||||
func plusOverflow(val1 int64, val2 int64) (any, error) {
|
||||
if val2 > 0 {
|
||||
if val1 > math.MaxInt64-val2 {
|
||||
return nil, errors.Errorf("bigint out of range")
|
||||
}
|
||||
} else {
|
||||
if val1 < math.MinInt64-val2 {
|
||||
return nil, errors.Errorf("bigint out of range")
|
||||
}
|
||||
}
|
||||
return val1 + val2, nil
|
||||
}
|
||||
|
||||
// date_pl_interval represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_pl_interval = framework.Function2{
|
||||
Name: "date_pl_interval",
|
||||
Return: pgtypes.Timestamp,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
date := val1.(time.Time)
|
||||
interval := val2.(duration.Duration)
|
||||
|
||||
// Add the interval to the date using the existing helper function
|
||||
return intervalPlusNonInterval(interval, date)
|
||||
},
|
||||
}
|
||||
|
||||
// date_pli represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var date_pli = framework.Function2{
|
||||
Name: "date_pli",
|
||||
Return: pgtypes.Date,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
date := val1.(time.Time)
|
||||
days := val2.(int32)
|
||||
|
||||
// Add the specified number of days to the date
|
||||
result := date.AddDate(0, 0, int(days))
|
||||
|
||||
return result, nil
|
||||
},
|
||||
}
|
||||
|
||||
// datetime_pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var datetime_pl = framework.Function2{
|
||||
Name: "datetime_pl",
|
||||
Return: pgtypes.Timestamp,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.Time},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
date := val1.(time.Time)
|
||||
timeVal := val2.(timeofday.TimeOfDay).ToTime()
|
||||
|
||||
// Combine date from first parameter with time from second parameter
|
||||
// Extract hour, minute, second, nanosecond from time
|
||||
hour, min, sec := timeVal.Clock()
|
||||
nsec := timeVal.Nanosecond()
|
||||
|
||||
// Create new timestamp with date components from date and time components from time
|
||||
result := time.Date(date.Year(), date.Month(), date.Day(), hour, min, sec, nsec, date.Location())
|
||||
|
||||
return result, nil
|
||||
},
|
||||
}
|
||||
|
||||
// datetimetz_pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var datetimetz_pl = framework.Function2{
|
||||
Name: "datetimetz_pl",
|
||||
Return: pgtypes.TimestampTZ,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Date, pgtypes.TimeTZ},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
date := val1.(time.Time)
|
||||
timetzVal := val2.(timetz.TimeTZ).ToTime()
|
||||
|
||||
// Combine date from first parameter with time+timezone from second parameter
|
||||
// Extract hour, minute, second, nanosecond, and timezone from timetz
|
||||
hour, min, sec := timetzVal.Clock()
|
||||
nsec := timetzVal.Nanosecond()
|
||||
location := timetzVal.Location()
|
||||
|
||||
// Create new timestamptz with date components from date and time+timezone components from timetz
|
||||
result := time.Date(date.Year(), date.Month(), date.Day(), hour, min, sec, nsec, location)
|
||||
|
||||
return result, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timedate_pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timedate_pl = framework.Function2{
|
||||
Name: "timedate_pl",
|
||||
Return: pgtypes.Timestamp,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Time, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
timeVal := val1.(timeofday.TimeOfDay).ToTime()
|
||||
date := val2.(time.Time)
|
||||
|
||||
// Combine time from first parameter with date from second parameter
|
||||
// Extract hour, minute, second, nanosecond from time
|
||||
hour, min, sec := timeVal.Clock()
|
||||
nsec := timeVal.Nanosecond()
|
||||
|
||||
// Create new timestamp with time components from time and date components from date
|
||||
result := time.Date(date.Year(), date.Month(), date.Day(), hour, min, sec, nsec, date.Location())
|
||||
|
||||
return result, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timetzdate_pl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timetzdate_pl = framework.Function2{
|
||||
Name: "timetzdate_pl",
|
||||
Return: pgtypes.TimestampTZ,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimeTZ, pgtypes.Date},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
timetzVal := val1.(timetz.TimeTZ).ToTime()
|
||||
date := val2.(time.Time)
|
||||
|
||||
// Combine timetz from first parameter with date from second parameter
|
||||
// Extract hour, minute, second, nanosecond, and timezone from timetz
|
||||
hour, min, sec := timetzVal.Clock()
|
||||
nsec := timetzVal.Nanosecond()
|
||||
location := timetzVal.Location()
|
||||
|
||||
// Create new timestamptz with time+timezone components from timetz and date components from date
|
||||
result := time.Date(date.Year(), date.Month(), date.Day(), hour, min, sec, nsec, location)
|
||||
|
||||
return result, nil
|
||||
},
|
||||
}
|
||||
|
||||
// timestamp_pl_interval represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamp_pl_interval = framework.Function2{
|
||||
Name: "timestamp_pl_interval",
|
||||
Return: pgtypes.Timestamp,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Timestamp, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
timestamp := val1.(time.Time)
|
||||
interval := val2.(duration.Duration)
|
||||
|
||||
// Add the interval to the timestamp using the existing helper function
|
||||
return intervalPlusNonInterval(interval, timestamp)
|
||||
},
|
||||
}
|
||||
|
||||
// timestamptz_pl_interval represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timestamptz_pl_interval = framework.Function2{
|
||||
Name: "timestamptz_pl_interval",
|
||||
Return: pgtypes.TimestampTZ,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimestampTZ, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
timestamptz := val1.(time.Time)
|
||||
interval := val2.(duration.Duration)
|
||||
|
||||
// Add the interval to the timestamptz using the existing helper function
|
||||
return intervalPlusNonInterval(interval, timestamptz)
|
||||
},
|
||||
}
|
||||
|
||||
// time_pl_interval represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var time_pl_interval = framework.Function2{
|
||||
Name: "time_pl_interval",
|
||||
Return: pgtypes.Time,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Time, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
timeVal := val1.(timeofday.TimeOfDay)
|
||||
interval := val2.(duration.Duration)
|
||||
return timeVal.Add(interval), nil
|
||||
},
|
||||
}
|
||||
|
||||
// timetz_pl_interval represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var timetz_pl_interval = framework.Function2{
|
||||
Name: "timetz_pl_interval",
|
||||
Return: pgtypes.TimeTZ,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.TimeTZ, pgtypes.Interval},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
timetzVal := val1.(timetz.TimeTZ)
|
||||
interval := val2.(duration.Duration)
|
||||
timetzVal.TimeOfDay = timetzVal.TimeOfDay.Add(interval)
|
||||
return timetzVal, nil
|
||||
},
|
||||
}
|
||||
|
||||
// intervalPlusNonInterval adds given interval duration to the given time.Time value.
|
||||
// During converting interval duration to time.Duration type, it can overflow.
|
||||
func intervalPlusNonInterval(d duration.Duration, t time.Time) (time.Time, error) {
|
||||
seconds, ok := d.AsInt64()
|
||||
if !ok {
|
||||
return time.Time{}, errors.Errorf("interval overflow")
|
||||
}
|
||||
nanos := float64(seconds) * functions.NanosPerSec
|
||||
if nanos > float64(math.MaxInt64) || nanos < float64(math.MinInt64) {
|
||||
return time.Time{}, errors.Errorf("interval overflow")
|
||||
}
|
||||
return t.Add(time.Duration(nanos)), nil
|
||||
}
|
||||
@@ -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 binary
|
||||
|
||||
import (
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '<<' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryShiftLeft registers the functions to the catalog.
|
||||
func initBinaryShiftLeft() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryShiftLeft, int2shl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryShiftLeft, int4shl)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryShiftLeft, int8shl)
|
||||
}
|
||||
|
||||
// int2shl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2shl = framework.Function2{
|
||||
Name: "int2shl",
|
||||
Return: pgtypes.Int16,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int16(int32(val1.(int16)) << val2.(int32)), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int4shl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4shl = framework.Function2{
|
||||
Name: "int4shl",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int32(val1.(int32) << val2.(int32)), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int8shl represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8shl = framework.Function2{
|
||||
Name: "int8shl",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int64(val1.(int64) << int64(val2.(int32))), nil
|
||||
},
|
||||
}
|
||||
@@ -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 binary
|
||||
|
||||
import (
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/doltgresql/server/functions/framework"
|
||||
pgtypes "github.com/dolthub/doltgresql/server/types"
|
||||
)
|
||||
|
||||
// These functions can be gathered using the following query from a Postgres 15 instance:
|
||||
// SELECT * FROM pg_operator o WHERE o.oprname = '>>' ORDER BY o.oprcode::varchar;
|
||||
|
||||
// initBinaryShiftRight registers the functions to the catalog.
|
||||
func initBinaryShiftRight() {
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryShiftRight, int2shr)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryShiftRight, int4shr)
|
||||
framework.RegisterBinaryFunction(framework.Operator_BinaryShiftRight, int8shr)
|
||||
}
|
||||
|
||||
// int2shr represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int2shr = framework.Function2{
|
||||
Name: "int2shr",
|
||||
Return: pgtypes.Int16,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int16, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int16(int32(val1.(int16)) >> val2.(int32)), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int4shr represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int4shr = framework.Function2{
|
||||
Name: "int4shr",
|
||||
Return: pgtypes.Int32,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int32, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int32(val1.(int32) >> val2.(int32)), nil
|
||||
},
|
||||
}
|
||||
|
||||
// int8shr represents the PostgreSQL function of the same name, taking the same parameters.
|
||||
var int8shr = framework.Function2{
|
||||
Name: "int8shr",
|
||||
Return: pgtypes.Int64,
|
||||
Parameters: [2]*pgtypes.DoltgresType{pgtypes.Int64, pgtypes.Int32},
|
||||
Strict: true,
|
||||
Callable: func(ctx *sql.Context, _ [3]*pgtypes.DoltgresType, val1 any, val2 any) (any, error) {
|
||||
return int64(val1.(int64) >> int64(val2.(int32))), nil
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user