You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@age.apache.org by de...@apache.org on 2021/04/14 23:27:22 UTC
[incubator-age] branch master updated: Add operator overload for
agtype to numeric
This is an automated email from the ASF dual-hosted git repository.
dehowef pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-age.git
The following commit(s) were added to refs/heads/master by this push:
new 10734a4 Add operator overload for agtype to numeric
10734a4 is described below
commit 10734a461e5a945745bf64c6217265c6b4432f6e
Author: Dehowe Feng <de...@gmail.com>
AuthorDate: Tue Apr 13 17:45:45 2021 -0700
Add operator overload for agtype to numeric
Overloaded comparison and arithmetic operators to handle numerics.
Added logic to handle agtype null input for any_functions.
Added regression tests for mod cases, which were previously missing.
Added regression tests to handle agtype null input.
---
age--0.4.0.sql | 415 +++++++++++++++++++++++++++++++++++++
regress/expected/agtype.out | 232 +++++++++++++++++++++
regress/sql/agtype.sql | 50 ++++-
src/backend/utils/adt/agtype_ops.c | 55 +++++
4 files changed, 750 insertions(+), 2 deletions(-)
diff --git a/age--0.4.0.sql b/age--0.4.0.sql
index fe50462..1280d8c 100644
--- a/age--0.4.0.sql
+++ b/age--0.4.0.sql
@@ -514,6 +514,36 @@ CREATE OPERATOR + (
COMMUTATOR = +
);
+CREATE FUNCTION ag_catalog.agtype_any_add(agtype, numeric)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR + (
+ FUNCTION = ag_catalog.agtype_any_add,
+ LEFTARG = agtype,
+ RIGHTARG = numeric,
+ COMMUTATOR = +
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_add(numeric, agtype)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR + (
+ FUNCTION = ag_catalog.agtype_any_add,
+ LEFTARG = numeric,
+ RIGHTARG = agtype,
+ COMMUTATOR = +
+);
+
CREATE FUNCTION ag_catalog.agtype_sub(agtype, agtype)
RETURNS agtype
LANGUAGE c
@@ -668,6 +698,34 @@ CREATE OPERATOR - (
RIGHTARG = agtype
);
+CREATE FUNCTION ag_catalog.agtype_any_sub(agtype, numeric)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR - (
+ FUNCTION = ag_catalog.agtype_any_sub,
+ LEFTARG = agtype,
+ RIGHTARG = numeric
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_sub(numeric, agtype)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR - (
+ FUNCTION = ag_catalog.agtype_any_sub,
+ LEFTARG = numeric,
+ RIGHTARG = agtype
+);
+
CREATE FUNCTION ag_catalog.agtype_neg(agtype)
RETURNS agtype
LANGUAGE c
@@ -846,6 +904,36 @@ CREATE OPERATOR * (
COMMUTATOR = *
);
+CREATE FUNCTION ag_catalog.agtype_any_mul(agtype, numeric)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR * (
+ FUNCTION = ag_catalog.agtype_any_mul,
+ LEFTARG = agtype,
+ RIGHTARG = numeric,
+ COMMUTATOR = *
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_mul(numeric, agtype)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR * (
+ FUNCTION = ag_catalog.agtype_any_mul,
+ LEFTARG = numeric,
+ RIGHTARG = agtype,
+ COMMUTATOR = *
+);
+
CREATE FUNCTION ag_catalog.agtype_div(agtype, agtype)
RETURNS agtype
LANGUAGE c
@@ -1000,6 +1088,34 @@ CREATE OPERATOR / (
RIGHTARG = agtype
);
+CREATE FUNCTION ag_catalog.agtype_any_div(agtype, numeric)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR / (
+ FUNCTION = ag_catalog.agtype_any_div,
+ LEFTARG = agtype,
+ RIGHTARG = numeric
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_div(numeric, agtype)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR / (
+ FUNCTION = ag_catalog.agtype_any_div,
+ LEFTARG = numeric,
+ RIGHTARG = agtype
+);
+
CREATE FUNCTION ag_catalog.agtype_mod(agtype, agtype)
RETURNS agtype
LANGUAGE c
@@ -1098,6 +1214,89 @@ CREATE OPERATOR % (
RIGHTARG = agtype
);
+CREATE FUNCTION ag_catalog.agtype_any_mod(agtype, real)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR % (
+ FUNCTION = ag_catalog.agtype_any_mod,
+ LEFTARG = agtype,
+ RIGHTARG = real
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_mod(real, agtype)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR % (
+ FUNCTION = ag_catalog.agtype_any_mod,
+ LEFTARG = real,
+ RIGHTARG = agtype
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_mod(agtype, double precision)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR % (
+ FUNCTION = ag_catalog.agtype_any_mod,
+ LEFTARG = agtype,
+ RIGHTARG = double precision
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_mod(double precision, agtype)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR % (
+ FUNCTION = ag_catalog.agtype_any_mod,
+ LEFTARG = double precision,
+ RIGHTARG = agtype
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_mod(agtype, numeric)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR % (
+ FUNCTION = ag_catalog.agtype_any_mod,
+ LEFTARG = agtype,
+ RIGHTARG = numeric
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_mod(numeric, agtype)
+RETURNS agtype
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR % (
+ FUNCTION = ag_catalog.agtype_any_mod,
+ LEFTARG = numeric,
+ RIGHTARG = agtype
+);
CREATE FUNCTION ag_catalog.agtype_pow(agtype, agtype)
RETURNS agtype
@@ -1315,6 +1514,42 @@ CREATE OPERATOR = (
JOIN = eqjoinsel
);
+CREATE FUNCTION ag_catalog.agtype_any_eq(agtype, numeric)
+RETURNS boolean
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR = (
+ FUNCTION = ag_catalog.agtype_any_eq,
+ LEFTARG = agtype,
+ RIGHTARG = numeric,
+ COMMUTATOR = =,
+ NEGATOR = <>,
+ RESTRICT = eqsel,
+ JOIN = eqjoinsel
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_eq(numeric, agtype)
+RETURNS boolean
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR = (
+ FUNCTION = ag_catalog.agtype_any_eq,
+ LEFTARG = numeric,
+ RIGHTARG = agtype,
+ COMMUTATOR = =,
+ NEGATOR = <>,
+ RESTRICT = eqsel,
+ JOIN = eqjoinsel
+);
+
CREATE FUNCTION ag_catalog.agtype_ne(agtype, agtype)
RETURNS boolean
LANGUAGE c
@@ -1513,6 +1748,42 @@ CREATE OPERATOR <> (
JOIN = neqjoinsel
);
+CREATE FUNCTION ag_catalog.agtype_any_ne(agtype, numeric)
+RETURNS boolean
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR <> (
+ FUNCTION = ag_catalog.agtype_any_ne,
+ LEFTARG = agtype,
+ RIGHTARG = numeric,
+ COMMUTATOR = <>,
+ NEGATOR = =,
+ RESTRICT = neqsel,
+ JOIN = neqjoinsel
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_ne(numeric, agtype)
+RETURNS boolean
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR <> (
+ FUNCTION = ag_catalog.agtype_any_ne,
+ LEFTARG = numeric,
+ RIGHTARG = agtype,
+ COMMUTATOR = <>,
+ NEGATOR = =,
+ RESTRICT = neqsel,
+ JOIN = neqjoinsel
+);
+
CREATE FUNCTION ag_catalog.agtype_lt(agtype, agtype)
RETURNS boolean
LANGUAGE c
@@ -1711,6 +1982,42 @@ CREATE OPERATOR < (
JOIN = scalarltjoinsel
);
+CREATE FUNCTION ag_catalog.agtype_any_lt(agtype, numeric)
+RETURNS boolean
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR < (
+ FUNCTION = ag_catalog.agtype_any_lt,
+ LEFTARG = agtype,
+ RIGHTARG = numeric,
+ COMMUTATOR = >,
+ NEGATOR = >=,
+ RESTRICT = scalarltsel,
+ JOIN = scalarltjoinsel
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_lt(numeric, agtype)
+RETURNS boolean
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR < (
+ FUNCTION = ag_catalog.agtype_any_lt,
+ LEFTARG = numeric,
+ RIGHTARG = agtype,
+ COMMUTATOR = >,
+ NEGATOR = >=,
+ RESTRICT = scalarltsel,
+ JOIN = scalarltjoinsel
+);
+
CREATE FUNCTION ag_catalog.agtype_gt(agtype, agtype)
RETURNS boolean
LANGUAGE c
@@ -1909,6 +2216,42 @@ CREATE OPERATOR > (
JOIN = scalargtjoinsel
);
+CREATE FUNCTION ag_catalog.agtype_any_gt(agtype, numeric)
+RETURNS boolean
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR > (
+ FUNCTION = ag_catalog.agtype_any_gt,
+ LEFTARG = agtype,
+ RIGHTARG = numeric,
+ COMMUTATOR = <,
+ NEGATOR = <=,
+ RESTRICT = scalargtsel,
+ JOIN = scalargtjoinsel
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_gt(numeric, agtype)
+RETURNS boolean
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR > (
+ FUNCTION = ag_catalog.agtype_any_gt,
+ LEFTARG = numeric,
+ RIGHTARG = agtype,
+ COMMUTATOR = <,
+ NEGATOR = <=,
+ RESTRICT = scalargtsel,
+ JOIN = scalargtjoinsel
+);
+
CREATE FUNCTION ag_catalog.agtype_le(agtype, agtype)
RETURNS boolean
LANGUAGE c
@@ -2107,6 +2450,42 @@ CREATE OPERATOR <= (
JOIN = scalarlejoinsel
);
+CREATE FUNCTION ag_catalog.agtype_any_le(agtype, numeric)
+RETURNS boolean
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR <= (
+ FUNCTION = ag_catalog.agtype_any_le,
+ LEFTARG = agtype,
+ RIGHTARG = numeric,
+ COMMUTATOR = >=,
+ NEGATOR = >,
+ RESTRICT = scalarlesel,
+ JOIN = scalarlejoinsel
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_le(numeric, agtype)
+RETURNS boolean
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR <= (
+ FUNCTION = ag_catalog.agtype_any_le,
+ LEFTARG = numeric,
+ RIGHTARG = agtype,
+ COMMUTATOR = >=,
+ NEGATOR = >,
+ RESTRICT = scalarlesel,
+ JOIN = scalarlejoinsel
+);
+
CREATE FUNCTION ag_catalog.agtype_ge(agtype, agtype)
RETURNS boolean
LANGUAGE c
@@ -2305,6 +2684,42 @@ CREATE OPERATOR >= (
JOIN = scalargejoinsel
);
+CREATE FUNCTION ag_catalog.agtype_any_ge(agtype, numeric)
+RETURNS boolean
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR >= (
+ FUNCTION = ag_catalog.agtype_any_ge,
+ LEFTARG = agtype,
+ RIGHTARG = numeric,
+ COMMUTATOR = <=,
+ NEGATOR = <,
+ RESTRICT = scalargesel,
+ JOIN = scalargejoinsel
+);
+
+CREATE FUNCTION ag_catalog.agtype_any_ge(numeric, agtype)
+RETURNS boolean
+LANGUAGE c
+STABLE
+RETURNS NULL ON NULL INPUT
+PARALLEL SAFE
+AS 'MODULE_PATHNAME';
+
+CREATE OPERATOR >= (
+ FUNCTION = ag_catalog.agtype_any_ge,
+ LEFTARG = numeric,
+ RIGHTARG = agtype,
+ COMMUTATOR = <=,
+ NEGATOR = <,
+ RESTRICT = scalargesel,
+ JOIN = scalargejoinsel
+);
+
CREATE FUNCTION ag_catalog.agtype_btree_cmp(agtype, agtype)
RETURNS INTEGER
LANGUAGE c
diff --git a/regress/expected/agtype.out b/regress/expected/agtype.out
index 4701d64..1022e95 100644
--- a/regress/expected/agtype.out
+++ b/regress/expected/agtype.out
@@ -339,6 +339,48 @@ SELECT agtype_div('4.0::numeric', '-3::numeric');
-1.3333333333333333::numeric
(1 row)
+SELECT agtype_mod('-11', '3');
+ agtype_mod
+------------
+ -2
+(1 row)
+
+SELECT agtype_mod('11', '-3.0');
+ agtype_mod
+------------
+ 2.0
+(1 row)
+
+SELECT agtype_mod('-11.0', '3');
+ agtype_mod
+------------
+ -2.0
+(1 row)
+
+SELECT agtype_mod('11.0', '-3.0');
+ agtype_mod
+------------
+ 2.0
+(1 row)
+
+SELECT agtype_mod('11', '-3.0::numeric');
+ agtype_mod
+--------------
+ 2.0::numeric
+(1 row)
+
+SELECT agtype_mod('-11.0', '3::numeric');
+ agtype_mod
+-------------
+ -2::numeric
+(1 row)
+
+SELECT agtype_mod('11.0::numeric', '-3::numeric');
+ agtype_mod
+--------------
+ 2.0::numeric
+(1 row)
+
SELECT agtype_pow('-2', '3');
agtype_pow
------------
@@ -493,6 +535,30 @@ SELECT agtype_any_div('-4.0::numeric', 3);
-1.3333333333333333::numeric
(1 row)
+SELECT agtype_any_mod('-11', 3);
+ agtype_any_mod
+----------------
+ -2
+(1 row)
+
+SELECT agtype_any_mod('11.0', -3);
+ agtype_any_mod
+----------------
+ 2.0
+(1 row)
+
+SELECT agtype_any_mod('-11::numeric', 3);
+ agtype_any_mod
+----------------
+ -2::numeric
+(1 row)
+
+SELECT agtype_any_mod('-11.0::numeric', 3);
+ agtype_any_mod
+----------------
+ -2.0::numeric
+(1 row)
+
--
-- Should fail with divide by zero
--
@@ -809,6 +875,172 @@ SELECT 3 % '3.14::numeric'::agtype;
(1 row)
--
+-- Test overloaded agytype any functions and operators for NULL input
+-- +, -, *, /, %, =, <>, <, >, <=, >=
+-- These should all return null
+SELECT agtype_any_add('null'::agtype, 1);
+ agtype_any_add
+----------------
+
+(1 row)
+
+SELECT agtype_any_sub('null'::agtype, 1);
+ agtype_any_sub
+----------------
+
+(1 row)
+
+SELECT agtype_any_mul('null'::agtype, 1);
+ agtype_any_mul
+----------------
+
+(1 row)
+
+SELECT agtype_any_div('null'::agtype, 1);
+ agtype_any_div
+----------------
+
+(1 row)
+
+SELECT agtype_any_mod('null'::agtype, 1);
+ agtype_any_mod
+----------------
+
+(1 row)
+
+SELECT 1 + 'null'::agtype;
+ ?column?
+----------
+
+(1 row)
+
+SELECT 1 - 'null'::agtype;
+ ?column?
+----------
+
+(1 row)
+
+SELECT 1 * 'null'::agtype;
+ ?column?
+----------
+
+(1 row)
+
+SELECT 1 / 'null'::agtype;
+ ?column?
+----------
+
+(1 row)
+
+SELECT 1 % 'null'::agtype;
+ ?column?
+----------
+
+(1 row)
+
+SELECT agtype_any_add('null'::agtype, 1);
+ agtype_any_add
+----------------
+
+(1 row)
+
+SELECT agtype_any_sub('null'::agtype, 1);
+ agtype_any_sub
+----------------
+
+(1 row)
+
+SELECT agtype_any_mul('null'::agtype, 1);
+ agtype_any_mul
+----------------
+
+(1 row)
+
+SELECT agtype_any_div('null'::agtype, 1);
+ agtype_any_div
+----------------
+
+(1 row)
+
+SELECT agtype_any_mod('null'::agtype, 1);
+ agtype_any_mod
+----------------
+
+(1 row)
+
+SELECT 1 = 'null'::agtype;
+ ?column?
+----------
+
+(1 row)
+
+SELECT 1 <> 'null'::agtype;
+ ?column?
+----------
+
+(1 row)
+
+SELECT 1 < 'null'::agtype;
+ ?column?
+----------
+
+(1 row)
+
+SELECT 1 > 'null'::agtype;
+ ?column?
+----------
+
+(1 row)
+
+SELECT 1 <= 'null'::agtype;
+ ?column?
+----------
+
+(1 row)
+
+SELECT 1 >= 'null'::agtype;
+ ?column?
+----------
+
+(1 row)
+
+SELECT agtype_any_eq('null'::agtype, 1);
+ agtype_any_eq
+---------------
+
+(1 row)
+
+SELECT agtype_any_ne('null'::agtype, 1);
+ agtype_any_ne
+---------------
+
+(1 row)
+
+SELECT agtype_any_lt('null'::agtype, 1);
+ agtype_any_lt
+---------------
+
+(1 row)
+
+SELECT agtype_any_gt('null'::agtype, 1);
+ agtype_any_gt
+---------------
+
+(1 row)
+
+SELECT agtype_any_le('null'::agtype, 1);
+ agtype_any_le
+---------------
+
+(1 row)
+
+SELECT agtype_any_ge('null'::agtype, 1);
+ agtype_any_ge
+---------------
+
+(1 row)
+
+--
-- Test orderability of comparison operators =, <>, <, >, <=, >=
-- These should all return true
-- Integer
diff --git a/regress/sql/agtype.sql b/regress/sql/agtype.sql
index fd9c194..f6ee3f3 100644
--- a/regress/sql/agtype.sql
+++ b/regress/sql/agtype.sql
@@ -133,6 +133,13 @@ SELECT agtype_div('4', '-3.0::numeric');
SELECT agtype_div('-4.0', '3::numeric');
SELECT agtype_div('4.0::numeric', '-3::numeric');
+SELECT agtype_mod('-11', '3');
+SELECT agtype_mod('11', '-3.0');
+SELECT agtype_mod('-11.0', '3');
+SELECT agtype_mod('11.0', '-3.0');
+SELECT agtype_mod('11', '-3.0::numeric');
+SELECT agtype_mod('-11.0', '3::numeric');
+SELECT agtype_mod('11.0::numeric', '-3::numeric');
SELECT agtype_pow('-2', '3');
SELECT agtype_pow('2', '-1.0');
@@ -148,7 +155,6 @@ SELECT agtype_pow('2.0::numeric', '-1.0::numeric');
-- Test overloaded agtype any mathematical operator functions
-- +, -, *, /, and %
--
-
SELECT agtype_any_add('1', -1);
SELECT agtype_any_add('1.0', -1);
SELECT agtype_any_add('1::numeric', 1);
@@ -168,6 +174,11 @@ SELECT agtype_any_div('-4', 3);
SELECT agtype_any_div('4.0', -3);
SELECT agtype_any_div('-4::numeric', 3);
SELECT agtype_any_div('-4.0::numeric', 3);
+
+SELECT agtype_any_mod('-11', 3);
+SELECT agtype_any_mod('11.0', -3);
+SELECT agtype_any_mod('-11::numeric', 3);
+SELECT agtype_any_mod('-11.0::numeric', 3);
--
-- Should fail with divide by zero
--
@@ -220,7 +231,6 @@ SELECT '3.14::numeric'::agtype + '3.14::numeric'::agtype;
--
-- Test overloaded agytype any operators +, -, *, /, %
--
-
SELECT '3'::agtype + 3;
SELECT '3.14'::agtype + 3;
SELECT '3.14::numeric'::agtype + 3;
@@ -257,6 +267,42 @@ SELECT 3 % '3.14'::agtype;
SELECT 3 % '3.14::numeric'::agtype;
--
+-- Test overloaded agytype any functions and operators for NULL input
+-- +, -, *, /, %, =, <>, <, >, <=, >=
+-- These should all return null
+SELECT agtype_any_add('null'::agtype, 1);
+SELECT agtype_any_sub('null'::agtype, 1);
+SELECT agtype_any_mul('null'::agtype, 1);
+SELECT agtype_any_div('null'::agtype, 1);
+SELECT agtype_any_mod('null'::agtype, 1);
+
+SELECT 1 + 'null'::agtype;
+SELECT 1 - 'null'::agtype;
+SELECT 1 * 'null'::agtype;
+SELECT 1 / 'null'::agtype;
+SELECT 1 % 'null'::agtype;
+
+SELECT agtype_any_add('null'::agtype, 1);
+SELECT agtype_any_sub('null'::agtype, 1);
+SELECT agtype_any_mul('null'::agtype, 1);
+SELECT agtype_any_div('null'::agtype, 1);
+SELECT agtype_any_mod('null'::agtype, 1);
+
+SELECT 1 = 'null'::agtype;
+SELECT 1 <> 'null'::agtype;
+SELECT 1 < 'null'::agtype;
+SELECT 1 > 'null'::agtype;
+SELECT 1 <= 'null'::agtype;
+SELECT 1 >= 'null'::agtype;
+
+SELECT agtype_any_eq('null'::agtype, 1);
+SELECT agtype_any_ne('null'::agtype, 1);
+SELECT agtype_any_lt('null'::agtype, 1);
+SELECT agtype_any_gt('null'::agtype, 1);
+SELECT agtype_any_le('null'::agtype, 1);
+SELECT agtype_any_ge('null'::agtype, 1);
+
+--
-- Test orderability of comparison operators =, <>, <, >, <=, >=
-- These should all return true
-- Integer
diff --git a/src/backend/utils/adt/agtype_ops.c b/src/backend/utils/adt/agtype_ops.c
index 21e8e3b..7cf0541 100644
--- a/src/backend/utils/adt/agtype_ops.c
+++ b/src/backend/utils/adt/agtype_ops.c
@@ -247,6 +247,11 @@ Datum agtype_any_add(PG_FUNCTION_ARGS)
lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+ if (lhs == NULL || rhs == NULL)
+ {
+ PG_RETURN_NULL();
+ }
+
result = DirectFunctionCall2(agtype_add, AGTYPE_P_GET_DATUM(lhs),
AGTYPE_P_GET_DATUM(rhs));
@@ -332,6 +337,11 @@ Datum agtype_any_sub(PG_FUNCTION_ARGS)
lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+ if (lhs == NULL || rhs == NULL)
+ {
+ PG_RETURN_NULL();
+ }
+
result = DirectFunctionCall2(agtype_sub, AGTYPE_P_GET_DATUM(lhs),
AGTYPE_P_GET_DATUM(rhs));
@@ -465,6 +475,11 @@ Datum agtype_any_mul(PG_FUNCTION_ARGS)
lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+ if (lhs == NULL || rhs == NULL)
+ {
+ PG_RETURN_NULL();
+ }
+
result = DirectFunctionCall2(agtype_mul, AGTYPE_P_GET_DATUM(lhs),
AGTYPE_P_GET_DATUM(rhs));
@@ -578,6 +593,11 @@ Datum agtype_any_div(PG_FUNCTION_ARGS)
lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+ if (lhs == NULL || rhs == NULL)
+ {
+ PG_RETURN_NULL();
+ }
+
result = DirectFunctionCall2(agtype_div, AGTYPE_P_GET_DATUM(lhs),
AGTYPE_P_GET_DATUM(rhs));
@@ -663,6 +683,11 @@ Datum agtype_any_mod(PG_FUNCTION_ARGS)
lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+ if (lhs == NULL || rhs == NULL)
+ {
+ PG_RETURN_NULL();
+ }
+
result = DirectFunctionCall2(agtype_mod, AGTYPE_P_GET_DATUM(lhs),
AGTYPE_P_GET_DATUM(rhs));
@@ -764,6 +789,11 @@ Datum agtype_any_eq(PG_FUNCTION_ARGS)
lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+ if (lhs == NULL || rhs == NULL)
+ {
+ PG_RETURN_NULL();
+ }
+
result = DirectFunctionCall2(agtype_eq, AGTYPE_P_GET_DATUM(lhs),
AGTYPE_P_GET_DATUM(rhs));
@@ -798,6 +828,11 @@ Datum agtype_any_ne(PG_FUNCTION_ARGS)
lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+ if (lhs == NULL || rhs == NULL)
+ {
+ PG_RETURN_NULL();
+ }
+
result = DirectFunctionCall2(agtype_ne, AGTYPE_P_GET_DATUM(lhs),
AGTYPE_P_GET_DATUM(rhs));
@@ -832,6 +867,11 @@ Datum agtype_any_lt(PG_FUNCTION_ARGS)
lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+ if (lhs == NULL || rhs == NULL)
+ {
+ PG_RETURN_NULL();
+ }
+
result = DirectFunctionCall2(agtype_lt, AGTYPE_P_GET_DATUM(lhs),
AGTYPE_P_GET_DATUM(rhs));
@@ -866,6 +906,11 @@ Datum agtype_any_gt(PG_FUNCTION_ARGS)
lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+ if (lhs == NULL || rhs == NULL)
+ {
+ PG_RETURN_NULL();
+ }
+
result = DirectFunctionCall2(agtype_gt, AGTYPE_P_GET_DATUM(lhs),
AGTYPE_P_GET_DATUM(rhs));
@@ -900,6 +945,11 @@ Datum agtype_any_le(PG_FUNCTION_ARGS)
lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+ if (lhs == NULL || rhs == NULL)
+ {
+ PG_RETURN_NULL();
+ }
+
result = DirectFunctionCall2(agtype_le, AGTYPE_P_GET_DATUM(lhs),
AGTYPE_P_GET_DATUM(rhs));
@@ -934,6 +984,11 @@ Datum agtype_any_ge(PG_FUNCTION_ARGS)
lhs = get_one_agtype_from_variadic_args(fcinfo, 0, 2);
rhs = get_one_agtype_from_variadic_args(fcinfo, 1, 1);
+ if (lhs == NULL || rhs == NULL)
+ {
+ PG_RETURN_NULL();
+ }
+
result = DirectFunctionCall2(agtype_ge, AGTYPE_P_GET_DATUM(lhs),
AGTYPE_P_GET_DATUM(rhs));